Merge pull request #23 from helium/kent-williams/migrate-disco-arduino-core-stm32l0

Migrate ST B-L072Z-LRWAN1 Examples to Arduino Core STM32L0
pull/24/head
Kent Williams 2020-05-29 15:57:45 -07:00 zatwierdzone przez GitHub
commit 20fad3aa59
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
6 zmienionych plików z 276 dodań i 964 usunięć

Wyświetl plik

@ -23,21 +23,6 @@ Once you save the lambda function, you will simply need to connect the lambda fu
Now you're done! Press the button and you should get a text message.
## 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)
## 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
@ -45,30 +30,30 @@ Arduino IDE:
[B-L072Z-LRWAN1 Product Page](https://www.st.com/en/evaluation-tools/b-l072z-lrwan1.html)
[B-L072Z-LRWAN1 User Manual](https://www.st.com/content/ccc/resource/technical/document/user_manual/group0/ac/62/15/c7/60/ac/4e/9c/DM00329995/files/DM00329995.pdf/jcr:content/translations/en.DM00329995.pdf)
## Programming (Uploading Method):
## Required Driver (Windows Only)
Download driver [here](https://www.st.com/en/development-tools/stsw-link009.html).
#### 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 Board Support & Library
### 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/148c4bc3646aaf71f8d9a0499c82fec4.png)
lib_deps =
MCCI LoRaWAN LMIC library
CayenneLPP
```
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

Wyświetl plik

@ -1,237 +1,101 @@
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#include "LoRaWAN.h"
#include "TimerMillis.h"
#include <CayenneLPP.h>
const char *devEui = "FILL_ME_IN";
const char *appEui = "FILL_ME_IN";
const char *appKey = "FILL_ME_IN";
// This should also be in little endian format
static const u1_t PROGMEM DEVEUI[8]= { FILL_ME_IN };
void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}
const uint32_t TX_INTERVAL = 15000;
TimerMillis timer_send;
// This should also be in little endian format
static const u1_t PROGMEM APPEUI[8]= { FILL_ME_IN };
void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}
// This key should be in big endian format
static const u1_t PROGMEM APPKEY[16] = { FILL_ME_IN };
void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);}
static uint8_t mydata[] = {0};
static osjob_t sendjob;
// Schedule TX every this many seconds (might become longer due to duty
// cycle limitations).
const unsigned TX_INTERVAL = 15;
// Pin mapping
#include "arduino_lmic_hal_boards.h"
// Pin mapping Discovery
const lmic_pinmap lmic_pins = *Arduino_LMIC::GetPinmap_Disco_L072cz_Lrwan1();
void printHex2(unsigned v) {
v &= 0xff;
if (v < 16)
Serial.print('0');
Serial.print(v, HEX);
}
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_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("AppSKey: ");
for (size_t i=0; i<sizeof(artKey); ++i) {
if (i != 0)
Serial.print("-");
printHex2(artKey[i]);
}
Serial.println("");
Serial.print("NwkSKey: ");
for (size_t i=0; i<sizeof(nwkKey); ++i) {
if (i != 0)
Serial.print("-");
printHex2(nwkKey[i]);
}
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;
case EV_TXCANCELED:
Serial.println(F("EV_TXCANCELED"));
break;
case EV_RXSTART:
/* do not print anything -- it wrecks timing */
break;
case EV_JOIN_TXCOMPLETE:
Serial.println(F("EV_JOIN_TXCOMPLETE: no JoinAccept"));
break;
default:
Serial.print(F("Unknown event: "));
Serial.println((unsigned) ev);
break;
}
}
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 update packet"));
} else {
mydata[0] = 0;
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, mydata, sizeof(mydata), 0);
Serial.println(F("Packet queued: Update Send"));
}
// Next TX is scheduled after TX_COMPLETE event.
}
bool async_send(){
// Check if there is not a current TX/RX job running
if (LMIC.opmode & OP_TXRXPEND) {
Serial.println(F("OP_TXRXPEND, not sending async send yet"));
return true;
} else {
mydata[0] = 1;
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, mydata, sizeof(mydata), 0);
Serial.println(F("Packet queued: Async Send"));
return false;
}
// Next TX is scheduled after TX_COMPLETE event.
}
// Max Payload 11 Bytes for DR 0
uint8_t payload[] = {0};
static volatile bool button_pushed;
static volatile bool uplink_attempted;
void push_button_ISR(){
button_pushed = true;
void push_button_ISR() { button_pushed = true; }
void async_timer_send() {
if (LoRaWAN.joined() && !LoRaWAN.busy()) {
Serial.println("Timer Send");
payload[0] = 0;
// Send Packet
LoRaWAN.sendPacket(1, payload, sizeof(payload));
uplink_attempted = true;
}
}
void setup() {
Serial.begin(9600);
Serial.println("Starting");
bool async_button_send() {
if (LoRaWAN.joined() && !LoRaWAN.busy()) {
Serial.println("Async Button Send");
payload[0] = 1;
// Send Packet
LoRaWAN.sendPacket(1, payload, sizeof(payload));
uplink_attempted = true;
return false;
} else {
return true;
}
}
SPI.setMOSI(RADIO_MOSI_PORT);
SPI.setMISO(RADIO_MISO_PORT);
SPI.setSCLK(RADIO_SCLK_PORT);
SPI.setSSEL(RADIO_NSS_PORT);
void setup(void) {
Serial.begin(9600);
while (!Serial) {
}
// Configure User Button
pinMode(USER_BTN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(USER_BTN), push_button_ISR, HIGH);
Serial.println("Setup Complete");
pinMode(BUTTON, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(BUTTON), push_button_ISR, FALLING);
// LMIC init
os_init();
// Reset the MAC state. Session and pending data transfers will be discarded.
LMIC_reset();
// US Region
LoRaWAN.begin(US915);
// Helium SubBand
LoRaWAN.setSubBand(2);
// Disable Adaptive Data Rate
LoRaWAN.setADR(false);
// Device IDs and Key
LoRaWAN.joinOTAA(appEui, appKey, devEui);
// 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);
Serial.println("JOIN( )");
LMIC_setLinkCheckMode(0);
LMIC_setDrTxpow(DR_SF7,14);
// Sub-band 2 - Helium Network
LMIC_selectSubBand(1); // zero indexed
while (!LoRaWAN.joined() && LoRaWAN.busy()) {
Serial.println("JOINING( )");
delay(5000);
}
Serial.println("JOINED( )");
// Start job (sending automatically starts OTAA too)
do_send(&sendjob);
// Start Continuous Uplink Timer
timer_send.start(async_timer_send, 0, TX_INTERVAL);
}
void loop() {
if(button_pushed) {
button_pushed = async_send();
}
os_runloop_once();
}
void loop(void) {
if (uplink_attempted) {
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(" )");
uplink_attempted = false;
}
if (button_pushed) {
button_pushed = async_button_send();
}
delay(500);
}

Wyświetl plik

@ -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,50 @@ 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 Driver (Windows Only)
Download driver [here](https://www.st.com/en/development-tools/stsw-link009.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/148c4bc3646aaf71f8d9a0499c82fec4.png)
lib_deps =
STM32duino LSM6DSO
STM32duino LIS2DW12
STM32duino STTS751
STM32duino LIS2MDL
STM32duino LPS22HH
STM32duino HTS221
MCCI LoRaWAN LMIC library
CayenneLPP
```
3. Open Boards Manager: Select Tools > Board: > Boards Manager...
4. Search for "Tlera Corp STM32L0 Boards"
5. Select the newest version and install.
### Temporary Manual Fix
This issue has been fixed but not released yet, until then you will need to insert three lines of code in a library file.
Insert the following:
```
#ifndef NULL
#define NULL 0
#endif
```
Into the file found here:
linux: /home/{user}/Arduino/libraries/IBM_LMIC_framework/src/lmic
windows: Documents/Arduino/libraries/IBM_LMIC_framework/src/lmic
mac os: Documents/Arduino/libraries/IBM_LMIC_framework/src/lmic
![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

Wyświetl plik

@ -1,39 +1,5 @@
/*******************************************************************************
* Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
* Copyright (c) 2018 Terry Moore, MCCI
*
* 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.
*
* 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 <SPI.h>
#include <arduino_lmic.h>
#include <arduino_lmic_hal_boards.h>
#include <arduino_lmic_hal_configuration.h>
#include <arduino_lmic_lorawan_compliance.h>
#include <arduino_lmic_user_configuration.h>
#include <hal/hal.h>
#include <lmic.h>
#include "LoRaWAN.h"
#include <CayenneLPP.h>
#include <LSM6DSOSensor.h>
#include <LIS2DW12Sensor.h>
@ -41,212 +7,18 @@
#include <LPS22HHSensor.h>
#include <STTS751Sensor.h>
#include <HTS221Sensor.h>
#include <CayenneLPP.h>
#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,111 +65,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(2);
// 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);
// Sub-band 2 - Helium Network
LMIC_selectSubBand(1); // zero indexed
// 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); //20 Seconds
}

Wyświetl plik

@ -1,30 +1,32 @@
# LongFi Arduino
## Installing the MCCI LMIC Library
From the Arduino IDE, open the Library Manager (Sketch->Include Library->Manage Libraries). In the search box, type MCCI and select the MCCI LoRaWAN LMIC library should be the first result.
![](https://developer.helium.com/static/library_manager-56bed2bb23b6f93e5cc3b25bdfd345a2.png)
## 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
# ST B-L072Z-LRWAN1 - Basic LongFi Example
[B-L072Z-LRWAN1 Product Page](https://www.st.com/en/evaluation-tools/b-l072z-lrwan1.html)
[B-L072Z-LRWAN1 User Manual](https://www.st.com/content/ccc/resource/technical/document/user_manual/group0/ac/62/15/c7/60/ac/4e/9c/DM00329995/files/DM00329995.pdf/jcr:content/translations/en.DM00329995.pdf)
## Programming (Uploading Method):
## Required Driver (Windows Only)
Download driver [here](https://www.st.com/en/development-tools/stsw-link009.html).
### B-L072Z-LRWAN1 - ST STM32L0 Discovery kit
#### 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 Board Support & Library
### Arduino Core for STM32L0
Arduino IDE:
Select Tools -> Upload Method -> STM32CubeProgrammer(SWD)
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.
```
https://grumpyoldpizza.github.io/ArduinoCore-stm32l0/package_stm32l0_boards_index.json
```
![arduino_preferences](https://i.gyazo.com/148c4bc3646aaf71f8d9a0499c82fec4.png)
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

Wyświetl plik

@ -1,321 +1,56 @@
/*******************************************************************************
* Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
* Copyright (c) 2018 Terry Moore, MCCI
*
* 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.
*
* 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.
*
*******************************************************************************/
#include "LoRaWAN.h"
/*******************************************************************************
*
* 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.
*
*******************************************************************************/
const char *devEui = "FILL_ME_IN";
const char *appEui = "FILL_ME_IN";
const char *appKey = "FILL_ME_IN";
#include <SPI.h>
#include <arduino_lmic.h>
#include <arduino_lmic_hal_boards.h>
#include <arduino_lmic_hal_configuration.h>
#include <arduino_lmic_lorawan_compliance.h>
#include <arduino_lmic_user_configuration.h>
#include <hal/hal.h>
#include <lmic.h>
// Max Payload 53 Bytes for DR 1
const uint8_t payload[] = "Hello, World!";
// 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); }
void setup( void )
{
Serial.begin(9600);
while (!Serial) { }
// 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); }
// US Region
LoRaWAN.begin(US915);
// Helium SubBand
LoRaWAN.setSubBand(2);
// 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);
// 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); }
Serial.println("JOIN( )");
}
static uint8_t mydata[] = "Hello, world!";
static osjob_t sendjob;
// 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"));
void loop( void )
{
if (LoRaWAN.joined() && !LoRaWAN.busy())
{
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("");
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(" )");
// Send Packet
LoRaWAN.sendPacket(1, payload, sizeof(payload));
}
// 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 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 {
// Prepare upstream data transmission at the next possible time.
LMIC_setTxData2(1, mydata, sizeof(mydata) - 1, 0);
Serial.println(F("Packet queued"));
}
// Next TX is scheduled after TX_COMPLETE event.
}
void setup() {
delay(5000);
while (!Serial)
;
Serial.begin(9600);
Serial.println(F("Starting"));
#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);
// Sub-band 2 - Helium Network
LMIC_selectSubBand(1); // zero indexed
// Start job (sending automatically starts OTAA too)
do_send(&sendjob);
}
void loop() { os_runloop_once(); }
namespace Arduino_LMIC {
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,
};
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); //20 Seconds
}