Created
October 23, 2016 18:40
-
-
Save ubergesundheit/b82c51eb39c95cc16dc9576f4e41fd77 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <rn2483.h> | |
#include <SoftwareSerial.h> | |
#define APP_EUI "70B3D57ED000042A" | |
#define APP_KEY "20FA476202AABBD1FCD1B91EFAEC7B98" | |
#define RESET D7 | |
SoftwareSerial mySerial(D6, D5); // RX, TX !! labels on relay board is swapped !! | |
//create an instance of the rn2483 library, | |
//giving the software UART as stream to use, | |
//and using LoRa WAN | |
rn2483 myLora(mySerial); | |
// CRC function used to ensure data validity | |
uint32_t calculateCRC32(const uint8_t *data, size_t length); | |
struct { | |
uint32_t crc32; | |
byte data[50]; | |
} rtcData; | |
bool readLoRaConfig() { | |
// Read struct from RTC memory | |
if (ESP.rtcUserMemoryRead(0, (uint32_t*) &rtcData, sizeof(rtcData))) { | |
uint32_t crcOfData = calculateCRC32(((uint8_t*) &rtcData) + 4, sizeof(rtcData) - 4); | |
if (crcOfData != rtcData.crc32) { | |
Serial.println("CRC32 in RTC memory doesn't match CRC32 of data. Data is probably invalid!"); | |
return false; | |
} | |
else { | |
Serial.println("CRC32 check ok, data is probably valid."); | |
return true; | |
} | |
} | |
return false; | |
} | |
bool checkLoRaConfigChanged() { | |
Serial.println("check Lora config changed"); | |
if (readLoRaConfig()) { // read the data and check crc32 | |
// compare to APP_EUI and APP_KEY | |
int memIndex = 0; | |
for (int i = 0, len = sizeof(APP_EUI); i < len; i++) { | |
if (rtcData.data[memIndex] != APP_EUI[i]) { | |
return true; | |
} | |
memIndex = memIndex + 1; | |
} | |
for (int i = 0, len = sizeof(APP_KEY); i < len; i++) { | |
if (rtcData.data[memIndex] != APP_KEY[i]) { | |
return true; | |
} | |
memIndex = memIndex + 1; | |
} | |
return false; | |
} else { // since the data was invalid, we cannot say if the config has changed. return true to reconnect | |
return true; | |
} | |
} | |
void writeLoRaConfig() { | |
int memIndex = 0; | |
for (int i = 0, len = sizeof(APP_EUI); i < len; i++) { | |
rtcData.data[memIndex] = APP_EUI[i]; | |
memIndex = memIndex + 1; | |
} | |
for (int i = 0, len = sizeof(APP_KEY); i < len; i++) { | |
rtcData.data[memIndex] = APP_KEY[i]; | |
memIndex = memIndex + 1; | |
} | |
// Update CRC32 of data | |
rtcData.crc32 = calculateCRC32(((uint8_t*) &rtcData) + 4, sizeof(rtcData) - 4); | |
// Write struct to RTC memory | |
ESP.rtcUserMemoryWrite(0, (uint32_t*) &rtcData, sizeof(rtcData)); | |
} | |
uint32_t calculateCRC32(const uint8_t *data, size_t length) | |
{ | |
uint32_t crc = 0xffffffff; | |
while (length--) { | |
uint8_t c = *data++; | |
for (uint32_t i = 0x80; i > 0; i >>= 1) { | |
bool bit = crc & 0x80000000; | |
if (c & i) { | |
bit = !bit; | |
} | |
crc <<= 1; | |
if (bit) { | |
crc ^= 0x04c11db7; | |
} | |
} | |
} | |
return crc; | |
} | |
void doTx() { | |
myLora.tx("!"); | |
Serial.println("Packet sent"); | |
} | |
// the setup routine runs once when you press reset: | |
void setup() { | |
// Open serial communications and wait for port to open: | |
Serial.begin(9600); | |
mySerial.begin(57600); | |
delay(1000); //wait for the arduino ide's serial console to open | |
Serial.println("Startup"); | |
initialize_radio(); | |
doTx(); | |
delay(500); | |
Serial.println("Going into deep sleep for 5 seconds"); | |
Serial.println("ping"); | |
myLora.sleep(5000); | |
Serial.println("pong"); | |
ESP.deepSleep(5e6); | |
} | |
void initialize_radio() | |
{ | |
if (checkLoRaConfigChanged()) { | |
Serial.println("LoRa config changed.. Resetting RN2483"); | |
//reset RN2483 | |
pinMode(RESET, OUTPUT); | |
digitalWrite(RESET, LOW); | |
delay(100); | |
digitalWrite(RESET, HIGH); | |
delay(100); //wait for the RN2483's startup message | |
mySerial.flush(); | |
//check communication with radio | |
String hweui = myLora.hweui(); | |
while (hweui.length() != 16) | |
{ | |
Serial.println("Communication with RN2483 unsuccesful. Power cycle the board."); | |
Serial.println(hweui); | |
delay(10000); | |
hweui = myLora.hweui(); | |
} | |
//print out the HWEUI so that we can register it via ttnctl | |
Serial.println("When using OTAA, register this DevEUI: "); | |
Serial.println(hweui); | |
Serial.println("RN2483 firmware version:"); | |
Serial.println(myLora.sysver()); | |
//configure your keys and join the network | |
Serial.println("Trying to join TTN"); | |
bool join_result = false; | |
//ABP: initABP(String addr, String AppSKey, String NwkSKey); | |
//join_result = myLora.initABP("02017201", "8D7FFEF938589D95AAD928C2E2E7E48F", "AE17E567AECC8787F749A62F5541D522"); | |
//OTAA: initOTAA(String AppEUI, String AppKey); | |
join_result = myLora.initOTAA(APP_EUI, APP_KEY); | |
while (!join_result) | |
{ | |
Serial.println("Unable to join. Are your keys correct, and do you have TTN coverage?"); | |
delay(60000); //delay a minute before retry | |
join_result = myLora.init(); | |
} | |
Serial.println("Successfully joined TTN"); | |
writeLoRaConfig(); | |
} else { | |
Serial.println("LoRa settings unchanged. Doing nothing"); | |
} | |
} | |
void loop() { | |
// doing nothing | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment