├── LICENSE ├── README.md ├── assets ├── radioenge-chip.png └── radioenge.png └── examples ├── Radioenge_Blink └── Radioenge_Blink.ino ├── Radioenge_ttn_abp └── Radioenge_ttn_abp.ino └── Radioenge_ttn_otaa └── Radioenge_ttn_otaa.ino /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Luiz Henrique Cassettari 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RadioEnge Module 2 | 3 | This is a reverse engineering project to make possible to program the RadioEnge LoRa Module on the Arduino IDE using [Arduino_Core_STM32](https://github.com/stm32duino/Arduino_Core_STM32). 4 | 5 | * This board works stable with [Arduino_Core_STM32 v1.8.0](https://github.com/stm32duino/Arduino_Core_STM32/releases) and [STM32 - arduino-lmic v3.1.0](https://github.com/ricaun/arduino-lmic). 6 | 7 | ## Board 8 | 9 | The board use the `stm32l071cz` mcu with the `sx1272` lora module, the pins connections is like the image below. 10 | 11 | chip 12 | 13 | ## Pinouts 14 | 15 | This image shows the pins of the mcu. 16 | 17 | chip 18 | 19 | ## Arduino IDE 20 | 21 | It's possible to burn and create your firmware using the Arduino IDE using the [Arduino_Core_STM32](https://github.com/stm32duino/Arduino_Core_STM32). Is not possible to burn the firwmare using the Serial, the BOOT0 pin is not accessible in this board, but is possible to use the SWD to programing the mcu, you need ST-LINK to do the job. 22 | 23 | You need to install the [STM32Cube MCU Packages](https://www.st.com/en/embedded-software/stm32cube-mcu-packages.html) or [STM32CubeProg](https://www.st.com/content/st_com/en/products/development-tools/software-development-tools/stm32-software-development-tools/stm32-programmers/stm32cubeprog.html) to be able to erase the original firmware, the original firmware is not available to re-burn, this process is irreversible. 24 | 25 | After installing the STM32CubeProgrammer, connect the ST-LINK. if your ST-LINK is new the STM32CubeProgrammer probably gonna update the ST-LINK firmware. 26 | 27 | Next, you need to connect the GND, SWDIO, SWCLK, and VCC of the ST-LINK to the Radioenge module, check the pinout of the module, you need to solder some pins to make easier. 28 | 29 | If you connect everything and tries to connect to the device you should get some error. 30 | 31 | You need to hold the reset pin to the GND and press to connect, then pull off the reset. 32 | 33 | The connection should be a success. 34 | 35 | Now you need to go on the OB (Option Bytes) and find the Read Out Protection (RDP) the value should be BB. Change to AA to remove the protection and press Apply. The board should be erased and is ready to work with the Arduino IDE. 36 | 37 | ### What board 38 | 39 | The [STM32Cube MCU Packages](https://www.st.com/en/embedded-software/stm32cube-mcu-packages.html) does not have the exactly mcu (stm32l071cz), but is possible to use some similar to make works. 40 | 41 | You can use the `stm32l073`, the pinout is really similar and should work like a charm. 42 | 43 | Select the board `Nucleo-64` and board part number `Nucleo L073RZ`. You need to change the upload method to 44 | `STM32CubeProgrammer (SWD)`. 45 | 46 | Now is possible to burn some blick example. 47 | 48 | Default Serial is on the pins GPIO0 and GPIO1. 49 | 50 | ### Pinout - IOs 51 | 52 |
 53 | #define RX_1	                PB7
 54 | #define TX_1	                PB6
 55 | 
 56 | #define GPIO0	                PA3
 57 | #define GPIO1	                PA2
 58 | #define GPIO2	                PA15
 59 | #define GPIO3	                PA10
 60 | #define GPIO4	                PA9
 61 | #define GPIO5	                PA8
 62 | #define GPIO6	                PB15
 63 | #define GPIO7	                PA0
 64 | #define GPIO8	                PA1
 65 | #define GPIO9	                PB11
 66 | 
 67 | #define LED_RED                 PB5
 68 | #define LED_GREEN               PB8
 69 | #define LED_YELLOW              PB9
 70 | 
71 | 72 | ## LoRa 73 | 74 | The original lmic part is a little unstable, `noInterrupt()` break the program and stops working. 75 | 76 | You need to download my version of the [arduino-lmic v3.1.0](https://github.com/ricaun/arduino-lmic) library. 77 | 78 | Remember you need to change the config file of the lmic library and define `CFG_sx1272_radio`. 79 | 80 | ### Pinout - Radio LoRa 81 | 82 |
 83 | #define RADIO_RESET_PORT        PB14
 84 | #define RADIO_MOSI_PORT         PA7
 85 | #define RADIO_MISO_PORT         PA6
 86 | #define RADIO_SCLK_PORT         PA5
 87 | #define RADIO_NSS_PORT          PA4
 88 | 
 89 | #define RADIO_DIO_0_PORT        PB10
 90 | #define RADIO_DIO_1_PORT        PB2
 91 | #define RADIO_DIO_2_PORT        PB1
 92 | #define RADIO_DIO_3_PORT        PB0
 93 | 
 94 | #define RADIO_RXTX_PORT         PB13
 95 | #define RADIO_RXTX2_PORT        PB12
 96 | 
97 | 98 | ### LMIC 99 | 100 | #### lmic_project_config.h 101 | 102 |
103 | #define CFG_au915 1
104 | #define CFG_sx1272_radio 1
105 | 
106 | 107 | #### lmic_pinmap 108 |
109 | const lmic_pinmap lmic_pins = {
110 |   .nss = RADIO_NSS_PORT,
111 |   .rxtx = RADIO_RXTX_PORT,
112 |   .rst = RADIO_RESET_PORT,
113 |   .dio = {RADIO_DIO_0_PORT, RADIO_DIO_1_PORT, RADIO_DIO_2_PORT},
114 |   .rxtx_rx_active = 1,
115 | };
116 | 
117 | 118 | #### setup 119 | 120 |
121 | pinMode(RADIO_RXTX2_PORT, OUTPUT);
122 | digitalWrite(RADIO_RXTX2_PORT, LOW);
123 | 
124 | 125 | ---- 126 | 127 | See news and other projects about LoRa on my [blog](http://loranow.com). 128 | -------------------------------------------------------------------------------- /assets/radioenge-chip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricaun/Radioenge-Module/e958b19e7fba715005ec2c8900aaed2c8d1d5b7e/assets/radioenge-chip.png -------------------------------------------------------------------------------- /assets/radioenge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ricaun/Radioenge-Module/e958b19e7fba715005ec2c8900aaed2c8d1d5b7e/assets/radioenge.png -------------------------------------------------------------------------------- /examples/Radioenge_Blink/Radioenge_Blink.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Radioenge Blink example 3 | */ 4 | 5 | #define LED_RED PB5 6 | #define LED_GREEN PB8 7 | #define LED_YELLOW PB9 8 | 9 | void setup() 10 | { 11 | Serial.begin(115200); 12 | Serial.println(); 13 | pinMode(LED_RED, OUTPUT); 14 | pinMode(LED_GREEN, OUTPUT); 15 | pinMode(LED_YELLOW, OUTPUT); 16 | } 17 | 18 | 19 | void loop() 20 | { 21 | digitalWrite(LED_RED, !digitalRead(LED_RED)); 22 | digitalWrite(LED_GREEN, !digitalRead(LED_GREEN)); 23 | digitalWrite(LED_YELLOW, !digitalRead(LED_YELLOW)); 24 | delay(100); 25 | } 26 | -------------------------------------------------------------------------------- /examples/Radioenge_ttn_abp/Radioenge_ttn_abp.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman 3 | * Copyright (c) 2018 Terry Moore, MCCI 4 | * 5 | * Permission is hereby granted, free of charge, to anyone 6 | * obtaining a copy of this document and accompanying files, 7 | * to do whatever they want with them without any restriction, 8 | * including, but not limited to, copying, modification and redistribution. 9 | * NO WARRANTY OF ANY KIND IS PROVIDED. 10 | * 11 | * This example sends a valid LoRaWAN packet with payload "Hello, 12 | * world!", using frequency and encryption settings matching those of 13 | * the The Things Network. 14 | * 15 | * This uses ABP (Activation-by-personalisation), where a DevAddr and 16 | * Session keys are preconfigured (unlike OTAA, where a DevEUI and 17 | * application key is configured, while the DevAddr and session keys are 18 | * assigned/generated in the over-the-air-activation procedure). 19 | * 20 | * Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in 21 | * g1, 0.1% in g2), but not the TTN fair usage policy (which is probably 22 | * violated by this sketch when left running for longer)! 23 | * 24 | * To use this sketch, first register your application and device with 25 | * the things network, to set or generate a DevAddr, NwkSKey and 26 | * AppSKey. Each device should have their own unique values for these 27 | * fields. 28 | * 29 | * Do not forget to define the radio type correctly in 30 | * arduino-lmic/project_config/lmic_project_config.h or from your BOARDS.txt. 31 | * 32 | *******************************************************************************/ 33 | 34 | /******************************************************************************* 35 | Exemplo da ttn abp para o modulo da Radioenge. 36 | Versão da lmic v2.3.2 - https://github.com/mcci-catena/arduino-lmic/archive/v2.3.2.zip 37 | Modificar o arquivo lmic_project_config.h, mudar a frequencia e chip 38 | #define CFG_au921 1 39 | #define CFG_sx1272_radio 1 40 | *******************************************************************************/ 41 | 42 | #define RX_1 PB7 43 | #define TX_1 PB6 44 | 45 | #define GPIO0 PA3 46 | #define GPIO1 PA2 47 | #define GPIO2 PA15 48 | #define GPIO3 PA10 49 | #define GPIO4 PA9 50 | #define GPIO5 PA8 51 | #define GPIO6 PB15 52 | #define GPIO7 PA0 53 | #define GPIO8 PA1 54 | #define GPIO9 PB11 55 | 56 | /*******************************************************************************/ 57 | 58 | #define LED_RED PB5 59 | #define LED_GREEN PB8 60 | #define LED_YELLOW PB9 61 | 62 | #define RADIO_RESET_PORT PB14 63 | #define RADIO_MOSI_PORT PA7 64 | #define RADIO_MISO_PORT PA6 65 | #define RADIO_SCLK_PORT PA5 66 | #define RADIO_NSS_PORT PA4 67 | 68 | #define RADIO_DIO_0_PORT PB10 69 | #define RADIO_DIO_1_PORT PB2 70 | #define RADIO_DIO_2_PORT PB1 71 | #define RADIO_DIO_3_PORT PB0 72 | 73 | #define RADIO_RXTX_PORT PB13 74 | #define RADIO_RXTX2_PORT PB12 75 | 76 | /*******************************************************************************/ 77 | 78 | #include 79 | #include 80 | #include 81 | 82 | // 83 | // For normal use, we require that you edit the sketch to replace FILLMEIN 84 | // with values assigned by the TTN console. However, for regression tests, 85 | // we want to be able to compile these scripts. The regression tests define 86 | // COMPILE_REGRESSION_TEST, and in that case we define FILLMEIN to a non- 87 | // working but innocuous value. 88 | // 89 | #ifdef COMPILE_REGRESSION_TEST 90 | # define FILLMEIN 0 91 | #else 92 | # warning "You must replace the values marked FILLMEIN with real values from the TTN control panel!" 93 | # define FILLMEIN (#dont edit this, edit the lines that use FILLMEIN) 94 | #endif 95 | 96 | // LoRaWAN NwkSKey, network session key 97 | static const PROGMEM u1_t NWKSKEY[16] = { FILLMEIN }; 98 | 99 | // LoRaWAN AppSKey, application session key 100 | static const u1_t PROGMEM APPSKEY[16] = { FILLMEIN }; 101 | 102 | // LoRaWAN end-device address (DevAddr) 103 | // See http://thethingsnetwork.org/wiki/AddressSpace 104 | // The library converts the address to network byte order as needed. 105 | static const u4_t DEVADDR = 0x00000000 ; // <-- Change this address for every node! 106 | 107 | // These callbacks are only used in over-the-air activation, so they are 108 | // left empty here (we cannot leave them out completely unless 109 | // DISABLE_JOIN is set in arduino-lmic/project_config/lmic_project_config.h, 110 | // otherwise the linker will complain). 111 | void os_getArtEui (u1_t* buf) { } 112 | void os_getDevEui (u1_t* buf) { } 113 | void os_getDevKey (u1_t* buf) { } 114 | 115 | static uint8_t mydata[] = "Hello, world!"; 116 | static osjob_t sendjob; 117 | 118 | // Schedule TX every this many seconds (might become longer due to duty 119 | // cycle limitations). 120 | const unsigned TX_INTERVAL = 60; 121 | 122 | // Pin mapping 123 | const lmic_pinmap lmic_pins = { 124 | .nss = RADIO_NSS_PORT, 125 | .rxtx = RADIO_RXTX_PORT, 126 | .rst = RADIO_RESET_PORT, 127 | .dio = {RADIO_DIO_0_PORT, RADIO_DIO_1_PORT, RADIO_DIO_2_PORT}, 128 | .rxtx_rx_active = 1, 129 | }; 130 | 131 | void onEvent (ev_t ev) { 132 | Serial.print(os_getTime()); 133 | Serial.print(": "); 134 | switch(ev) { 135 | case EV_SCAN_TIMEOUT: 136 | Serial.println(F("EV_SCAN_TIMEOUT")); 137 | break; 138 | case EV_BEACON_FOUND: 139 | Serial.println(F("EV_BEACON_FOUND")); 140 | break; 141 | case EV_BEACON_MISSED: 142 | Serial.println(F("EV_BEACON_MISSED")); 143 | break; 144 | case EV_BEACON_TRACKED: 145 | Serial.println(F("EV_BEACON_TRACKED")); 146 | break; 147 | case EV_JOINING: 148 | Serial.println(F("EV_JOINING")); 149 | break; 150 | case EV_JOINED: 151 | Serial.println(F("EV_JOINED")); 152 | break; 153 | /* 154 | || This event is defined but not used in the code. No 155 | || point in wasting codespace on it. 156 | || 157 | || case EV_RFU1: 158 | || Serial.println(F("EV_RFU1")); 159 | || break; 160 | */ 161 | case EV_JOIN_FAILED: 162 | Serial.println(F("EV_JOIN_FAILED")); 163 | break; 164 | case EV_REJOIN_FAILED: 165 | Serial.println(F("EV_REJOIN_FAILED")); 166 | break; 167 | case EV_TXCOMPLETE: 168 | Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)")); 169 | if (LMIC.txrxFlags & TXRX_ACK) 170 | Serial.println(F("Received ack")); 171 | if (LMIC.dataLen) { 172 | Serial.println(F("Received ")); 173 | Serial.println(LMIC.dataLen); 174 | Serial.println(F(" bytes of payload")); 175 | } 176 | // Schedule next transmission 177 | os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send); 178 | break; 179 | case EV_LOST_TSYNC: 180 | Serial.println(F("EV_LOST_TSYNC")); 181 | break; 182 | case EV_RESET: 183 | Serial.println(F("EV_RESET")); 184 | break; 185 | case EV_RXCOMPLETE: 186 | // data received in ping slot 187 | Serial.println(F("EV_RXCOMPLETE")); 188 | break; 189 | case EV_LINK_DEAD: 190 | Serial.println(F("EV_LINK_DEAD")); 191 | break; 192 | case EV_LINK_ALIVE: 193 | Serial.println(F("EV_LINK_ALIVE")); 194 | break; 195 | /* 196 | || This event is defined but not used in the code. No 197 | || point in wasting codespace on it. 198 | || 199 | || case EV_SCAN_FOUND: 200 | || Serial.println(F("EV_SCAN_FOUND")); 201 | || break; 202 | */ 203 | case EV_TXSTART: 204 | Serial.println(F("EV_TXSTART")); 205 | break; 206 | default: 207 | Serial.print(F("Unknown event: ")); 208 | Serial.println((unsigned) ev); 209 | break; 210 | } 211 | } 212 | 213 | void do_send(osjob_t* j){ 214 | // Check if there is not a current TX/RX job running 215 | if (LMIC.opmode & OP_TXRXPEND) { 216 | Serial.println(F("OP_TXRXPEND, not sending")); 217 | } else { 218 | // Prepare upstream data transmission at the next possible time. 219 | LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0); 220 | Serial.println(F("Packet queued")); 221 | } 222 | // Next TX is scheduled after TX_COMPLETE event. 223 | } 224 | 225 | void setup() { 226 | Serial.begin(115200); 227 | delay(100); 228 | Serial.println(F("Starting")); 229 | 230 | pinMode(LED_RED, OUTPUT); 231 | pinMode(LED_GREEN, OUTPUT); 232 | pinMode(LED_YELLOW, OUTPUT); 233 | 234 | // turn leds off 235 | digitalWrite(LED_RED, HIGH); 236 | digitalWrite(LED_GREEN, HIGH); 237 | digitalWrite(LED_YELLOW, HIGH); 238 | 239 | pinMode(RADIO_RXTX2_PORT, OUTPUT); 240 | digitalWrite(RADIO_RXTX2_PORT, LOW); 241 | 242 | // LMIC init 243 | os_init(); 244 | // Reset the MAC state. Session and pending data transfers will be discarded. 245 | LMIC_reset(); 246 | 247 | // Set static session parameters. Instead of dynamically establishing a session 248 | // by joining the network, precomputed session parameters are be provided. 249 | #ifdef PROGMEM 250 | // On AVR, these values are stored in flash and only copied to RAM 251 | // once. Copy them to a temporary buffer here, LMIC_setSession will 252 | // copy them into a buffer of its own again. 253 | uint8_t appskey[sizeof(APPSKEY)]; 254 | uint8_t nwkskey[sizeof(NWKSKEY)]; 255 | memcpy_P(appskey, APPSKEY, sizeof(APPSKEY)); 256 | memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY)); 257 | LMIC_setSession (0x13, DEVADDR, nwkskey, appskey); 258 | #else 259 | // If not running an AVR with PROGMEM, just use the arrays directly 260 | LMIC_setSession (0x13, DEVADDR, NWKSKEY, APPSKEY); 261 | #endif 262 | 263 | LMIC_selectSubBand(1); 264 | 265 | LMIC_setAdrMode(0); 266 | LMIC_setLinkCheckMode(0); 267 | LMIC_setClockError (MAX_CLOCK_ERROR * 10 / 100); 268 | 269 | // Start job 270 | do_send(&sendjob); 271 | } 272 | 273 | void loop() { 274 | unsigned long now; 275 | now = millis(); 276 | if ((now & 512) != 0) { 277 | digitalWrite(LED_GREEN, HIGH); 278 | } 279 | else { 280 | digitalWrite(LED_GREEN, LOW); 281 | } 282 | 283 | os_runloop_once(); 284 | 285 | } 286 | -------------------------------------------------------------------------------- /examples/Radioenge_ttn_otaa/Radioenge_ttn_otaa.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman 3 | * Copyright (c) 2018 Terry Moore, MCCI 4 | * 5 | * Permission is hereby granted, free of charge, to anyone 6 | * obtaining a copy of this document and accompanying files, 7 | * to do whatever they want with them without any restriction, 8 | * including, but not limited to, copying, modification and redistribution. 9 | * NO WARRANTY OF ANY KIND IS PROVIDED. 10 | * 11 | * This example sends a valid LoRaWAN packet with payload "Hello, 12 | * world!", using frequency and encryption settings matching those of 13 | * the The Things Network. 14 | * 15 | * This uses OTAA (Over-the-air activation), where where a DevEUI and 16 | * application key is configured, which are used in an over-the-air 17 | * activation procedure where a DevAddr and session keys are 18 | * assigned/generated for use with all further communication. 19 | * 20 | * Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in 21 | * g1, 0.1% in g2), but not the TTN fair usage policy (which is probably 22 | * violated by this sketch when left running for longer)! 23 | 24 | * To use this sketch, first register your application and device with 25 | * the things network, to set or generate an AppEUI, DevEUI and AppKey. 26 | * Multiple devices can use the same AppEUI, but each device has its own 27 | * DevEUI and AppKey. 28 | * 29 | * Do not forget to define the radio type correctly in 30 | * arduino-lmic/project_config/lmic_project_config.h or from your BOARDS.txt. 31 | * 32 | *******************************************************************************/ 33 | 34 | /******************************************************************************* 35 | Exemplo da ttn otaa para o modulo da Radioenge. 36 | Versão da lmic v2.3.2 - https://github.com/mcci-catena/arduino-lmic/archive/v2.3.2.zip 37 | Modificar o arquivo lmic_project_config.h, mudar a frequencia e chip 38 | #define CFG_au921 1 39 | #define CFG_sx1272_radio 1 40 | *******************************************************************************/ 41 | 42 | #define RX_1 PB7 43 | #define TX_1 PB6 44 | 45 | #define GPIO0 PA3 46 | #define GPIO1 PA2 47 | #define GPIO2 PA15 48 | #define GPIO3 PA10 49 | #define GPIO4 PA9 50 | #define GPIO5 PA8 51 | #define GPIO6 PB15 52 | #define GPIO7 PA0 53 | #define GPIO8 PA1 54 | #define GPIO9 PB11 55 | 56 | /*******************************************************************************/ 57 | 58 | #define LED_RED PB5 59 | #define LED_GREEN PB8 60 | #define LED_YELLOW PB9 61 | 62 | #define RADIO_RESET_PORT PB14 63 | #define RADIO_MOSI_PORT PA7 64 | #define RADIO_MISO_PORT PA6 65 | #define RADIO_SCLK_PORT PA5 66 | #define RADIO_NSS_PORT PA4 67 | 68 | #define RADIO_DIO_0_PORT PB10 69 | #define RADIO_DIO_1_PORT PB2 70 | #define RADIO_DIO_2_PORT PB1 71 | #define RADIO_DIO_3_PORT PB0 72 | 73 | #define RADIO_RXTX_PORT PB13 74 | #define RADIO_RXTX2_PORT PB12 75 | 76 | /*******************************************************************************/ 77 | 78 | #include 79 | #include 80 | #include 81 | 82 | // 83 | // For normal use, we require that you edit the sketch to replace FILLMEIN 84 | // with values assigned by the TTN console. However, for regression tests, 85 | // we want to be able to compile these scripts. The regression tests define 86 | // COMPILE_REGRESSION_TEST, and in that case we define FILLMEIN to a non- 87 | // working but innocuous value. 88 | // 89 | #ifdef COMPILE_REGRESSION_TEST 90 | # define FILLMEIN 0 91 | #else 92 | # warning "You must replace the values marked FILLMEIN with real values from the TTN control panel!" 93 | # define FILLMEIN (#dont edit this, edit the lines that use FILLMEIN) 94 | #endif 95 | 96 | // This EUI must be in little-endian format, so least-significant-byte 97 | // first. When copying an EUI from ttnctl output, this means to reverse 98 | // the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3, 99 | // 0x70. 100 | static const u1_t PROGMEM APPEUI[8]={ FILLMEIN }; 101 | void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);} 102 | 103 | // This should also be in little endian format, see above. 104 | static const u1_t PROGMEM DEVEUI[8]={ FILLMEIN }; 105 | void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);} 106 | 107 | // This key should be in big endian format (or, since it is not really a 108 | // number but a block of memory, endianness does not really apply). In 109 | // practice, a key taken from ttnctl can be copied as-is. 110 | static const u1_t PROGMEM APPKEY[16] = { FILLMEIN }; 111 | void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);} 112 | 113 | static uint8_t mydata[] = "Hello, world!"; 114 | static osjob_t sendjob; 115 | 116 | // Schedule TX every this many seconds (might become longer due to duty 117 | // cycle limitations). 118 | const unsigned TX_INTERVAL = 60; 119 | 120 | // Pin mapping 121 | const lmic_pinmap lmic_pins = { 122 | .nss = RADIO_NSS_PORT, 123 | .rxtx = RADIO_RXTX_PORT, 124 | .rst = RADIO_RESET_PORT, 125 | .dio = {RADIO_DIO_0_PORT, RADIO_DIO_1_PORT, RADIO_DIO_2_PORT}, 126 | .rxtx_rx_active = 1, 127 | }; 128 | 129 | void onEvent (ev_t ev) { 130 | Serial.print(os_getTime()); 131 | Serial.print(": "); 132 | switch(ev) { 133 | case EV_SCAN_TIMEOUT: 134 | Serial.println(F("EV_SCAN_TIMEOUT")); 135 | break; 136 | case EV_BEACON_FOUND: 137 | Serial.println(F("EV_BEACON_FOUND")); 138 | break; 139 | case EV_BEACON_MISSED: 140 | Serial.println(F("EV_BEACON_MISSED")); 141 | break; 142 | case EV_BEACON_TRACKED: 143 | Serial.println(F("EV_BEACON_TRACKED")); 144 | break; 145 | case EV_JOINING: 146 | Serial.println(F("EV_JOINING")); 147 | break; 148 | case EV_JOINED: 149 | Serial.println(F("EV_JOINED")); 150 | { 151 | u4_t netid = 0; 152 | devaddr_t devaddr = 0; 153 | u1_t nwkKey[16]; 154 | u1_t artKey[16]; 155 | LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey); 156 | Serial.print("netid: "); 157 | Serial.println(netid, DEC); 158 | Serial.print("devaddr: "); 159 | Serial.println(devaddr, HEX); 160 | Serial.print("artKey: "); 161 | for (int i=0; i