/******* V.O. at https://RandomNerdTutorials.com/esp32-plot-readings-charts-multiple/ rev 2025 paulfjujo **********/ #define VERSION "2025-0604" //14h00 // rajout traitement des infos 3 switches...OK //#define VERSION "2025-0603" //19h00 //C:\Users\Paul\AppData\Local\Temp\arduino_build_469012/_ESP32_Orange_30pins_6Charts_5gauges_1slider_3sw_2025_06.spiffs.bin //[SPIFFS] data : D:\_ESP32_2025_2024\_ESP32_Orange_30pins_6Charts_5gauges_1slider_3sw_2025_06\data // rajout 3 switch et 2em sonde sur page web //#define VERSION "2025-0530" // PB resolu : le choix de BOARD etait mauvais .. OK avec ESP32 Dev Module ou DOIT ESP32 DEVkit // test OK avec 2 sondes DS18B20 //#define VERSION "2025-0527" //... PB lecture sensor 1 (DS18B20 #3)????? avec ESP Wrover Kit (all versions) // suite remplacement Freebox V5 ADSL2 par Freebox Revolution sur Fibre Optique en Mars 2025 // 5 charts + 4 instrument + 1 slider cde PWM sur led bleue // ESP pastille Orange ID : ESP_5472F5 // SANS MCP connecté // PB DS18B20 non rafraichie ..si Ntpserver utilisé ?? // rajout 6em Graph : Y axis MCP23017 0 à 255 (lecture port B) // suite rajout image animé de durée reduite de 3sec à 2sec Data I2C OK // sans Graph MCP23017 // modif pause Loop de 2500 à 3000mS // Rajout d'une table contenant gauge DS18B20 + gauge pression + image + gif animé //#define VERSION "2022-0618" //last :19h18 // new script.js see RNTLAB forum // add recherche adresse OWS //#define VERSION "10-06-2022" // 1 seule sonde OWS #include #include // 23/02/2024 renommé ESPAsyncWebServer-master.h en #include // correctif en ligne 842 AsyncWebSocket.cpp #include #include #include #include #include #ifdef With_MCP #include #endif #include #include #include #include #include #define WithNTP //#define With_MCP // OK avec reseau PHONE Redminote11 //const char* ssid = "RedmiNote11"; //const char* password = "k9m5jfurubn"; // pwd > 8 chars //with WIFI freebox revolution const char* ssid = "Freebox-5CF3C9"; const char* password = "mxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; // debut adresses : 192.168.1.2 jusqu'à 192.168.1.12 //passerelle 192.168.1.254 IPAddress ip(192,168,1,11); IPAddress gateway(192,168,1,254); IPAddress subnet(255,255,255,0); IPAddress dns(212,27,40,241); //optional #define OLED_ADDR 0x3C #define SCREEN_WIDTH 128 // OLED display width, in pixels #define SCREEN_HEIGHT 32 // OLED display height, in pixels #define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) #define SCREEN_ADDRESS 0x3C // See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32 #define LOGO_HEIGHT 16 #define LOGO_WIDTH 16 #define paulfjujo_WIDTH 128 #define paulfjujo_HEIGHT 32 // Json Variable to Hold Sensor Readings JSONVar readings; // Timer variables unsigned long lastTime = 0; unsigned long timerDelay =3000; //10sec->60sec char BMPOK=0; char Presschar [10]; #ifdef With_MCP byte mcp_PA=0; byte mcp_PB=0; unsigned int mcp_PAB=0; char MCP_Readchar[10]; #define MCP23017_ADDR 0x22 MCP23017 mcp = MCP23017(MCP23017_ADDR); #endif char Oled_Msg[64]; // up to 18 char en taille 1 int i,j,k; byte type_s; float temperatureC; float temperatureC2; unsigned int Cpt=0; // 22-06 float p = 0.0; // BMP085 Pression float t = 0.0 ; // AM2302 temper float h = 0.0 ; // AM2302 Humid #define DHTTYPE DHT22 ; // DHT type (DHT11, DHT22) int DHTPIN = 5 ; // GPIO D5 <-- Broche du capteur AM2302 char Tempchar [10]; char Humidchar[10]; byte nDevices = 0; byte error=0; byte address=0; #define SCL 22 //ESP32 SCL I2C fil jaune --> SCL BMP085 #define SDA 21 //ESP32 SDA I2C fil vert --> SDA BMP085 const int LedOnBoard = 2; //led bleue sur module ESP const int OutputPWM = 23; const int LedRouge = 19; const int LedBleue = 15; const int LedVerte = 18; #define NUM_OUTPUTS 3 // Assign each GPIO to an output 15= bleue 18=Led verte 19 =led Rouge int outputGPIOs[NUM_OUTPUTS] = {15,18,19}; //String Etat_Sw1= "0"; //String Etat_Sw2= "0"; //String Etat_Sw3= "0"; String message =" "; String sliderValue1 = "0"; int dutyCycle1; char Duty_Slider[10]; //String SW1_Checked="0"; //String SW2_Checked="0"; //String SW3_Checked="0"; #ifdef WithNTP // NTP server to request epoch time const char* ntpServer ="fr.pool.ntp.org"; struct tm timeinfo; // Variable to save current epoch time unsigned long epochTime; const long gmtOffset_sec = 7200; const int daylightOffset_sec = 0; // 0 heure d'ete 3600 heure d'hiver #endif // Création des objets // GPIO DS18B20 const int one_Wire_Bus= 4 ; OneWire ds(one_Wire_Bus);// Setup a oneWire instance to communicate with OneWire devices (DS18B20) DallasTemperature sensors(&ds);// Pass our oneWire reference to Dallas Temperature sensor int NumberOfDevices; //DeviceAddress sensor1= {0x28,0xAA,0x56,0xC1,0x38,0x14,0x01,0x40}; // repere #3 (CRC= 0x40 ) //DeviceAddress sensor2= {0x28,0xAA,0x0D,0x82,0x38,0x14,0x01,0xCD}; // repere #6 Adafruit_BMP085 bmp; // connect to ESP32 I2C (GPIO 21 = SDA, GPIO 22 = SCL) DHTesp dht; // AM2302 DHT12 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); String hostname = "ESP_Orange"; AsyncWebServer server(80); AsyncEventSource events("/events");// Create an Event Source AsyncWebSocket ws("/ws");// Create a WebSocket object byte donnes[12]; byte addr[8]; void check_if_exist_I2C() { nDevices = 0; Serial.println(" "); for (address = 1; address < 127; address++ ) { // The i2c_scanner uses the return value of // the Write.endTransmisstion to see if // a device did acknowledge to the address. Wire.beginTransmission(address); error = Wire.endTransmission(); if (error == 0) { Serial.print("I2C device found at address 0x"); if (address < 16) Serial.print("0"); Serial.print(address, HEX); switch (address) { case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: Serial.println(" MCP23017 2x8 Bits I/O"); // de base + 7 autres break; case 0x28: case 0x29: case 0x2A: // case etc .. Serial.println(" PCF8574 8bits I/O"); // de base + 7 autres break; case 0x37: Serial.println(" LCD 2119 2x16cars"); // de base + 7 autres break; case 0x38: case 0x39: case 0x3A: case 0x3B: // case etc .. Serial.println(" PCF8574A 8bits I/O"); // de base + 7 autres break; case 0x3C: Serial.println( " OLED SSD1306"); break; case 0x53: Serial.println(" ADXL345 board"); break; case 0x57: Serial.println(" EEPROM 512bytes"); break; case 0x68: Serial.println(" RTC DS3231"); break; case 0x77: Serial.println(" BMP 085 Pression"); break; default: Serial.println(" non reconnue"); break; } //switch nDevices++; } delay(20); } //for loop if (nDevices == 0) Serial.println("No I2C devices found"); else Serial.printf("Trouve %3d devices sur le Bus I2C\r\n",nDevices); error=0; delay(200); } String getOutputStates(){ JSONVar myArray; for (int i =0; i3) return; } else {break; } } while(t<4); if(t<3) { Serial.println(); Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); Serial.print("Day of week: "); Serial.println(&timeinfo, "%A"); Serial.print("Month: "); Serial.println(&timeinfo, "%B"); Serial.print("Day of Month: "); Serial.println(&timeinfo, "%d"); Serial.print("Year: "); Serial.println(&timeinfo, "%Y"); Serial.print("Hour: "); Serial.println(&timeinfo, "%H"); Serial.print("Minute: "); Serial.println(&timeinfo, "%M"); Serial.print("Second: "); Serial.println(&timeinfo, "%S"); Serial.println(); } } #endif void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) { AwsFrameInfo *info = (AwsFrameInfo*)arg; if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) { data[len] = 0; message = (char*)data; // Serial.print("Msg :"); Serial.println(message); // rajout 04-06-2025 3 swithes if (message.indexOf("states") >= 0) { notifyClients(getOutputStates()); } else{ int gpio = atoi((char*)data); Serial.println(gpio); digitalWrite(gpio, !digitalRead(gpio)); notifyClients(getOutputStates()); } // 01-11-2024 if (message.indexOf("1s") >= 0) // pwmSlider1 { sliderValue1 = message.substring(2); dutyCycle1 = map(sliderValue1.toInt(), 0, 100, 0, 1023); // Serial.println(dutyCycle1); // Serial.println( sliderValue1); } } } void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) { switch (type) { case WS_EVT_CONNECT: Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str()); break; case WS_EVT_DISCONNECT: Serial.printf("WebSocket client #%u disconnected\n", client->id()); break; case WS_EVT_DATA: // Serial.printf("WebSocket client #%u EVT Data\n", client->id()); handleWebSocketMessage(arg, data, len); break; case WS_EVT_PONG: case WS_EVT_ERROR: break; } } void initWebSocket() { ws.onEvent(onEvent); server.addHandler(&ws); } void setup() { // Serial port for debugging purposes delay(500); Serial.begin(115200); delay(2000); // some time to connect the Teraterm terminal ON pinMode(4, INPUT_PULLUP); //pinMode(5, INPUT_PULLUP); pinMode(LedBleue, OUTPUT); pinMode(LedRouge, OUTPUT); pinMode(LedVerte, OUTPUT); pinMode(LedOnBoard, OUTPUT); digitalWrite(LedRouge, 0); /* Serial.println(" PWM test sur pin 23"); for (dutyCycle1=0;dutyCycle1<255;dutyCycle1=dutyCycle1+50) { analogWrite(OutputPWM, dutyCycle1); delay(1000); } */ Serial.println("Directory D:\\_ESP32_Orange_30pins_6Charts5_gauges_1slider_3sw_2025_06"); Serial.print(" ESP32_Orange_30pins_6Charts_5gauges_1slider_3sw_"); Serial.println(VERSION); Serial.println(" Tools -> Board type definition -> DOIT ESP32 DEVKIT V1 80Mhz"); Serial.println(" -> library -> ESP32 version 2.01"); Serial.println(" ESP32 ESPRESSIF wroom 32 2x15 pins (Orange) ESP_5472F5 sur COM 2 115200bds))"); Serial.println(" with 2x DS18B20,BMP085,Cpt,AM2302 Temp,Humidity,OLED,PWM "); Serial.println(" Led Rouge D19, Led verte D18, Led Bleue D15, Led OuputPWM D23"); Serial.println(" DHT11-AM2302 sur D5"); Serial.println(" Sondes temper.OWS DS18B20 #3 et #6 sur D4 "); Serial.println(" I2C Bus sur D21(SDA) et D22(SCL)"); dutyCycle1=0; analogWrite(OutputPWM, dutyCycle1); digitalWrite(LedOnBoard, 0); #ifdef With_MCP Serial.println(" BMP085 + OLED SSD1306 + MCP23017 sur le bus I2C"); #else Serial.println(" BMP085 + OLED SSD1306 sur le bus I2C"); #endif Serial.println("\r\nInit I2C1 bus"); Serial.println(" Recherche devices presents sur le bus I2C SCL=22 SDA=21"); Wire.begin(SDA,SCL); // pin on ESP32 delay(1000); check_if_exist_I2C(); Serial.println(".. Fin de test I2C bus \r\n"); sensors.begin(); Serial.println(" Sensors begin :"); // Grab a count of devices on the wire NumberOfDevices = sensors.getDeviceCount(); Serial.print("Locating devices..."); Serial.print("Found "); Serial.print(NumberOfDevices, DEC); Serial.println(" devices sur le bus OWS (D4)."); sensors.requestTemperatures(); j=0; do { OneWireScanner(); j++; }while(jsend(SPIFFS, "/index.html", "text/html"); }); delay(1000); // Request for the latest sensor readings server.on("/readings", HTTP_GET, [](AsyncWebServerRequest *request){ String json = getSensorReadings(); request->send(200, "application/json", json); json = String(); }); server.on("/currentValue1", HTTP_GET, [](AsyncWebServerRequest *request) { request->send(200, "/text/plain", String(sliderValue1).c_str()); //25-02-2024 k=sliderValue1.length()+1; sliderValue1.toCharArray(Duty_Slider, k); dutyCycle1=atoi(Duty_Slider); }); // new version 2023-1223 // First request will return 0 results unless you start scan from somewhere else (loop/setup) // Do not request more often than 3-5 seconds server.on("/scan", HTTP_GET, [](AsyncWebServerRequest *request) { String json = "["; int n = WiFi.scanComplete(); if(n == -2){ WiFi.scanNetworks(true); } else if(n){ for (int i = 0; i < n; ++i){ if(i) json += ","; json += "{"; json += "\"rssi\":"+String(WiFi.RSSI(i)); json += ",\"ssid\":\""+WiFi.SSID(i)+"\""; json += ",\"bssid\":\""+WiFi.BSSIDstr(i)+"\""; json += ",\"channel\":"+String(WiFi.channel(i)); json += ",\"secure\":"+String(WiFi.encryptionType(i)); // json += ",\"hidden\":"+String(WiFi.isHidden(i)?"true":"false"); json += "}"; } WiFi.scanDelete(); if(WiFi.scanComplete() == -2) { WiFi.scanNetworks(true); } } json += "]"; request->send(200, "application/json", json); json = String(); }); events.onConnect([](AsyncEventSourceClient *client){ if(client->lastId()){ Serial.printf("Client reconnected! Last msg ID : %u %c%c", client->lastId(),13,10);// 01/11/2024 } client->send("hello!", NULL, millis(), 10000); }); server.addHandler(&events); display.clearDisplay(); #ifdef WithNTP // Init and get the time Serial.println(" Get and print time from ntpServer"); configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); printLocalTime(); #endif // Start server server.begin(); Serial.println("init Websocket"); initWebSocket(); } //******************************* void loop() { if ((millis() - lastTime) > timerDelay) { // Send Events to the client with the Sensor Readings Every 10 seconds events.send("ping",NULL,millis()); events.send(getSensorReadings().c_str(),"new_readings" ,millis()); lastTime = millis(); delay(1500); } else //1 { #ifdef WithNTP if(Cpt %16==0) { getLocalTime(&timeinfo); Serial.print("Heure: "); Serial.print(&timeinfo, "%H"); Serial.print(":"); Serial.println(&timeinfo, "%M"); } #endif //delay(500); Serial.printf(" Cpt= %5d ",Cpt); display.clearDisplay(); display.setCursor(0,0); display.print(F("Compteur ")); display.setCursor(70,0); snprintf(Oled_Msg,6,"% 5d",Cpt); display.print(Oled_Msg); // p = bmp.readPressure() / 100.0F; if (p>1100.0) p=999.99; if (p<940.0) p=999.99; Serial.printf(", BMP085 P.% 5.0f mBar ",p); display.setCursor(0,8); delay(50); display.print(F("BMP085 P. ")); display.setCursor(70,8); display.print(p); // h=dht.getHumidity(); // delay(250); if (isnan(h)) snprintf(Humidchar,6,"%s\t"," ???"); else snprintf(Humidchar,6,"%2.2f\t",h); Serial.print(F(", Humid: ")); Serial.print(Humidchar); display.setCursor(0,16); display.print(F("AM2302 Humi ")); display.setCursor(76,16); display.print(Humidchar); display.display(); // t = dht.getTemperature(); // delay(250); if (isnan(t)) snprintf(Tempchar,6,"%s\t"," ???"); else snprintf(Tempchar,6,"%3.2f\t",t); Serial.print(F(",Temp: ")); Serial.print(Tempchar); // sensors.requestTemperatures(); // temperatureC = sensors.getTempCByIndex(0); // if (temperatureC < -10.0) temperatureC= -10.0; Serial.printf(",DS#1 =% 3.2f C ",temperatureC); if (NumberOfDevices>1) { // sensors.requestTemperatures(); // temperatureC2 = sensors.getTempCByIndex(1); Serial.printf(",DS#2 =% 3.2f C ",temperatureC2); } Serial.printf(", Slider =%5d ", dutyCycle1); // affiche en alternance sur la 4em ligne afficheur OLED // soit Temperature AM2302 , // soit OWS DS18B20 if ((Cpt %4)==0) { // digitalWrite(LedRouge,HIGH); digitalWrite(LedOnBoard,HIGH); display.setCursor(0,24); delay(50); display.print(F("AM2302 Temp ")); display.setCursor(76,24); delay(50); display.print(Tempchar); } else //3 { // digitalWrite(LedRouge,LOW); digitalWrite(LedOnBoard,LOW); display.setCursor(0,24); delay(50); display.print(F("DS18B20 #1 ")); display.setCursor(76,24); delay(50); display.print(temperatureC); } delay(50); display.display(); #ifdef With_MCP mcp_PA= mcp.readPort(MCP23017Port::A); mcp_PB= mcp.readPort(MCP23017Port::B); mcp.writePort(MCP23017Port::A, i & 0x00FF); Serial.print(",MCP : 0x"); if(mcp_PA<16) Serial.print("0"); Serial.print(mcp_PA, HEX); Serial.print(",0x"); if(mcp_PB<16) Serial.print("0"); Serial.println(mcp_PB, HEX); #else //Serial.printf(", k=%5d",k); Serial.println("."); #endif // PWM led (23) analogWrite(OutputPWM, dutyCycle1); Cpt=Cpt+1.0; if (Cpt>999) Cpt=0; } ws.cleanupClients(); delay(800); } /* * * * * * * * * */