#include #include #include #include "ota.h" #include #include "CCS811.h" int PHOTORESISTOR = 0; // pin 0 is analog #define CHECK_FREQUENCY 2 // check sensors every 2 seconds WiFiClient *wific = 0; int DHTPIN = 2; int mosfet_pin = 0; int DHTTYPE = 11; // Tempature + Humidity Sensor DHT dht(DHTPIN, DHTTYPE); CCS811 ccs; void setupCCS811() { switch (ccs.begin()) { case ERR_DATA_BUS: Serial.println("ccs: ERR_DATA_BUS"); return; case ERR_IC_VERSION: Serial.println("ccs: ERR_IC_VERSION"); return; case ERR_OK: Serial.println("ccs: ERR_OK"); break; default: Serial.println("ccs: unexpected error"); return; } ccs.setMeasCycle(ccs.eCycle_250ms); } void setup(void) { Serial.begin(115200); Serial.println("\rSerial."); Serial.println("\rSetupWifi."); setupWifi((char *) hostname); Serial.println("SetupOTA."); setupOTA((char *) hostname); Serial.println("SetupCCS811."); setupCCS811(); Serial.println("Dht.begin."); dht.begin(); // temp+humidity sensor Serial.println("PinMode."); pinMode(mosfet_pin, OUTPUT); pinMode(14, OUTPUT); Serial.println("WifiClient."); wific = new WiFiClient(); setupCCS811(); } void writeBoth(const char *buf) { Serial.print(buf); if (wific->connected()) { wific->write(buf); } } const int readings_per_second = 3; const int seconds_to_average = 5; const size_t readings_size = seconds_to_average * readings_per_second; struct SensorState { virtual void sense() = 0; std::list readings; void record(float r) { readings.push_back(r); if (readings.size() > readings_size) { readings.pop_front(); } }; float avg() { int n = 0; float total = std::accumulate(readings.begin(), // float total = 0; readings.end(), // for (auto p = readings.begin(); p != readings.end(); ++p) 0.0, // { [&n](float sum, int x) { // if (!isnan(*p)) { if (isnan(x)) return sum; ++n; return sum + x; // total += *p; }); // ++n; // } // } return n ? total / n : NAN; }; }; struct TemperatureSensor : public SensorState { virtual void sense() { record(dht.readTemperature(true)); } }; struct HumiditySensor : public SensorState { virtual void sense() { record(dht.readHumidity()); } }; struct PhotoSensor : public SensorState { virtual void sense() { record(analogRead(PHOTORESISTOR)); } }; struct CO2Sensor : public SensorState { virtual void sense() { record(ccs.getCO2PPM()); } }; struct TVOCSensor : public SensorState { virtual void sense() { record(ccs.getTVOCPPB()); } }; TemperatureSensor temperatureSensor; HumiditySensor humiditySensor; PhotoSensor photoSensor; CO2Sensor cO2Sensor; TVOCSensor tVOCSensor; void log_reading() { float temp = temperatureSensor.avg(); float humidity = humiditySensor.avg(); float heat_index = dht.computeHeatIndex(temp, humidity, true); int photons = photoSensor.avg(); uint32_t co2 = cO2Sensor.avg(); uint32_t tvoc = tVOCSensor.avg(); auto fmt = "T: %.2f H: %.2f HI: %.2f Light: %d CO2: %u TVOC: %u\r\n"; char buf[500]; snprintf(buf, sizeof(buf), fmt, temp, humidity, heat_index, photons, co2, tvoc); writeBoth(buf); } void sensor_loop() { SensorState *sensors[] = { &temperatureSensor, &humiditySensor, &photoSensor, &cO2Sensor, &tVOCSensor }; for (size_t i=0; isense(); } } int seconds = 0; void timer_switches() { switch (seconds % 10) { case 0: analogWrite(mosfet_pin, 255); break; case 1: analogWrite(mosfet_pin, 0); break; case 2: digitalWrite(14, 1); delay(10); digitalWrite(14, 0); break; } } void loop() { ArduinoOTA.handle(); if (++seconds < 0) seconds = 0; timer_switches(); auto ip = IPAddress(192,168,0,1); auto port = 3141; if (!wific->connected()) { //Serial.println("Attempting to connect"); wific->connect(ip, port); } for (int i=0; i