Announcement

Collapse
No announcement yet.

Converting NodeMCU API sketch to work with ESP32 board?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Converting NodeMCU API sketch to work with ESP32 board?

    I'm still evaluating the plugin and came across the ESP32 units which can handle more than one analogue input. I've loaded the board manager and libraries and managed to change the majority of the code to work with the ESP32 board but I've hit the buffers trying to work out how to get a version to compile if I don't comment out the OTA section.

    The changes below address the differences with the changed libraries
    Code:
    //************Do not change anything after Here*****************
    
    #define ISIP 1
    #define BoardType 3
    const byte BoardAdd = 2;
    unsigned long LastAlive = 0;
    
    #if BoardType == 3 || BoardType == 5
    // #include <ESP8266WiFi.h>
    #include <WiFi.h> // changes required for ESP32
    #define UDP_TX_PACKET_MAX_SIZE 24 // changes required for ESP32
    #include <WiFiUdp.h>
    // #include <ESP8266mDNS.h>
    #include <ESPmDNS.h> // changes required for ESP32
    #include <ArduinoOTA.h>
    // #include <ESP8266HTTPClient.h>
    // #include <ESP8266httpUpdate.h>
    #include <HTTPClient.h> // changes required for ESP32
    #include <HTTPUpdate.h> // changes required for ESP32
    The main problem I have is that the void InstallUpdates() section generates a compile error as the change from ESPhttpUpdate.update to httpUpdate.update generates the error below.

    I'm not a C++ coder so at the moment it's trial and error unfortunately. Any assistance would be appreciated as once I can get past this issue I should be able to do what I need to do repurposing some code from a post in the HS3 plugin forum to get a multiple one wire and DHT11 environment working.

    I've also now got an ADS1115 4 channel ADC which I may be able to use with the NodeMCU unit as a fall back but it looks like the ESP32 could be a one board solution if it can work with the plugin.

    Any help would be appreciated.

    Dave

    Code:
    C:\Users\david\AppData\Local\Temp\APIBoard2temp\APIBoard2tem p.ino: In function 'void InstallUpdates()':
    
    APIBoard2temp:539:62: error: no matching function for call to 'HTTPUpdate::update(char*&)'
    
    t_httpUpdate_return ret = httpUpdate.update(fwImageURL); // changes required for ESP32
    
    ^
    
    In file included from C:\Users\david\AppData\Local\Temp\APIBoard2temp\APIBoard2tem p.ino:141:0:
    
    C:\Users\david\AppData\Local\Arduino15\packages\esp32\hardwa re\esp32\1.0.4\libraries\HTTPUpdate\src/HTTPUpdate.h:73:25: note: candidate: t_httpUpdate_return HTTPUpdate::update(WiFiClient&, const String&, const String&)
    
    t_httpUpdate_return update(WiFiClient& client, const String& url, const String& currentVersion = "");
    
    ^
    
    C:\Users\david\AppData\Local\Arduino15\packages\esp32\hardwa re\esp32\1.0.4\libraries\HTTPUpdate\src/HTTPUpdate.h:73:25: note: candidate expects 3 arguments, 1 provided
    
    C:\Users\david\AppData\Local\Arduino15\packages\esp32\hardwa re\esp32\1.0.4\libraries\HTTPUpdate\src/HTTPUpdate.h:75:25: note: candidate: t_httpUpdate_return HTTPUpdate::update(WiFiClient&, const String&, uint16_t, const String&, const String&)
    
    t_httpUpdate_return update(WiFiClient& client, const String& host, uint16_t port, const String& uri = "/",
    
    ^
    
    C:\Users\david\AppData\Local\Arduino15\packages\esp32\hardwa re\esp32\1.0.4\libraries\HTTPUpdate\src/HTTPUpdate.h:75:25: note: candidate expects 5 arguments, 1 provided
    
    Multiple libraries were found for "WiFi.h"
    Used: C:\Users\david\AppData\Local\Arduino15\packages\esp32\hardwa re\esp32\1.0.4\libraries\WiFi
    Not used: C:\Program Files (x86)\Arduino\libraries\WiFi
    exit status 1
    no matching function for call to 'HTTPUpdate::update(char*&)'

    #2
    I use Tasmota for the infrastructure for my sketches because of all the standard support it provides. This makes the interface to HS WiFi rather than cabled. I have a port when I did my BLE location trilateration project. I did not use Analog for the project but the Analog libraries are implemented. There is a version of this project at Http://mcsSprinklers.com/BLEScannerSource.zip.

    Comment


      #3
      Originally posted by Michael McSharry View Post
      I use Tasmota for the infrastructure for my sketches because of all the standard support it provides. This makes the interface to HS WiFi rather than cabled. I have a port when I did my BLE location trilateration project. I did not use Analog for the project but the Analog libraries are implemented. There is a version of this project at Http://mcsSprinklers.com/BLEScannerSource.zip.
      Thanks for the quick response Michael. Unfortunately thats beyond my comprehension at the moment. I'm just starting off with Arduino/NodeMCU modules and finding its a steep learning curve. My coding is limited to BASIC and scripting, at the moment I'm literally picking through code line by line trying to work out if it's a native command, a variable, function or some other cryptic inclusion.

      Comment


        #4
        After much Googling and fiddling with the code, I've managed to modify the NodeMCU API default sketch to compile for the ESP32 Dev Board. After uploading I was able to make a network connection to the board from the Arduino IDE and upload an updated sketch.

        Next step is to start to add two OneWire temp sensors, BME280 Temp/Humidity/pressure sensor, analog flow sensor, analog PH sensor, analog EC sensor and an Adafruit TSL2591 High Dynamic Range Digital Light Sensor.

        Changed lines have '/// Changed to support ESP32 HTTP FOTA' after them.

        Code:
        /************************************************************ *
        Arduino to Homeseer 4 Plugin API written by Enigma Theatre.
        V4.0.2.0
        * *
        ************************************************************ */
        int FromHS[50];
        boolean IsConnected = false;
        byte AlivePin = 255;
        //************************************************************
        //To Use the Alive pin change the 255 to the pin number above.
        // REQUIRES the following Arduino libraries:
        
        
        //**************Declare your variables here*******************
        bool isFahreheit = false; // change to true for Celsius
        
        
        //************************************************************ ****
        
        
        
        
        void HSSetup() {
        
        //************************
        //Add YOUR SETUP HERE;
        //************************
        // dht.begin();
        
        }
        
        
        void HSloop() {
        //************************
        //Add YOUR CODE HERE;
        //************************
        /* To Send Data to Homeseer use SendToHS(Device,Value)
        Eg.. SendToHS(1,200); where 1 is the API device in homeseer and 200 is the value to send
        To Recieve data from Homeseer look up the FromHS array that is updated when the device value changes.
        Eg.. FromHS[5] would be the data from API Output device 5
        All code that is located just below this block will execute regardless of connection status!
        You can include SendToHS() calls, however when there isn't an active connection, it will just return and continue.
        If you only want code to execute when HomeSeer is connected, put it inside the if statement below.
        */
        
        /*Execute regardless of connection status*/
        
        
        if (IsConnected == true) {
        /*Execute ONLY when HomeSeer is connected*/
        // Wait a few seconds between measurements.
        
        SendToHS (1,101);
        SendToHS (2,202);
        SendToHS (3,303);
        
        }
        
        }
        
        //Voids After here.
        
        
        
        
        //************Do not change anything after Here*****************
        
        #define ISIP 1
        #define BoardType 3
        #define UDP_TX_PACKET_MAX_SIZE 24 /// Changed to support ESP32 HTTP FOTA
        const byte BoardAdd = 2;
        unsigned long LastAlive = 0;
        
        #if BoardType == 3 || BoardType == 5
        #include <WiFi.h> /// Changed to support ESP32 HTTP FOTA
        #include <WiFiUdp.h>
        #include <ESPmDNS.h> /// Changed to support ESP32 HTTP FOTA
        #include <ArduinoOTA.h>
        #include <HTTPClient.h> /// Changed to support ESP32 HTTP FOTA
        #include <HTTPUpdate.h> /// Changed to support ESP32 HTTP FOTA
        #include <Update.h> /// Changed to support ESP32 HTTP FOTA
        #include <WIFIClient.h> /// Changed to support ESP32 HTTP FOTA
        WiFiClient client; /// Changed to support ESP32 HTTP FOTA
        char ssid[] = "ssid";
        char pass[] = "ssid key";
        #else
        #include <SPI.h>
        #include <Ethernet.h>
        #include <EthernetUdp.h>
        #endif
        
        
        #if ISIP == 1
        
        
        byte mac[] = {0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02};
        IPAddress ip(10,1,1,102); //IP entered In HS config.
        const unsigned int localPort = 8901; //port entered In HS config.
        IPAddress HomeseerIP(10,1,1,100); //Homeseer IP address
        IPAddress gateway(10,1,1,240);
        IPAddress subnet(255,255,255,0);
        char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
        #endif
        
        
        
        
        #if BoardType == 3 || BoardType == 5
        WiFiUDP Udp;
        WiFiUDP SendPort;
        void resetFunc() {
        ESP.restart();
        }
        #else
        void(*resetFunc) (void) = 0;
        EthernetUDP Udp;
        #endif
        
        
        
        const char* Version = "API4.0.2.0";
        byte Byte1, Byte2, Byte3;
        unsigned int Byte4, Byte5;
        
        
        void setup() {
        
        
        #if ISIP == 1
        
        #if BoardType == 3 || BoardType == 5
        //Serial.begin(115200);
        WiFi.begin(ssid, pass);
        WiFi.config(ip, gateway, subnet);
        WiFi.mode(WIFI_STA);
        while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        }
        OTA();
        #else
        Ethernet.begin(mac, ip, gateway, gateway, subnet);
        #endif
        Udp.begin(localPort);
        Udp.setTimeout(0);
        delay(1000);
        
        #else
        Serial.begin(115200);
        Serial.flush();
        Serial.setTimeout(0);
        delay(1000);
        #endif
        
        Send(F("Connect "));
        Send(String(BoardAdd));
        Send();
        
        IsConnected = false;
        HSSetup();
        
        pinMode(AlivePin, OUTPUT);
        
        }
        
        
        void loop() {
        #if BoardType == 3 || BoardType == 5
        ArduinoOTA.handle();
        #endif
        HSloop();
        #if ISIP == 1
        UDPCheck();
        #endif
        AliveCheck();
        }
        
        
        #if ISIP == 1
        void UDPCheck() {
        int packetSize = Udp.parsePacket();
        if (packetSize)
        {
        if (Udp.remoteIP() != HomeseerIP) {
        HomeseerIP = Udp.remoteIP();
        }
        
        #if BoardType == 3 || BoardType == 5
        Byte1 = Udp.parseInt();
        Udp.read();
        Byte2 = Udp.read();
        Udp.read();
        Byte3 = Udp.parseInt();
        Udp.read();
        Byte4 = Udp.parseInt();
        Udp.read();
        Byte5 = Udp.parseInt();
        DataEvent();
        #else
        Byte1 = Udp.parseInt();
        Udp.read();
        Byte2 = Udp.read();
        Byte3 = Udp.parseInt();;
        Byte4 = Udp.parseInt();
        Byte5 = Udp.parseInt();;
        DataEvent();
        #endif
        }
        }
        
        #else
        void serialEvent() {
        while (Serial.available() > 0) {
        delay(17);
        Byte1 = Serial.parseInt();
        Serial.read();
        Byte2 = Serial.read();
        Byte3 = Serial.parseInt();
        Byte4 = Serial.parseInt();
        Byte5 = Serial.parseInt();
        DataEvent();
        }
        }
        #endif
        
        
        /*
        
        Used Data Input Cases
        D Disconnect
        r reset
        K Keepalive
        O PinMode Output Set
        d Input debounce time set
        C Connect request
        c Connection established - report current status
        */
        void DataEvent() {
        
        if (Byte1 == BoardAdd) {
        LastAlive = millis();//Reset the Alive timer if board Data recieved
        
        switch (Byte2) {
        case 'c':
        IsConnected = true;
        break;
        
        case 'C':
        Send();
        Send(F("Version "));
        Send(String(BoardAdd));
        Send(F(" "));
        Send(String(Version));
        Send(F(" HS4"));
        Send();
        delay(1000);
        Send(F("Connected "));
        Send(String(BoardAdd));
        Send();
        IsConnected = false;
        break;
        
        case 'K':
        delay(200);
        Send(F("Alive "));
        Send(String(BoardAdd));
        Send();
        
        break;
        
        case 'r':
        delay(200);
        resetFunc(); //call reset
        break;
        
        case 'O':
        FromHS[Byte3] = Byte4;
        break;
        
        case 'U':
        InstallUpdates();
        break;
        
        case 'D':
        IsConnected = false;
        break;
        }
        }
        }
        
        
        //**********************************Alive Check***********************************
        
        void AliveCheck() {
        
        if (millis() - LastAlive < 40000 && IsConnected == true) { //if connected and data recieved within 40sec set Alive pin High.
        if (AlivePin < 255) {
        digitalWrite(AlivePin, HIGH);
        }
        }
        else if (millis() - LastAlive > 60000 && millis() - LastAlive < 60005 && IsConnected == true) { //if connected but no data recieved for 81sec reset Ack.
        Send(F("Alive "));
        Send(String(BoardAdd));
        Send();
        }
        
        else {
        if (AlivePin < 255 && millis() - LastAlive > 81000 && millis() - LastAlive < 81005) {
        Send(F("Connect "));
        Send(String(BoardAdd));
        Send();
        digitalWrite(AlivePin, LOW);
        }
        }
        
        if (millis() - LastAlive > 90000 && IsConnected == true) { //if connected but no data recieved for 90sec reset the board.
        resetFunc();
        }
        }
        
        void SendToHS(byte Device, long Data) {
        if (IsConnected == true) {
        #if ISIP == 1
        Udp.beginPacket(HomeseerIP, 8888);
        Udp.print(BoardAdd);
        Udp.print(" API ");
        Udp.print(Device);
        Udp.print(" ");
        Udp.print(Data);
        Udp.endPacket();
        #else
        Serial.print(BoardAdd);
        Serial.print(" API ");
        Serial.print(Device);
        Serial.print(" ");
        Serial.println(Data);
        #endif
        }
        }
        
        void SendToHS(byte Device, int Data) {
        if (IsConnected == true) {
        #if ISIP == 1
        Udp.beginPacket(HomeseerIP, 8888);
        Udp.print(BoardAdd);
        Udp.print(" API ");
        Udp.print(Device);
        Udp.print(" ");
        Udp.print(Data);
        Udp.endPacket();
        #else
        Serial.print(BoardAdd);
        Serial.print(" API ");
        Serial.print(Device);
        Serial.print(" ");
        Serial.println(Data);
        #endif
        }
        }
        
        void SendToHS(byte Device, float Data) {
        if (IsConnected == true) {
        #if ISIP == 1
        Udp.beginPacket(HomeseerIP, 8888);
        Udp.print(BoardAdd);
        Udp.print(" API ");
        Udp.print(Device);
        Udp.print(" ");
        Udp.print(Data);
        Udp.endPacket();
        #else
        Serial.print(BoardAdd);
        Serial.print(" API ");
        Serial.print(Device);
        Serial.print(" ");
        Serial.println(Data);
        #endif
        }
        }
        
        void SendToHS(byte Device, double Data) {
        if (IsConnected == true) {
        #if ISIP == 1
        Udp.beginPacket(HomeseerIP, 8888);
        Udp.print(BoardAdd);
        Udp.print(" API ");
        Udp.print(Device);
        Udp.print(" ");
        Udp.print(Data);
        Udp.endPacket();
        #else
        Serial.print(BoardAdd);
        Serial.print(" API ");
        Serial.print(Device);
        Serial.print(" ");
        Serial.println(Data);
        #endif
        }
        }
        
        bool UdpSend = false;
        void Send(const String& Data)
        {
        #if ISIP == 0
        Serial.print(Data);
        #else
        if (UdpSend == false) {
        UdpSend = true;
        Udp.beginPacket(HomeseerIP, 8888);
        Udp.print(Data);
        }
        else {
        Udp.print(Data);
        }
        #if Debug
        Serial.print(Data);//debug
        #endif
        #endif
        }
        
        void Send()
        {
        #if ISIP == 0
        Serial.println();
        #else
        Udp.endPacket();
        UdpSend = false;
        #if Debug
        Serial.print(F(", Sent to "));//debug
        Serial.println(HomeseerIP);//debug
        #endif
        #endif
        
        }
        
        
        #if BoardType == 3 || BoardType == 5
        //*******************************OTA Update*************************
        void OTA() {
        char OTAName[50];
        sprintf(OTAName, "Homeseer API Board:%02i", BoardAdd);
        ArduinoOTA.setHostname(OTAName);
        ArduinoOTA.onStart([]() {
        
        });
        ArduinoOTA.onEnd([]() {
        
        });
        ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
        
        });
        ArduinoOTA.onError([](ota_error_t error) {
        
        });
        ArduinoOTA.begin();
        
        }
        
        int PrevWiFiStatus = 0;
        void WiFiStatus() {
        if (PrevWiFiStatus - 10 > WiFi.RSSI() || PrevWiFiStatus + 10 < WiFi.RSSI()) {
        Send(F("WiFi "));
        Send(String(BoardAdd));
        Send(" ");
        Send(String(WiFi.RSSI()));
        Send();
        PrevWiFiStatus = WiFi.RSSI();
        }
        }
        
        char* fwImageURL = "http://10.1.1.100:80/Arduino-4/APIBoard2.ino/APIBoard2.bin";
        
        void InstallUpdates() {
        
        
        HTTPClient httpClient;
        httpClient.begin(fwImageURL);
        int httpCode = httpClient.GET();
        if (httpCode == 200) {
        
        // Serial.println("Update file found, starting update");
        t_httpUpdate_return ret = httpUpdate.update( client, fwImageURL); /// Changed to support ESP32 HTTP FOTA
        
        Send(F("Updating "));
        Send(String(BoardAdd));
        Send();
        
        switch (ret) {
        case HTTP_UPDATE_FAILED:
        Send(F("UpdatingF "));
        Send(String(httpUpdate.getLastError())); /// Changed to support ESP32 HTTP FOTA
        Send();
        
        // Serial.printf("HTTP_UPDATE_FAILD Error (%d): %s", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str()); /// Changed to support ESP32 HTTP FOTA
        break;
        }
        }
        else {
        // Serial.print("Firmware check failed, got HTTP response code ");
        Serial.println(httpCode);
        Send(F("UpdatingF "));
        Send(String(httpCode));
        Send();
        }
        httpClient.end();
        }
        #endif

        Comment


          #5
          Originally posted by Michael McSharry View Post
          I use Tasmota for the infrastructure for my sketches because of all the standard support it provides. This makes the interface to HS WiFi rather than cabled. I have a port when I did my BLE location trilateration project. I did not use Analog for the project but the Analog libraries are implemented. There is a version of this project at Http://mcsSprinklers.com/BLEScannerSource.zip.
          Michael, 72 hours in I have a much better understanding of ESP8266 and ESP32 devices. Are you planning on porting your plugin to HS4 natively?

          Comment

          Working...
          X