View difference between Paste ID: TAiNykt3 and ULzTKicJ
SHOW: | | - or go back to the newest paste.
1
#include "esp_wifi.h"
2
#include "driver/adc.h"
3
4
5
#include <WiFi.h>
6
#include "nvs_flash.h"
7
#include <SimplePgSQL.h>
8
#include "time.h"
9
//#include <ESP32Time.h>
10
#include "SPI.h"
11
12
13
#include <Adafruit_BMP280.h>
14
#include <Adafruit_AHTX0.h>
15
16
#include <Adafruit_GFX.h>
17
#include <Adafruit_PCD8544.h>
18
#include <ADS1115_WE.h> 
19
#include <Wire.h>
20
bool isSetNtp = false;                                 // flag to indicate if we had a successful NTP call
21
            // test variable in RTC memory
22
23
// callback to check if NTP was called
24
#include "esp_sntp.h"
25
void cbSyncTime(struct timeval *tv) { // callback function to show when NTP was synchronized
26
  Serial.println("NTP time synched");
27
  isSetNtp = true;
28
}
29
30
#define I2C_ADDRESS 0x48
31
32
ADS1115_WE adc = ADS1115_WE(I2C_ADDRESS);
33
34
 Adafruit_PCD8544 display = Adafruit_PCD8544(0, 1, 2);
35
36
37
Adafruit_AHTX0 aht;
38
Adafruit_BMP280 bmp;
39
40
//ESP32Time rtc(0);  // offset in seconds
41
42
int16_t adc0, adc1, adc2, adc3;
43
float volts0, volts1, volts2, volts3;
44
float abshum;
45
46
47
48
#include <Preferences.h>
49
Preferences prefs;
50
  struct tm timeinfo;
51
52
RTC_DATA_ATTR int readingCnt = -1;
53
RTC_DATA_ATTR int arrayCnt = 0;
54
55
int i;
56
57
typedef struct {
58
  float temp1;
59
  float temp2;
60
  unsigned long   time;
61
  float volts;
62
  float pres;
63
} sensorReadings;
64
65
#define maximumReadings 360 // The maximum number of readings that can be stored in the available space
66
#define sleeptimeSecs   30 
67
#define WIFI_TIMEOUT 20000
68
#define TIME_TIMEOUT 20000
69
70
RTC_DATA_ATTR sensorReadings Readings[maximumReadings];
71
72
const char* ntpServer = "pool.ntp.org";
73
const long gmtOffset_sec = -18000;  //Replace with your GMT offset (secs)
74
const int daylightOffset_sec = 3600;   //Replace with your daylight offset (secs)
75
int hours, mins, secs;
76
float tempC;
77
bool sent = false;
78
79
80-
IPAddress PGIP(216,110,224,105);
80+
IPAddress PGIP(x,x,x,x);
81
82
const char ssid[] = "xxxx";      //  your network SSID (name)
83
const char pass[] = "xxxx";      // your network password
84
85
const char user[] = "xxxx";       // your database user
86
const char password[] = "xxxx";   // your database password
87
const char dbname[] = "xxxx";         // your database name
88
89
90
int WiFiStatus;
91
WiFiClient client;
92
93
94
95
96
97
/////////////////////////
98
//POSTGRESQL CODE BEGIN//
99
/////////////////////////
100
101
102
103
104
105
106
char buffer[1024];
107
PGconnection conn(&client, 0, 1024, buffer);
108
109
char tosend[192];
110
String tosendstr;
111
112
113
#ifndef USE_ARDUINO_ETHERNET
114
void checkConnection()
115
{
116
    int status = WiFi.status();
117
    if (status != WL_CONNECTED) {
118
        if (WiFiStatus == WL_CONNECTED) {
119
            Serial.println("Connection lost");
120
            WiFiStatus = status;
121
        }
122
    }
123
    else {
124
        if (WiFiStatus != WL_CONNECTED) {
125
            Serial.println("Connected");
126
            WiFiStatus = status;
127
        }
128
    }
129
}
130
131
#endif
132
133
static PROGMEM const char query_rel[] = "\
134
SELECT a.attname \"Column\",\
135
  pg_catalog.format_type(a.atttypid, a.atttypmod) \"Type\",\
136
  case when a.attnotnull then 'not null ' else 'null' end as \"null\",\
137
  (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)\
138
   FROM pg_catalog.pg_attrdef d\
139
   WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef) \"Extras\"\
140
 FROM pg_catalog.pg_attribute a, pg_catalog.pg_class c\
141
 WHERE a.attrelid = c.oid AND c.relkind = 'r' AND\
142
 c.relname = %s AND\
