Zwer2k / WeatherStationDataRx

Arduino library for read weather data from Venus W174/W132 (tested), Auriol H13726, Hama EWS 1500, Meteoscan W155/W160
MIT License
22 stars 8 forks source link

Problem with arduinoOTA #6

Closed Merlin-33 closed 3 years ago

Merlin-33 commented 4 years ago

Hello,

I signed up on github because I don't know how to ask you for help with your arduino library. I am putting OTA support but I am having upload problems due to wsdr.begin (); which causes me errors every time. A priori this blocks me the OTA update and I do not know how to stop this function because the wsdr.end (); does not exist according to my IDE compiler ... How can I do? I hope I put it in the right place because I have no idea how Github works ... Thank you

Zwer2k commented 4 years ago

Hello,

Which ESP board do you use?

Merlin-33 commented 4 years ago

hello, so I'm using the Wemos D1 mini ESP card. I'm trying to see how I can work around my problem, I had a solution with delay (); but it blocks me all, even the OTA update.

Zwer2k commented 4 years ago

Hello, i have tested OTA update with two diferent librarys (ArduinoOTA and ESP8266httpUpdate), both work fine for me. Here is my test code. It include both librarys and mqtt

#include <ESP8266WiFi.h>
#include <ESP8266httpUpdate.h>
#include <ArduinoOTA.h>
#include <PubSubClient.h>
#include "WeatherStationDataRx.h"

#ifdef ESP8266
#define DATA_PIN D5
#define BATT_PIN A0
#else
#define DATA_PIN 2
#define BATT_PIN A0
#endif

const String hostName            = "WeatherStation";
const char* version              = "0.0.7";
const char* wifi_ssid            = "your SSID";
const char* wifi_pass            = "your password";
const char* ota_url              = "http://your-update-server/WeatherStation.bin";
const char* mqtt_server          = "your mqtt server ip";
const char* mqtt_user            = "mqtt usr";
const char* mqtt_pass            = "mqtt password";
const unsigned long reconnectInterval = 5000;   // reconnect interval if mqtt disconnected
const unsigned long battReadInterval = 60000;   // battery read interval

unsigned long lastReconnect = 0;
unsigned long lastBattRead = 0;
WiFiClient espClient;
PubSubClient client(espClient);
WeatherStationDataRx wsdr(DATA_PIN, true);

void PubSubCallback(char* topic, byte* payload, unsigned int length) {
  String sTopic((const __FlashStringHelper*)topic);
  Serial.print("Message arrived [" + sTopic + "]");
  String sVal((const __FlashStringHelper*)payload);
  sVal = sVal.substring(0, length);
  Serial.println(sVal);
}

void PairedDeviceAdded(byte newID)
{
#if defined(ESP8266) || defined(ESP32)
    Serial.printf("New device paired %d\r\n", newID);
#else
    Serial.print("New device paired ");
    Serial.println(newID, DEC);
#endif

    wsdr.pair(NULL, PairedDeviceAdded);
}

void setup()
{
  Serial.begin(115200);
  delay(5000);
  Serial.println(String("Init ") + hostName + "@" + version);  
  Serial.println(hostName);

  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);

  /* Explicitly set the ESP8266 to be a WiFi-client, otherwise, it by default,
    would try to act as both a client and an access-point and could cause
    network-issues with your other WiFi-devices on your WiFi-network. */
  WiFi.mode(WIFI_STA);
  WiFi.hostname(hostName);
  WiFi.begin(wifi_ssid, wifi_pass);

  int retrys = 30;
  while ((WiFi.status() != WL_CONNECTED) && (retrys > 0)) {
    delay(1000);
    Serial.print(".");
    retrys--;
  }

  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP()); 

    Serial.println("get firmware"); 
    t_httpUpdate_return ret = ESPhttpUpdate.update(ota_url, version);

    switch(ret) {
      case HTTP_UPDATE_FAILED:
        Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
        Serial.println("");
        break;

      case HTTP_UPDATE_NO_UPDATES:
        Serial.println("HTTP_UPDATE_NO_UPDATES");
        break;

      case HTTP_UPDATE_OK:
        Serial.println("HTTP_UPDATE_OK");
        break;
    }
  } else {
    Serial.println("WiFi not connected");
  }

  ArduinoOTA.onStart([]() {
    String type;
    if (ArduinoOTA.getCommand() == U_FLASH) {
      type = "sketch";
    } else { // U_SPIFFS
      type = "filesystem";
    }

    // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end()
    Serial.println("Start updating " + type);
  });
  ArduinoOTA.onEnd([]() {
    Serial.println("\nEnd");
  });
  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
    Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
  });
  ArduinoOTA.onError([](ota_error_t error) {
    Serial.printf("Error[%u]: ", error);
    if (error == OTA_AUTH_ERROR) {
      Serial.println("Auth Failed");
    } else if (error == OTA_BEGIN_ERROR) {
      Serial.println("Begin Failed");
    } else if (error == OTA_CONNECT_ERROR) {
      Serial.println("Connect Failed");
    } else if (error == OTA_RECEIVE_ERROR) {
      Serial.println("Receive Failed");
    } else if (error == OTA_END_ERROR) {
      Serial.println("End Failed");
    }
  });
  ArduinoOTA.begin();

  client.setServer(mqtt_server, 1883);
  client.setCallback(PubSubCallback);

  wsdr.begin();
  wsdr.pair(NULL, PairedDeviceAdded);
}

