Basic config functions
This commit is contained in:
625
Lora-Wsen.ino
625
Lora-Wsen.ino
@@ -1,3 +1,6 @@
|
||||
//Arduino Board = Arduino Pro or Pro Mini
|
||||
//Processor = Atmega328p (3.3v 8MHz)
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <SPI.h>
|
||||
//#include <EEPROM.h>
|
||||
@@ -17,18 +20,6 @@
|
||||
#define EEPROM_CONFIG_OFFSET 0
|
||||
|
||||
#ifdef ABP
|
||||
// LoRaWAN NwkSKey, network session key
|
||||
// This should be in big-endian (aka msb).
|
||||
static const PROGMEM u1_t NWKSKEY[16] = {0xE9, 0x4C, 0x5A, 0xD6, 0xA1, 0x16, 0xAF, 0x4A, 0xB5, 0x2B, 0xB8, 0xAC, 0x3D, 0xCD, 0x60, 0x2C};
|
||||
|
||||
// LoRaWAN AppSKey, application session key
|
||||
// This should also be in big-endian (aka msb).
|
||||
static const u1_t PROGMEM APPSKEY[16] = {0x44, 0x49, 0x19, 0x26, 0x74, 0x0E, 0x59, 0x00, 0x2F, 0xF5, 0x8D, 0xE7, 0x00, 0x91, 0x1D, 0x40};
|
||||
|
||||
// LoRaWAN end-device address (DevAddr)
|
||||
// The library converts the address to network byte order as needed, so this should be in big-endian (aka msb) too.
|
||||
static const u4_t DEVADDR = 0x2601119A;
|
||||
|
||||
// These callbacks are only used in over-the-air activation, so they are
|
||||
// left empty here (we cannot leave them out completely unless
|
||||
// DISABLE_JOIN is set in arduino-lmic/project_config/lmic_project_config.h,
|
||||
@@ -38,100 +29,112 @@ void os_getDevEui(u1_t *buf) {}
|
||||
void os_getDevKey(u1_t *buf) {}
|
||||
#endif
|
||||
|
||||
#ifdef OTAA
|
||||
|
||||
struct config_t
|
||||
{
|
||||
const u1_t APPEUI[8] = {}; // = { 0xB8, 0x34, 0x02, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 };
|
||||
const u1_t DEVEUI[8] = {}; // = { 0xBC, 0xAD, 0x24, 0x90, 0xB5, 0x52, 0xD6, 0xA8 };
|
||||
const u1_t APPKEY[16] = {}; // = { 0xE9, 0x64, 0x28, 0x39, 0x10, 0x47, 0x4B, 0x65, 0x35, 0xF3, 0x51, 0x59, 0xC8, 0xDF, 0x9A, 0x22 };
|
||||
//ABP
|
||||
// LoRaWAN NwkSKey, network session key, This should be in big-endian (aka msb).
|
||||
const u1_t NWKSKEY[16] = {}; // = {0xE9, 0x4C, 0x5A, 0xD6, 0xA1, 0x16, 0xAF, 0x4A, 0xB5, 0x2B, 0xB8, 0xAC, 0x3D, 0xCD, 0x60, 0x2C};
|
||||
// LoRaWAN AppSKey, application session key, This should also be in big-endian (aka msb).
|
||||
const u1_t APPSKEY[16] = {}; //= {0x44, 0x49, 0x19, 0x26, 0x74, 0x0E, 0x59, 0x00, 0x2F, 0xF5, 0x8D, 0xE7, 0x00, 0x91, 0x1D, 0x40};
|
||||
// LoRaWAN end-device address (DevAddr), The library converts the address to network byte order as needed, so this should be in big-endian (aka msb) to
|
||||
const u4_t DEVADDR = {}; //= 0x2601119A;
|
||||
|
||||
//OTAA
|
||||
// This EUI must be in little-endian format, so least-significant-byte
|
||||
// first. When copying an EUI from ttnctl output, this means to reverse
|
||||
// the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3,
|
||||
// 0x70.
|
||||
//const u1_t APPEUI[8] = {}; // = { 0xB8, 0x34, 0x02, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 };
|
||||
const u1_t APPEUI[8] = { 0xB8, 0x34, 0x02, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 };
|
||||
|
||||
// This should also be in little endian format, see above.
|
||||
//const u1_t DEVEUI[8] = {}; // = { 0xBC, 0xAD, 0x24, 0x90, 0xB5, 0x52, 0xD6, 0xA8 };
|
||||
const u1_t DEVEUI[8] = { 0xBC, 0xAD, 0x24, 0x90, 0xB5, 0x52, 0xD6, 0xA8 };
|
||||
|
||||
// This key should be in big endian format (or, since it is not really a
|
||||
// number but a block of memory, endianness does not really apply). In
|
||||
// practice, a key taken from ttnctl can be copied as-is.
|
||||
//const u1_t APPKEY[16] = {}; // = { 0xE9, 0x64, 0x28, 0x39, 0x10, 0x47, 0x4B, 0x65, 0x35, 0xF3, 0x51, 0x59, 0xC8, 0xDF, 0x9A, 0x22 };
|
||||
const u1_t APPKEY[16] = { 0xE9, 0x64, 0x28, 0x39, 0x10, 0x47, 0x4B, 0x65, 0x35, 0xF3, 0x51, 0x59, 0xC8, 0xDF, 0x9A, 0x22 };
|
||||
|
||||
} configuration;
|
||||
|
||||
// This EUI must be in little-endian format, so least-significant-byte
|
||||
// first. When copying an EUI from ttnctl output, this means to reverse
|
||||
// the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3,
|
||||
// 0x70.
|
||||
//static const u1_t PROGMEM APPEUI[8]={ 0xB8, 0x34, 0x02, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 };
|
||||
//void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}
|
||||
void os_getArtEui(u1_t *buf) { memcpy(buf, configuration.APPEUI, 8); }
|
||||
|
||||
// This should also be in little endian format, see above.
|
||||
//static const u1_t PROGMEM DEVEUI[8]={ 0xBC, 0xAD, 0x24, 0x90, 0xB5, 0x52, 0xD6, 0xA8 };
|
||||
//void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}
|
||||
void os_getDevEui(u1_t *buf) { memcpy(buf, configuration.DEVEUI, 8); }
|
||||
|
||||
// This key should be in big endian format (or, since it is not really a
|
||||
// number but a block of memory, endianness does not really apply). In
|
||||
// practice, a key taken from ttnctl can be copied as-is.
|
||||
//static const u1_t PROGMEM APPKEY[16] = { 0xE9, 0x64, 0x28, 0x39, 0x10, 0x47, 0x4B, 0x65, 0x35, 0xF3, 0x51, 0x59, 0xC8, 0xDF, 0x9A, 0x22 };
|
||||
//void os_getDevKey (u1_t* buf) { memcpy_P(buf, APPKEY, 16);}
|
||||
void os_getDevKey(u1_t *buf) { memcpy(buf, configuration.APPKEY, 16); }
|
||||
|
||||
#ifdef OTAA
|
||||
void os_getArtEui(u1_t *buf) {
|
||||
memcpy(buf, configuration.APPEUI, 8);
|
||||
}
|
||||
void os_getDevEui(u1_t *buf) {
|
||||
memcpy(buf, configuration.DEVEUI, 8);
|
||||
}
|
||||
void os_getDevKey(u1_t *buf) {
|
||||
memcpy(buf, configuration.APPKEY, 16);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static uint8_t mydata[] = "X";
|
||||
static osjob_t sendjob;
|
||||
|
||||
const unsigned TX_INTERVAL = 60; //seconds
|
||||
|
||||
const lmic_pinmap lmic_pins = {
|
||||
.nss = 10, // chip select on feather (rf95module) CS
|
||||
.rxtx = LMIC_UNUSED_PIN,
|
||||
.rst = 9, // reset pin
|
||||
.dio = {2, 5, LMIC_UNUSED_PIN}, // DIO0, DIO1, DIO2
|
||||
.nss = 10, // chip select on feather (rf95module) CS
|
||||
.rxtx = LMIC_UNUSED_PIN,
|
||||
.rst = 9, // reset pin
|
||||
.dio = {2, 5, LMIC_UNUSED_PIN}, // DIO0, DIO1, DIO2
|
||||
};
|
||||
|
||||
void onEvent(ev_t ev)
|
||||
{
|
||||
Serial.print(os_getTime());
|
||||
Serial.print(": ");
|
||||
switch (ev)
|
||||
{
|
||||
Serial.print(os_getTime());
|
||||
Serial.print(": ");
|
||||
switch (ev)
|
||||
{
|
||||
case EV_SCAN_TIMEOUT:
|
||||
Serial.println(F("EV_SCAN_TIMEOUT"));
|
||||
break;
|
||||
Serial.println(F("EV_SCAN_TIMEOUT"));
|
||||
break;
|
||||
case EV_BEACON_FOUND:
|
||||
Serial.println(F("EV_BEACON_FOUND"));
|
||||
break;
|
||||
Serial.println(F("EV_BEACON_FOUND"));
|
||||
break;
|
||||
case EV_BEACON_MISSED:
|
||||
Serial.println(F("EV_BEACON_MISSED"));
|
||||
break;
|
||||
Serial.println(F("EV_BEACON_MISSED"));
|
||||
break;
|
||||
case EV_BEACON_TRACKED:
|
||||
Serial.println(F("EV_BEACON_TRACKED"));
|
||||
break;
|
||||
Serial.println(F("EV_BEACON_TRACKED"));
|
||||
break;
|
||||
case EV_JOINING:
|
||||
Serial.println(F("EV_JOINING"));
|
||||
break;
|
||||
Serial.println(F("EV_JOINING"));
|
||||
break;
|
||||
case EV_JOINED:
|
||||
Serial.println(F("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(F("netid: "));
|
||||
Serial.println(netid, DEC);
|
||||
Serial.print(F("devaddr: "));
|
||||
Serial.println(devaddr, HEX);
|
||||
Serial.print(F("artKey: "));
|
||||
for (size_t i = 0; i < sizeof(artKey); ++i)
|
||||
{
|
||||
u4_t netid = 0;
|
||||
devaddr_t devaddr = 0;
|
||||
u1_t nwkKey[16];
|
||||
u1_t artKey[16];
|
||||
LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey);
|
||||
Serial.print(F("netid: "));
|
||||
Serial.println(netid, DEC);
|
||||
Serial.print(F("devaddr: "));
|
||||
Serial.println(devaddr, HEX);
|
||||
Serial.print(F("artKey: "));
|
||||
for (size_t i = 0; i < sizeof(artKey); ++i)
|
||||
{
|
||||
Serial.print(artKey[i], HEX);
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.print(F("nwkKey: "));
|
||||
for (size_t i = 0; i < sizeof(nwkKey); ++i)
|
||||
{
|
||||
Serial.print(nwkKey[i], HEX);
|
||||
}
|
||||
Serial.println("");
|
||||
Serial.print(artKey[i], HEX);
|
||||
}
|
||||
// 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;
|
||||
Serial.println("");
|
||||
Serial.print(F("nwkKey: "));
|
||||
for (size_t i = 0; i < sizeof(nwkKey); ++i)
|
||||
{
|
||||
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.
|
||||
@@ -139,42 +142,42 @@ void onEvent(ev_t ev)
|
||||
|| case EV_RFU1:
|
||||
|| Serial.println(F("EV_RFU1"));
|
||||
|| break;
|
||||
*/
|
||||
*/
|
||||
case EV_JOIN_FAILED:
|
||||
Serial.println(F("EV_JOIN_FAILED"));
|
||||
break;
|
||||
Serial.println(F("EV_JOIN_FAILED"));
|
||||
break;
|
||||
case EV_REJOIN_FAILED:
|
||||
Serial.println(F("EV_REJOIN_FAILED"));
|
||||
break;
|
||||
Serial.println(F("EV_REJOIN_FAILED"));
|
||||
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;
|
||||
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;
|
||||
Serial.println(F("EV_LOST_TSYNC"));
|
||||
break;
|
||||
case EV_RESET:
|
||||
Serial.println(F("EV_RESET"));
|
||||
break;
|
||||
Serial.println(F("EV_RESET"));
|
||||
break;
|
||||
case EV_RXCOMPLETE:
|
||||
// data received in ping slot
|
||||
Serial.println(F("EV_RXCOMPLETE"));
|
||||
break;
|
||||
// data received in ping slot
|
||||
Serial.println(F("EV_RXCOMPLETE"));
|
||||
break;
|
||||
case EV_LINK_DEAD:
|
||||
Serial.println(F("EV_LINK_DEAD"));
|
||||
break;
|
||||
Serial.println(F("EV_LINK_DEAD"));
|
||||
break;
|
||||
case EV_LINK_ALIVE:
|
||||
Serial.println(F("EV_LINK_ALIVE"));
|
||||
break;
|
||||
Serial.println(F("EV_LINK_ALIVE"));
|
||||
break;
|
||||
/*
|
||||
|| This event is defined but not used in the code. No
|
||||
|| point in wasting codespace on it.
|
||||
@@ -182,357 +185,131 @@ void onEvent(ev_t ev)
|
||||
|| case EV_SCAN_FOUND:
|
||||
|| Serial.println(F("EV_SCAN_FOUND"));
|
||||
|| break;
|
||||
*/
|
||||
*/
|
||||
case EV_TXSTART:
|
||||
Serial.println(F("EV_TXSTART"));
|
||||
break;
|
||||
Serial.println(F("EV_TXSTART"));
|
||||
break;
|
||||
case EV_RXSTART:
|
||||
Serial.println(F("EV_RXSTART"));
|
||||
break;
|
||||
Serial.println(F("EV_RXSTART"));
|
||||
break;
|
||||
case EV_JOIN_TXCOMPLETE:
|
||||
Serial.println(F("EV_JOIN_TXCOMPLETE"));
|
||||
break;
|
||||
Serial.println(F("EV_JOIN_TXCOMPLETE"));
|
||||
break;
|
||||
default:
|
||||
Serial.print(F("Unknown event: "));
|
||||
Serial.println((unsigned)ev);
|
||||
break;
|
||||
}
|
||||
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.
|
||||
// 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.
|
||||
}
|
||||
|
||||
//Timer 1 interrupt callback
|
||||
ISR(TIMER1_COMPA_vect)
|
||||
{
|
||||
digitalWrite(LED_GREEN, !digitalRead(LED_GREEN));
|
||||
digitalWrite(LED_ORANGE, !digitalRead(LED_ORANGE));
|
||||
digitalWrite(LED_RED, !digitalRead(LED_RED));
|
||||
digitalWrite(LED_GREEN, !digitalRead(LED_GREEN));
|
||||
digitalWrite(LED_ORANGE, !digitalRead(LED_ORANGE));
|
||||
digitalWrite(LED_RED, !digitalRead(LED_RED));
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600, SERIAL_8N1);
|
||||
Serial.println(F("Starting"));
|
||||
Serial.begin(9600, SERIAL_8N1);
|
||||
Serial.println(F("Starting"));
|
||||
|
||||
pinMode(LED_RED, OUTPUT);
|
||||
pinMode(LED_ORANGE, OUTPUT);
|
||||
pinMode(LED_GREEN, OUTPUT);
|
||||
pinMode(LED_RED, OUTPUT);
|
||||
pinMode(LED_ORANGE, OUTPUT);
|
||||
pinMode(LED_GREEN, OUTPUT);
|
||||
|
||||
pinMode(INPUT_1, INPUT_PULLUP);
|
||||
pinMode(INPUT_2, INPUT_PULLUP);
|
||||
pinMode(INPUT_1, INPUT_PULLUP);
|
||||
pinMode(INPUT_2, INPUT_PULLUP);
|
||||
|
||||
digitalWrite(LED_GREEN, HIGH);
|
||||
digitalWrite(LED_ORANGE, LOW);
|
||||
digitalWrite(LED_RED, HIGH);
|
||||
digitalWrite(LED_GREEN, HIGH);
|
||||
digitalWrite(LED_ORANGE, LOW);
|
||||
digitalWrite(LED_RED, HIGH);
|
||||
|
||||
// initialize timer1 1 sec
|
||||
noInterrupts(); // disable all interrupts
|
||||
TCCR1A = 0;
|
||||
TCCR1B = 0;
|
||||
TCNT1 = 0;
|
||||
OCR1A = 31250; // compare match register 16MHz/256/2Hz
|
||||
TCCR1B |= (1 << WGM12); // CTC mode
|
||||
TCCR1B |= (1 << CS12); // 256 prescaler
|
||||
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
|
||||
interrupts(); // enable all interrupts
|
||||
// initialize timer1 1 sec
|
||||
noInterrupts(); // disable all interrupts
|
||||
TCCR1A = 0;
|
||||
TCCR1B = 0;
|
||||
TCNT1 = 0;
|
||||
OCR1A = 31250; // compare match register 16MHz/256/2Hz
|
||||
TCCR1B |= (1 << WGM12); // CTC mode
|
||||
TCCR1B |= (1 << CS12); // 256 prescaler
|
||||
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
|
||||
interrupts(); // enable all interrupts
|
||||
|
||||
//eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
|
||||
eeprom_read_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
|
||||
//eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
|
||||
eeprom_read_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
|
||||
|
||||
// LMIC init
|
||||
os_init();
|
||||
// Reset the MAC state. Session and pending data transfers will be discarded.
|
||||
LMIC_reset();
|
||||
// LMIC init
|
||||
os_init();
|
||||
// Reset the MAC state. Session and pending data transfers will be discarded.
|
||||
LMIC_reset();
|
||||
|
||||
// Use with Arduino Pro Mini ATmega328P 3.3V 8 MHz
|
||||
// Let LMIC compensate for +/- 1% clock error
|
||||
LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);
|
||||
// Use with Arduino Pro Mini ATmega328P 3.3V 8 MHz
|
||||
// Let LMIC compensate for +/- 1% clock error
|
||||
LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);
|
||||
|
||||
#ifdef ABP
|
||||
// Set static session parameters. Instead of dynamically establishing a session
|
||||
// by joining the network, precomputed session parameters are be provided.
|
||||
// Set static session parameters. Instead of dynamically establishing a session
|
||||
// by joining the network, precomputed session parameters are be provided.
|
||||
#ifdef PROGMEM
|
||||
// On AVR, these values are stored in flash and only copied to RAM
|
||||
// once. Copy them to a temporary buffer here, LMIC_setSession will
|
||||
// copy them into a buffer of its own again.
|
||||
uint8_t appskey[sizeof(APPSKEY)];
|
||||
uint8_t nwkskey[sizeof(NWKSKEY)];
|
||||
memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
|
||||
memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
|
||||
LMIC_setSession(0x13, DEVADDR, nwkskey, appskey);
|
||||
// On AVR, these values are stored in flash and only copied to RAM
|
||||
// once. Copy them to a temporary buffer here, LMIC_setSession will
|
||||
// copy them into a buffer of its own again.
|
||||
uint8_t appskey[sizeof(configuration.APPSKEY)];
|
||||
uint8_t nwkskey[sizeof(configuration.NWKSKEY)];
|
||||
memcpy_P(appskey, configuration.APPSKEY, sizeof(configuration.APPSKEY));
|
||||
memcpy_P(nwkskey, configuration.NWKSKEY, sizeof(configuration.NWKSKEY));
|
||||
|
||||
LMIC_setSession(0x13, configuration.DEVADDR, nwkskey, appskey);
|
||||
#else
|
||||
// If not running an AVR with PROGMEM, just use the arrays directly
|
||||
LMIC_setSession(0x13, DEVADDR, NWKSKEY, APPSKEY);
|
||||
// If not running an AVR with PROGMEM, just use the arrays directly
|
||||
LMIC_setSession(0x13, configuration.DEVADDR, configuration.NWKSKEY, configuration.APPSKEY);
|
||||
#endif
|
||||
|
||||
LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band
|
||||
LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
|
||||
LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band
|
||||
|
||||
// Disable link check validation
|
||||
LMIC_setLinkCheckMode(0);
|
||||
// Disable link check validation
|
||||
LMIC_setLinkCheckMode(0);
|
||||
|
||||
// TTN uses SF9 for its RX2 window.
|
||||
LMIC.dn2Dr = DR_SF9;
|
||||
// TTN uses SF9 for its RX2 window.
|
||||
LMIC.dn2Dr = DR_SF9;
|
||||
|
||||
// Set data rate and transmit power for uplink
|
||||
LMIC_setDrTxpow(DR_SF7, 14);
|
||||
// Set data rate and transmit power for uplink
|
||||
LMIC_setDrTxpow(DR_SF7, 14);
|
||||
#endif
|
||||
|
||||
// Start job
|
||||
do_send(&sendjob);
|
||||
// Start job
|
||||
do_send(&sendjob);
|
||||
}
|
||||
|
||||
#define CMDLINELEN 20
|
||||
|
||||
char cmdline[CMDLINELEN];
|
||||
int idx = 0;
|
||||
int timeout = 0;
|
||||
|
||||
#define STX 0x02
|
||||
#define ETX 0x03
|
||||
|
||||
void loop()
|
||||
{
|
||||
timeout++;
|
||||
if (timeout == 2000)
|
||||
{
|
||||
idx = 0;
|
||||
memset(cmdline, '\0', CMDLINELEN);
|
||||
timeout = 0;
|
||||
}
|
||||
|
||||
if (Serial.available() > 0)
|
||||
{
|
||||
int incomingByte = Serial.read();
|
||||
|
||||
if (incomingByte == STX)
|
||||
{
|
||||
//Serial.println("STX");
|
||||
idx = 0;
|
||||
}
|
||||
else if (incomingByte == ETX)
|
||||
{
|
||||
//Serial.println("ETX");
|
||||
//Serial.println(cmdline);
|
||||
|
||||
char buf[17];
|
||||
switch (cmdline[0])
|
||||
{
|
||||
case 'a': //get DevEUI
|
||||
memcpy(buf, configuration.DEVEUI, 8);
|
||||
buf[9] = '\0';
|
||||
Serial.write(STX);
|
||||
//Serial.println(F("get deveui"));
|
||||
Serial.write('a');
|
||||
Serial.write(buf, 8);
|
||||
Serial.write(ETX);
|
||||
break;
|
||||
case 'b': //get appEUI
|
||||
memcpy(buf, configuration.APPEUI, 8);
|
||||
buf[9] = '\0';
|
||||
Serial.write(STX);
|
||||
//Serial.println(F("get appeui"));
|
||||
Serial.write('b');
|
||||
Serial.write(buf, 8);
|
||||
Serial.write(ETX);
|
||||
break;
|
||||
case 'c': //get appkey
|
||||
memcpy(buf, configuration.APPKEY, 16);
|
||||
buf[17] = '\0';
|
||||
Serial.write(STX);
|
||||
//Serial.println(F("get appkey"));
|
||||
Serial.write('c');
|
||||
Serial.write(buf, 16);
|
||||
Serial.write(ETX);
|
||||
break;
|
||||
case 'd': //get devaddr
|
||||
memset(buf, 0x00, 8);
|
||||
buf[9] = '\0';
|
||||
Serial.write(STX);
|
||||
//Serial.println(F("get devaddr"));
|
||||
Serial.write('d');
|
||||
Serial.write(buf, 8);
|
||||
Serial.write(ETX);
|
||||
break;
|
||||
case 'e': //get nwkskey
|
||||
memset(buf, 0x00, 16);
|
||||
buf[9] = '\0';
|
||||
Serial.write(STX);
|
||||
//Serial.println(F("get nwkskey"));
|
||||
Serial.write('e');
|
||||
Serial.write(buf, 16);
|
||||
Serial.write(ETX);
|
||||
break;
|
||||
case 'f': //get appskey
|
||||
memset(buf, 0x00, 16);
|
||||
buf[9] = '\0';
|
||||
Serial.write(STX);
|
||||
//Serial.println(F("get appskey"));
|
||||
Serial.write('f');
|
||||
Serial.write(buf, 16);
|
||||
Serial.write(ETX);
|
||||
break;
|
||||
|
||||
case 'A': //Set DevEUI
|
||||
Serial.println(F("set deveui"));
|
||||
// Serial.println(&cmdline[1]);
|
||||
// memcpy(configuration.DEVEUI, &cmdline[1], 8);
|
||||
break;
|
||||
case 'B': //Set appEUI
|
||||
Serial.println(F("set appeui"));
|
||||
// Serial.println(&cmdline[1]);
|
||||
// memcpy(configuration.APPEUI, &cmdline[1], 8);
|
||||
break;
|
||||
case 'C': //Set APPKEY
|
||||
Serial.println(F("set appkey"));
|
||||
// Serial.println(&cmdline[1]);
|
||||
// memcpy(configuration.APPKEY, &cmdline[1], 16);
|
||||
break;
|
||||
case 'D': //Set devaddr
|
||||
Serial.println(F("set devaddr"));
|
||||
// Serial.println(&cmdline[1]);
|
||||
break;
|
||||
case 'E': //Set NwkSKey
|
||||
Serial.println(F("set nwkskey"));
|
||||
// Serial.println(&cmdline[1]);
|
||||
break;
|
||||
case 'F': //Set appskey
|
||||
Serial.println(F("set appskey"));
|
||||
// Serial.println(&cmdline[1]);
|
||||
break;
|
||||
}
|
||||
|
||||
memset(cmdline, '\0', CMDLINELEN);
|
||||
idx = 0;
|
||||
}
|
||||
else if (idx >= CMDLINELEN)
|
||||
{
|
||||
memset(cmdline, '\0', CMDLINELEN);
|
||||
idx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmdline[idx] = incomingByte;
|
||||
idx++;
|
||||
//Serial.println(incomingByte, HEX);
|
||||
}
|
||||
|
||||
// say what you got:
|
||||
//Serial.print("I received: ");
|
||||
//Serial.println(incomingByte, HEX);
|
||||
//Serial.write(incomingByte);
|
||||
|
||||
//Serial.println(Serial.available());
|
||||
//timeout = 0;
|
||||
//cmdline[idx] = Serial.read();
|
||||
|
||||
//if (cmdline[idx] == '\n' || cmdline[idx] == '\r')
|
||||
//{
|
||||
// Serial.println("End of line");
|
||||
//}
|
||||
|
||||
//idx++;
|
||||
|
||||
//cmdline[idx] = '\0';
|
||||
|
||||
//Serial.print(F("RX="));
|
||||
//Serial.println(cmdline);
|
||||
|
||||
//Serial.print(strlen(cmdline));
|
||||
//Serial.write(strlen(cmdline));
|
||||
// for (size_t i = 0; i < strlen(cmdline); i++)
|
||||
// {
|
||||
// //Serial.print(cmdline[i]);
|
||||
// Serial.write(cmdline[i]);
|
||||
// }
|
||||
//Serial.println();
|
||||
|
||||
// if (cmdline[(idx - 1)] == '\n' || cmdline[(idx - 1)] == '\r')
|
||||
// {
|
||||
// char buf[17];
|
||||
// switch (cmdline[0])
|
||||
// {
|
||||
// case 'a': //get DevEUI
|
||||
// Serial.println(F("get deveui"));
|
||||
// memcpy(buf, configuration.DEVEUI, 8);
|
||||
// buf[9] = '\0';
|
||||
// Serial.println(buf);
|
||||
// break;
|
||||
// case 'b': //get appEUI
|
||||
// Serial.println(F("get appeui"));
|
||||
// memcpy(buf, configuration.APPEUI, 8);
|
||||
// buf[9] = '\0';
|
||||
// Serial.println(buf);
|
||||
// break;
|
||||
// case 'c': //get appkey
|
||||
// Serial.println(F("get appkey"));
|
||||
// memcpy(buf, configuration.APPKEY, 16);
|
||||
// buf[17] = '\0';
|
||||
// Serial.println(buf);
|
||||
// break;
|
||||
// case 'd': //get devaddr
|
||||
// Serial.println(F("get devaddr"));
|
||||
// break;
|
||||
// case 'e': //get nwkskey
|
||||
// Serial.println(F("get nmkskey"));
|
||||
// break;
|
||||
// case 'f': //get appskey
|
||||
// Serial.println(F("get appskey"));
|
||||
// break;
|
||||
|
||||
// case 'A': //Set DevEUI
|
||||
// Serial.println(F("set deveui"));
|
||||
// Serial.println(&cmdline[1]);
|
||||
// memcpy(configuration.DEVEUI, &cmdline[1], 8);
|
||||
// break;
|
||||
// case 'B': //Set appEUI
|
||||
// Serial.println(F("set appeui"));
|
||||
// Serial.println(&cmdline[1]);
|
||||
// memcpy(configuration.APPEUI, &cmdline[1], 8);
|
||||
// break;
|
||||
// case 'C': //Set APPKEY
|
||||
// Serial.println(F("set appkey"));
|
||||
// Serial.println(&cmdline[1]);
|
||||
// memcpy(configuration.APPKEY, &cmdline[1], 16);
|
||||
// break;
|
||||
// case 'D': //Set devaddr
|
||||
// Serial.println(F("set devaddr"));
|
||||
// Serial.println(&cmdline[1]);
|
||||
// break;
|
||||
// case 'E': //Set NwkSKey
|
||||
// Serial.println(F("set nwkskey"));
|
||||
// Serial.println(&cmdline[1]);
|
||||
// break;
|
||||
// case 'F': //Set appskey
|
||||
// Serial.println(F("set appskey"));
|
||||
// Serial.println(&cmdline[1]);
|
||||
// break;
|
||||
// }
|
||||
// memset(cmdline, '\0', CMDLINELEN);
|
||||
// idx = 0;
|
||||
// }
|
||||
}
|
||||
|
||||
os_runloop_once();
|
||||
}
|
||||
receiveSerialCommand();
|
||||
os_runloop_once();
|
||||
}
|
||||
|
||||
166
Lora-Wsen_SerialCommands.ino
Normal file
166
Lora-Wsen_SerialCommands.ino
Normal file
@@ -0,0 +1,166 @@
|
||||
#define CMDLINELEN 20
|
||||
#define STX 0x02
|
||||
#define ETX 0x03
|
||||
|
||||
char cmdline[CMDLINELEN];
|
||||
int idx = 0;
|
||||
int timeout = 0;
|
||||
|
||||
void receiveSerialCommand() {
|
||||
|
||||
timeout++;
|
||||
if (timeout == 2000)
|
||||
{
|
||||
idx = 0;
|
||||
memset(cmdline, '\0', CMDLINELEN);
|
||||
timeout = 0;
|
||||
}
|
||||
|
||||
if (Serial.available() > 0)
|
||||
{
|
||||
int incomingByte = Serial.read();
|
||||
if (incomingByte == STX)
|
||||
{
|
||||
idx = 0;
|
||||
}
|
||||
else if (incomingByte == ETX)
|
||||
{
|
||||
checkSerialCommand(cmdline);
|
||||
memset(cmdline, '\0', CMDLINELEN);
|
||||
idx = 0;
|
||||
}
|
||||
else if (idx >= CMDLINELEN)
|
||||
{
|
||||
memset(cmdline, '\0', CMDLINELEN);
|
||||
idx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
cmdline[idx] = incomingByte;
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sendDevEUI() {
|
||||
char buf[11];
|
||||
memcpy(buf, configuration.DEVEUI, 8);
|
||||
buf[9] = '\0';
|
||||
Serial.write(STX);
|
||||
Serial.write('a');
|
||||
Serial.write(buf, 8);
|
||||
Serial.write(ETX);
|
||||
}
|
||||
void sendAppEUI() {
|
||||
char buf[11];
|
||||
memcpy(buf, configuration.APPEUI, 8);
|
||||
buf[9] = '\0';
|
||||
Serial.write(STX);
|
||||
Serial.write('b');
|
||||
Serial.write(buf, 8);
|
||||
Serial.write(ETX);
|
||||
}
|
||||
void sendAppKey() {
|
||||
char buf[19];
|
||||
memcpy(buf, configuration.APPKEY, 16);
|
||||
buf[17] = '\0';
|
||||
Serial.write(STX);
|
||||
Serial.write('c');
|
||||
Serial.write(buf, 16);
|
||||
Serial.write(ETX);
|
||||
}
|
||||
void sendDevAddr() {
|
||||
char buf[11];
|
||||
memset(buf, configuration.DEVADDR, 8);
|
||||
buf[9] = '\0';
|
||||
Serial.write(STX);
|
||||
Serial.write('d');
|
||||
Serial.write(buf, 8);
|
||||
Serial.write(ETX);
|
||||
}
|
||||
void sendNwksKey() {
|
||||
char buf[19];
|
||||
memset(buf, configuration.NWKSKEY, 16);
|
||||
buf[9] = '\0';
|
||||
Serial.write(STX);
|
||||
Serial.write('e');
|
||||
Serial.write(buf, 16);
|
||||
Serial.write(ETX);
|
||||
}
|
||||
void sendAppsKey() {
|
||||
char buf[19];
|
||||
memset(buf, configuration.APPSKEY, 16);
|
||||
buf[9] = '\0';
|
||||
Serial.write(STX);
|
||||
Serial.write('f');
|
||||
Serial.write(buf, 16);
|
||||
Serial.write(ETX);
|
||||
}
|
||||
|
||||
void checkSerialCommand(char cmd[]) {
|
||||
char buf[17];
|
||||
switch (cmd[0])
|
||||
{
|
||||
case 'a': //get DevEUI
|
||||
sendDevEUI();
|
||||
break;
|
||||
case 'b': //get appEUI
|
||||
sendAppEUI();
|
||||
break;
|
||||
case 'c': //get appkey
|
||||
sendAppKey();
|
||||
break;
|
||||
case 'd': //get devaddr
|
||||
sendDevAddr();
|
||||
break;
|
||||
case 'e': //get nwkskey
|
||||
sendNwksKey();
|
||||
break;
|
||||
case 'f': //get appskey
|
||||
sendAppsKey();
|
||||
break;
|
||||
case '?': //ABP or ATAA
|
||||
Serial.write(STX);
|
||||
Serial.write('?');
|
||||
#ifdef ABP
|
||||
Serial.write('A');
|
||||
#endif
|
||||
#ifdef OTAA
|
||||
Serial.write('O');
|
||||
#endif
|
||||
Serial.write(ETX);
|
||||
break;
|
||||
|
||||
case 'A': //Set DevEUI
|
||||
memcpy(configuration.DEVEUI, &cmdline[1], 8);
|
||||
eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
|
||||
sendDevEUI();
|
||||
break;
|
||||
case 'B': //Set appEUI
|
||||
memcpy(configuration.APPEUI, &cmdline[1], 8);
|
||||
eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
|
||||
sendAppEUI();
|
||||
break;
|
||||
case 'C': //Set APPKEY
|
||||
memcpy(configuration.APPKEY, &cmdline[1], 16);
|
||||
eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
|
||||
sendAppKey();
|
||||
break;
|
||||
|
||||
case 'D': //Set devaddr
|
||||
memcpy(configuration.DEVADDR, &cmdline[1], 8);
|
||||
eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
|
||||
sendDevAddr();
|
||||
break;
|
||||
case 'E': //Set NwkSKey
|
||||
memcpy(configuration.NWKSKEY, &cmdline[1], 16);
|
||||
eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
|
||||
sendNwksKey();
|
||||
break;
|
||||
case 'F': //Set appskey
|
||||
memcpy(configuration.APPSKEY, &cmdline[1], 16);
|
||||
eeprom_write_block(&configuration, EEPROM_CONFIG_OFFSET, sizeof(configuration));
|
||||
sendAppsKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user