I have repo code that I am working on as part of an internship that they have me trying to get to work with a sensor. When I load the code and upload it it doesn't seem to want to update the shadow onto AWS. The timestamp appears but the sensor readings don't show up (temp, humidity, etc). Can anyone look at the code that is familiar with AWS and help me figure out why this wont update? Please be aware that this is public repo that I am just working with and I didnt write this code. I am simply trying to make it work as part of my assignment for work.
1 #include <eeprom.h>
2 #include <time.h>
3 #include "adp5350.h"
4 #include "certs.h"
5 #include <wificlientsecure.h>
6 #include <mqttclient.h>
7 #include "ESPAsyncWebServer.h"
8 #include <espmdns.h>
9
10 #include <adafruit_bme280.h>
11
12 #include <wifi.h>
15
16 char WIFI_SSID[]="Your WiFi SSID Here";
18 char WIFI_PASSWORD[]="Your WiFi Password Here";
19
20 int status = WL_IDLE_STATUS;
22
23 char payload[512];
25
26 int counter = 0;
28
29 #define BME_SCL 4
31 #define BME_SDA 19
32 TwoWire I2CBME = TwoWire(0);
33 Adafruit_BME280 bme;
34
35 ADP5350 adp;
37
38 #define uS_TO_S_FACTOR 1000000ULL /* Conversion factor for micro seconds to seconds */
40 #define TIME_TO_SLEEP 30 * 60 /* Time ESP32 will go to sleep (in seconds) */
41
42 #define WAKEUP_PIN 35
43
44 struct READY_PIN {
46 const uint8_t PIN;
47 bool pressed;
48 };
49
50 READY_PIN ready_pin = { 16, false };
51
52 void IRAM_ATTR isr() {
53 ready_pin.pressed = true;
54 }
55
56 void IRAM_ATTR wakeup_isr() {
57 Serial.println("wakeup pin pressed");
58 }
59
60 int startTimeMicros;
61 int endTimeMicros;
62
63 #define DEVICE_NAME "co2-sensor"
65
66 #define AWS_IOT_ENDPOINT "a1qphq4dovfqf6-ats.iot.us-east-2.amazonaws.com"
68
69 #define AWS_IOT_TOPIC "$aws/things/co2-sensor/shadow/update"
71
73 #define AWS_MAX_RECONNECT_TRIES 50
75
76 WiFiClientSecure net = WiFiClientSecure();
77 MQTTClient client = MQTTClient(512);
78
79 hw_timer_t * timer = NULL;
80 portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
81 AsyncWebServer server(80);
82 bool sleepFlag = false;
83
84 void IRAM_ATTR timerExpired() {
85 Serial.println("Timer Expired");
87 detachInterrupt(digitalPinToInterrupt(35));
88 sleepFlag = true;
89 }
91
92 int getco2() {
94 ready_pin.pressed = false;
95 adp.enableLDO(2, 1);
96 int timeout = 0;
97 while (ready_pin.pressed == false) {
98 delay(1);
99 timeout++;
100 if (timeout > 5000) {
101 Serial.println("nready timed out at 5 sec");
102 adp.enableLDO(2, 0);
103 return 0;
104 }
105 }
106
107 Serial2.flush();
108 Serial2.print('Z', 1);
109 timeout = 0;
110 while (Serial2.available() <= 0) {
111 delay(1);
112 timeout++;
113 if (timeout > 3000) {
114 Serial.println("timed out");
115 adp.enableLDO(2, 0);
116 return 0;
117 }
118 }
119 byte co2array[Serial2.available()];
120 int i = 0;
121 while (Serial2.peek() != -1) {
122 co2array[i] = Serial2.read();
123 i++;
124 }
125 if (sizeof(co2array) < 3) {
126 Serial.println("response is incomplete");
127 adp.enableLDO(2, 0);
128 return 0;
129 }
130 if (co2array[2] != 0x55) {
131 Serial.println("response is not reliable");
132 adp.enableLDO(2, 0);
133 return 0;
134 }
135 int co2 = (co2array[0] << 8) | co2array[1];
136
137 digitalWrite(15, HIGH);
138 ready_pin.pressed = false;
139 adp.enableLDO(2, 0);
140
141 return co2;
142 }
143
144 void connectToAWS()
145 {
146 net.setCACert(AWS_CERT_CA);
148 net.setCertificate(AWS_CERT_CRT);
149 net.setPrivateKey(AWS_CERT_PRIVATE);
150
151 client.begin(AWS_IOT_ENDPOINT, 8883, net);
153
154 int retries = 0;
156 Serial.print("Connecting to AWS IOT");
157
158 while (!client.connect(DEVICE_NAME) && retries < AWS_MAX_RECONNECT_TRIES) {
159 Serial.print(".");
160 delay(100);
161 retries++;
162 }
163
164 if(!client.connected()){
167 Serial.println(" Timeout!");
168 return;
169 }
170
171 Serial.println("Connected!");
174 }
175
176
177 void goToSleep() {
179 WiFi.disconnect(true);
181
182 Serial.println("Going to sleep now");
183 Serial.flush();
184
185 endTimeMicros = micros();
187 esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR - (endTimeMicros - startTimeMicros));
188 esp_sleep_enable_ext0_wakeup(GPIO_NUM_35, 0);
189 esp_deep_sleep_start();
190 }
191
192
193 void updateShadow() {
194 connectToAWS();
196
197 Serial.println("Sending data...");
198 digitalWrite(18, HIGH);
200
201 float temperature = bme.readTemperature();
203 float humidity = bme.readHumidity();
204 float pressure = bme.readPressure();
205 int co2 = getco2();
206 uint16_t battery = adp.batteryVoltage();
207
208 if (co2 == 0) {
210 adp.enableLDO(2,0);
211 delay(3000);
212
213 return;
214 }
215
216 char rule_payload[512];
217 time_t now = time(nullptr);
218 time_t delete_time = now + (5 * 24 * 60 * 60);
219 sprintf(rule_payload, "{\"state\":{\"reported\":{\"co2\":\" %d \", \"temperature\":\" %f \", \"humidity\":\" %f \", \"pressure\":\" %f \", \"battery\":\" %d \", \"name\":\" co2-sensor \", \"timestamp\":\" %d \", \"ttl\": \" %d \" }}}",co2,temperature,humidity,pressure,battery,now,delete_time);
220 Serial.println(rule_payload);
221 int err = client.publish(AWS_IOT_TOPIC, rule_payload);
222 if (err == 0) {
223 Serial.println("publish success");
224 } else {
225 Serial.println("publish fail");
226 Serial.print(err);
227 Serial.println("");
228 }
229
230
231 digitalWrite(18, LOW);
232 goToSleep();
233 }
234
235 void enableSleepTimer() {
236 Serial.println("Enabling Timer");
237 timer = timerBegin(0,80,true);
238 timerAttachInterrupt(timer, &timerExpired, true);
239
240 timerAlarmWrite(timer, 30000000, true);
241 timerAlarmEnable(timer);
242 }
243
244 void disableSleepTimer() {
245 Serial.println("Disabling Timer");
246 timerAlarmDisable(timer);
247 timerDetachInterrupt(timer);
248 timerEnd(timer);
249 }
250
251 void enterServerMode() {
252 Serial.println("Entering Server Mode for Measurements and Calibration");
253
254 if (!MDNS.begin("esp32")) {
255 Serial.println("Error setting up MDNS responder!");
256 goToSleep();
257 }
258
259 enableSleepTimer();
260 disableCore0WDT();
261 disableCore1WDT();
262 disableLoopWDT();
263
264 server.on("/values/co2", HTTP_GET, [](AsyncWebServerRequest *request) {
265 Serial.println("Getting CO2");
266 disableSleepTimer();
267 enableSleepTimer();
268 digitalWrite(18, HIGH);
269 adp.enableLDO(2,0);
270 int co2 = getco2();
271 adp.enableLDO(2,0);
272 char payload[512];
273 time_t now = time(nullptr);
274 sprintf(payload, "{\"co2\":\" %d \", \"timestamp\":\" %d \" }",co2,now);
275 Serial.println(payload);
276 request->send(200, "text/plain", payload);
277 digitalWrite(18, LOW);
278 });
279
280 server.on("/values/temperature", HTTP_GET , [](AsyncWebServerRequest *request){
281 Serial.println("Getting Temperature");
282 disableSleepTimer();
283 enableSleepTimer();
284 digitalWrite(18, HIGH);
285 float temperature = bme.readTemperature();
286 char payload[512];
287 time_t now = time(nullptr);
288 sprintf(payload, "{\"temperature\":\" %f \", \"timestamp\":\" %d \" }",temperature,now);
289 Serial.println(payload);
290 request->send(200, "text/plain", payload);
291 digitalWrite(18, LOW);
292 });
293
294 server.on("/values/humidity", HTTP_GET, [](AsyncWebServerRequest *request){
295 Serial.println("Getting Humidity");
296 disableSleepTimer();
297 enableSleepTimer();
298 digitalWrite(18, HIGH);
299 float humidity = bme.readHumidity();
300 char payload[512];
301 time_t now = time(nullptr);
302 sprintf(payload, "{\"humidity\":\" %f \", \"timestamp\":\" %d \" }",humidity,now);
303 Serial.println(payload);
304 request->send(200, "text/plain", payload);
305 digitalWrite(18, LOW);
306 });
307
308 server.on("/values/pressure", HTTP_GET, [](AsyncWebServerRequest *request){
309 Serial.println("Getting Pressure");
310 disableSleepTimer();
311 enableSleepTimer();
312 digitalWrite(18, HIGH);
313 float pressure = bme.readPressure();
314 char payload[512];
315 time_t now = time(nullptr);
316 sprintf(payload, "{\"pressure\":\" %f \", \"timestamp\":\" %d \" }",pressure,now);
317 Serial.println(payload);
318 request->send(200, "text/plain", payload);
319 digitalWrite(18, LOW);
320 });
321
322 server.on("/values/battery", HTTP_GET, [](AsyncWebServerRequest *request){
323 Serial.println("Getting Battery");
324 disableSleepTimer();
325 enableSleepTimer();
326 digitalWrite(18, HIGH);
327 uint16_t battery = adp.batteryVoltage();
328 char payload[512];
329 time_t now = time(nullptr);
330 sprintf(payload, "{\"battery\":\" %d \", \"timestamp\":\" %d \" }",battery,now);
331 Serial.println(payload);
332 request->send(200, "text/plain", payload);
333 digitalWrite(18, LOW);
334 });
335
336 server.on("/values/all", HTTP_GET, [](AsyncWebServerRequest *request){
337 Serial.println("Getting All");
338 disableSleepTimer();
339 enableSleepTimer();
340 digitalWrite(18, HIGH);
341 int co2 = getco2();
342 float temperature = bme.readTemperature();
343 float humidity = bme.readHumidity();
344 float pressure = bme.readPressure();
345 uint16_t battery = adp.batteryVoltage();
346 char payload[512];
347 time_t now = time(nullptr);
348 sprintf(payload, "{\"co2\":\" %d \", \"temperature\":\" %f \", \"humidity\":\" %f \", \"pressure\":\" %f \", \"timestamp\":\" %d \", \"battery\":\" %d \" }",co2,temperature,humidity,pressure,now,battery);
349 Serial.println(payload);
350 request->send(200, "text/plain", payload);
351 digitalWrite(18, LOW);
352 });
353
354 server.on("/values/calibrate", HTTP_GET, [](AsyncWebServerRequest *request) {
355 Serial.println("Calibrating to Target");
356 disableSleepTimer();
357 enableSleepTimer();
358 digitalWrite(18, HIGH);
359 const char * calibrationPoint = request->getParam("cal")->value().c_str();
360 adp.enableLDO(2,1);
361 int timeout = 0;
362 while (ready_pin.pressed == false) {
363 delay(1);
364 timeout++;
365 if (timeout > 5000) {
366 Serial.println("nready timed out at 5 sec");
367 adp.enableLDO(2, 0);
368 return 0;
369 }
370 }
371 Serial2.print('Z',1);
372 delay(100);
373 if (Serial2.available() > 0) {
374 byte co2[Serial2.available()];
375 Serial2.readBytes(co2, Serial2.available());
376 }
377 delay(100);
378 char * cal_command = (char *)malloc(16);
379 sprintf(cal_command, "X %s\r\n", calibrationPoint);
380 Serial.print(cal_command);
381 Serial2.print(cal_command);
382 delay(100);
383 if (Serial2.available() > 0) {
384 byte cal_ret[Serial2.available()];
385 Serial2.readBytes(cal_ret, Serial2.available());
386 }
387 adp.enableLDO(2,0);
388 digitalWrite(18, LOW);
389 });
390
391 server.on("/values/zero", HTTP_GET, [](AsyncWebServerRequest *request) {
392 Serial.println("Zero Calibrating");
393 disableSleepTimer();
394 enableSleepTimer();
395 digitalWrite(18, HIGH);
396 adp.enableLDO(2,1);
397 int timeout = 0;
398 while (ready_pin.pressed == false) {
399 delay(1);
400 timeout++;
401 if (timeout > 5000) {
402 Serial.println("nready timed out at 5 sec");
403 adp.enableLDO(2, 0);
404 return 0;
405 }
406 }
407 Serial2.print('Z',1);
408 delay(100);
409 if (Serial2.available() > 0) {
410 byte co2[Serial2.available()];
411 Serial2.readBytes(co2, Serial2.available());
412 }
413 delay(100);
414 Serial2.print("U\r\n");
415 delay(100);
416 if (Serial2.available() > 0) {
417 byte cal_ret[Serial2.available()];
418 Serial2.readBytes(cal_ret, Serial2.available());
419 }
420 adp.enableLDO(2,0);
421 digitalWrite(18, LOW);
422 });
423
424 server.on("/values/ambient", HTTP_GET, [](AsyncWebServerRequest *request) {
425 Serial.println("Ambient Calibrating");
426 disableSleepTimer();
427 enableSleepTimer();
428 digitalWrite(18, HIGH);
429 adp.enableLDO(2,1);
430 int timeout = 0;
431 while (ready_pin.pressed == false) {
432 delay(1);
433 timeout++;
434 if (timeout > 5000) {
435 Serial.println("nready timed out at 5 sec");
436 adp.enableLDO(2, 0);
437 return 0;
438 }
439 }
440 Serial2.print('Z',1);
441 delay(100);
442 if (Serial2.available() > 0) {
443 byte co2[Serial2.available()];
444 Serial2.readBytes(co2, Serial2.available());
445 }
446 delay(100);
447 Serial2.print("G\r\n");
448 delay(100);
449 if (Serial2.available() > 0) {
450 byte cal_ret[Serial2.available()];
451 Serial2.readBytes(cal_ret, Serial2.available());
452 }
453 adp.enableLDO(2,0);
454 digitalWrite(18, LOW);
455 });
456
457 server.begin();
458 MDNS.addService("co2sensor", "_tcp", 80);
459 }
460
461
462 void setup() {
463 adp.enableLDO(3, 1);
466 adp.setCharger(1);
467 adp.enableFuelGauge(1);
468 startTimeMicros = micros();
469 delay(1000);
470 setCpuFrequencyMhz(80);
472
473 Serial.begin(115200);
475 Serial.println("starting aws iot application");
476
477 WiFi.disconnect(true);
479 int attempts = 0;
481 while (status != WL_CONNECTED) {
482 if (attempts > 5) {
484 goToSleep();
485 }
486 Serial.print("Attempting to connect to Wifi network: ");
487 status = WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
488 delay(5000);
489 }
490 Serial.println("Connected to Wifi!");
491
492 Serial.print("IP address: ");
493 Serial.println(WiFi.localIP());
494
495 configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");
497 while (!time(nullptr)) {
498 delay(1000);
499 }
500
501 pinMode(18, OUTPUT);
503 digitalWrite(18, LOW);
504
505 adp.setCharger(1);
507 adp.enableFuelGauge(1);
508
509 adp.enableLDO(2, 0);
511
512 delay(10);
514 pinMode(ready_pin.PIN, INPUT);
515 attachInterrupt(ready_pin.PIN, isr, RISING);
516 pinMode(WAKEUP_PIN, INPUT);
517 attachInterrupt(WAKEUP_PIN, wakeup_isr, FALLING);
518
519 Serial2.begin(38400, SERIAL_8N1, 14, 13);
521 delay(120);
522
523 I2CBME.begin(BME_SDA,BME_SCL,100000);
525 unsigned status;
526 status = bme.begin(0x77,&I2CBME);
527 if (!status) {
528 Serial.println("Could not find a valid BME280 sensor, check wiring, address, sensor ID!");
529 Serial.print("SensorID was: 0x"); Serial.println(bme.sensorID(),16);
530 Serial.print(" ID of 0xFF probably means a bad address, a BMP 180 or BMP 085\n");
531 Serial.print(" ID of 0x56-0x58 represents a BMP 280,\n");
532 Serial.print(" ID of 0x60 represents a BME 280.\n");
533 Serial.print(" ID of 0x61 represents a BME 680.\n");
534
535 goToSleep();
536 }
537
538 esp_sleep_wakeup_cause_t wakeup_reason;
539
540 wakeup_reason = esp_sleep_get_wakeup_cause();
541
542 switch(wakeup_reason)
543 {
544 case ESP_SLEEP_WAKEUP_EXT0 : enterServerMode(); break;
545 case ESP_SLEEP_WAKEUP_EXT1 : enterServerMode(); break;
546 case ESP_SLEEP_WAKEUP_TIMER : updateShadow(); break;
547 case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
548 case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
549 default : updateShadow(); break;
550 }
551 }
552
553 void loop() {
554 if (sleepFlag) {
556 sleepFlag = false;
557 goToSleep();
558 }
559 }
What I have tried:
I tried online articles but I am not familiar with AWS. There are various ways to "fix" the issue but every time I try something it doesn't seem to work.