LoRaWAN demo.

Dependencies:   modem_ref_helper DebouncedInterrupt

Committer:
Jeej
Date:
Fri Feb 19 14:58:25 2021 +0000
Revision:
21:f0aecd41db08
Parent:
20:49a8ecd1dda3
Updated for v5.6.x

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jeej 0:06ba20deb797 1 // @autor: jeremie@wizzilab.com
Jeej 0:06ba20deb797 2 // @date: 2017-09-21
Jeej 0:06ba20deb797 3
Jeej 0:06ba20deb797 4 #include "DebouncedInterrupt.h"
Jeej 20:49a8ecd1dda3 5 #include "modem_d7a.h"
Jeej 20:49a8ecd1dda3 6 #include "d7a_callbacks.h"
Jeej 20:49a8ecd1dda3 7 #include "lwan_callbacks.h"
Jeej 0:06ba20deb797 8 #include "files.h"
Jeej 0:06ba20deb797 9 #include "sensor.h"
Jeej 0:06ba20deb797 10
Jeej 0:06ba20deb797 11 // Minimum time between alarms
Jeej 0:06ba20deb797 12 #define ALARM_COOLDOWN_TIME 10000 // ms
Jeej 2:9112445299fa 13 #define MIN_REPORT_PERIOD (10) // Seconds
Jeej 0:06ba20deb797 14
Jeej 15:86f6fa566d89 15 Semaphore modem_urc(0);
Jeej 0:06ba20deb797 16 Semaphore button_user(0);
Jeej 0:06ba20deb797 17 sensor_config_t g_light_config;
Jeej 20:49a8ecd1dda3 18 Queue<uint8_t, 8> g_file_modified;
Jeej 20:49a8ecd1dda3 19 Queue<uint32_t, 8> g_urc;
Jeej 21:f0aecd41db08 20 int itf_busy;
Jeej 16:59d93cb1efee 21 Timer busy_tim;
Jeej 0:06ba20deb797 22
Jeej 1:bca89c43e171 23 bool alarm_ready = false;
Jeej 0:06ba20deb797 24
wizziguy 5:2d5d3124703a 25 #define USE_WL_TTN
wizziguy 5:2d5d3124703a 26 #ifdef USE_WL_TTN
wizziguy 5:2d5d3124703a 27 // This is WizziLab's The Things Network LoRaWAN configuration file
wizziguy 5:2d5d3124703a 28 // This device is already registered on WizziLab's APP
wizziguy 5:2d5d3124703a 29 //
wizziguy 5:2d5d3124703a 30 // You can create your own account to get custom app_id and app_key.
wizziguy 5:2d5d3124703a 31 // The device EUI is the modem's UID.
wizziguy 5:2d5d3124703a 32 // https://account.thethingsnetwork.org/register
wizziguy 5:2d5d3124703a 33 // https://console.thethingsnetwork.org/applications
wizziguy 5:2d5d3124703a 34
wizziguy 5:2d5d3124703a 35 #define MY_APP_ID {0x70, 0xB3, 0xD5, 0x7E, 0xF0, 0x00, 0x3A, 0xF1 }
wizziguy 5:2d5d3124703a 36 #define MY_APP_KEY {0x73, 0x90, 0x54, 0x78, 0xB5, 0x0B, 0xA8, 0x9A, 0x78, 0x23, 0xB7, 0x12, 0xD5, 0x5C, 0x70, 0x99 }
wizziguy 5:2d5d3124703a 37 #else
wizziguy 5:2d5d3124703a 38 // This is your APP_ID and APP_KEY, as defined on your own TTN account
wizziguy 5:2d5d3124703a 39 // https://account.thethingsnetwork.org/register
wizziguy 5:2d5d3124703a 40 // https://console.thethingsnetwork.org/applications
wizziguy 5:2d5d3124703a 41
wizziguy 5:2d5d3124703a 42 #define MY_APP_ID { 0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x00, 0xAC, 0xB2 }
wizziguy 5:2d5d3124703a 43 #define MY_APP_KEY { 0xDF, 0xF7, 0x26, 0x21, 0x22, 0xAD, 0x9A, 0xD6, 0x16, 0x84, 0xD1, 0x95, 0xBA, 0x8C, 0xD1, 0x1E }
wizziguy 5:2d5d3124703a 44
wizziguy 5:2d5d3124703a 45 #endif
wizziguy 5:2d5d3124703a 46
Jeej 20:49a8ecd1dda3 47 lwan_cfg_t lwan_cfg = {
Jeej 0:06ba20deb797 48 // LoRaWAN device class
Jeej 20:49a8ecd1dda3 49 .dev_class = LWAN_CLASS_A,
Jeej 0:06ba20deb797 50 // State of adaptative Datarate
Jeej 20:49a8ecd1dda3 51 .adr_enable = 1,
Jeej 0:06ba20deb797 52 // Uplink datarate, if adr_enable is off
Jeej 20:49a8ecd1dda3 53 .tx_datarate = 0,
Jeej 4:f83753357cdf 54 // ISM Band
Jeej 20:49a8ecd1dda3 55 .ism_band = ISM_BAND_868,
Jeej 20:49a8ecd1dda3 56 // maximum join attempts
Jeej 20:49a8ecd1dda3 57 .join_trials = 2,
Jeej 20:49a8ecd1dda3 58 // Rejoin period (hours)
Jeej 20:49a8ecd1dda3 59 .rejoin_period = 24
Jeej 20:49a8ecd1dda3 60 };
Jeej 20:49a8ecd1dda3 61
Jeej 20:49a8ecd1dda3 62 lwan_nls_t lwan_nls = {
Jeej 20:49a8ecd1dda3 63 // Application identifier
Jeej 20:49a8ecd1dda3 64 .app_id = MY_APP_ID,
Jeej 20:49a8ecd1dda3 65 // Application key
Jeej 20:49a8ecd1dda3 66 .app_key = MY_APP_KEY,
Jeej 0:06ba20deb797 67 };
Jeej 0:06ba20deb797 68
Jeej 20:49a8ecd1dda3 69 alp_d7a_itf_t report_itf = {
Jeej 20:49a8ecd1dda3 70 .type = ALP_ITF_TYPE_D7A,
Jeej 20:49a8ecd1dda3 71 .cfg.to = D7A_CTF(0),
Jeej 20:49a8ecd1dda3 72 .cfg.te = D7A_CTF(0),
Jeej 20:49a8ecd1dda3 73 .cfg.qos.bf.resp = D7A_RESP_PREFERRED,
Jeej 20:49a8ecd1dda3 74 .cfg.qos.bf.retry = ALP_RPOL_ONESHOT,
Jeej 20:49a8ecd1dda3 75 .cfg.addressee.ctrl.bf.nls = D7A_NLS_AES_CCM_64,
Jeej 20:49a8ecd1dda3 76 .cfg.addressee.ctrl.bf.idf = D7A_ID_NBID,
Jeej 20:49a8ecd1dda3 77 .cfg.addressee.xcl.bf = {.m = 0x1, .s = 2},// XXX D7A_XCL_GW,
Jeej 20:49a8ecd1dda3 78 .cfg.addressee.id = { D7A_CTF_ENCODE(2) }
Jeej 20:49a8ecd1dda3 79 };
Jeej 20:49a8ecd1dda3 80
Jeej 20:49a8ecd1dda3 81 modem_ref_callbacks_t callbacks = {
Jeej 20:49a8ecd1dda3 82 .read = my_read,
Jeej 20:49a8ecd1dda3 83 .write = my_write,
Jeej 20:49a8ecd1dda3 84 .read_fprop = my_read_fprop,
Jeej 20:49a8ecd1dda3 85 .flush = my_flush,
Jeej 20:49a8ecd1dda3 86 .remove = my_delete,
Jeej 20:49a8ecd1dda3 87 .udata = my_udata,
Jeej 20:49a8ecd1dda3 88 .lqual = my_lqual,
Jeej 20:49a8ecd1dda3 89 .ldown = my_ldown,
Jeej 20:49a8ecd1dda3 90 .reset = my_reset,
Jeej 20:49a8ecd1dda3 91 .boot = my_boot,
Jeej 20:49a8ecd1dda3 92 .busy = my_busy,
Jeej 20:49a8ecd1dda3 93 .itf_busy = NULL,
Jeej 20:49a8ecd1dda3 94 };
Jeej 20:49a8ecd1dda3 95
Jeej 20:49a8ecd1dda3 96 modem_lwan_callbacks_t lwan_callbacks = {
Jeej 20:49a8ecd1dda3 97 .packet_sent = lwan_packet_sent,
Jeej 20:49a8ecd1dda3 98 .itf_busy = lwan_busy,
Jeej 20:49a8ecd1dda3 99 .join_failed = lwan_join_failed,
Jeej 20:49a8ecd1dda3 100 };
Jeej 20:49a8ecd1dda3 101
Jeej 20:49a8ecd1dda3 102
Jeej 0:06ba20deb797 103 // Interrupt Service Routine on button press.
Jeej 0:06ba20deb797 104 void button_push_isr( void )
Jeej 0:06ba20deb797 105 {
Jeej 1:bca89c43e171 106 if (alarm_ready)
Jeej 0:06ba20deb797 107 {
Jeej 0:06ba20deb797 108 button_user.release();
Jeej 0:06ba20deb797 109 }
Jeej 0:06ba20deb797 110 else
Jeej 0:06ba20deb797 111 {
Jeej 0:06ba20deb797 112 PRINT("YOU CAN'T SEND ALARM AGAIN SO SOON.\n");
Jeej 0:06ba20deb797 113 }
Jeej 0:06ba20deb797 114 }
Jeej 0:06ba20deb797 115
Jeej 2:9112445299fa 116 static bool report_ok(uint32_t last_report_time)
Jeej 2:9112445299fa 117 {
Jeej 2:9112445299fa 118 // Do not send a report if it's been less than MIN_REPORT_PERIOD since the last report
Jeej 2:9112445299fa 119 if ((last_report_time/1000) < MIN_REPORT_PERIOD)
Jeej 2:9112445299fa 120 {
Jeej 2:9112445299fa 121 PRINT("Report Skipped, next in %ds min\n", MIN_REPORT_PERIOD - (last_report_time/1000));
Jeej 2:9112445299fa 122 return false;
Jeej 2:9112445299fa 123 }
Jeej 2:9112445299fa 124
Jeej 2:9112445299fa 125 return true;
Jeej 2:9112445299fa 126 }
Jeej 2:9112445299fa 127
Jeej 0:06ba20deb797 128 // Check parameters to see if data should be send
Jeej 20:49a8ecd1dda3 129 static bool report_needed(sensor_config_t* config, int32_t value, int32_t last_value, uint32_t last_report_time)
Jeej 0:06ba20deb797 130 {
Jeej 2:9112445299fa 131 switch (config->report_type)
Jeej 0:06ba20deb797 132 {
Jeej 0:06ba20deb797 133 case REPORT_ALWAYS:
Jeej 0:06ba20deb797 134 // Send a report at each measure
Jeej 20:49a8ecd1dda3 135 PRINT("Report always\r\n");
Jeej 2:9112445299fa 136 return report_ok(last_report_time);
Jeej 0:06ba20deb797 137 case REPORT_ON_DIFFERENCE:
Jeej 0:06ba20deb797 138 // Send a report when the difference between the last reported measure and the current mesure is greater than max_diff
Jeej 2:9112445299fa 139 if (abs(last_value - value) >= config->max_diff && config->max_diff)
Jeej 0:06ba20deb797 140 {
Jeej 20:49a8ecd1dda3 141 PRINT("Report on difference (last:%d new:%d max_diff:%d)\r\n", last_value, value, config->max_diff);
Jeej 2:9112445299fa 142 return report_ok(last_report_time);
Jeej 0:06ba20deb797 143 }
Jeej 0:06ba20deb797 144 break;
Jeej 0:06ba20deb797 145 case REPORT_ON_THRESHOLD:
Jeej 0:06ba20deb797 146 // Send a report when crossing a threshold
Jeej 2:9112445299fa 147 if ( (value >= config->threshold_high && last_value < config->threshold_high)
Jeej 2:9112445299fa 148 || (value <= config->threshold_low && last_value > config->threshold_low)
Jeej 2:9112445299fa 149 || (value < config->threshold_high && last_value >= config->threshold_high)
Jeej 2:9112445299fa 150 || (value > config->threshold_low && last_value <= config->threshold_low))
Jeej 0:06ba20deb797 151 {
Jeej 20:49a8ecd1dda3 152 PRINT("Reporton threshold (last:%d new:%d th:%d tl:%d)\r\n", last_value, value, config->threshold_high, config->threshold_low);
Jeej 2:9112445299fa 153 return report_ok(last_report_time);
Jeej 0:06ba20deb797 154 }
Jeej 0:06ba20deb797 155 break;
Jeej 0:06ba20deb797 156 default:
Jeej 0:06ba20deb797 157 break;
Jeej 0:06ba20deb797 158 }
Jeej 0:06ba20deb797 159
Jeej 0:06ba20deb797 160 // Send a report if it's been more than max_period since the last report
Jeej 2:9112445299fa 161 if (((last_report_time/1000) >= config->max_period) && config->max_period)
Jeej 0:06ba20deb797 162 {
Jeej 20:49a8ecd1dda3 163 PRINT("Report on period (max_period:%d time:%d)\r\n", config->max_period, last_report_time);
Jeej 2:9112445299fa 164 return report_ok(last_report_time);
Jeej 0:06ba20deb797 165 }
Jeej 0:06ba20deb797 166
Jeej 0:06ba20deb797 167 return false;
Jeej 0:06ba20deb797 168 }
Jeej 0:06ba20deb797 169
Jeej 0:06ba20deb797 170 void thread_file_modified()
Jeej 0:06ba20deb797 171 {
Jeej 0:06ba20deb797 172 uint8_t fid;
Jeej 0:06ba20deb797 173 osEvent evt;
Jeej 0:06ba20deb797 174
Jeej 0:06ba20deb797 175 while (true)
Jeej 0:06ba20deb797 176 {
Jeej 0:06ba20deb797 177 evt = g_file_modified.get();
Jeej 0:06ba20deb797 178 fid = (evt.status == osEventMessage)? (uint8_t)(uint32_t)evt.value.p : NULL;
Jeej 0:06ba20deb797 179
Jeej 0:06ba20deb797 180 switch (fid)
Jeej 0:06ba20deb797 181 {
Jeej 0:06ba20deb797 182 case FID_SENSOR_CONFIG:
Jeej 0:06ba20deb797 183 // Update sensor configuration
Jeej 20:49a8ecd1dda3 184 ram_fs_read(FID_SENSOR_CONFIG, (uint8_t*)&g_light_config, 0, SIZE_SENSOR_CONFIG);
Jeej 0:06ba20deb797 185 PRINT("Sensor configuration updated\r\n");
Jeej 0:06ba20deb797 186 break;
Jeej 0:06ba20deb797 187 default:
Jeej 0:06ba20deb797 188 break;
Jeej 0:06ba20deb797 189 }
Jeej 0:06ba20deb797 190 }
Jeej 0:06ba20deb797 191 }
Jeej 0:06ba20deb797 192
Jeej 20:49a8ecd1dda3 193 void d7a_thread()
Jeej 20:49a8ecd1dda3 194 {
Jeej 20:49a8ecd1dda3 195 light_value_t light_level;
Jeej 20:49a8ecd1dda3 196 light_value_t light_level_old = 0;
Jeej 21:f0aecd41db08 197 alp_payload_t* alp = NULL;
Jeej 20:49a8ecd1dda3 198 revision_t rev;
Jeej 20:49a8ecd1dda3 199
Jeej 20:49a8ecd1dda3 200 // To force a first report
Jeej 20:49a8ecd1dda3 201 uint32_t last_report_time = 0xFFFFFFFF;
Jeej 20:49a8ecd1dda3 202
Jeej 20:49a8ecd1dda3 203 // Add files to local file system
Jeej 20:49a8ecd1dda3 204 ram_fs_new(FID_SENSOR_CONFIG, (uint8_t*)&h_sensor_config, (uint8_t*)&f_sensor_config);
Jeej 20:49a8ecd1dda3 205 ram_fs_new(FID_ALARM, (uint8_t*)&h_alarm, (uint8_t*)&f_alarm);
Jeej 20:49a8ecd1dda3 206
Jeej 20:49a8ecd1dda3 207 DPRINT("D7A: Register Files\n");
Jeej 20:49a8ecd1dda3 208 // Allow remote access.
Jeej 20:49a8ecd1dda3 209 modem_declare_file(FID_SENSOR_CONFIG, (alp_file_header_t*)&h_sensor_config);
Jeej 20:49a8ecd1dda3 210 modem_declare_file(FID_ALARM, (alp_file_header_t*)&h_alarm);
Jeej 20:49a8ecd1dda3 211
Jeej 20:49a8ecd1dda3 212 PRINT("D7A: Notify Revision\n");
Jeej 21:f0aecd41db08 213 modem_d7a_enable_itf();
Jeej 20:49a8ecd1dda3 214
Jeej 20:49a8ecd1dda3 215 // Host revision file is in the modem. Update it.
Jeej 20:49a8ecd1dda3 216 modem_write_file(FID_HOST_REV, &f_rev, 0, sizeof(revision_t));
Jeej 20:49a8ecd1dda3 217
Jeej 20:49a8ecd1dda3 218 // Retrieve modem revision
Jeej 20:49a8ecd1dda3 219 modem_read_file(FID_WM_REV, &rev, 0, sizeof(revision_t));
Jeej 20:49a8ecd1dda3 220
Jeej 20:49a8ecd1dda3 221 // Send both to the server
Jeej 20:49a8ecd1dda3 222 // Build payload
Jeej 20:49a8ecd1dda3 223 alp = NULL;
Jeej 20:49a8ecd1dda3 224 alp = alp_payload_rsp_f_data(alp, FID_WM_REV, &rev, 0, sizeof(revision_t));
Jeej 20:49a8ecd1dda3 225 alp = alp_payload_rsp_f_data(alp, FID_HOST_REV, &f_rev, 0, sizeof(revision_t));
Jeej 20:49a8ecd1dda3 226 // Send
Jeej 21:f0aecd41db08 227 modem_remote_raw_alp((void*)&report_itf, alp, NULL, 10000);
Jeej 20:49a8ecd1dda3 228
Jeej 20:49a8ecd1dda3 229 // Get the sensor configuration
Jeej 20:49a8ecd1dda3 230 ram_fs_read(FID_SENSOR_CONFIG, (uint8_t*)&g_light_config, 0, SIZE_SENSOR_CONFIG);
Jeej 20:49a8ecd1dda3 231
Jeej 20:49a8ecd1dda3 232 while (true)
Jeej 20:49a8ecd1dda3 233 {
Jeej 20:49a8ecd1dda3 234 light_level = sensor_get_light();
Jeej 20:49a8ecd1dda3 235
Jeej 20:49a8ecd1dda3 236 //PRINT("Light %d\r\n", light_level);
Jeej 20:49a8ecd1dda3 237
Jeej 20:49a8ecd1dda3 238 if (report_needed(&g_light_config, light_level, light_level_old, last_report_time))
Jeej 20:49a8ecd1dda3 239 {
Jeej 20:49a8ecd1dda3 240 PRINT("D7A: Light report %d\r\n", light_level);
Jeej 21:f0aecd41db08 241
Jeej 21:f0aecd41db08 242 // Build payload
Jeej 21:f0aecd41db08 243 alp = NULL;
Jeej 21:f0aecd41db08 244 alp = alp_payload_rsp_f_data(alp, FID_SENSOR_LIGHT, &light_level, 0, SIZE_SENSOR_LIGHT);
Jeej 21:f0aecd41db08 245 // Send
Jeej 21:f0aecd41db08 246 modem_remote_raw_alp((void*)&report_itf, alp, NULL, 1000);
Jeej 20:49a8ecd1dda3 247
Jeej 20:49a8ecd1dda3 248 // Update
Jeej 20:49a8ecd1dda3 249 light_level_old = light_level;
Jeej 20:49a8ecd1dda3 250 last_report_time = 0;
Jeej 20:49a8ecd1dda3 251 }
Jeej 20:49a8ecd1dda3 252
Jeej 20:49a8ecd1dda3 253 // Update last report time
Jeej 20:49a8ecd1dda3 254 last_report_time += g_light_config.read_period;
Jeej 20:49a8ecd1dda3 255
Jeej 20:49a8ecd1dda3 256 ThisThread::sleep_for(g_light_config.read_period);
Jeej 20:49a8ecd1dda3 257 }
Jeej 20:49a8ecd1dda3 258 }
Jeej 20:49a8ecd1dda3 259
Jeej 20:49a8ecd1dda3 260 void lwan_thread()
Jeej 0:06ba20deb797 261 {
Jeej 0:06ba20deb797 262 alarm_t alarm;
Jeej 21:f0aecd41db08 263 alp_payload_t* alp = NULL;
Jeej 0:06ba20deb797 264
Jeej 20:49a8ecd1dda3 265 DebouncedInterrupt user_interrupt(DEBUG_BUTTON);
Jeej 20:49a8ecd1dda3 266 user_interrupt.attach(button_push_isr, IRQ_FALL, 500, true);
Jeej 0:06ba20deb797 267
Jeej 0:06ba20deb797 268 // Load alarm value
Jeej 20:49a8ecd1dda3 269 ram_fs_read(FID_ALARM, (uint8_t*)&alarm, 0, SIZE_ALARM);
Jeej 15:86f6fa566d89 270
Jeej 20:49a8ecd1dda3 271 PRINT("LoRaWAN: Update parameters\n");
Jeej 20:49a8ecd1dda3 272 modem_lwan_set_cfg(&lwan_cfg);
Jeej 20:49a8ecd1dda3 273 modem_lwan_set_nls(&lwan_nls);
Jeej 20:49a8ecd1dda3 274
Jeej 20:49a8ecd1dda3 275 PRINT("LoRaWAN: Start (first join)\n");
Jeej 20:49a8ecd1dda3 276 modem_lwan_open(&lwan_callbacks);
Jeej 0:06ba20deb797 277
Jeej 0:06ba20deb797 278 while (true)
Jeej 0:06ba20deb797 279 {
Jeej 0:06ba20deb797 280 // Wait for button press
Jeej 0:06ba20deb797 281 PRINT("PRESS BUTTON TO SEND LORAWAN ALARM...\r\n");
Jeej 1:bca89c43e171 282 alarm_ready = true;
Jeej 16:59d93cb1efee 283 button_user.acquire();
Jeej 1:bca89c43e171 284 alarm_ready = false;
Jeej 16:59d93cb1efee 285
Jeej 16:59d93cb1efee 286 itf_busy -= (int32_t)busy_tim.read();
Jeej 16:59d93cb1efee 287
Jeej 16:59d93cb1efee 288 if (itf_busy > 0)
Jeej 15:86f6fa566d89 289 {
Jeej 20:49a8ecd1dda3 290 PRINT("LoRaWAN: Still busy for %ds.\r\n", itf_busy);
Jeej 16:59d93cb1efee 291 busy_tim.reset();
Jeej 21:f0aecd41db08 292
Jeej 21:f0aecd41db08 293 lwan_status_t lwan;
Jeej 21:f0aecd41db08 294
Jeej 21:f0aecd41db08 295 modem_lwan_get_status(&lwan);
Jeej 21:f0aecd41db08 296
Jeej 21:f0aecd41db08 297 PRINT(
Jeej 21:f0aecd41db08 298 "LoRaWAN: Joined :%d\r\n"
Jeej 21:f0aecd41db08 299 " NetID :%d\r\n"
Jeej 21:f0aecd41db08 300 " IsmBand :%d\r\n"
Jeej 21:f0aecd41db08 301 " PublicNetwork :%d\r\n"
Jeej 21:f0aecd41db08 302 " UpLinkCounter :%d\r\n"
Jeej 21:f0aecd41db08 303 " DownLinkCounter :%d\r\n"
Jeej 21:f0aecd41db08 304 " TxDr :%d\r\n",
Jeej 21:f0aecd41db08 305 lwan.IsNetworkJoined,
Jeej 21:f0aecd41db08 306 lwan.NetID,
Jeej 21:f0aecd41db08 307 lwan.IsmBand,
Jeej 21:f0aecd41db08 308 lwan.PublicNetwork,
Jeej 21:f0aecd41db08 309 lwan.UpLinkCounter,
Jeej 21:f0aecd41db08 310 lwan.DownLinkCounter,
Jeej 21:f0aecd41db08 311 lwan.TxDr
Jeej 21:f0aecd41db08 312 );
Jeej 15:86f6fa566d89 313 }
Jeej 15:86f6fa566d89 314 else
Jeej 15:86f6fa566d89 315 {
Jeej 16:59d93cb1efee 316 busy_tim.stop();
Jeej 16:59d93cb1efee 317
Jeej 15:86f6fa566d89 318 // load/save value to keep choerency in case of remote access...
Jeej 20:49a8ecd1dda3 319 ram_fs_read(FID_ALARM, (uint8_t*)&alarm, 0, SIZE_ALARM);
Jeej 0:06ba20deb797 320
Jeej 15:86f6fa566d89 321 // Toggle alarm state
Jeej 15:86f6fa566d89 322 alarm = !alarm;
Jeej 15:86f6fa566d89 323
Jeej 20:49a8ecd1dda3 324 ram_fs_write(FID_ALARM, &alarm, 0, SIZE_ALARM);
Jeej 15:86f6fa566d89 325
Jeej 15:86f6fa566d89 326 PRINT("BUTTON ALARM %d\r\n", alarm);
Jeej 20:49a8ecd1dda3 327
Jeej 20:49a8ecd1dda3 328 // Build payload
Jeej 20:49a8ecd1dda3 329 alp = NULL;
Jeej 20:49a8ecd1dda3 330 alp = alp_payload_rsp_f_data(alp, FID_ALARM, &alarm, 0, sizeof(alarm_t));
Jeej 20:49a8ecd1dda3 331
Jeej 20:49a8ecd1dda3 332 // Send
Jeej 20:49a8ecd1dda3 333 modem_lwan_send(alp);
Jeej 15:86f6fa566d89 334 }
Jeej 15:86f6fa566d89 335 }
Jeej 15:86f6fa566d89 336 }
Jeej 15:86f6fa566d89 337
Jeej 0:06ba20deb797 338
Jeej 0:06ba20deb797 339 /*** Main function ------------------------------------------------------------- ***/
Jeej 0:06ba20deb797 340 int main()
Jeej 0:06ba20deb797 341 {
Jeej 0:06ba20deb797 342 // Start & initialize
Jeej 0:06ba20deb797 343 #ifdef DEBUG_LED
Jeej 0:06ba20deb797 344 DBG_OPEN(DEBUG_LED);
Jeej 0:06ba20deb797 345 #else
Jeej 0:06ba20deb797 346 DBG_OPEN(NC);
Jeej 0:06ba20deb797 347 #endif
Jeej 0:06ba20deb797 348 PRINT("\n"
Jeej 0:06ba20deb797 349 "-----------------------------------------\n"
Jeej 0:06ba20deb797 350 "-------------- Demo LoRaWAN -------------\n"
Jeej 0:06ba20deb797 351 "-----------------------------------------\n");
Jeej 20:49a8ecd1dda3 352
Jeej 20:49a8ecd1dda3 353 modem_open(&callbacks);
Jeej 0:06ba20deb797 354
Jeej 0:06ba20deb797 355 // Start file modified thread
Jeej 0:06ba20deb797 356 Thread th_file_modified(osPriorityNormal, 1024, NULL);
Jeej 0:06ba20deb797 357 osStatus status = th_file_modified.start(thread_file_modified);
Jeej 0:06ba20deb797 358 ASSERT(status == osOK, "Failed to start thread_file_modified (err: %d)\r\n", status);
Jeej 0:06ba20deb797 359
Jeej 0:06ba20deb797 360 // Start light measure thread
Jeej 0:06ba20deb797 361 Thread th_sensor_light(osPriorityNormal, 1024, NULL);
Jeej 20:49a8ecd1dda3 362 status = th_sensor_light.start(d7a_thread);
Jeej 20:49a8ecd1dda3 363 ASSERT(status == osOK, "Failed to start d7a_thread (err: %d)\r\n", status);
Jeej 0:06ba20deb797 364
Jeej 0:06ba20deb797 365 Thread but_th(osPriorityNormal, 1024, NULL);
Jeej 20:49a8ecd1dda3 366 status = but_th.start(lwan_thread);
Jeej 0:06ba20deb797 367 ASSERT(status == osOK, "Failed to start but thread (err: %d)\r\n", status);
Jeej 0:06ba20deb797 368
Jeej 0:06ba20deb797 369 #ifdef DEBUG_LED
Jeej 0:06ba20deb797 370 DigitalOut my_led(DEBUG_LED);
Jeej 0:06ba20deb797 371 #endif
Jeej 0:06ba20deb797 372
Jeej 0:06ba20deb797 373 // Set main task to lowest priority
Jeej 16:59d93cb1efee 374 osThreadSetPriority(osThreadGetId(), osPriorityLow);
Jeej 0:06ba20deb797 375 while(true)
Jeej 0:06ba20deb797 376 {
Jeej 16:59d93cb1efee 377 ThisThread::sleep_for(500);
Jeej 0:06ba20deb797 378 #ifdef DEBUG_LED
Jeej 0:06ba20deb797 379 my_led = !my_led;
Jeej 0:06ba20deb797 380 #endif
Jeej 0:06ba20deb797 381 }
Jeej 0:06ba20deb797 382 }