-
Notifications
You must be signed in to change notification settings - Fork 0
/
application.c
446 lines (387 loc) · 11.5 KB
/
application.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
/*
* File: weather_application.c
* Author: C16783
*
* Created on May 18, 2020, 2:39 PM
*/
#include "mcc_generated_files/system/system.h"
#include <util/delay.h>
#include "application.h"
/**
Section: Variable Definitions
*/
#define DEFAULT_STANDBY_TIME BME280_STANDBY_HALFMS
#define DEFAULT_FILTER_COEFF BME280_FILTER_COEFF_OFF
#define DEFAULT_TEMP_OSRS BME280_OVERSAMP_X1
#define DEFAULT_PRESS_OSRS BME280_OVERSAMP_X1
#define DEFAULT_HUM_OSRS BME280_OVERSAMP_X1
#define DEFAULT_SENSOR_MODE BME280_FORCED_MODE
bool weather_initialized = 0;
bool label_initial = false;
/**
Section: Driver APIs
*/
void WeatherClick_initialize(void) {
BME280_reset();
_delay_ms(50);
BME280_readFactoryCalibrationParams();
BME280_config(BME280_STANDBY_HALFMS, BME280_FILTER_COEFF_OFF);
BME280_ctrl_meas(BME280_OVERSAMP_X1, BME280_OVERSAMP_X1, BME280_FORCED_MODE);
BME280_ctrl_hum(BME280_OVERSAMP_X1);
BME280_initializeSensor();
weather_initialized = 1;
}
void PrintUtility_enable(void) {
TERM_ReceiveEnable();
TERM_TransmitEnable();
}
void LR2_reset(void) {
#ifdef DEBUG
USB_sendStringRaw("\rResetting LR2 Click\n");
USB_sendStringRaw("----------------------------------------------------\n");
USB_sendStringRaw("Firmware: ");
#endif
/* Reset the RN2903 */
LR2_RST_SetHigh();
_delay_ms(100);
LR2_RST_SetLow();
_delay_ms(300);
LR2_RST_SetHigh();
_delay_ms(100);
LR2_RTS_SetHigh();
uint8_t done = 0;
char data;
while(!done)
{
if(LR2__IsRxReady()) {
TERM_tx_buff_Push(LR2_Read());
}
//if(TERM_tx_buff_Count() && TERM_IsTxReady()) {
if(TERM_IsTxReady()) {
data = TERM_tx_buff_Pop();
TERM_sendByte(data);
if(data== '\n') {
done = 1;
}
}
}
_delay_ms(1000);
}
void LR2_sendStringCmd(char *str)
{
//Print Command to the Terminal for Debug Purposes
USB_sendStringRaw("\r\nTx: ");
USB_sendStringRaw(str);
//Add the string to the LR2 Buffer
LR2_tx_buff_Push_Str(str);
//Transmit over the LR2 UART
for (uint8_t i = 0; str[i] != '\0'; )
{
if (LR2_IsTxReady())
{
LR2_Write(LR2_tx_buff_Pop());
i++;
}
}
//while(!TERM_IsTxReady());
_delay_ms(100);
}
void LR2_sendAppSKey(char *str)
{
//Print Command to the Terminal for Debug Purposes
//USB_sendStringRaw("\r\n");
USB_sendStringRaw("\r\nTx: mac set appskey\r\n");
LR2_tx_buff_Push_Str(str);
_delay_ms(100);
//Transmit over the LR2 UART
for (uint8_t i = 0; str[i] != '\0'; )
{
if (LR2_IsTxReady())
{
LR2_Write(LR2_tx_buff_Pop());
i++;
}
}
_delay_ms(100);
}
void LR2_sendNwkSKey(char *str)
{
//Print Command to the Terminal for Debug Purposes
USB_sendStringRaw("\r\nTx: mac set nwkskey\r\n");
LR2_tx_buff_Push_Str(str);
_delay_ms(100);
//Transmit over the LR2 UART
for (uint8_t i = 0; str[i] != '\0'; )
{
if (LR2_IsTxReady())
{
LR2_Write(LR2_tx_buff_Pop());
i++;
}
}
}
void LR2_recvRsp()
{
uint8_t done = 0;
USB_sendStringRaw("\rRx: ");
LR2_RTS_SetHigh();
while(!done)
{
if(LR2__IsRxReady()) {
TERM_tx_buff_Push(LR2_Read());
}
if(TERM_tx_buff_Count() && TERM_IsTxReady()) {
char data = TERM_tx_buff_Pop();
TERM_Write(data);
if(data== '\n') {
done = 1;
}
}
}
LR2_RTS_SetLow();
//_delay_ms(100);
}
// Receive 2 responses for mac join and mac tx
void LR2_recvRsp2()
{
uint8_t done = 0;
USB_sendStringRaw("Rx: ");
while(!done)
{
if(LR2__IsRxReady()) {
TERM_tx_buff_Push(LR2_Read());
}
if(TERM_tx_buff_Count() && TERM_IsTxReady()) {
char data = TERM_tx_buff_Pop();
TERM_Write(data);
if(data== '\n') {
done = 1;
}
}
}
}
void LR2_config_abp()
{
USB_sendStringRaw("\n\nConfiguring LR2 Click For ABP\n");
USB_sendStringRaw("-----------------------------------------------------------------------\n");
LR2_sendStringCmd("mac set deveui " DEVEUI "\r\n");
LR2_recvRsp();
LR2_sendStringCmd("mac set devaddr " DEVADDR "\r\n");
LR2_recvRsp();
LR2_sendAppSKey("mac set appskey " APPSKEY "\r\n");
LR2_recvRsp();
LR2_sendNwkSKey("mac set nwkskey " NWKSKEY "\r\n");
LR2_recvRsp();
LR2_sendStringCmd("mac set ar on\r\n");
LR2_recvRsp();
LR2_sendStringCmd("mac set rxdelay1 5000\r\n");
LR2_recvRsp();
LR2_sendStringCmd("mac set adr on\r\n");
LR2_recvRsp();
LR2_sendStringCmd("mac save\r\n");
LR2_recvRsp();
USB_sendStringRaw("\n\n");
_delay_ms(100);
}
void LR2_config_otaa()
{
USB_sendStringRaw("\n\nConfiguring LR2 Click for OTAA\n");
USB_sendStringRaw("-----------------------------------------------------------------------\n");
LR2_sendStringCmd("mac set deveui " DEVEUI "\r\n");
LR2_recvRsp();
LR2_sendStringCmd("mac set appkey " APPKEY "\r\n");
LR2_recvRsp();
LR2_sendStringCmd("mac set appeui " APPEUI "\r\n");
LR2_recvRsp();
LR2_sendStringCmd("mac set ar on\r\n");
LR2_recvRsp();
LR2_sendStringCmd("mac set rxdelay1 5000\r\n");
LR2_recvRsp();
LR2_sendStringCmd("mac set adr on\r\n");
LR2_recvRsp();
LR2_sendStringCmd("mac save\r\n");
LR2_recvRsp();
LR2_sendStringCmd("mac pause\r\n");
LR2_recvRsp();
_delay_ms(100);
LR2_sendStringCmd("mac resume\r\n");
LR2_recvRsp();
USB_sendStringRaw("\n\n");
_delay_ms(100);
}
void LR2_join_abp()
{
#ifdef DEBUG
USB_sendStringRaw("\n\nJoining TTN\n");
USB_sendStringRaw("-----------------------------------------------------------------------\n");
#endif
LR2_sendStringCmd("mac join abp\r\n");
LR2_recvRsp();
}
void LR2_join_otaa()
{
#ifdef DEBUG
USB_sendStringRaw("\n\nJoining TTN\n");
USB_sendStringRaw("-----------------------------------------------------------------------\n");
#endif
LR2_sendStringCmd("mac join otaa\r\n");
LR2_recvRsp2();
_delay_ms(1000);
}
void LR2_config()
{
//Prepare LR2 for Tx/Rx according to activation procedure (ABP or OTAA))
#ifdef ABP
//Set DEVEUI, DEVADDR, Session Keys, Auto Reply and Receive Window
LR2_config_abp();
#endif
#ifdef OTAA
//Set DEVEUI,DEVADDR, APPKEY, APPEUI, Auto Reply and Receive Window (5 sec)
LR2_config_otaa();
#endif
}
void LR2_join()
{
#ifdef ABP
//Join TTN using Activation By Personalization
LR2_join_abp();
#endif
#ifdef OTAA
//Join TTN using Over the Air Activation
LR2_join_otaa();
#endif
}
void WeatherClick_readSensors(void) {
if (DEFAULT_SENSOR_MODE == BME280_FORCED_MODE) {
BME280_startForcedSensing();
}
BME280_readMeasurements();
}
//Get 100 raw values from soil moisture sensor for calibration
void printRawValues() {
uint8_t count = 0;
uint16_t val;
uint16_t min = ADC0_GetConversion(7);
uint16_t max = min;
printf("\nAfter 100 Moisture Readings\n");
printf("-----------------------------------------------------------------------\n");
while(count < 100) {
val = ADC0_GetConversion(7);
if(val < min && val != 0){
min = val;
}
if(val > max) {
max = val;
}
//printf("%d\n",val);
count++;
}
printf("The MAX reading was %d\n", max);
printf("The MIN reading was %d\n\n", min);
printf("The MAX maps to %d\n", map(max));
printf("The MIN maps to %d\n", map(min));
}
uint8_t map(uint16_t raw) {
float val;
// Account for random sporadic outlier values well out of range
if(raw > IN_MAX) {
raw = IN_MAX;
}
if(raw < IN_MIN) {
raw = IN_MIN;
}
val = (raw - IN_MIN) * CONVERSION_PERCENT;
return 100 - (uint8_t) val;
}
uint8_t getMoistureMeasurement() {
uint16_t val = ADC0_GetConversion(7);
return map(val);
}
//Gets Data from the Weather Click and Soil Moisture Sensor
void getSensorData(sensor_data_t *data)
{
WeatherClick_readSensors();
data->temp = (int8_t) BME280_getTemperature();
data->press = BME280_getPressure();
data->humid = (uint8_t) BME280_getHumidity();
data->moist = getMoistureMeasurement();
#ifdef DEBUG
printSensorData(data); //To compare and demonstrate successful transmission
#endif
}
/*
* For Debug Purposes, prints retrieved data
*/
void printSensorData(sensor_data_t *data)
{
USB_sendStringRaw("\n\nCurrent Sensor Data\n");
USB_sendStringRaw("-----------------------------------------------------------------------\n");
printf("Relative Humidity: %u%% \r\n", data->humid);
printf("Moisture: %u%% \r\n", data->moist);
printf("Pressure: %u hPa\r\n", data->press);
printf("Temperature: %i C \r\n\n", data->temp);
printf("\nJSON Format\r\n");
printf("-----------------------------------------------------------------------\n");
printf("Payload: { humidity: %u, moisture: %u, pressure: %u, temperature: %i }\r\n\n", data->humid, data->moist, data->press, data->temp);
}
/**
* Converts Measurements to a Hex String for LoRa Transmission
* Temperature, Humidity and Moisture only require 2 hex chars, pressure
* requires 4 chars, RN2903 payload string is terminated with "\r\n\0"
*/
void formatPayload(char *str, sensor_data_t *data) {
char hex[]= "0123456789ABCDEF";
str[0] = hex[((data->temp >> 4) & 0x0F)];
str[1] = hex[data->temp & 0x0F];
str[2] = hex[((data->humid >> 4) & 0x0F)];
str[3] = hex[data->humid & 0x0F];
str[4] = hex[((data->moist >> 4) & 0x0F)];
str[5] = hex[data->moist & 0x0F];
str[6] = hex[((data->press >> 12) & 0x0F)];
str[7] = hex[((data->press >> 8) & 0x0F)];
str[8] = hex[((data->press >> 4) & 0x0F)];
str[9] = hex[data->press & 0x0F];
str[10] = '\r';
str[11] = '\n';
str[12] = '\0';
}
//Transmits a formatted payload string on port 1 using confirmed uplink
void LR2_tx(char *str) {
#ifdef DEBUG
USB_sendStringRaw("\n\nTransmitting Data\n");
USB_sendStringRaw("----------------------------------------------------\n");
//Prints Command and Payload on Terminal for debugging
USB_sendStringRaw("\nTx: mac tx cnf 42 ");
USB_sendStringRaw(str);
#endif
//Send Transmission to LR2 UART Tx
LR2_tx_buff_Push_Str("mac tx cnf 42 ");
LR2_tx_buff_Push_Str(str);
}
//Transmits a formatted payload string on port 1 using unconfirmed uplink
void LR2_tx_uncnf(char *str) {
#ifdef DEBUG
USB_sendStringRaw("\n\nTransmitting Data\n");
USB_sendStringRaw("----------------------------------------------------\n");
//Prints Command and Payload on Terminal for debugging
USB_sendStringRaw("\nTx: mac tx uncnf 43 ");
USB_sendStringRaw(str);
#endif
//Send Transmission to LR2 UART Tx
LR2_tx_buff_Push_Str("mac tx uncnf 43 ");
LR2_tx_buff_Push_Str(str);
}
void sendAndReceiveBuffers() {
if(TERM__IsRxReady()) {
LR2_tx_buff_Push(TERM_Read());
}
if(LR2__IsRxReady()) {
TERM_tx_buff_Push(LR2_Read());
}
if(TERM_tx_buff_Count() && TERM_IsTxReady()) {
TERM_Write(TERM_tx_buff_Pop());
}
if(LR2_tx_buff_Count() && LR2_IsTxReady()) {
LR2_Write(LR2_tx_buff_Pop());
}
}