/* * WiFiClientBasic * * Run this code on a "master" NodeMCU with an I2C OLED and an * I2C Humidity/Temperature sensor * * This same code will run on an ESP8266-01 with the I2C OLED and sensor * * It will connect to multiple ESP-8266-01 units, * each running WiFiWebServer-TH_18x (192.168.1.180 etc. IP address) * to get temp and humidity from remote ESP-8266-01 units, each having * an I2C Humidity/Temperature sensor * // 3.3v NodeMCU_V1 // NodeMCU SPI: SS D8 GPIO_15 internal pull-down 12k MOSI D7 GPIO_13 MISO D6 GPIO_12 CLK D5 GPIO_14 NodeMCU IIC (I2C): SDA D3 GPIO_0 internal pull-up 12k SCL D4 GPIO_2 internal pull-up 12k NodeMCU Serial: RXD0 D9 GPIO_3 TXD0 D10 GPIO_1 NodeMCU on-board LED: IO D0 GPIO_16 pulled HI through LED (LOW = ON) NodeMCU: IO D1 GPIO_5 IO D2 GPIO_4 IO SD2 GPIO_9 IO SD3 GPIO_10 NodeMCU as yet not understood: SD1 CMD SD01 CLK NodeMCU Analog Input: A0 ADC0 1) OLED 96x96 0.96in SSD1327 - I2C - GROVE - SEEED 2) I2C Humidity/Temperature Sensor Texas Instruments HDC1080 mounted on: SparkFun Humidity and Temperature Sensor Breakout - HTU21D In order to get SeeedGrayOLED.h to work with an ESP8266 the SeeedGrayOLED.cpp file in LCD_Display9696_Library must be modified to remove references to PROGMEM (since PROGMEM is designed for Atmel processor memory). line 24: comment out entire line line 36: delete "PROGMEM" line 36 now reads: const unsigned char BasicFont[][8] = I had problems compiling the program with the latest version of "ESP8266 by ESP8266 Community" in Boards Manager. I had to remove the package and install the original version of 1.6.5-947-g39819f // WZ 3-6-2016 */ #include #include #define LED_IND 16 // LED on the NodeMCU #define SERBAUD 115200 //========================================== PERSONAL DATA =============== #include /* * my_info.h contains my personal information * instead use the following lines: * #define myssid "x" // Replace x with YOUR ssid * #define mypassword "y" // Replace y with YOUR password * #define THNG_SPK_IP "184.106.153.149" // thingspeak.com * #define THINGSPEAK_KEY_W "z" // Replace z with YOUR Thingspeak Write Key */ //========================================== PERSONAL DATA =============== #include // This code also works with the HDC1080 HDC1000 mySensor; //HDC1000 mySensor(addr, drdyn_pin) <--- you can change default options if you want. float temperature = 0; float tempF = 0; float humidity = 0; char buf [10]; ESP8266WiFiMulti WiFiMulti; //----- Thingspeak stuff ---------------------------------- String GET = "GET /update?key="; // field1 = 192.168.1.180 Temperature // field2 = 192.168.1.180 Humidity // field3 = 192.168.1.181 Temperature // field4 = 192.168.1.181 Humidity // field5 = Local Temperature // field6 = Local Humidity String secondValue180a = ""; String thirdValue180a = ""; String secondValue181a = ""; String thirdValue181a = ""; //-------------------------------------- long previousMillis = 0; // will store last time updated // the follow variable is a long because the time, measured in miliseconds, // will quickly become a bigger number than can be stored in an int. long interval = 1; // interval in MINUTES at which to send data to Thingspeak #include "Wire.h" #define I2C_SCL 2 #define I2C_SDA 0 #include // ===================================================== // Use this section to get readings from the HDC1080 that // is connected directly to the NodeMCU void readHDC1000() { yield(); Serial.print("Temperature: "); //too bad the Arduino version of sprintf Serial.print(((mySensor.getTemp()*1.8) + 32),1); //doesn't support floats, tempF = ((mySensor.getTemp()*1.8) + 32); delay(500); yield(); Serial.print("F, Humidity: "); //I hate Serial.print(). Serial.print(mySensor.getHumi(),1); humidity = (mySensor.getHumi()); Serial.println("%"); delay(500); Serial.println(); Serial.println("========================"); delay(50); ESP.wdtFeed(); yield(); return; } // ===================================================== void setup() { Serial.begin(SERBAUD); delay(10); interval = interval * 60000; // convert interval from minutes to millis // Set Indicator LED as output pinMode(LED_IND , OUTPUT); digitalWrite(LED_IND, 1); // LED on NOdeMCU is sunk by pin = OFF //--------------------------------------------- Wire.begin(I2C_SDA, I2C_SCL); SeeedGrayOled.init(); //initialize SEEED OLED display SeeedGrayOled.clearDisplay(); //Clear Display. SeeedGrayOled.setNormalDisplay(); //Set Normal Display Mode SeeedGrayOled.setVerticalMode(); // Set to vertical mode for displaying text //--------------------------------------------- // We start by connecting to a WiFi network WiFiMulti.addAP(myssid, mypassword); Serial.println(); Serial.println(); Serial.print("Wait for WiFi... "); while(WiFiMulti.run() != WL_CONNECTED) { Serial.print("."); delay(500); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); // Ping this to get local temp/humidity at any time delay(500); } void loop() { //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= readHDC1000(); Serial.print("tempF = "); Serial.println(tempF,1); // round temp for OLED the same way Serialprint rounds // so the OLED will agree with the Serial output int tempint = 0; float tempfrac = 0; float tempfrac10 = 0; int tempfrac10int = 0; // need to round so that 1.5 = 2 float tempfrac10float = 0; // need to round so that 1.5 = 2 tempint = tempF; tempfrac = tempF - tempint; tempfrac10 = tempfrac * 10; tempfrac10int = tempfrac10; tempfrac10float = tempfrac10int; if ((tempfrac10 - tempfrac10float) >= .5) // make all floats { tempfrac10int = tempfrac10int + 1; } Serial.print("Humidity = "); Serial.println(humidity,1); // round humidity for OLED the same way Serialprint rounds // so the OLED will agree with the Serial output int humint = 0; float humfrac = 0; float humfrac10 = 0; int humfrac10int = 0; // need to round so that 1.5 = 2 float humfrac10float = 0; // need to round so that 1.5 = 2 humint = humidity; humfrac = humidity - humint; humfrac10 = humfrac * 10; humfrac10int = humfrac10; humfrac10float = humfrac10int; if ((humfrac10 - humfrac10float) >= .5) // make all floats { humfrac10int = humfrac10int + 1; } SeeedGrayOled.setTextXY(7,0); //set Cursor to 0th line, 0th column SeeedGrayOled.setGrayLevel(7); //Set Grayscale level. Any number between 0 - 15. SeeedGrayOled.putString("tempF = "); //Print if (tempF >= 100) { SeeedGrayOled.setTextXY(7,7); //set Cursor to 0th line, 7th column } else if (tempF < 10) { SeeedGrayOled.setTextXY(7,9); //set Cursor to 0th line, 8th column } else { SeeedGrayOled.setTextXY(7,8); //set Cursor to 0th line, 8th column } SeeedGrayOled.setGrayLevel(7); //Set Grayscale level. Any number between 0 - 15. SeeedGrayOled.putNumber(tempF); //Print SeeedGrayOled.setTextXY(7,10); //set Cursor to 0th line, 10th column SeeedGrayOled.setGrayLevel(7); //Set Grayscale level. Any number between 0 - 15. SeeedGrayOled.putString("."); //Print SeeedGrayOled.setTextXY(7,11); //set Cursor to 0th line, 11th column SeeedGrayOled.setGrayLevel(7); //Set Grayscale level. Any number between 0 - 15. SeeedGrayOled.putNumber(tempfrac10int); //Print SeeedGrayOled.setTextXY(9,0); //set Cursor to 2nd line, 0th column SeeedGrayOled.setGrayLevel(7); //Set Grayscale level. Any number between 0 - 15. SeeedGrayOled.putString("Hum = "); //Print if (humidity < 10) { SeeedGrayOled.setTextXY(9,9); //set Cursor to 0th line, 8th column } else { SeeedGrayOled.setTextXY(9,8); //set Cursor to 0th line, 8th column } SeeedGrayOled.setGrayLevel(7); //Set Grayscale level. Any number between 0 - 15. SeeedGrayOled.putNumber(humidity); //Print SeeedGrayOled.setTextXY(9,10); //set Cursor to 2nd line, 10th column SeeedGrayOled.setGrayLevel(7); //Set Grayscale level. Any number between 0 - 15. SeeedGrayOled.putString("."); //Print SeeedGrayOled.setTextXY(9,11); //set Cursor to 2nd line, 11th column SeeedGrayOled.setGrayLevel(7); //Set Grayscale level. Any number between 0 - 15. SeeedGrayOled.putNumber(humfrac10int); //Print delay(100); //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= const uint16_t port = 9701; // port used by my remote ESP8266-01 units const char * host180 = "192.168.1.180"; // the ESP8266-01 with HDC1080 in my Attic const char * host181 = "192.168.1.181"; // the ESP8266-01 with HDC1080 in my Cellar const char * hostTHSPK = THNG_SPK_IP; // thingspeak.com const uint16_t portTHSPK = 80; // port used by thingspeak.com String Temp_180_str = ""; String Humid_180_str = ""; String Temp_181_str = ""; String Humid_181_str = ""; int commaIndex ; int secondCommaIndex; String firstValue180 = ""; String secondValue180 = ""; String thirdValue180 = ""; String firstValue181 = ""; String secondValue181 = ""; String thirdValue181 = ""; int sn; float sn_temp; float sn_hum; String cmd = ""; unsigned long currentMillis = millis(); if(currentMillis - previousMillis < 0) { // see if millis has rolled over previousMillis = 0; // happens after ~ 50 days } // Use WiFiClient class to create TCP connections WiFiClient client; digitalWrite(LED_IND, 0); // LED on NodeMCU is sunk by pin = ON Serial.print("connecting to "); Serial.print(host180); Serial.print(":"); Serial.println(port); // Use WiFiClient class to create TCP connections // WiFiClient client; if (!client.connect(host180, port)) { Serial.println("connection failed"); Serial.println("wait 5 sec..."); delay(5000); return; } // This will send the request to the server Serial.println("/?request=GetSensor_Non-HTML"); client.print("/?request=GetSensor_Non-HTML"); //read back one line from server delay(1000); String line1 = client.readStringUntil('\r'); //+++++++++++++++++++++++++++++++++++++++++++++++++ // somtimes a remote sensor read will fail // and return 0 for temperature and humidity // Keep the last valid reading from each sensor // so that a reading is availbale to send to // thingspeak, it may be a little stale but // it's better than sending 0 commaIndex = line1.indexOf(','); // Search for the next comma just after the first secondCommaIndex = line1.indexOf(',', commaIndex+1); firstValue180 = line1.substring(0, commaIndex); secondValue180 = line1.substring(commaIndex+1, secondCommaIndex); if (secondValue180.length() > 0){ secondValue180a = secondValue180; } thirdValue180 = line1.substring(secondCommaIndex+1); // To the end of the string if (thirdValue180.length() > 0){ thirdValue180a = thirdValue180; } Serial.print("secondValue180a = "); Serial.println(secondValue180a); Serial.print("thirdValue180a = "); Serial.println(thirdValue180a); cmd = GET; cmd += THINGSPEAK_KEY_W; // Write API Key cmd += ("&field1="); // Attic Temperature cmd += secondValue180a; cmd += ("&field2="); // Attic Humidity cmd += thirdValue180a; //+++++++++++++++++++++++++++++++++++++++++++++++++ Serial.println(line1); client.println(line1); SeeedGrayOled.setTextXY(1,0); //set Cursor to ith line, 0th column SeeedGrayOled.setGrayLevel(7); //Set Grayscale level. Any number between 0 - 15. char str1[13]; String str3 = ""; Serial.print("str1 = "); Serial.println(str1); char str2 = ' '; for (int k=0; k<(12);k++){ str1[k] = str2; } Serial.print("str1 = "); Serial.println(str1); for (int j=0; j<(13);j++){ str1[j] = line1.charAt(j+1); // need to drop one character to fit OLED width // so drop first character (1 from 180 of IP address) str3 = str1[j]; if (str3 == ","){ // replace commas with blanks so OLED looks better str1[j] = str2; } } Serial.print("str1 = "); Serial.println(str1); SeeedGrayOled.putString(str1); Serial.println("closing connection"); client.stop(); Serial.println("wait 3 sec..."); Serial.println("------------------------------"); digitalWrite(LED_IND, 1); // LED on NOdeMCU is sunk by pin = OFF delay(3000); yield(); //======================================================== digitalWrite(LED_IND, 0); // LED on NOdeMCU is sunk by pin = ON Serial.print("connecting to "); Serial.print(host181); Serial.print(":"); Serial.println(port); // Use WiFiClient class to create TCP connections // WiFiClient client; if (!client.connect(host181, port)) { Serial.println("connection failed"); Serial.println("wait 5 sec..."); delay(5000); return; } // This will send the request to the server Serial.println("/?request=GetSensor_Non-HTML"); client.print("/?request=GetSensor_Non-HTML"); //read back one line from server delay(1000); String line3 = client.readStringUntil('\r'); //+++++++++++++++++++++++++++++++++++++++++++++++++ commaIndex = line3.indexOf(','); // Search for the next comma just after the first secondCommaIndex = line3.indexOf(',', commaIndex+1); firstValue181 = line3.substring(0, commaIndex); secondValue181 = line3.substring(commaIndex+1, secondCommaIndex); if (secondValue181.length() > 0){ secondValue181a = secondValue181; } thirdValue181 = line3.substring(secondCommaIndex+1); // To the end of the string if (thirdValue181.length() > 0){ thirdValue181a = thirdValue181; } Serial.print("secondValue181a = "); Serial.println(secondValue181a); Serial.print("thirdValue181a = "); Serial.println(thirdValue181a); cmd += ("&field3="); // Cellar Temperature cmd += secondValue181a; cmd += ("&field4="); // Cellar Humidity cmd += thirdValue181a; cmd += ("&field5="); // Local Temperature cmd += tempF; cmd += ("&field6="); // Local Humidity cmd += humidity; //+++++++++++++++++++++++++++++++++++++++++++++++++ Serial.println(line3); client.println(line3); SeeedGrayOled.setTextXY(3,0); //set Cursor to ith line, 0th column SeeedGrayOled.setGrayLevel(7); //Set Grayscale level. Any number between 0 - 15. str3 = ""; Serial.print("str1 = "); Serial.println(str1); str2 = ' '; for (int k=0; k<(12);k++){ str1[k] = str2; } Serial.print("str1 = "); Serial.println(str1); for (int j=0; j<(13);j++){ str1[j] = line3.charAt(j+1); // need to drop one character to fit OLED width // so drop first character (1 from 181 of IP address) str3 = str1[j]; if (str3 == ","){ // replace commas with blanks so OLED looks better str1[j] = str2; } } Serial.print("str1 = "); Serial.println(str1); SeeedGrayOled.putString(str1); Serial.println("closing connection"); client.stop(); Serial.println("wait 3 sec..."); Serial.println("------------------------------"); digitalWrite(LED_IND, 1); // LED on NOdeMCU is sunk by pin = OFF delay(3000); yield(); //+++++++++++++++++++++++++++++++++++++++++++++++++ // See if it's time to send data to Thingspeak Serial.print("The Interval is: "); Serial.println(interval); Serial.print("The time is: "); Serial.println(currentMillis - previousMillis); if(currentMillis - previousMillis > interval) { // save the last time you "blinked" previousMillis = currentMillis; if (!client.connect(hostTHSPK,portTHSPK)) { /// ThinkSpeak IP Addresss Serial.println("connection THNG_SPK_IP failed"); Serial.println("wait 5 sec..."); delay(5000); return; } // This will send the request to the server Serial.println(cmd); client.println(cmd); Serial.println("closing connection"); client.stop(); Serial.println("wait 3 sec..."); Serial.println("------------------------------"); delay(3000); yield(); } //+++++++++++++++++++++++++++++++++++++++++++++++++ }