/
AirSensorNodeMoteV2.ino
320 lines (271 loc) · 10.1 KB
/
AirSensorNodeMoteV2.ino
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
/*****************************************************
* Initial version of the Air Sensor Node
* assumes a circuit that includes:
* - Moteino (433MHz, RFM69HW)
* - DHT22 + 10K resistor
* - TCS34725
* - RGB 5mm LED + 3 330 ohm resistors
* Copyright M Johnson 12/2013
******************************************************/
#include <Narcoleptic.h>
//Turn on/off debug statements by setting DEBUG to 1 BEFORE including debugHelpers.h
#define DEBUG 1
#include <debugHelpers.h>
#define SERIAL_BAUD 115200
typedef enum State{
LOW_SIGNAL_STRENGTH,
NOT_WORKING_SENSORS,
DATA_NOT_SENT,
WORKING
}
State;
State state;
const uint8_t redPin = 3;
const uint8_t greenPin = 5;
const uint8_t bluePin = 6;
/******************************************************************************
* Start of initializing
*******************************************************************************/
/*****************************************************
* RFM69
******************************************************/
#include <SPI.h>
#include <SPIFlash.h>
#include <RFM69.h>
#define NODEID 2 //unique for each node on same network
#define NETWORKID 100 //the same on all nodes that talk to each other
#define BASESYSTEMID 1
#define FREQUENCY RF69_433MHZ
RFM69 radio;
const uint8_t SEND_RETRIES = 5;
//amount of time to wait between sensor readings
const uint16_t MS_DELAY=5000;
/*****************************************************
* Let the sketch know the number of sensor readings
* Each reading takes 2 bytes. The first byte lets the rx know the
* total number of sensor readings. V1 has 4 readings: Humidity, Air Temp, LUX, and Color Temp
******************************************************/
const byte NUMSENSORREADINGS=4;
unsigned char sensorReadings[NUMSENSORREADINGS*2+1] = {
0};
/*****************************************************
* DHT22 Temp and Humidity Sensor
******************************************************/
#include <DHT.h>
const byte DHTPIN=7;
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
/*****************************************************
* TCS34725 light sensor
******************************************************/
//I2C library
#include <Wire.h>
#include "Adafruit_TCS34725.h"
Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_700MS, TCS34725_GAIN_1X);
void setup() {
#if DEBUG
Serial.begin(SERIAL_BAUD);
#endif
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
DEBUG_PRINTLNF("************** SensorNodeMoteV1 ***************");
DEBUG_PRINTF("****>>>>Free Ram: ");
DEBUG_PRINTLN(getFreeRam());
DEBUG_PRINTF("****>>>>Sketch Size: ");
DEBUG_PRINT(sketchSize());
DEBUG_PRINTLNF("");
//blink blue
blink(0,0,255,5,50);
radio.initialize(FREQUENCY,NODEID,NETWORKID);
radio.setHighPower();
//blink green
blink(0,255,0,5,50);
//turn LED off
setColor(0,0,0);
//at least start the loop if we got this far
/******************************************************************************
* Set the state of the device to WORKING.
*******************************************************************************/
state = WORKING;
/******************************************************************************
* End of initializing
*******************************************************************************/
}
void loop() {
/******************************************************************************
* Check to see if the battery level is low. If it is, give a visual clue through the RGB.
*******************************************************************************/
//*****>>>>>TBD: check battery level
/******************************************************************************
* Read sensors and send readings to the Base System.
*******************************************************************************/
doTasks();
if (state == NOT_WORKING_SENSORS) {
//LED = aqua: Failed to get sensor readings
blink(0,255,255,2,50);
}
else if (state == DATA_NOT_SENT) {
//blink purple: Failed to find the Base System
blink(128,0,128,2,50);
}
//successfully read and sent sensor data
else {
//blink green
blink(0,255,0,2,50);
}
delay(MS_DELAY);
}
/******************************************************************************
* Shift the bits around to be the right order to send on the wire
*******************************************************************************/
uint16_t wireValue(uint16_t value,unsigned char *buf) {
buf[0] = value >> 8;
buf[1] = value;
return value;
}
/******************************************************************************
* narcoleptic library at https://code.google.com/p/narcoleptic/
* The Narcoleptic sleep function can range from 16 to 8,000 milliseconds (eight seconds).
* This helper function allows for longer (low power) sleeping
*******************************************************************************/
void narcolepticDelay(long milliseconds)
{
while(milliseconds > 0)
{
if(milliseconds > 8000)
{
milliseconds -= 8000;
Narcoleptic.delay(8000);
}
else
{
Narcoleptic.delay(milliseconds);
break;
}
}
}
/******************************************************************************
* Set the RGB 0 (OFF) to 255 (MAX) from http://arduino.cc/en/Tutorial/ReadASCIIString
*******************************************************************************/
void setColor( uint8_t red, uint8_t green, uint8_t blue)
{
// constrain the values to 0 - 255 and invert
red = 255 - constrain(red, 0, 255);
green = 255 - constrain(green, 0, 255);
blue = 255 - constrain(blue, 0, 255);
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}
/******************************************************************************
* Read Sensors and send readings to Base System
*******************************************************************************/
void doTasks() {
byte currentPosInSensorReadings = 1;
float floatVal;
uint16_t value;
/******************************************************************************
* Try several times to get the sensor readings
*******************************************************************************/
for (byte i=0; i<=SEND_RETRIES; i++) {
/******************************************************************************
* Readings from DHT22
*******************************************************************************/
//----------------- HUMIDITY --------------------------
floatVal = dht.readHumidity();
//check if a valid float was returned
if (!isnan(floatVal)) {
//round to higher integer
value = floatVal + .5;
value = wireValue(value,&sensorReadings[currentPosInSensorReadings]);
currentPosInSensorReadings += 2;
DEBUG_PRINTF("\n---> Humidity: ");
DEBUG_PRINTLN(value);
}
else {
DEBUG_PRINTF("\n---> ERROR: Could not read the Humidity from the DHT22");
state = NOT_WORKING_SENSORS;
return;
}
//----------------- AIR TEMPERATURE --------------------
floatVal = dht.readTemperature();
//check if a valid float was returned
if (!isnan(floatVal)) {
//convert to Fahrenheit
floatVal = round(floatVal*9.0/5.0+32.0);
//then round to higher integer
value = floatVal + .5;
value = wireValue(value,&sensorReadings[currentPosInSensorReadings]);
currentPosInSensorReadings += 2;
DEBUG_PRINTF("\n---> Air Temp: ");
DEBUG_PRINTLN(value);
}
else {
DEBUG_PRINTF("\n---> ERROR: Could not read the air temp");
state = NOT_WORKING_SENSORS;
return;
}
/******************************************************************************
* Readings from TCS34725
*******************************************************************************/
//----------------- COLOR TEMPERATURE -------------------
uint16_t r, g, b, c;
tcs.getRawData(&r, &g, &b, &c);
value = tcs.calculateColorTemperature(r, g, b);
if (!isnan(value)) {
value = wireValue(value,&sensorReadings[currentPosInSensorReadings]);
currentPosInSensorReadings += 2;
DEBUG_PRINTF("\n---> Color Temp: ");
DEBUG_PRINTLN(value);
}
else {
DEBUG_PRINTF("\n---> ERROR: Could not read the color temp");
state = NOT_WORKING_SENSORS;
return;
}
//----------------- LUX ----------------------------------
value = tcs.calculateLux(r, g, b);
if (!isnan(value)) {
value = wireValue(value,&sensorReadings[currentPosInSensorReadings]);
DEBUG_PRINTF("\n---> LUX: ");
DEBUG_PRINTLN(value);
}
else {
DEBUG_PRINTF("\n---> ERROR: Could not read the LUX");
state = NOT_WORKING_SENSORS;
return;
}
if (state == WORKING) break;
}
/******************************************************************************
* Send readings to the Base System
*******************************************************************************/
// RFM69.cpp defaults: bool sendWithRetry(byte toAddress, const void* buffer, byte bufferSize, byte retries=2, byte retryWaitTime=15);
//Try several times to give time for the Base System to send an ACK
for (byte i=0; i<=SEND_RETRIES; i++)
{
if (radio.sendWithRetry(BASESYSTEMID, sensorReadings,sizeof sensorReadings)) {
DEBUG_PRINTF("\n---> Sensor readings received by Base System....");
DEBUG_PRINTF(" [RX_RSSI:");
DEBUG_PRINT(radio.RSSI);
DEBUG_PRINTLNF("]");
return;
}
}
DEBUG_PRINTLNF("---> Could not send sensor readings to Base System");
state = DATA_NOT_SENT;
return;
}
/******************************************************************************
* Blink the RGB LED with a color of red, green, blue
* numTimesToBlink. Delay delay_ms between turning on/off blink
*******************************************************************************/
void blink(uint8_t red,uint8_t green,uint8_t blue,uint8_t numTimesToBlink,uint16_t delay_ms) {
for (int i=0;i<numTimesToBlink;i++) {
setColor(red,green,blue);
delay(delay_ms);
setColor(0,0,0);
delay(delay_ms);
}
}