|
|
|
|
@ -6,61 +6,6 @@
@@ -6,61 +6,6 @@
|
|
|
|
|
#include "mbed.h" |
|
|
|
|
#include "nvstore.h" |
|
|
|
|
|
|
|
|
|
#define NVKEY_LORA_DEVICE_EUI 0x01 |
|
|
|
|
#define NVKEY_LORA_APP_EUI 0x02 |
|
|
|
|
#define NVKEY_LORA_APP_KEY 0x03 |
|
|
|
|
#define NVKEY_HX711_OFFSET 0x04 |
|
|
|
|
#define NVKEY_HX711_SCALE 0x05 |
|
|
|
|
|
|
|
|
|
#if MBED_CONF_APP_MODE_BOOTSTRAP |
|
|
|
|
|
|
|
|
|
const static uint8_t dev_eui[] = MBED_CONF_LORA_DEVICE_EUI; |
|
|
|
|
const static uint8_t app_eui[] = MBED_CONF_LORA_APPLICATION_EUI; |
|
|
|
|
const static uint8_t app_key[] = MBED_CONF_LORA_APPLICATION_KEY; |
|
|
|
|
|
|
|
|
|
int main(void) { |
|
|
|
|
int rc; |
|
|
|
|
uint16_t key; |
|
|
|
|
|
|
|
|
|
NVStore &nvstore = NVStore::get_instance(); |
|
|
|
|
|
|
|
|
|
rc = nvstore.init(); |
|
|
|
|
if (rc != NVSTORE_SUCCESS) { |
|
|
|
|
printf("Unable to init NVStore : %d\n", rc); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
rc = nvstore.reset(); |
|
|
|
|
if (rc != NVSTORE_SUCCESS) { |
|
|
|
|
printf("Unable to reset NVStore : %d\n", rc); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
printf("NVStore initiated and reseted\n"); |
|
|
|
|
|
|
|
|
|
key = NVKEY_LORA_DEVICE_EUI; |
|
|
|
|
if (nvstore.set(key, sizeof(dev_eui), dev_eui) != NVSTORE_SUCCESS) { |
|
|
|
|
printf("Unable to write LoRa Device EUI\n"); |
|
|
|
|
} |
|
|
|
|
key = NVKEY_LORA_APP_EUI; |
|
|
|
|
if (nvstore.set(key, sizeof(app_eui), app_eui) != NVSTORE_SUCCESS) { |
|
|
|
|
printf("Unable to write LoRa Application EUI\n"); |
|
|
|
|
} |
|
|
|
|
key = NVKEY_LORA_APP_KEY; |
|
|
|
|
if (nvstore.set(key, sizeof(app_key), app_key) != NVSTORE_SUCCESS) { |
|
|
|
|
printf("Unable to write LoRa Application key\n"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
while(1) { |
|
|
|
|
printf("Bootstrap done\n"); |
|
|
|
|
wait(1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#else // MBED_CONF_APP_MODE_BOOTSTRAP
|
|
|
|
|
|
|
|
|
|
static uint8_t dev_eui[] = MBED_CONF_LORA_DEVICE_EUI; |
|
|
|
|
static uint8_t app_eui[] = MBED_CONF_LORA_APPLICATION_EUI; |
|
|
|
|
static uint8_t app_key[] = MBED_CONF_LORA_APPLICATION_KEY; |
|
|
|
|
|
|
|
|
|
#if MBED_CONF_APP_DHT_ENABLED |
|
|
|
|
#include "DHT.h" |
|
|
|
|
#endif |
|
|
|
|
@ -93,28 +38,22 @@ static CayenneLPP cayenne(51);
@@ -93,28 +38,22 @@ static CayenneLPP cayenne(51);
|
|
|
|
|
|
|
|
|
|
#if MBED_CONF_APP_BATTERY_ENABLED |
|
|
|
|
AnalogIn bat(MBED_CONF_APP_BATTERY_ADC); |
|
|
|
|
AnalogIn vref(ADC_VREF); |
|
|
|
|
AnalogIn vrefint(ADC_VREF); |
|
|
|
|
|
|
|
|
|
static float battery_voltage() { |
|
|
|
|
float vbat = bat.read(); |
|
|
|
|
float vrefin = vref.read(); |
|
|
|
|
|
|
|
|
|
float vrefcal = (float)(*(uint16_t*)VREFINT_CAL_ADDR) * (1.0f / (float)0xFFF); |
|
|
|
|
float vdda = 3.0f * vrefcal / vrefin; |
|
|
|
|
double vdd = (1.224f) / vrefint.read(); |
|
|
|
|
|
|
|
|
|
return vbat * vdda * MBED_CONF_APP_BATTERY_RATIO; |
|
|
|
|
return vbat * MBED_CONF_APP_BATTERY_RATIO * vdd; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static uint8_t battery_level() { |
|
|
|
|
float vbat = battery_voltage(); |
|
|
|
|
|
|
|
|
|
if (vbat >= MBED_CONF_APP_BATTERY_MAX) { |
|
|
|
|
return 254; |
|
|
|
|
} else if (vbat > MBED_CONF_APP_BATTERY_MIN && vbat < MBED_CONF_APP_BATTERY_MAX) { |
|
|
|
|
return ( 253 * ( vbat - MBED_CONF_APP_BATTERY_MIN ) ) / ( MBED_CONF_APP_BATTERY_MAX - MBED_CONF_APP_BATTERY_MIN ) + 1; |
|
|
|
|
} else { |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
double ratio = 253.0f / (4.2f - 3.3f); |
|
|
|
|
int value = ratio * (vbat - 3.4f) + 1.0f; |
|
|
|
|
|
|
|
|
|
return value < 1 ? 1 : (value > 254 ? 254 : value); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
@ -128,45 +67,35 @@ HX711 loadcell(MBED_CONF_APP_HX711_DATA, MBED_CONF_APP_HX711_CLK);
@@ -128,45 +67,35 @@ HX711 loadcell(MBED_CONF_APP_HX711_DATA, MBED_CONF_APP_HX711_CLK);
|
|
|
|
|
|
|
|
|
|
int main(void) { |
|
|
|
|
lorawan_status_t retcode; |
|
|
|
|
lorawan_connect_t connect; |
|
|
|
|
int rc; |
|
|
|
|
uint16_t key; |
|
|
|
|
uint16_t readsize; |
|
|
|
|
|
|
|
|
|
// NVStore is a sigleton, get its instance
|
|
|
|
|
#if NVSTORE_ENABLED |
|
|
|
|
NVStore &nvstore = NVStore::get_instance(); |
|
|
|
|
|
|
|
|
|
if (nvstore.init() != NVSTORE_SUCCESS) { |
|
|
|
|
debug("\r\n NVStore initialization failed! \r\n"); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
key = NVKEY_LORA_DEVICE_EUI; |
|
|
|
|
rc = nvstore.get(key, sizeof(dev_eui), dev_eui, readsize); |
|
|
|
|
if (rc != NVSTORE_SUCCESS || readsize != sizeof(dev_eui)) { |
|
|
|
|
debug("\r\n Failed to read LoRa Device EUI from NVStore! \r\n"); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
key = NVKEY_LORA_APP_EUI; |
|
|
|
|
rc = nvstore.get(key, sizeof(app_eui), app_eui, readsize); |
|
|
|
|
if (rc != NVSTORE_SUCCESS || readsize != sizeof(app_eui)) { |
|
|
|
|
debug("\r\n Failed to read LoRa Application EUI from NVStore! \r\n"); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
key = NVKEY_LORA_APP_KEY; |
|
|
|
|
rc =nvstore.get(key, sizeof(app_key), app_key, readsize); |
|
|
|
|
if (rc != NVSTORE_SUCCESS || readsize != sizeof(app_key)) { |
|
|
|
|
debug("\r\n Failed to read LoRa Application Key from NVStore! \r\n"); |
|
|
|
|
return -1; |
|
|
|
|
int rc; |
|
|
|
|
uint16_t key; |
|
|
|
|
// Values read or written by NVStore need to be aligned to a uint32_t address (even if their sizes
|
|
|
|
|
// aren't)
|
|
|
|
|
uint32_t value; |
|
|
|
|
// Initialize NVstore. Note that it can be skipped, as it is lazily called by all other APIs
|
|
|
|
|
rc = nvstore.init(); |
|
|
|
|
printf("Init NVStore. \n"); |
|
|
|
|
// Show NVStore size, maximum number of keys and area addresses and sizes
|
|
|
|
|
printf("NVStore size is %d.\n", nvstore.size()); |
|
|
|
|
printf("NVStore max number of keys is %d (out of %d possible ones in this flash configuration).\n", |
|
|
|
|
nvstore.get_max_keys(), nvstore.get_max_possible_keys()); |
|
|
|
|
printf("NVStore areas:\n"); |
|
|
|
|
for (uint8_t area = 0; area < NVSTORE_NUM_AREAS; area++) { |
|
|
|
|
uint32_t area_address; |
|
|
|
|
size_t area_size; |
|
|
|
|
nvstore.get_area_params(area, area_address, area_size); |
|
|
|
|
printf("Area %d: address 0x%08lx, size %d (0x%x).\n", area, area_address, area_size, area_size); |
|
|
|
|
} |
|
|
|
|
#else |
|
|
|
|
printf("NVStore is disabled for this board\n"); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
connect.connect_type = LORAWAN_CONNECTION_OTAA; |
|
|
|
|
connect.connection_u.otaa.app_eui = const_cast<uint8_t *>(app_eui); |
|
|
|
|
connect.connection_u.otaa.dev_eui = const_cast<uint8_t *>(dev_eui); |
|
|
|
|
connect.connection_u.otaa.app_key = const_cast<uint8_t *>(app_key); |
|
|
|
|
connect.connection_u.otaa.nb_trials = MBED_CONF_LORA_NB_TRIALS; |
|
|
|
|
while(1) { |
|
|
|
|
wait(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if MBED_CONF_APP_HX711_ENABLED |
|
|
|
|
loadcell.powerDown(); |
|
|
|
|
@ -204,7 +133,7 @@ int main(void) {
@@ -204,7 +133,7 @@ int main(void) {
|
|
|
|
|
|
|
|
|
|
debug("\r\n Adaptive data rate (ADR) - Enabled \r\n"); |
|
|
|
|
|
|
|
|
|
retcode = lorawan.connect(connect); |
|
|
|
|
retcode = lorawan.connect(); |
|
|
|
|
|
|
|
|
|
if(retcode == LORAWAN_STATUS_OK || retcode == LORAWAN_STATUS_CONNECT_IN_PROGRESS) { |
|
|
|
|
} else { |
|
|
|
|
@ -225,30 +154,16 @@ int main(void) {
@@ -225,30 +154,16 @@ int main(void) {
|
|
|
|
|
*/ |
|
|
|
|
static void send_message() { |
|
|
|
|
int16_t retcode; |
|
|
|
|
int eid; |
|
|
|
|
|
|
|
|
|
// setup next transmission
|
|
|
|
|
eid = ev_queue.call_in(MBED_CONF_APP_TX_TIMER, send_message); |
|
|
|
|
|
|
|
|
|
// check backoff time before sending new frame
|
|
|
|
|
if (MBED_CONF_LORA_DUTY_CYCLE_ON) { |
|
|
|
|
lorawan_status_t status; |
|
|
|
|
int backoff; |
|
|
|
|
|
|
|
|
|
status = lorawan.get_backoff_metadata(backoff); |
|
|
|
|
if (status == LORAWAN_STATUS_OK && backoff > 0) { |
|
|
|
|
debug("\r\n %d ms backoff, delay next send \r\n", backoff); |
|
|
|
|
ev_queue.cancel(eid); |
|
|
|
|
ev_queue.call_in(backoff+MBED_CONF_APP_TX_TIMER, send_message); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#if MBED_CONF_APP_BATTERY_ENABLED && MBED_CONF_APP_BATTERY_IN_LPP |
|
|
|
|
cayenne.addAnalogInput(1, battery_voltage()); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if MBED_CONF_APP_DHT_ENABLED |
|
|
|
|
int err = dht.read(); |
|
|
|
|
if(err == DHT::SUCCESS) { |
|
|
|
|
cayenne.addTemperature(MBED_CONF_APP_DHT_TEMP_LPP_ID, dht.getTemperature()); |
|
|
|
|
cayenne.addRelativeHumidity(MBED_CONF_APP_DHT_HUM_LPP_ID, dht.getHumidity()); |
|
|
|
|
cayenne.addTemperature(1, dht.getTemperature()); |
|
|
|
|
cayenne.addRelativeHumidity(1, dht.getHumidity()); |
|
|
|
|
} else { |
|
|
|
|
debug("Error code : %d\r\n", err); |
|
|
|
|
} |
|
|
|
|
@ -257,15 +172,11 @@ static void send_message() {
@@ -257,15 +172,11 @@ static void send_message() {
|
|
|
|
|
#if MBED_CONF_APP_HX711_ENABLED |
|
|
|
|
loadcell.powerUp(); |
|
|
|
|
if(loadcell.waitReadyRetry(20, 100)) { |
|
|
|
|
cayenne.addAnalogInput(MBED_CONF_APP_HX711_LPP_ID, loadcell.getUnits(5)); |
|
|
|
|
cayenne.addAnalogInput(2, loadcell.getUnits(5)); |
|
|
|
|
} |
|
|
|
|
loadcell.powerDown(); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if MBED_CONF_APP_BATTERY_ENABLED && MBED_CONF_APP_BATTERY_IN_LPP |
|
|
|
|
cayenne.addAnalogInput(MBED_CONF_APP_BATTERY_LPP_ID, battery_voltage()); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
// No data to send
|
|
|
|
|
if(cayenne.getSize() == 0) { |
|
|
|
|
return; |
|
|
|
|
@ -312,7 +223,13 @@ static void lora_event_handler(lorawan_event_t event) {
@@ -312,7 +223,13 @@ static void lora_event_handler(lorawan_event_t event) {
|
|
|
|
|
switch(event) { |
|
|
|
|
case CONNECTED: |
|
|
|
|
debug("\r\n Connection - Successful \r\n"); |
|
|
|
|
send_message(); |
|
|
|
|
if(MBED_CONF_LORA_DUTY_CYCLE_ON) { |
|
|
|
|
send_message(); |
|
|
|
|
} else { |
|
|
|
|
send_message(); |
|
|
|
|
ev_queue.call_every(MBED_CONF_APP_TX_TIMER, send_message); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
break; |
|
|
|
|
case DISCONNECTED: |
|
|
|
|
ev_queue.break_dispatch(); |
|
|
|
|
@ -320,12 +237,19 @@ static void lora_event_handler(lorawan_event_t event) {
@@ -320,12 +237,19 @@ static void lora_event_handler(lorawan_event_t event) {
|
|
|
|
|
break; |
|
|
|
|
case TX_DONE: |
|
|
|
|
debug("\r\n Message Sent to Network Server \r\n"); |
|
|
|
|
if(MBED_CONF_LORA_DUTY_CYCLE_ON) { |
|
|
|
|
send_message(); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case TX_TIMEOUT: |
|
|
|
|
case TX_ERROR: |
|
|
|
|
case TX_CRYPTO_ERROR: |
|
|
|
|
case TX_SCHEDULING_ERROR: |
|
|
|
|
debug("\r\n Transmission Error - EventCode = %d \r\n", event); |
|
|
|
|
// try again
|
|
|
|
|
if(MBED_CONF_LORA_DUTY_CYCLE_ON) { |
|
|
|
|
send_message(); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case RX_DONE: |
|
|
|
|
debug("\r\n Received message from Network Server \r\n"); |
|
|
|
|
@ -342,5 +266,3 @@ static void lora_event_handler(lorawan_event_t event) {
@@ -342,5 +266,3 @@ static void lora_event_handler(lorawan_event_t event) {
|
|
|
|
|
MBED_ASSERT("Unknown Event"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#endif // MBED_APP_MODE_BOOTSTRAP
|