So you're a Noob? Post your questions here until you graduate! Don't be shy.

User avatar
By nzhillnet
#77018 Hi,

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.

Code: Select all// 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