-
Notifications
You must be signed in to change notification settings - Fork 1
/
Outdoor-Weather-Sensor.ino
267 lines (223 loc) · 9.33 KB
/
Outdoor-Weather-Sensor.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
/* -----------------------------------------------------------------
Outdoor Weather Sensor
https://github.com/Andy4495/Outdoor-Weather-Sensor
10/22/17 - A.T. - Original
11/03/17 - A.T. - Add internal MSP430 temp and voltage sensing
- Add SHT21 temp and humidity sensing
- Converted float code to int
- Code and comment cleanup
11/12/17 - A.T. - Removed Object Temperature measurement from
TMP006 because it requires floating point
calculation.
11/18/17 - A.T. - Updated to use F5529
12/20/17 - A.T. - Increase sleep time (and fix data type).
01/02/18 - A.T. - Major update:
- Change to SENSORS BoosterPack instead of SENSORHUB
- Embrace floats for measurements, in order to be
able to use existing libraries
- Remove references to FRAM and circular buffer
(previously used to store weather data in NVM).
- Remove support for built-in LCD, since code is
specific to F5529 LaunchPad
01/17/18 - A.T. - Use MspTandV library
- Change lux measurement from int to long.
02/01/18 - A.T. - Update message structure to align on word boundary.
03/12/18 - A.T. - Changed TX to Channel 4 to allow use of repeater
Default is Chananel 4.
Press and hold PUSH1/S1/P2.1 during reset to
change to Channel 1.
10/20/18 - A.T. - Use Software I2C (SWI2C) for comms with SENSORS BoosterPack.
Implement custom interface to TMP007, OPT3001, BME280
sensors.
Cut down code size to fit on MSP430G2553.
Go back to integer-only math.
Use sleepSeconds(), so sleep time is now in seconds, not ms
11/10/18 - A.T. - Fix TMP007 temp calculations in "sensor_functions.h" (signed
value, so don't clear the sign bit)
05/19/20 - A.T. - Sensor interfacing moved to new Weather_Sensors_SWI2C library.
08/16/20 - A.T. - Re-arrange calls to library to optimize code size.
Comment out code that prints out packet data; uncomment if needed for debugging.
02/21/22 - A.T. - Minor updates.
*/
/* -----------------------------------------------------------------
Design is specific to MSP430G2553, SENSORS BoosterPack, and
CC110L BoosterPack.
With minor modifications (e.g. BOARD_LED and PUSH2 definitions), this could be modified
to work with other MSP430 variants.
Configuration:
- Update sleepTime variable to set the number of milliseconds to
sleep between sensor readings.
- Define BOARD_LED to the LED name appropriate for the board:
- For FR6989 and F5529, use #DEFINE BOARD_LED RED_LED
- For FR4133, use #DEFINE BOARD_LED LED2
- For G2553, Do not define BOARD_LED
setup()
I/O and sensor setup
MSP430 temperature calibration
loop()
Read and process individual sensor data
Send data to receiver hub
Data collected: Units
- BME280 sensor: Temperature 0.1 degrees F
Humidity 0.1 %RH
Pressure 0.01 mmHg
- TMP007 sensor: Die temperature 0.1 degrees F
External temperature 0.1 degrees F
- OPT3001 sensor: Ambient light lux
- MSP430: Internal Temperature 0.1 degrees F
- MSP430: Supply voltage (Vcc) mV
- Internal Timing:
# of times loop() has run
Current value of millis()
External libraries:
Weather_Sensors_SWI2C
https://github.com/Andy4495/Weather_Sensors_SWI2C
Software I2C "SWI2C"
https://github.com/Andy4495/SWI2C
Calibrated Temp and Vcc library "MspTandV"
https://github.com/Andy4495/MspTandV
*/
// ****** Compile-time Configuration Options ****** //
// If using without CC110L BoosterPack,
// then comment out the following line:
#define ENABLE_RADIO
// G2553 LED conflict with CC110L BoosterPack, so don't use
//#define BOARD_LED RED_LED
const unsigned long sleepTime = 55; // Seconds, not ms
// ************************************************ //
#include "Weather_Sensors_SWI2C.h"
#include "MspTandV.h"
#include <SPI.h>
#include <AIR430BoostFCC.h>
// CC110L Declarations
#define ADDRESS_LOCAL 0x02 // This device
#define ADDRESS_REMOTE 0x01 // Receiver hub
channel_t txChannel = CHANNEL_4; // Can be changed with PUSH2
enum {WEATHER_STRUCT, TEMP_STRUCT};
struct WeatherData {
int BME280_T; // Tenth degrees F
unsigned int BME280_P; // Pressure in inches of Hg * 100
int BME280_H; // % Relative Humidity
int TMP007_Ti; // Tenth degrees F
int TMP007_Te; // Tenth degrees F
unsigned long LUX; // Lux units
int MSP_T; // Tenth degrees F
unsigned int Batt_mV; // milliVolts
unsigned int Loops;
unsigned long Millis;
};
struct sPacket
{
uint8_t from; // Local node address that message originated from
uint8_t struct_type; // Flag to indicate type of message structure
union {
uint8_t message[58]; // Local node message keep even word boundary
WeatherData weatherdata;
};
};
struct sPacket txPacket;
#define SDA_PIN 10
#define SCL_PIN 9
#define TMP007_ADDRESS 0x40
#define OPT3001_ADDRESS 0x47
#define BME280_ADDRESS 0x77
TMP007_SWI2C myTMP007(SDA_PIN, SCL_PIN, TMP007_ADDRESS);
OPT3001_SWI2C myOPT3001(SDA_PIN, SCL_PIN, OPT3001_ADDRESS);
BME280_SWI2C myBME280(SDA_PIN, SCL_PIN, BME280_ADDRESS);
MspTemp msp430Temp;
MspVcc msp430Vcc;
unsigned int loopCount = 0;
void setup() {
Serial.begin(9600);
pinMode(PUSH2, INPUT_PULLUP); // Used to select TX channel
#ifdef BOARD_LED
digitalWrite(BOARD_LED, LOW);
pinMode(BOARD_LED, OUTPUT);
#endif
// If PUSH2 pressed during reset, then use CH1. Otherwise, use default (CH4).
if ( digitalRead(PUSH2) == LOW) txChannel = CHANNEL_1;
if (txChannel == CHANNEL_1) Serial.println("TX: CHANNEL_1");
else Serial.println("TX: CHANNEL_4");
// CC110L Setup
txPacket.from = ADDRESS_LOCAL;
txPacket.struct_type = WEATHER_STRUCT;
memset(txPacket.message, 0, sizeof(txPacket.message));
#ifdef ENABLE_RADIO
Serial.println(F("Radio Enabled"));
Radio.begin(ADDRESS_LOCAL, txChannel, POWER_MAX);
Serial.print("Tx 'From' address: ");
Serial.println(txPacket.from);
#endif
myTMP007.begin();
Serial.println("TMP007 Init");
myOPT3001.begin();
Serial.println("OPT3001 Init");
myBME280.begin();
Serial.println("BME280 Init");
#ifdef BOARD_LED
// Flash the LED to indicate we started
// Number of flashes indicates TX channel number
int flashes = 4;
if (txChannel == CHANNEL_1) flashes = 1;
for (int i = 0; i < flashes; i++) {
digitalWrite(BOARD_LED, HIGH);
delay(350);
digitalWrite(BOARD_LED, LOW);
delay(350);
}
#endif
}
void loop() {
loopCount++;
myTMP007.readSensor();
myOPT3001.readSensor();
myBME280.readSensor();
msp430Temp.read(CAL_ONLY); // Only get the calibrated reading
msp430Vcc.read(CAL_ONLY); // Only get the calibrated reading
txPacket.weatherdata.BME280_T = myBME280.getTempF();
txPacket.weatherdata.BME280_P = myBME280.getPressureInHg();
txPacket.weatherdata.BME280_H = myBME280.getRH();
txPacket.weatherdata.TMP007_Ti = myTMP007.getIntTempF();
txPacket.weatherdata.TMP007_Te = myTMP007.getExtTempF();
txPacket.weatherdata.LUX = myOPT3001.getLux();
txPacket.weatherdata.MSP_T = msp430Temp.getTempCalibratedF();
txPacket.weatherdata.Batt_mV = msp430Vcc.getVccCalibrated();
txPacket.weatherdata.Loops = loopCount;
txPacket.weatherdata.Millis = millis();
Serial.print("TMP007 Int (0.1 C): ");
Serial.println(myTMP007.getIntTempC());
Serial.print("TMP007 Int (0.1 F): ");
Serial.println(txPacket.weatherdata.TMP007_Ti);
Serial.print("TMP007 Ext (0.1 C): ");
Serial.println(myTMP007.getExtTempC());
Serial.print("TMP007 Ext (0.1 F): ");
Serial.println(txPacket.weatherdata.TMP007_Te);
Serial.print("OTP3001 Lux: ");
Serial.println(txPacket.weatherdata.LUX);
Serial.print("BME280 T (0.01 C): ");
Serial.println(myBME280.getTempC());
Serial.print("BME280 T (0.1 F): ");
Serial.println(txPacket.weatherdata.BME280_T);
Serial.print("BME280 P (Pa): ");
Serial.println(myBME280.getPressurePa());
Serial.print("BME280 P (0.01 inHG): ");
Serial.println(txPacket.weatherdata.BME280_P);
Serial.print("BME280 H (0.1%RH): ");
Serial.println(txPacket.weatherdata.BME280_H);
// MSP430 internal temp sensor
Serial.println("MSP430");
Serial.print(" Temp (0.1 F): ");
Serial.println(txPacket.weatherdata.MSP_T);
// MSP430 battery voltage (Vcc)
Serial.print(" Batt (mV): ");
Serial.println(txPacket.weatherdata.Batt_mV);
// Loop count and millis
Serial.print("Loops, millis: ");
Serial.print(loopCount);
Serial.print(", ");
Serial.println(txPacket.weatherdata.Millis);
#ifdef ENABLE_RADIO
Radio.transmit(ADDRESS_REMOTE, (unsigned char*)&txPacket, sizeof(WeatherData) + 4);
#endif
sleepSeconds(sleepTime);
}