Created
October 23, 2016 19:32
-
-
Save ubergesundheit/299c1373f7470e848a11905b16dc8156 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 | |
#define PIN_SERIAL1_TX D5 | |
#define PIN_SERIAL1_RX D6 | |
SoftwareSerial mySerial(PIN_SERIAL1_RX, PIN_SERIAL1_TX); // 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 wakeUP_RN2483() { | |
mySerial.end(); | |
pinMode(PIN_SERIAL1_TX, OUTPUT); | |
digitalWrite(PIN_SERIAL1_TX, LOW); | |
delay(5); | |
digitalWrite(PIN_SERIAL1_TX, HIGH); | |
mySerial.begin(57600); | |
mySerial.write(0x55); | |
} | |
void initialize_radio() | |
{ | |
wakeUP_RN2483(); | |
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