Self taught "hobbiest" here with lots to learn...
In short the code below polls various sensors, publishes their data to my MQTT server then displays the data on a Nextion display. In addition it also fetches a weather forecast, again to display.
The issue is that the MQTT part works, the forecast "GET" dosn't. Well if I'm lucky I get an initial one then nothing after that. The code with the MQTT part removed does work, so I think it is a network connection issue, with MQTT closing the connection and the "GET" code not reopeninging it....but I'm guessing.
I've searched the internet and tried changes but I'm going nowhere.
// Inspired by ESP32 Weather Station Project
// http://educ8s.tv/esp32-weather-station
// Code from a number of sources
// This version was created by Roland Hill, July 2018
// Board = ESP8266_12mod LoLin NodeMcu V3
#define ARDUINOJSON_ENABLE_PROGMEM 0
/*-----( Import needed libraries )-----*/
#include <ArduinoJson.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <DHT_U.h>
#include <DHT.h>
#include <Wire.h>
#include <ESP8266WiFi.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <PubSubClient.h>
/*-----( Declare Constants and Pin Numbers )-----*/
//spare data pin is GPIO2,D4
#define DHTPIN 4 // GPI04,D2
#define DHTTYPE DHT22 // DHT22(AM2302)
#define ONE_WIRE_BUS 5 // GPIO5,D1
#define I2C_SDA 12 // GPIO12,D6
#define I2C_SCL 14 // GPIO14,D5
#define ALTITUDE 0 // Altitude in Papamoa, NZ
#define LED_PIN LED_BUILTIN
#define tho "sensor/dht22a/humidity"
#define tto "sensor/dht22a/temperature"
#define tt3 "sensor/28FF0E3E8C1603CA/temperature"
#define tpo "sensor/bme280/pressure"
const char* ssid = "redacted";
const char* password = "redacted";
String CityID = "2184975"; //Papamoa, NZ
String APIKEY = "redacted";
int weatherID = 0;
const char* servername = "api.openweathermap.org"; // remote server we will connect to
String result;
int iterations = 1800;
String weatherDescription = "";
String weatherLocation = "";
float temperature = 0;
float temp_out = 0;
float humidity = 0;
float pressure = 0;
/*-----( Declare objects )-----*/
//BME280
Adafruit_BME280 bme;
// DHT 22(AM2302)
DHT dht(DHTPIN, DHTTYPE);
// DS18B20 sensor
OneWire oneWire(ONE_WIRE_BUS); //oneWire instance to communicate with any OneWire devices
DallasTemperature sensors(&oneWire);// Pass address of our oneWire instance to Dallas Temperature.
DeviceAddress Probe03 = { 0x28, 0xFF, 0x0E, 0x3E, 0x8C, 0x16, 0x03, 0xCA };
// Initialize the Ethernet and MQTT client objects
WiFiClient espClient;
PubSubClient client(espClient);
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
setup_wifi();
client.setServer("redacted", 1883);
// BME280
initSensor();
// DS18B20 sensor, resolution, 9 to 12 bits (lower is faster)
sensors.setResolution(Probe03, 10);
// DHT 22(AM2302)
dht.begin();
}
void loop() {
// Connect to MQTT
if (!client.connected())
{
reconnect();
} else {
client.loop();
}
delay(2000);
if (iterations == 1800) //We check for updated weather forecast once every hour
{
getWeatherData();
printWeatherIcon(weatherID);
iterations = 0;
}
getTemp_In();
sendTemp_InToNextion();
getTemp_Out();
sendTemp_OutToNextion();
getHumidity();
sendHumidityToNextion();
getPressure();
sendPressureToNextion();
iterations++;
blinkLED();
// Publish
client.publish(tho, String(humidity).c_str(), true);
delay(1000);
client.publish(tto, String(temp_out).c_str(), true);
delay(1000);
client.publish(tt3, String(temperature).c_str(), true);
delay(1000);
client.publish(tpo, String(pressure).c_str(), true);
delay(1000);
}
void setup_wifi() {
delay(10);
WiFi.hostname("hillnode_3");
// We start by connecting to a WiFi network
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
// Attempt to connect
if (client.connect("ESP8266Client_3", "redacted", "redacted")) {
Serial.println("connected\n");
} else {
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void initSensor() {
Wire.begin(I2C_SDA, I2C_SCL);
bool status = bme.begin(BME280_ADDRESS);
if (!status) {
Serial.println("Could not find a valid BME280 sensor, check wiring!");
while (1);
}
}
void blinkLED() {
digitalWrite(LED_PIN, HIGH);
delay(100);
digitalWrite(LED_PIN, LOW);
}
float getTemp_Out() {
temp_out = dht.readTemperature();
}
float getTemp_In() {
sensors.requestTemperatures();
temperature = sensors.getTempC(Probe03);
}
float getHumidity() {
humidity = dht.readHumidity();
}
float getPressure() {
pressure = bme.readPressure();
pressure = bme.seaLevelForAltitude(ALTITUDE, pressure);
pressure = pressure / 100.0F;
}
void getWeatherData() { //client function to send/receive GET request data.
String result = "";
WiFiClient client;
const int httpPort = 80;
if (!client.connect(servername, httpPort)) {
return;
}
// We now create a URI for the request
String url = "/data/2.5/forecast?id=" + CityID + "&units=metric&cnt=1&APPID=" + APIKEY;
// This will send the request to the server
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + servername + "\r\n" +
"Connection: close\r\n\r\n");
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
client.stop();
return;
}
}
// Read all the lines of the reply from server
while (client.available()) {
result = client.readStringUntil('\r');
}
result.replace('[', ' ');
result.replace(']', ' ');
char jsonArray [result.length() + 1];
result.toCharArray(jsonArray, sizeof(jsonArray));
jsonArray[result.length() + 1] = '\0';
StaticJsonBuffer<1024> json_buf;
JsonObject &root = json_buf.parseObject(jsonArray);
if (!root.success())
{
Serial.println("parseObject() failed");
}
String location = root["city"]["name"];
String temperature = root["list"]["main"]["temp"];
String weather = root["list"]["weather"]["main"];
String description = root["list"]["weather"]["description"];
String idString = root["list"]["weather"]["id"];
String timeS = root["list"]["dt_txt"];
weatherID = idString.toInt();
Serial.print("\nWeatherID: ");
Serial.print(weatherID);
endNextionCommand(); //We need that in order the nextion to recognise the first command after the serial print
}
void showConnectingIcon() {
Serial.println();
String command = "weatherIcon.pic=3";
Serial.print(command);
endNextionCommand();
}
void sendHumidityToNextion() {
String command = "humidity.txt=\"" + String(humidity, 1) + "\"";
Serial.print(command);
endNextionCommand();
}
void sendTemp_InToNextion() {
String command = "temperature.txt=\"" + String(temperature, 1) + "\"";
Serial.print(command);
endNextionCommand();
}
void sendTemp_OutToNextion() {
String command = "temp_out.txt=\"" + String(temp_out, 1) + "\"";
Serial.print(command);
endNextionCommand();
}
void sendPressureToNextion() {
String command = "pressure.txt=\"" + String(pressure, 1) + "\"";
Serial.print(command);
endNextionCommand();
}
void endNextionCommand() {
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);
}
void printWeatherIcon(int id) {
switch (id)
{
case 800: drawClearWeather(); break;
case 801: drawFewClouds(); break;
case 802: drawFewClouds(); break;
case 803: drawCloud(); break;
case 804: drawCloud(); break;
case 200: drawThunderstorm(); break;
case 201: drawThunderstorm(); break;
case 202: drawThunderstorm(); break;
case 210: drawThunderstorm(); break;
case 211: drawThunderstorm(); break;
case 212: drawThunderstorm(); break;
case 221: drawThunderstorm(); break;
case 230: drawThunderstorm(); break;
case 231: drawThunderstorm(); break;
case 232: drawThunderstorm(); break;
case 300: drawLightRain(); break;
case 301: drawLightRain(); break;
case 302: drawLightRain(); break;
case 310: drawLightRain(); break;
case 311: drawLightRain(); break;
case 312: drawLightRain(); break;
case 313: drawLightRain(); break;
case 314: drawLightRain(); break;
case 321: drawLightRain(); break;
case 500: drawLightRainWithSunOrMoon(); break;
case 501: drawLightRainWithSunOrMoon(); break;
case 502: drawLightRainWithSunOrMoon(); break;
case 503: drawLightRainWithSunOrMoon(); break;
case 504: drawLightRainWithSunOrMoon(); break;
case 511: drawLightRain(); break;
case 520: drawModerateRain(); break;
case 521: drawModerateRain(); break;
case 522: drawHeavyRain(); break;
case 531: drawHeavyRain(); break;
case 600: drawLightSnowfall(); break;
case 601: drawModerateSnowfall(); break;
case 602: drawHeavySnowfall(); break;
case 611: drawLightSnowfall(); break;
case 612: drawLightSnowfall(); break;
case 615: drawLightSnowfall(); break;
case 616: drawLightSnowfall(); break;
case 620: drawLightSnowfall(); break;
case 621: drawModerateSnowfall(); break;
case 622: drawHeavySnowfall(); break;
case 701: drawFog(); break;
case 711: drawFog(); break;
case 721: drawFog(); break;
case 731: drawFog(); break;
case 741: drawFog(); break;
case 751: drawFog(); break;
case 761: drawFog(); break;
case 762: drawFog(); break;
case 771: drawFog(); break;
case 781: drawFog(); break;
default: break;
}
}
void drawFog() {
String command = "weatherIcon.pic=13";
Serial.print(command);
endNextionCommand();
}
void drawHeavySnowfall() {
String command = "weatherIcon.pic=8";
Serial.print(command);
endNextionCommand();
}
void drawModerateSnowfall() {
String command = "weatherIcon.pic=8";
Serial.print(command);
endNextionCommand();
}
void drawLightSnowfall() {
String command = "weatherIcon.pic=11";
Serial.print(command);
endNextionCommand();
}
void drawHeavyRain() {
String command = "weatherIcon.pic=10";
Serial.print(command);
endNextionCommand();
}
void drawModerateRain() {
String command = "weatherIcon.pic=6";
Serial.print(command);
endNextionCommand();
}
void drawLightRain() {
String command = "weatherIcon.pic=6";
Serial.print(command);
endNextionCommand();
}
void drawLightRainWithSunOrMoon() {
String command = "weatherIcon.pic=7";
Serial.print(command);
endNextionCommand();
}
void drawThunderstorm() {
String command = "weatherIcon.pic=3";
Serial.print(command);
endNextionCommand();
}
void drawClearWeather() {
String command = "weatherIcon.pic=4";
Serial.print(command);
endNextionCommand();
}
void drawCloud() {
String command = "weatherIcon.pic=9";
Serial.print(command);
endNextionCommand();
}
void drawFewClouds() {
String command = "weatherIcon.pic=5";
Serial.print(command);
endNextionCommand();
}
All advice, suggestions welcomed.
--
Roland
Everday is good day for learning