1
+ /* ********************************************************************
2
+ Learn Guide: BLE Temperature Monitoring Armband
3
+
4
+ Adafruit invests time and resources providing this open source code,
5
+ please support Adafruit and open-source hardware by purchasing
6
+ products from Adafruit!
7
+
8
+ MIT license, check LICENSE for more information
9
+ All text above, and the splash screen below must be included in
10
+ any redistribution
11
+ *********************************************************************/
12
+ #include < bluefruit.h>
13
+ #include < Adafruit_LittleFS.h>
14
+ #include < InternalFileSystem.h>
15
+ #include < Wire.h>
16
+ #include < Adafruit_NeoPixel.h>
17
+ #include " Adafruit_MCP9808.h"
18
+
19
+ // Read temperature in degrees Fahrenheit
20
+ #define TEMPERATURE_F
21
+ // uncomment the following line if you want to read temperature in degrees Celsius
22
+ // #define TEMPERATURE_C
23
+
24
+ // Feather NRF52840 Built-in NeoPixel
25
+ #define PIN 16
26
+ Adafruit_NeoPixel pixels (1 , PIN, NEO_GRB + NEO_KHZ800);
27
+
28
+ // Maximum temperature value for armband's fever indicator
29
+ // NOTE: This is in degrees Fahrenheit
30
+ float fever_temp = 100.4 ;
31
+
32
+ // temperature calibration offset is +0.5 to +1.0 degree
33
+ // to make axillary temperature comparible to ear or temporal.
34
+ float temp_offset = 0.5 ;
35
+
36
+ // Sensor read delay, in minutes
37
+ int sensor_delay = 1 ;
38
+
39
+ // Measuring your armpit temperature for a minimum of 12 minutes
40
+ // is equivalent to measuring your core body temperature.
41
+ int calibration_time = 12 ;
42
+
43
+ // BLE transmit buffer
44
+ char temperature_buf [8 ];
45
+
46
+ // BLE Service
47
+ BLEDfu bledfu; // OTA DFU service
48
+ BLEDis bledis; // device information
49
+ BLEUart bleuart; // uart over ble
50
+ BLEBas blebas; // battery
51
+
52
+ // Create the MCP9808 temperature sensor object
53
+ Adafruit_MCP9808 tempsensor = Adafruit_MCP9808();
54
+
55
+ void setup () {
56
+ Serial.begin (115200 );
57
+ Serial.println (" Wearable BlueFruit Temperature Sensor" );
58
+ Serial.println (" -------------------------------------\n " );
59
+
60
+
61
+ if (!tempsensor.begin (0x18 )) {
62
+ Serial.println (" Couldn't find MCP9808! Check your connections and verify the address is correct." );
63
+ while (1 );
64
+ }
65
+ Serial.println (" Found MCP9808!" );
66
+
67
+ // Sets the resolution of reading
68
+ tempsensor.setResolution (3 );
69
+
70
+ // Configure BLE
71
+ // Setup the BLE LED to be enabled on CONNECT
72
+ // Note: This is actually the default behaviour, but provided
73
+ // here in case you want to control this LED manually via PIN 19
74
+ Bluefruit.autoConnLed (true );
75
+
76
+ // Config the peripheral connection with maximum bandwidth
77
+ Bluefruit.configPrphBandwidth (BANDWIDTH_MAX);
78
+
79
+ Bluefruit.begin ();
80
+ Bluefruit.setTxPower (4 ); // Check bluefruit.h for supported values
81
+ Bluefruit.setName (" Bluefruit52" );
82
+ Bluefruit.Periph .setConnectCallback (connect_callback);
83
+ Bluefruit.Periph .setDisconnectCallback (disconnect_callback);
84
+
85
+ // To be consistent OTA DFU should be added first if it exists
86
+ bledfu.begin ();
87
+
88
+ // Configure and Start Device Information Service
89
+ bledis.setManufacturer (" Adafruit Industries" );
90
+ bledis.setModel (" Bluefruit Feather52" );
91
+ bledis.begin ();
92
+
93
+ // Configure and Start BLE Uart Service
94
+ bleuart.begin ();
95
+
96
+ // Start BLE Battery Service
97
+ blebas.begin ();
98
+ blebas.write (100 );
99
+
100
+ // Set up and start advertising
101
+ startAdv ();
102
+
103
+ Serial.println (" Please use Adafruit's Bluefruit LE app to connect in UART mode" );
104
+
105
+ // initialize neopixel object
106
+ pixels.begin ();
107
+
108
+ // set all pixel colors to 'off'
109
+ pixels.clear ();
110
+ }
111
+
112
+ void loop () {
113
+
114
+ // wakes up MCP9808 - power consumption ~200 mikro Ampere
115
+ Serial.println (" Wake up MCP9808" );
116
+ tempsensor.wake ();
117
+
118
+ // read and print the temperature
119
+ Serial.print (" Temp: " );
120
+ #if defined(TEMPERATURE_F)
121
+ float temp = tempsensor.readTempF ();
122
+ // add temperature offset
123
+ temp += temp_offset;
124
+ Serial.print (temp);
125
+ Serial.println (" *F." );
126
+ #elif defined(TEMPERATURE_C)
127
+ float temp = tempsensor.readTempC ();
128
+ // add temperature offset
129
+ temp += temp_offset;
130
+ Serial.print (temp);
131
+ Serial.println (" *C." );
132
+ #else
133
+ #warning "Must define TEMPERATURE_C or TEMPERATURE_F!"
134
+ #endif
135
+
136
+ // set NeoPixels to RED if fever_temp
137
+ if (temp >= fever_temp) {
138
+ pixels.setPixelColor (1 , pixels.Color (255 , 0 , 0 ));
139
+ pixels.show ();
140
+ }
141
+
142
+ // float to buffer
143
+ snprintf (temperature_buf, sizeof (temperature_buf) - 1 , " %0.*f" , 1 , temp);
144
+
145
+ if (calibration_time == 0 ) {
146
+ Serial.println (" Writing to UART" );
147
+ // write to UART
148
+ bleuart.write (temperature_buf);
149
+ }
150
+ else {
151
+ Serial.print (" Calibration time:" );
152
+ Serial.println (calibration_time);
153
+ calibration_time-=1 ;
154
+ }
155
+
156
+ // shutdown MSP9808 - power consumption ~0.1 mikro Ampere
157
+ Serial.println (" Shutting down MCP9808" );
158
+ tempsensor.shutdown_wake (1 );
159
+
160
+ // sleep for sensor_delay minutes
161
+ // NOTE: NRF delay() puts mcu into a low-power sleep mode
162
+ delay (1000 *60 *sensor_delay);
163
+ }
164
+
165
+ void startAdv (void )
166
+ {
167
+ // Advertising packet
168
+ Bluefruit.Advertising .addFlags (BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
169
+ Bluefruit.Advertising .addTxPower ();
170
+
171
+ // Include bleuart 128-bit uuid
172
+ Bluefruit.Advertising .addService (bleuart);
173
+
174
+ // Secondary Scan Response packet (optional)
175
+ // Since there is no room for 'Name' in Advertising packet
176
+ Bluefruit.ScanResponse .addName ();
177
+
178
+ /* Start Advertising
179
+ * - Enable auto advertising if disconnected
180
+ * - Interval: fast mode = 20 ms, slow mode = 152.5 ms
181
+ * - Timeout for fast mode is 30 seconds
182
+ * - Start(timeout) with timeout = 0 will advertise forever (until connected)
183
+ *
184
+ * For recommended advertising interval
185
+ * https://developer.apple.com/library/content/qa/qa1931/_index.html
186
+ */
187
+ Bluefruit.Advertising .restartOnDisconnect (true );
188
+ Bluefruit.Advertising .setInterval (32 , 244 ); // in unit of 0.625 ms
189
+ Bluefruit.Advertising .setFastTimeout (30 ); // number of seconds in fast mode
190
+ Bluefruit.Advertising .start (0 ); // 0 = Don't stop advertising after n seconds
191
+ }
192
+
193
+ // callback invoked when central connects
194
+ void connect_callback (uint16_t conn_handle)
195
+ {
196
+ // Get the reference to current connection
197
+ BLEConnection* connection = Bluefruit.Connection (conn_handle);
198
+
199
+ char central_name[32 ] = { 0 };
200
+ connection->getPeerName (central_name, sizeof (central_name));
201
+
202
+ Serial.print (" Connected to " );
203
+ Serial.println (central_name);
204
+ }
205
+
206
+ /* *
207
+ * Callback invoked when a connection is dropped
208
+ * @param conn_handle connection where this event happens
209
+ * @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
210
+ */
211
+ void disconnect_callback (uint16_t conn_handle, uint8_t reason)
212
+ {
213
+ (void ) conn_handle;
214
+ (void ) reason;
215
+
216
+ Serial.println ();
217
+ Serial.print (" Disconnected, reason = 0x" ); Serial.println (reason, HEX);
218
+ }
0 commit comments