void reconnect() 
{
  // Loop until we're reconnected
  if (!client.connected()) 
  {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    //if you MQTT broker has clientID,username and password
    //please change following line to    if (client.connect(clientId,userName,passWord))
    if (client.connect(hostName.c_str(), mqtt_user, mqtt_pass))
    {
      Serial.println("connected");
     //once connected to MQTT broker, subscribe command if any
      client.publish((hostName + "/Version").c_str(), version);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
    }
  }
}

void loop()
{
  unsigned long now = millis();
  if (!client.connected() && (now - lastReconnect > reconnectInterval)) {
    reconnect();
    lastReconnect = now;
    now = millis();
  }

  ArduinoOTA.handle();

  if (now - lastBattRead > battReadInterval) {
    int battValueSum = 0;
    for (int i=0; i<10; i++) {
      battValueSum += analogRead(BATT_PIN);
      delay(10);
    }
    battValueSum = battValueSum / 10;
    float battValue = (float)battValueSum / 10;
    Serial.print("Battery state: ");
    Serial.print(battValue);
    Serial.println("V");

    client.publish((hostName + "/Battery").c_str(), String(battValue).c_str());
    lastBattRead = now;
  }

  String sensorID = String(wsdr.sensorID());
  bool batteryLow = bitRead(wsdr.batteryStatus(), 0) != 0;
  client.loop();

  char newData = wsdr.readData();
  switch (newData)
  {
  case 'T': {
    String temperature = String(wsdr.readTemperature());
    String humidity = String(wsdr.readHumidity());      
    Serial.print("Temperature: ");
    Serial.print(temperature);
    Serial.print("°");
    Serial.println("C");
    Serial.print("Humidity: ");
    Serial.print(humidity);
    Serial.println("%");
    Serial.print("Battery: ");
    Serial.println(batteryLow ? "Low" : "OK");
    Serial.print("Sensor ID: ");
    Serial.println(sensorID);

    client.publish((hostName + "/" + wsdr.sensorID() + "/Temperature").c_str(), temperature.c_str());
    client.publish((hostName + "/" + wsdr.sensorID() + "/Humidity").c_str(), humidity.c_str());
    client.publish((hostName + "/" + wsdr.sensorID() + "/BatteryLow").c_str(), String(batteryLow).c_str());
    break;
  }
  case 'S': {
    String windSpeed = String(wsdr.readWindSpeed());
    Serial.print("Wind speed: ");
    Serial.print(windSpeed);
    Serial.println("m/s");
    Serial.print("Battery: ");
    Serial.println(batteryLow ? "Low" : "OK");
    Serial.print("Sensor ID: ");
    Serial.println(sensorID);

    client.publish((hostName + "/" + wsdr.sensorID() + "/WindSpeed").c_str(), windSpeed.c_str());
    client.publish((hostName + "/" + wsdr.sensorID() + "/BatteryLow").c_str(), String(batteryLow).c_str());
    break;
  }
  case 'G': {
    String windDirection = String(wsdr.readWindDirection());
    String windGust = String(wsdr.readWindGust());
    Serial.print("Wind direction: ");
    Serial.print(windDirection);
    Serial.println("°");
    Serial.print("Wind gust: ");
    Serial.print(windGust);
    Serial.println("m/s");
    Serial.print("Battery: ");
    Serial.println(batteryLow ? "Low" : "OK");
    Serial.print("Sensor ID: ");
    Serial.println(sensorID);

    client.publish((hostName + "/" + wsdr.sensorID() + "/WindDirection").c_str(), windDirection.c_str());
    client.publish((hostName + "/" + wsdr.sensorID() + "/WindGust").c_str(), windGust.c_str());
    client.publish((hostName + "/" + wsdr.sensorID() + "/BatteryLow").c_str(), String(batteryLow).c_str());
    break;
  }
  case 'R': {
    String rainVolume = String(wsdr.readRainVolume());
    Serial.print("Rain volume: ");
    Serial.print(rainVolume);
    Serial.println("mm");
    Serial.print("Battery: ");
    Serial.println(batteryLow ? "Low" : "OK");
    Serial.print("Sensor ID: ");
    Serial.println(sensorID);

    client.publish((hostName + "/" + wsdr.sensorID() + "/RainVolume").c_str(), rainVolume.c_str());
    client.publish((hostName + "/" + wsdr.sensorID() + "/BatteryLow").c_str(), String(batteryLow).c_str());
    break;
  }
  default:
      break;
  }
}
Merlin-33 commented 4 years ago

Ok thank you, my code is not quite the same, but a priori it is a loop which pisses off at the level of the wifi which takes back the hand according to certain people ... Suddenly it does not even work with the solution of your code. So I sought to develop an update system through a button to block the launch of wsdr.begin () and let the OTA update be done. It's not yet finished but I'm almost there, if it works I could say how to do it here, if it's possible :)

Zwer2k commented 4 years ago

I have implemented end() function. I hope it helps you with your problem.

Merlin-33 commented 4 years ago

Ok thanks, so if I do wsdr.end (); this will therefore stop me from all the functions that have been launched by wsdr.begin (); ?

Zwer2k commented 3 years ago

Yes exactly.