// Sietse Jonker & Dano Bosch // 27/02/2024 // include these libraries #include #include #include #include #include #include #include // define pins on esp32 #define MICPIN 6 #define DHTPIN 7 #define SCL 9 #define SDA 8 #define DHTTYPE DHT11 #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define i2c_adress 0x3c #define USE_SERIAL Serial // make new objects Adafruit_SH1106G display = Adafruit_SH1106G(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire); DHT dht(DHTPIN, DHTTYPE); WiFiMulti WiFiMulti; Adafruit_SGP30 sgp; WebSocketsClient webSocket; // define variables uint16_t TVOC_base, eCO2_base; uint16_t counter = 0; float temperature = 0; float humidity = 0; uint16_t eCO2 = 0; uint16_t TVOC = 0; bool noise = false; unsigned long currentCounter; unsigned long lastCounter; uint16_t interval = 5000; bool errorSGP30 = false; bool errorDHT11 = false; // hexdump function for websockets binary handler void hexdump(const void *mem, uint32_t len, uint8_t cols = 16) { const uint8_t* src = (const uint8_t*) mem; USE_SERIAL.printf("\n[HEXDUMP] Address: 0x%08X len: 0x%X (%d)", (ptrdiff_t)src, len, len); for(uint32_t i = 0; i < len; i++) { if(i % cols == 0) { USE_SERIAL.printf("\n[0x%08X] 0x%08X: ", (ptrdiff_t)src, i); } USE_SERIAL.printf("%02X ", *src); src++; } USE_SERIAL.printf("\n"); } // handler for websocket events void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) { switch(type) { case WStype_DISCONNECTED: USE_SERIAL.printf("[WSc] Disconnected!\n"); break; case WStype_CONNECTED: USE_SERIAL.printf("[WSc] Connected to url: %s\n", payload); // send message to server when Connected webSocket.sendTXT("Connected"); break; case WStype_TEXT: USE_SERIAL.printf("[WSc] get text: %s\n", payload); // send message to server // webSocket.sendTXT("message here"); break; case WStype_BIN: USE_SERIAL.printf("[WSc] get binary length: %u\n", length); hexdump(payload, length); // send data to server // webSocket.sendBIN(payload, length); break; case WStype_ERROR: case WStype_FRAGMENT_TEXT_START: case WStype_FRAGMENT_BIN_START: case WStype_FRAGMENT: case WStype_FRAGMENT_FIN: break; } } // special function to setup websocket void websocketSetup(){ WiFiMulti.addAP("iotroam", "vbK9gbDBIB"); WiFiMulti.addAP("LansanKPN-boven", "19sander71vlieland14"); while(WiFiMulti.run() != WL_CONNECTED) { delay(100); } // server address, port and URL webSocket.begin("145.92.8.114", 80, "/ws"); // event handler webSocket.onEvent(webSocketEvent); // try ever 500 again if connection has failed webSocket.setReconnectInterval(500); } // fucntion to reset the values if needed void resetValues() { TVOC_base; eCO2_base; counter = 0; temperature = 0; humidity = 0; eCO2 = 0; TVOC = 0; noise = false; lastCounter = 0; currentCounter = 0; } // function to check for errors in sensors bool checkForError(){ if (!sgp.IAQmeasure()) { Serial.println("SGP30: BAD"); errorSGP30 = true; return true; } else { Serial.println("SGP30: OK"); errorSGP30 = false; return false; } if (isnan(temperature) || isnan(humidity)){ Serial.println("DHT11: BAD"); errorDHT11 = true; return true; } else { Serial.println("DHT11: OK"); errorDHT11 = false; return false; } } // function to update when interval is met (see intervalCounter variable) void update(){ webSocket.sendTXT("Temp: " + String(temperature)); webSocket.sendTXT("Humi: " + String(humidity)); webSocket.sendTXT("eCO2: " + String(sgp.eCO2)); webSocket.sendTXT("TVOC: " + String(sgp.TVOC)); sgp.getIAQBaseline(&eCO2_base, &TVOC_base); // read dht11 sensor temperature = float(dht.readTemperature()); humidity = float(dht.readHumidity()); // display sensordata on oled screen displayData(); } // function to display data on oled screen void displayData() { // clear display for new info display.clearDisplay(); // set custom text properties display.setTextSize(2); display.setTextColor(SH110X_WHITE); display.setCursor(0, 0); // display info on oled screen display.println((String) "Temp: " + int(temperature) + "C" + '\n' + "Humi: " + int(humidity) + "%" + '\n' + "eCO2: " + int(sgp.eCO2) + '\n' + "TVOC: " + int(sgp.TVOC)); display.display(); } // setup function void setup() { Serial.begin(115200); // tell display what settings to use display.begin(i2c_adress, true); display.clearDisplay(); // tell sensors to start reading dht.begin(); sgp.begin(); pinMode(MICPIN, INPUT); pinMode(DHTPIN, INPUT); websocketSetup(); resetValues(); } // loop function void loop() { webSocket.loop(); if (currentCounter - lastCounter >= interval){ lastCounter = millis(); update(); } currentCounter = millis(); }