143
 pg_catalog.pg_table_is_visible(c.oid)\
144
 AND a.attnum > 0 AND NOT a.attisdropped\
145
    ORDER BY a.attnum";
146
147
static PROGMEM const char query_tables[] = "\
148
SELECT n.nspname as \"Schema\",\
149
  c.relname as \"Name\",\
150
  CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN 'materialized view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 's' THEN 'special' WHEN 'f' THEN 'foreign table' END as \"Type\",\
151
  pg_catalog.pg_get_userbyid(c.relowner) as \"Owner\"\
152
 FROM pg_catalog.pg_class c\
153
     LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\
154
 WHERE c.relkind IN ('r','v','m','S','f','')\
155
      AND n.nspname <> 'pg_catalog'\
156
      AND n.nspname <> 'information_schema'\
157
      AND n.nspname !~ '^pg_toast'\
158
  AND pg_catalog.pg_table_is_visible(c.oid)\
159
 ORDER BY 1,2";
160
161
int pg_status = 0;
162
163
void doPg(void)
164
{
165
    char *msg;
166
    int rc;
167
    if (!pg_status) {
168
        conn.setDbLogin(PGIP,
169
            user,
170
            password,
171
            dbname,
172
            "utf8");
173
        pg_status = 1;
174
        return;
175
    }
176
177
    if (pg_status == 1) {
178
        rc = conn.status();
179
        if (rc == CONNECTION_BAD || rc == CONNECTION_NEEDED) {
180
            char *c=conn.getMessage();
181
            if (c) Serial.println(c);
182
            pg_status = -1;
183
        }
184
        else if (rc == CONNECTION_OK) {
185
            pg_status = 2;
186
            Serial.println("Enter query");
187
        }
188
        return;
189
    }
190
    if (pg_status == 2) {
191
        if (!Serial.available()) return;
192
        char inbuf[192];
193
        int n = Serial.readBytesUntil('\n',inbuf,191);
194
        while (n > 0) {
195
            if (isspace(inbuf[n-1])) n--;
196
            else break;
197
        }
198
        inbuf[n] = 0;
199
200
        if (!strcmp(inbuf,"\\d")) {
201
            if (conn.execute(query_tables, true)) goto error;
202
            Serial.println("Working...");
203
            pg_status = 3;
204
            return;
205
        }
206
        if (!strncmp(inbuf,"\\d",2) && isspace(inbuf[2])) {
207
            char *c=inbuf+3;
208
            while (*c && isspace(*c)) c++;
209
            if (!*c) {
210
                if (conn.execute(query_tables, true)) goto error;
211
                Serial.println("Working...");
212
                pg_status = 3;
213
                return;
214
            }
215
            if (conn.executeFormat(true, query_rel, c)) goto error;
216
            Serial.println("Working...");
217
            pg_status = 3;
218
            return;
219
        }
220
221
        if (!strncmp(inbuf,"exit",4)) {
222
            conn.close();
223
            Serial.println("Thank you");
224
            pg_status = -1;
225
            return;
226
        }
227
        if (conn.execute(inbuf)) goto error;
228
        Serial.println("Working...");
229
        pg_status = 3;
230
    }
231
    if (pg_status == 3) {
232
        rc=conn.getData();
233
        if (rc < 0) goto error;
234
        if (!rc) return;
235
        if (rc & PG_RSTAT_HAVE_COLUMNS) {
236
            for (i=0; i < conn.nfields(); i++) {
237
                if (i) Serial.print(" | ");
238
                Serial.print(conn.getColumn(i));
239
            }
240
            Serial.println("\n==========");
241
        }
242
        else if (rc & PG_RSTAT_HAVE_ROW) {
243
            for (i=0; i < conn.nfields(); i++) {
244
                if (i) Serial.print(" | ");
245
                msg = conn.getValue(i);
246
                if (!msg) msg=(char *)"NULL";
247
                Serial.print(msg);
248
            }
249
            Serial.println();
250
        }
251
        else if (rc & PG_RSTAT_HAVE_SUMMARY) {
252
            Serial.print("Rows affected: ");
253
            Serial.println(conn.ntuples());
254
        }
255
        else if (rc & PG_RSTAT_HAVE_MESSAGE) {
256
            msg = conn.getMessage();
257
            if (msg) Serial.println(msg);
258
        }
259
        if (rc & PG_RSTAT_READY) {
260
            pg_status = 2;
261
            Serial.println("Enter query");
262
        }
263
    }
264
    return;
265
error:
266
    msg = conn.getMessage();
267
    if (msg) Serial.println(msg);
268
    else Serial.println("UNKNOWN ERROR");
269
    if (conn.status() == CONNECTION_BAD) {
270
        Serial.println("Connection is bad");
271
        pg_status = -1;
272
    }
273
}
274
275
276
277
278
279
280
281
282
/////////////////////////
283
//POSTGRESQL CODE END  //
284
/////////////////////////
285
286
287
288
289
290
291
292
293
294
void gotosleep() {
295
      //WiFi.disconnect();
296
      delay(1);
297
      esp_sleep_enable_timer_wakeup(sleeptimeSecs * 1000000ULL);
298
      delay(1);
299
      esp_deep_sleep_start();
300
      delay(1000);
301
}
302
303
304
void killwifi() {
305
            WiFi.disconnect(); 
306
}
307
308
void transmitReadings() {
309
  i=0;
310
          while (i<maximumReadings) {
311
            doPg();
312
            display.clearDisplay();   // clears the screen and buffer
313
            display.setCursor(0,0);
314
            display.print("TXing #");
315
            display.print(i);
316
            display.print(",");
317
            display.println(arrayCnt);
318
            display.display();
319
320
            if ((pg_status == 2) && (i<maximumReadings)){
321
              tosendstr = "insert into burst values (42,1," + String(Readings[i].time) + "," + String(Readings[i].temp1,3) + "), (42,2," + String(Readings[i].time) + "," + String(Readings[i].volts,4) + "), (42,3," + String(Readings[i].time) + "," + String(Readings[i].temp2,3) + "), (42,4," + String(Readings[i].time) + "," + String(Readings[i].pres,3) + ")";
322
              conn.execute(tosendstr.c_str());
323
              pg_status = 3;
324
              delay(10);
325
              i++;
326
            }
327
            delay(10);
328
            
329
          }
330
          
331
}
332
333
334
float readChannel(ADS1115_MUX channel) {
335
  float voltage = 0.0;
336
  adc.setCompareChannels(channel);
337
  adc.startSingleMeasurement();
338
  while(adc.isBusy()){}
339
  voltage = adc.getResult_V(); // alternative: getResult_mV for Millivolt
340
  return voltage;
341
}
342
343
344
345
void initTime(String timezone){
346
  configTzTime(timezone.c_str(), "time.cloudflare.com", "pool.ntp.org", "time.nist.gov");
347
348
  while ((!isSetNtp) && (millis() < TIME_TIMEOUT)) {
349
        delay(250);
350
        display.print(".");
351
        display.display();
352
        }
353
354
}
355
356
357
void setup(void)
358
{
359
  sntp_set_time_sync_notification_cb(cbSyncTime);
360
  display.begin(20, 7);
361
362
363
  display.display(); // show splashscreen
364
  display.clearDisplay();   // clears the screen and buffer
365
  display.setTextSize(1);
366
  display.setTextColor(BLACK);
367
  display.setCursor(0,0);
368
  display.setTextWrap(true);
369
  if ((readingCnt == -1)) {
370
371
      WiFi.mode(WIFI_STA);
372
      WiFi.begin((char *)ssid, pass);
373
      display.print("Connecting to get time...");
374
      display.display();
375
      while ((WiFi.status() != WL_CONNECTED) && (millis() < WIFI_TIMEOUT)) {
376
        delay(250);
377
        display.print(".");
378
        display.display();
379
      }
380
          display.clearDisplay();   // clears the screen and buffer
381
          display.setCursor(0,0);
382
          if (WiFi.status() == WL_CONNECTED) {
383
            display.print("Connected. Getting time...");
384
          }
385
          else
386
          {
387
            display.print("Connection timed out. :(");
388
          }
389
          display.display();
390
          initTime("EST5EDT,M3.2.0,M11.1.0");
391
          //rtc.setTimeStruct(timeinfo);
392
          killwifi();
393
          readingCnt = 0;
394
          delay(1);
395
          readingCnt = 0;
396
          delay(1);
397
398
          esp_sleep_enable_timer_wakeup(1 * 1000000);
399
          esp_deep_sleep_start();
400
          delay(1000);
401
  }
402
403
  Wire.begin();
404
  adc.init();
405
  adc.setVoltageRange_mV(ADS1115_RANGE_4096);
406
407
  float volts0 = 2.0 * readChannel(ADS1115_COMP_3_GND);
408
409
410
  bmp.begin();
411
  bmp.setSampling(Adafruit_BMP280::MODE_FORCED,     /* Operating Mode. */
412
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
413
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
414
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
415
                  Adafruit_BMP280::STANDBY_MS_500);
416
  bmp.takeForcedMeasurement();
417
  float presread = bmp.readPressure() / 100.0;
418
  aht.begin();
419
  sensors_event_t humidity, temp;
420
  aht.getEvent(&humidity, &temp);
421
  abshum = (6.112 * pow(2.71828, ((17.67 * temp.temperature)/(temp.temperature + 243.5))) * humidity.relative_humidity * 2.1674)/(273.15 + temp.temperature); //calculate absolute humidity
422
  display.print("Time: ");
423
  setenv("TZ","EST5EDT,M3.2.0,M11.1.0",1);  //  Now adjust the TZ.  Clock settings are adjusted to show the new local time
424
  tzset();
425
  getLocalTime(&timeinfo);
426
  int hr12 = timeinfo.tm_hour;
427
  String AMPM;
428
  if (hr12 > 12) {
429
    hr12 -= 12;
430
    AMPM = "PM";
431
  }
432
  else {AMPM = "AM";}
433
434
  display.print(hr12);
435
  if (timeinfo.tm_min < 10) {display.print(":0");}
436
  else {display.print(":");}
437
  
438
  display.print(timeinfo.tm_min);
439
  display.println(AMPM);
440
441
  display.print(temp.temperature, 2);
442
  display.print("C ");
443
  display.print(humidity.relative_humidity, 1);
444
  display.println("%");
445
446
  display.print("Abs: ");
447
  display.print(abshum, 2);
448
  display.println("g");
449
450
  display.print("Batt: ");
451
  display.print(volts0, 4);
452
  display.println("v");
453
454
  display.print("Pres: ");
455
  display.print(presread, 2);
456
  display.println("m");
457
458
  display.print("R");
459
  display.print(readingCnt); 
460
  display.print("/");
461
  display.print(maximumReadings); 
462
  display.print(" A");
463
  display.print(arrayCnt);
464
  display.display();
465
466
  //Store the sensor readings in the struct we declared earlier, using the RTC-ram integer "readingCnt" to increment the array index by one each reading
467
  Readings[readingCnt].temp1 = temp.temperature;    // Units °C
468
  Readings[readingCnt].temp2 = abshum; //humidity is temp2
469
  Readings[readingCnt].time = mktime(&timeinfo); 
470
  Readings[readingCnt].volts = volts0;
471
  Readings[readingCnt].pres = presread;
472
473
474
475
  ++readingCnt; 
476
  delay(1);
477
478
  if (readingCnt >= maximumReadings) { 
479
480
      prefs.begin("stuff", false, "nvs2"); //open up a prefs on the custom NVS2 partition
481
      WiFi.mode(WIFI_STA);
482
      WiFi.begin((char *)ssid, pass);
483
      display.clearDisplay();   // clears the screen and buffer
484
      display.setCursor(0,0);
485
      display.print("Connecting to transmit...");
486
      display.display();
487
      while ((WiFi.status() != WL_CONNECTED) && (millis() < WIFI_TIMEOUT)) {
488
        delay(250);
489
        display.print(".");
490
        display.display();
491
      }
492
493
      if ((WiFi.status() != WL_CONNECTED) && (millis() >= WIFI_TIMEOUT)) {
494
495
        delay(1);
496
        ++arrayCnt;
497
        delay(1);
498
        prefs.putBytes(String(arrayCnt).c_str(), &Readings, sizeof(Readings));
499
        readingCnt = 0;
500
        killwifi();
501
        esp_sleep_enable_timer_wakeup(1 * 1000000);
502
        esp_deep_sleep_start();
503
        delay(1000);
504
      }
505
      display.clearDisplay();   // clears the screen and buffer
506
      display.setCursor(0,0);
507
      display.print("Connected. Transmitting #0");
508
      display.display();
509
      transmitReadings();
510
      while (arrayCnt > 0) {
511
        display.clearDisplay();   // clears the screen and buffer
512
        display.setCursor(0,0);
513
        display.print("Transmitting #");
514
        display.print(arrayCnt);
515
        display.display();
516
        delay(50);
517
        prefs.getBytes(String(arrayCnt).c_str(), &Readings, sizeof(Readings));
518
        arrayCnt--;
519
        transmitReadings();
520
      }
521
      arrayCnt = 0;
522
      readingCnt = -1;
523
      delay(1);
524
      arrayCnt = 0;
525
      readingCnt = -1;
526
      delay(1);
527
      display.clearDisplay();   // clears the screen and buffer
528
      display.setCursor(0,0);
529
      display.print("Done.  Closing connection...");
530
      display.display();
531
      conn.close();
532
533
      killwifi();
534
535
      ESP.restart();
536
  } 
537
538
539
        gotosleep();
540
541
}
542
543
544
void loop()
545
{
546
gotosleep();
547
}
548