From 2a0ff4dceeadff47994951f073f13c8aab349aa4 Mon Sep 17 00:00:00 2001 From: Kent Wiliams Date: Mon, 11 May 2020 13:44:50 -0700 Subject: [PATCH] migrated cayenne sensor example to new lw lib --- .../longfi-us915-cayenne-sensor/README.md | 73 ++-- .../longfi-us915-cayenne-sensor.ino | 403 ++++-------------- 2 files changed, 107 insertions(+), 369 deletions(-) diff --git a/ST-B-L072Z-LRWAN1/longfi-us915-cayenne-sensor/README.md b/ST-B-L072Z-LRWAN1/longfi-us915-cayenne-sensor/README.md index 2731c68..92138c9 100644 --- a/ST-B-L072Z-LRWAN1/longfi-us915-cayenne-sensor/README.md +++ b/ST-B-L072Z-LRWAN1/longfi-us915-cayenne-sensor/README.md @@ -1,24 +1,7 @@ -# ST B-L072Z-LRWAN1 - Cayenne Example +# ST B-L072Z-LRWAN1 - Cayenne Sensor Example This example demonstrates sending motion and environmental sensor data in [CayenneLPP](https://developers.mydevices.com/cayenne/docs/lora/#lora-cayenne-low-power-payload) format, using a B-L072Z-LRWAN1 development board with a X-NUCLEO-IKS01A3 expansion shield, to the myDevices Cayenne dashboard. For more information on adding your device to the Helium network, visit our quickstart guide [here](https://developer.helium.com/console/quickstart). For more information on adding your device to myDevices Cayenne, visit our guide [here](https://developer.helium.com/console/integrations/mydevices-cayenne-integration). -## Required Arduino Libraries - -From the Arduino IDE, open the Library Manager (Sketch->Include Library->Manage Libraries). In the search box, type the library name below and install the latest version. - -[MCCI Arduino LoRaWAN Library](https://github.com/mcci-catena/arduino-lmic) -[CayenneLPP](https://github.com/ElectronicCats/CayenneLPP) -[X-NUCLEO-IKS01A3](https://github.com/stm32duino/X-NUCLEO-IKS01A3) - -## Required Arduino Board Support - -### B-L072Z-LRWAN1 - ST STM32L0 Discovery kit -Install board support package, find instructions [here](https://github.com/stm32duino/Arduino_Core_STM32#getting-started). - -Arduino IDE: -1. Select Tools -> Board: -> Discovery -2. Select Tools -> Board part number: -> Discovery L072Z-LRWAN1 - ## Required Hardware ### B-L072Z-LRWAN1 - ST STM32L0 Discovery kit @@ -30,36 +13,34 @@ Arduino IDE: [X-NUCLEO-IKS01A3 Product Page](https://www.st.com/en/ecosystems/x-nucleo-iks01a3.html) [X-NUCLEO-IKS01A3 User Manual](https://www.st.com/resource/en/user_manual/dm00601501-getting-started-with-the-xnucleoiks01a3-motion-mems-and-environmental-sensor-expansion-board-for-stm32-nucleo-stmicroelectronics.pdf) -## Programming (Uploading Method): -#### STM32CubeProgrammer(SWD) -Will use onboard ST-Link(Flasher/Debugger) to upload sketch. -Download and Install required utility from ST [here](https://www.st.com/en/development-tools/stm32cubeprog.html). +## Required Arduino Libraries +From the Arduino IDE, open the Library Manager (Sketch->Include Library->Manage Libraries). In the search box, type the library name below and install the latest version. + +[X-NUCLEO-IKS01A3](https://github.com/stm32duino/X-NUCLEO-IKS01A3) + +## Required Board Support + +### Arduino Core for STM32L0 Arduino IDE: -Select Tools -> Upload Method -> STM32CubeProgrammer(SWD) - -### PlatformIO Support - -The PlatformIO Board file for this board is currently using the incorrect OpenOCD (Upload/Debug) -script for the microcontroller on this board. We are in the process of pushing a fix upstream. When -uploading or debugging, hold the reset button down right until the upload or debug process initiates -it's routine in communicating with the board, this seems to aleviate the issue for right now. - -`platformio.ini` +1. Navigate to (File > Preferences) +Find the section at the bottom called Additional Boards Manager URLs: +2. Add the URL below to the list and click ok to close the preferences. ``` -[env:disco_l072cz_lrwan1] -platform = ststm32 -board = disco_l072cz_lrwan1 -framework = arduino +https://grumpyoldpizza.github.io/ArduinoCore-stm32l0/package_stm32l0_boards_index.json +``` +![arduino_preferences](https://i.gyazo.com/558b58a463578b28e17ffb763a592c69.png) -lib_deps = - STM32duino LSM6DSO - STM32duino LIS2DW12 - STM32duino STTS751 - STM32duino LIS2MDL - STM32duino LPS22HH - STM32duino HTS221 - MCCI LoRaWAN LMIC library - CayenneLPP -``` \ No newline at end of file +3. Open Boards Manager: Select Tools > Board: > Boards Manager... +4. Search for "Tlera Corp STM32L0 Boards" +5. Select the newest version and install. + +![arduino_board_support](https://i.gyazo.com/216457ad64b8f85016d1b6d7cc6df044.png) +## Programming (Uploading): + +Arduino IDE: +1. Select Board: Tools > Board: > B-L072Z-LRWAN1 +2. Select Port: Tools > Port > COM# or /dev/ttyACM#(B-L072Z-LRWAN1) +3. Upload Sketch: Select > Upload +4. (Optional) View Serial Debug Output: Tools > Serial Monitor > 9600 baud \ No newline at end of file diff --git a/ST-B-L072Z-LRWAN1/longfi-us915-cayenne-sensor/longfi-us915-cayenne-sensor.ino b/ST-B-L072Z-LRWAN1/longfi-us915-cayenne-sensor/longfi-us915-cayenne-sensor.ino index 3c77094..d3a5bc8 100644 --- a/ST-B-L072Z-LRWAN1/longfi-us915-cayenne-sensor/longfi-us915-cayenne-sensor.ino +++ b/ST-B-L072Z-LRWAN1/longfi-us915-cayenne-sensor/longfi-us915-cayenne-sensor.ino @@ -1,39 +1,32 @@ -/******************************************************************************* - * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman - * Copyright (c) 2018 Terry Moore, MCCI +/* Simple OTAA join for a LoRaWAN network + * + * In setup() below please replace the argument to LoRaWAN.begin() + * with your appropriate region specific band: * - * Permission is hereby granted, free of charge, to anyone - * obtaining a copy of this document and accompanying files, - * to do whatever they want with them without any restriction, - * including, but not limited to, copying, modification and redistribution. - * NO WARRANTY OF ANY KIND IS PROVIDED. + * AS923 + * AU915 + * EU868 + * IN865 + * KR920 + * US915 * - * This example sends a valid LoRaWAN packet with payload "Hello, - * world!", using frequency and encryption settings matching those of - * the The Things Network. It's pre-configured for the Adafruit - * Feather M0 LoRa. - * - *******************************************************************************/ - -/******************************************************************************* - * - * For Helium developers, follow the Arduino Quickstart guide: - * https://developer.helium.com/device/arduino-quickstart - * TLDR: register your device on the console: - * https://console.helium.com/devices - * - * The App EUI (as lsb) and App Key (as msb) get inserted below. - * - *******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include + * AU915/US915 networks have 64+8 channels. Typical gateways support only + * 8 (9) channels. Hence it's a good idea to pick the proper channel + * subset via select via LoRaWAN.setSubBand(), + * + * EU868/IN865 have duty cycle restrictions. For debugging it makes sense + * to disable those via setDutyCycle(false); + * + * For an external antenna one should set the proper antenna gain + * (default is 2.0) via setAntennaGain(). + * + * Please edit the keys below as they are just debugging samples. + * + * + * This example code is in the public domain. + */ +#include "LoRaWAN.h" +#include #include #include @@ -41,212 +34,18 @@ #include #include #include -#include -#ifdef ARDUINO_SAM_DUE -#define DEV_I2C Wire1 -#elif defined(ARDUINO_ARCH_STM32) -#define DEV_I2C Wire -#else -#define DEV_I2C Wire -#endif +const char *devEui = "FILL_ME_IN"; +const char *appEui = "FILL_ME_IN"; +const char *appKey = "FILL_ME_IN"; // Sensors LSM6DSOSensor *AccGyr; LPS22HHSensor *PressTemp; HTS221Sensor *HumTemp; -// This is the "App EUI" in Helium. Make sure it is little-endian (lsb). -static const u1_t PROGMEM APPEUI[8] = {FILL_ME_IN}; -void os_getArtEui(u1_t *buf) { memcpy_P(buf, APPEUI, 8); } - -// This should also be in little endian format -// These are user configurable values and Helium console permits anything -static const u1_t PROGMEM DEVEUI[8] = {FILL_ME_IN}; -void os_getDevEui(u1_t *buf) { memcpy_P(buf, DEVEUI, 8); } - -// This is the "App Key" in Helium. It is big-endian (msb). -static const u1_t PROGMEM APPKEY[16] = {FILL_ME_IN}; -void os_getDevKey(u1_t *buf) { memcpy_P(buf, APPKEY, 16); } - +// Init CayenneLPP Payload CayenneLPP lpp(51); -static osjob_t sendjob; -void do_send(osjob_t *j); - -// Schedule TX every this many seconds (might become longer due to duty -// cycle limitations). -const unsigned TX_INTERVAL = 60; - -// Pin mapping -// -// Adafruit BSPs are not consistent -- m0 express defs ARDUINO_SAMD_FEATHER_M0, -// m0 defs ADAFRUIT_FEATHER_M0 -// -#if defined(ARDUINO_SAMD_FEATHER_M0) || defined(ADAFRUIT_FEATHER_M0) -// Pin mapping for Adafruit Feather M0 LoRa, etc. -const lmic_pinmap lmic_pins = { - .nss = 8, - .rxtx = LMIC_UNUSED_PIN, - .rst = 4, - .dio = {3, 6, LMIC_UNUSED_PIN}, - .rxtx_rx_active = 0, - .rssi_cal = 8, // LBT cal for the Adafruit Feather M0 LoRa, in dB - .spi_freq = 8000000, -}; -#elif defined(ARDUINO_AVR_FEATHER32U4) -// Pin mapping for Adafruit Feather 32u4 LoRa, etc. -// Just like Feather M0 LoRa, but uses SPI at 1MHz; and that's only -// because MCCI doesn't have a test board; probably higher frequencies -// will work. -const lmic_pinmap lmic_pins = { - .nss = 8, - .rxtx = LMIC_UNUSED_PIN, - .rst = 4, - .dio = {7, 6, LMIC_UNUSED_PIN}, - .rxtx_rx_active = 0, - .rssi_cal = 8, // LBT cal for the Adafruit Feather 32U4 LoRa, in dB - .spi_freq = 1000000, -}; -#elif defined(ARDUINO_CATENA_4551) -// Pin mapping for Murata module / Catena 4551 -const lmic_pinmap lmic_pins = { - .nss = 7, - .rxtx = 29, - .rst = 8, - .dio = - { - 25, // DIO0 (IRQ) is D25 - 26, // DIO1 is D26 - 27, // DIO2 is D27 - }, - .rxtx_rx_active = 1, - .rssi_cal = 10, - .spi_freq = 8000000 // 8MHz -}; -#elif defined(MCCI_CATENA_4610) -#include "arduino_lmic_hal_boards.h" -const lmic_pinmap lmic_pins = *Arduino_LMIC::GetPinmap_Catena4610(); -#elif defined(ARDUINO_DISCO_L072CZ_LRWAN1) -const lmic_pinmap lmic_pins = *Arduino_LMIC::GetPinmap_Disco_L072cz_Lrwan1(); -#else -#error "Unknown target" -#endif - -void onEvent(ev_t ev) { - Serial.print(os_getTime()); - Serial.print(": "); - switch (ev) { - case EV_SCAN_TIMEOUT: - Serial.println(F("EV_SCAN_TIMEOUT")); - break; - case EV_BEACON_FOUND: - Serial.println(F("EV_BEACON_FOUND")); - break; - case EV_BEACON_MISSED: - Serial.println(F("EV_BEACON_MISSED")); - break; - case EV_BEACON_TRACKED: - Serial.println(F("EV_BEACON_TRACKED")); - break; - case EV_JOINING: - Serial.println(F("EV_JOINING")); - break; - case EV_JOIN_TXCOMPLETE: - Serial.println(F("EV_JOIN_TXCOMPLETE")); - break; - case EV_JOINED: - Serial.println(F("EV_JOINED")); - { - u4_t netid = 0; - devaddr_t devaddr = 0; - u1_t nwkKey[16]; - u1_t artKey[16]; - LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey); - Serial.print("netid: "); - Serial.println(netid, DEC); - Serial.print("devaddr: "); - Serial.println(devaddr, HEX); - Serial.print("artKey: "); - for (size_t i = 0; i < sizeof(artKey); ++i) { - if (i != 0) - Serial.print("-"); - Serial.print(artKey[i], HEX); - } - Serial.println(""); - Serial.print("nwkKey: "); - for (size_t i = 0; i < sizeof(nwkKey); ++i) { - if (i != 0) - Serial.print("-"); - Serial.print(nwkKey[i], HEX); - } - Serial.println(""); - } - // Disable link check validation (automatically enabled - // during join, but because slow data rates change max TX - // size, we don't use it in this example. - LMIC_setLinkCheckMode(0); - break; - /* - || This event is defined but not used in the code. No - || point in wasting codespace on it. - || - || case EV_RFU1: - || Serial.println(F("EV_RFU1")); - || break; - */ - case EV_JOIN_FAILED: - Serial.println(F("EV_JOIN_FAILED")); - break; - case EV_REJOIN_FAILED: - Serial.println(F("EV_REJOIN_FAILED")); - break; - break; - case EV_TXCOMPLETE: - Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); - if (LMIC.txrxFlags & TXRX_ACK) - Serial.println(F("Received ack")); - if (LMIC.dataLen) { - Serial.println(F("Received ")); - Serial.println(LMIC.dataLen); - Serial.println(F(" bytes of payload")); - } - // Schedule next transmission - os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), - do_send); - break; - case EV_LOST_TSYNC: - Serial.println(F("EV_LOST_TSYNC")); - break; - case EV_RESET: - Serial.println(F("EV_RESET")); - break; - case EV_RXCOMPLETE: - // data received in ping slot - Serial.println(F("EV_RXCOMPLETE")); - break; - case EV_LINK_DEAD: - Serial.println(F("EV_LINK_DEAD")); - break; - case EV_LINK_ALIVE: - Serial.println(F("EV_LINK_ALIVE")); - break; - /* - || This event is defined but not used in the code. No - || point in wasting codespace on it. - || - || case EV_SCAN_FOUND: - || Serial.println(F("EV_SCAN_FOUND")); - || break; - */ - case EV_TXSTART: - Serial.println(F("EV_TXSTART")); - break; - default: - Serial.print(F("Unknown event: ")); - Serial.println((unsigned)ev); - break; - } -} void readSensors() { // Read humidity and temperature. @@ -293,110 +92,68 @@ void readSensors() { Serial.print(" "); Serial.print(gyroscope[1]); Serial.print(" "); - Serial.print(gyroscope[2]); + Serial.println(gyroscope[2]); } -void do_send(osjob_t *j) { - // Check if there is not a current TX/RX job running - if (LMIC.opmode & OP_TXRXPEND) { - Serial.println(F("OP_TXRXPEND, not sending")); - } else { - readSensors(); - // Prepare upstream data transmission at the next possible time. - LMIC_setTxData2(1, lpp.getBuffer(), lpp.getSize(), 0); - Serial.println(F("Packet queued")); - } - // Next TX is scheduled after TX_COMPLETE event. -} +void setup( void ) +{ + Serial.begin(9600); + + while (!Serial) { } -void setup() { // Initialize I2C bus. - DEV_I2C.begin(); + Wire.begin(); - AccGyr = new LSM6DSOSensor (&DEV_I2C); + // Enable Sensors + AccGyr = new LSM6DSOSensor (&Wire); AccGyr->Enable_X(); AccGyr->Enable_G(); - PressTemp = new LPS22HHSensor(&DEV_I2C); + PressTemp = new LPS22HHSensor(&Wire); PressTemp->Enable(); - HumTemp = new HTS221Sensor (&DEV_I2C); + HumTemp = new HTS221Sensor (&Wire); HumTemp->Enable(); - delay(5000); - while (!Serial) - ; - Serial.begin(9600); - Serial.println(F("Starting")); + // US Region + LoRaWAN.begin(US915); + // Helium SubBand + LoRaWAN.setSubBand(7); + // Disable Adaptive Data Rate + LoRaWAN.setADR(false); + // Set Data Rate 1 - Max Payload 53 Bytes + LoRaWAN.setDataRate(1); + // Device IDs and Key + LoRaWAN.joinOTAA(appEui, appKey, devEui); -#if defined(ARDUINO_DISCO_L072CZ_LRWAN1) - SPI.setMOSI(RADIO_MOSI_PORT); - SPI.setMISO(RADIO_MISO_PORT); - SPI.setSCLK(RADIO_SCLK_PORT); - SPI.setSSEL(RADIO_NSS_PORT); -// SPI.begin(); -#endif - -#ifdef VCC_ENABLE - // For Pinoccio Scout boards - pinMode(VCC_ENABLE, OUTPUT); - digitalWrite(VCC_ENABLE, HIGH); - delay(1000); -#endif - - // LMIC init - os_init(); - // Reset the MAC state. Session and pending data transfers will be discarded. - LMIC_reset(); - - // allow much more clock error than the X/1000 default. See: - // https://github.com/mcci-catena/arduino-lorawan/issues/74#issuecomment-462171974 - // https://github.com/mcci-catena/arduino-lmic/commit/42da75b56#diff-16d75524a9920f5d043fe731a27cf85aL633 - // the X/1000 means an error rate of 0.1%; the above issue discusses using - // values up to 10%. so, values from 10 (10% error, the most lax) to 1000 - // (0.1% error, the most strict) can be used. - LMIC_setClockError(1 * MAX_CLOCK_ERROR / 40); - - LMIC_setLinkCheckMode(0); - LMIC_setDrTxpow(DR_SF8, 20); - LMIC_selectSubBand(6); - - // Start job (sending automatically starts OTAA too) - do_send(&sendjob); + Serial.println("JOIN( )"); } -void loop() { os_runloop_once(); } +void loop( void ) +{ + if (LoRaWAN.joined() && !LoRaWAN.busy()) + { + Serial.print("TRANSMIT( "); + Serial.print("TimeOnAir: "); + Serial.print(LoRaWAN.getTimeOnAir()); + Serial.print(", NextTxTime: "); + Serial.print(LoRaWAN.getNextTxTime()); + Serial.print(", MaxPayloadSize: "); + Serial.print(LoRaWAN.getMaxPayloadSize()); + Serial.print(", DR: "); + Serial.print(LoRaWAN.getDataRate()); + Serial.print(", TxPower: "); + Serial.print(LoRaWAN.getTxPower(), 1); + Serial.print("dbm, UpLinkCounter: "); + Serial.print(LoRaWAN.getUpLinkCounter()); + Serial.print(", DownLinkCounter: "); + Serial.print(LoRaWAN.getDownLinkCounter()); + Serial.println(" )"); -namespace Arduino_LMIC { + // Read Sensor Values + readSensors(); -class HalConfiguration_Disco_L072cz_Lrwan1_t : public HalConfiguration_t { -public: - enum DIGITAL_PINS : uint8_t { - PIN_SX1276_NSS = 37, - PIN_SX1276_NRESET = 33, - PIN_SX1276_DIO0 = 38, - PIN_SX1276_DIO1 = 39, - PIN_SX1276_DIO2 = 40, - PIN_SX1276_RXTX = 21, - }; + // Send Packet + LoRaWAN.sendPacket(1, lpp.getBuffer(), lpp.getSize()); + } - virtual bool queryUsingTcxo(void) override { return false; }; -}; -// save some typing by bringing the pin numbers into scope -static HalConfiguration_Disco_L072cz_Lrwan1_t myConfig; - -static const HalPinmap_t myPinmap = { - .nss = HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_NSS, - .rxtx = HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_RXTX, - .rst = HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_NRESET, - - .dio = - { - HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_DIO0, - HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_DIO1, - HalConfiguration_Disco_L072cz_Lrwan1_t::PIN_SX1276_DIO2, - }, - .rxtx_rx_active = 1, - .rssi_cal = 10, - .spi_freq = 8000000, /* 8MHz */ - .pConfig = &myConfig}; - -}; // end namespace Arduino_LMIC + delay(20000); +} \ No newline at end of file