Announcement

Collapse
No announcement yet.

ESP8266 OTA using the API sketch (code included)

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

  • ESP8266 OTA using the API sketch (code included)

    I have 10 ESP8266 nodeMCUs installed. I run a standard sketch in them. All the same other than a bit of board specific configs. When I find a problem or develop a new function that all boards should use, it was a real pain to go to each location and update the board. Sometimes I would bring it back to the bench and sometimes I would take my laptop to the location for updating. Either way, the process sometimes justified not keeping them all up to date.

    I found out about being able to update the ESP8266 across wifi. It has been implemented in my basic sketch and I'm starting the process of updating all the boards with the hope I won't have to do this nearly as often.

    If you are using the API sketch for the ESP8266, below are the changes required to enable OTA. I'm assuming that you know your way around the sketch and the IDE.

    You will need to install python ver. 2.7.13. It is used to do the actual wireless upload. There is a newer version but the doc I found said to use 2.7.13 and it worked for me so that is what I am passing along. I actually had installed it a while back in relation to testing the ESP32 so I thought I was good to go. Turns out no. There was a question during installation that I remember thinking no which was to add it to the path. Should have taken it. I had to add the python folder to my global path. Then all was good. If you install it, opt in for adding to the path.

    https://www.python.org/downloads/

    Next, look in the examples for the ESP8266 for File/Examples/nodeMCU/ArduinoOTA/BasicOTA. Make sure you can get a clean compile. That will make sure you have the libraries you need. Play around with it a bit to get familiar with how OTA works. Add some blinking code to the sketch. On the nodeMCU, the built in LED is pin 2. Upload the sketch.

    This next step is important. When you add a new board to OTA, you have to exit the IDE and re-enter for it to be seen by the IDE. Once you do that, you should be able to go into Tools/Port in the IDE and see your new node. The naming convention in the code that follows is "Arduino API Board:xx" where xx is the board number. Select that as you would have the comm port before and it should upload to it. You will see a difference in the way the dots are shown during upload so you will know it is the new OTA loader.

    Once you've got that working, the rest is pretty much cut and paste into your sketch.
    Last edited by logbuilder; August 11th, 2017, 09:22 PM.

  • #2
    So here we go with the code.

    First is to include a couple of libraries. I put them at the beginning of the sketch.
    Code:
    #include <ESP8266mDNS.h>           // changes required for OTA
    #include <ArduinoOTA.h>               // changes required for OTA
    Next is a single line that goes at the first of HSLoop. I'm including the preceding and following lines for location reference. New code is in green. Location reference code in black.
    Code:
        /*Execute regardless of connection status*/
    
    ArduinoOTA.handle();                 // changes required for OTA
    
     if (IsConnected == true) {
    The next part is actually within the sketch. Maybe someone can come up with a better place but here I know it works. Maybe we will even see this in the base API sketch someday. But until then, I'll deal with migrating when needed. I'm including the preceding and following lines for location reference. The line in purple is another mod I have made to the base sketch. It keeps the nodeMCU wifi node name from being broadcast. I didn't like seeing them all out there when I did a wifi scan nor did want to broadcast their presence.

    Code:
    #if BoardType == 3
    Serial.begin(115200);
      WiFi.begin(ssid, pass);
      WiFi.config(ip, gateway, subnet);
    
      WiFi.mode(WIFI_STA);                //RBD - keep SSID from being broadcast
      
      while (WiFi.status() != WL_CONNECTED) {
        delay(500);
      }
      char OTAName[50];                                       // changes required for OTA      
      sprintf(OTAName, "Arduino API Board:%02i", BoardAdd );  // changes required for OTA
      ArduinoOTA.setHostname(OTAName);                        // changes required for OTA
      ArduinoOTA.onStart([]() {                               // changes required for OTA
        Serial.println("Start");                              // changes required for OTA
      });                                                     // changes required for OTA
      ArduinoOTA.onEnd([]() {                                 // changes required for OTA
        Serial.println("\nEnd");                              // changes required for OTA
      });                                                     // changes required for OTA
      ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {   // changes required for OTA
        Serial.printf("Progress: %u%%\r", (progress / (total / 100)));        // changes required for OTA
      });                                                     // changes required for OTA
      ArduinoOTA.onError([](ota_error_t error) {              // changes required for OTA
        Serial.printf("Error[%u]: ", error);                  // changes required for OTA                        
        if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");                        // changes required for OTA
        else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");                 // changes required for OTA
        else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");             // changes required for OTA
        else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");             // changes required for OTA
        else if (error == OTA_END_ERROR) Serial.println("End Failed");                     // changes required for OTA
      });                                                   // changes required for OTA
      ArduinoOTA.begin();                                   // changes required for OTA
      
    #else

    Comment


    • #3
      Thanks you logbuilder

      Sent from my SM-G935V using Tapatalk

      Comment


      • #4
        I just finished the update for the last board. Had to bring each one to the bench. Hopefully won't have to do that again.

        I did learn something that I wanted to pass along. When I am in the IDE, in Tools/Port I now see each one of the nodes on the network. The IDE remembers the last port used. I forgot to set the port when updating one of the boards. When I said to compile and upload, it sent the update to the last node I had updated. I learned to be more diligent on setting the port.

        Comment


        • #5
          Was curious whether the OTA code would work on the ESP32.

          Surprisingly, it worked fine with no changes.

          Comment


          • #6
            Originally posted by logbuilder View Post
            Was curious whether the OTA code would work on the ESP32.

            Surprisingly, it worked fine with no changes.
            Doesn't work on my ESP32 (Rev 1) for some reason, keep getting the dreaded error[4]. Thinking my partitions aren't defined correctly as I don't see two OTA partitions. How do you partition yours?

            I think I'll just clear the flash memory and start over..

            Originally I had it retrieving the new bin from my webserver whenever I sent it a command (ie Pull vs Push). But I'm leaning towards pushing it now.

            My biggest headache is trying to figure out a way to pull the device config (ie IPaddr, MQTT broker, DeviceID, DigIn, DigOut, Analog pin #'s, etc) from the NVS when it starts up so I can send it generic sketches. Can't get it to work outside of setup().

            Z

            Comment


            • #7
              Originally posted by vasrc View Post
              Doesn't work on my ESP32 (Rev 1) for some reason, keep getting the dreaded error[4]. Thinking my partitions aren't defined correctly as I don't see two OTA partitions. How do you partition yours?

              I think I'll just clear the flash memory and start over..

              Originally I had it retrieving the new bin from my webserver whenever I sent it a command (ie Pull vs Push). But I'm leaning towards pushing it now.

              My biggest headache is trying to figure out a way to pull the device config (ie IPaddr, MQTT broker, DeviceID, DigIn, DigOut, Analog pin #'s, etc) from the NVS when it starts up so I can send it generic sketches. Can't get it to work outside of setup().

              Z
              I didn't have to set up anything in regards to partitions. I'm guessing it is handled in the ArduinoOTA library. I just set the board type to ESP32 Dev Module and compiled and flashed with cable. Then, it showed up in the IDE network ports just as expected. Tested loading several sketches OTA and no problem.

              Right now, I have my main sketch which all the nodes run. However, I do have to set board specific parms and compile for that target board. I need to clean that up. First step would be to isolate all those board specific defines to a .h that lives in each board's folder which gets included at compile. That would help a bunch when changing the base sketch such that all boards need to be updated now. That might be as far as I need to go but I see the value in a generic sketch. Intentionally loading from the IDE seems like a natural process. Not sure I want any reloading without my direction.

              Haven't thought this out enough but off the top of my head next step would be to get those board specific items in the eeprom on the board. Then a totally generic app could be loaded which looks in eeprom and tailors itself. I think that is where you are going when you mention NVS but not sure what that acronym means in this context (non-volatile storage?).

              To be honest, I'm just tickled I don't have to go to each device to do updates. I have them in three different buildings around my property and some in not so easy to get to locations.

              ETA: My ESP32 is a ESP-WROOM-32S V1.1 and I use the Arduino IDE.

              Comment


              • #8
                Originally posted by logbuilder View Post
                I didn't have to set up anything in regards to partitions. I'm guessing it is handled in the ArduinoOTA library. I just set the board type to ESP32 Dev Module and compiled and flashed with cable. Then, it showed up in the IDE network ports just as expected. Tested loading several sketches OTA and no problem.

                Right now, I have my main sketch which all the nodes run. However, I do have to set board specific parms and compile for that target board. I need to clean that up. First step would be to isolate all those board specific defines to a .h that lives in each board's folder which gets included at compile. That would help a bunch when changing the base sketch such that all boards need to be updated now. That might be as far as I need to go but I see the value in a generic sketch. Intentionally loading from the IDE seems like a natural process. Not sure I want any reloading without my direction.

                Haven't thought this out enough but off the top of my head next step would be to get those board specific items in the eeprom on the board. Then a totally generic app could be loaded which looks in eeprom and tailors itself. I think that is where you are going when you mention NVS but not sure what that acronym means in this context (non-volatile storage?).

                To be honest, I'm just tickled I don't have to go to each device to do updates. I have them in three different buildings around my property and some in not so easy to get to locations.

                ETA: My ESP32 is a ESP-WROOM-32S V1.1 and I use the Arduino IDE.
                Not sure why it's being crabby, using both a Dev board as well as Adafruits new Huzzah board. Just downloaded the newest code and it's no better. Odd thing is the Pull OTA works, just not the generic arduinoOTA code. Quite a few comments online about others having the same problem, just no solutions I can find yet. Got to be something stupid, simple...

                Yup, NVS is non-volatile. Look at the Preferences code, it works really well, not as cryptic as EEPROM is (which is still there).
                I was also looking at having an Init sketch that burns in the defaults (to NVS) and let it go from there, but like I said, it's not easy (at least for me) to get it out of NVS (or EEPROM for that matter) and into the device prior to setup() (mainly for IP addr, and MQTT broker configs info).
                Primary problem seems to be replacing all of the #define values with variables. Not sure if it's Adruino or just C? Haven't messed with C for a bazillion years ..

                Z

                Comment


                • #9
                  Originally posted by vasrc View Post
                  Haven't messed with C for a bazillion years ..
                  Z
                  Yea, me either but I did work in it for 15 years in deeply technical areas. I find it refreshing that the IDE is so vanilla. I seldom see anyone using pointers or dereferencing. Nice and mellow.

                  Comment


                  • #10
                    Looks like I'm SOL with the Sparkfun boards. Apparently the flash on these is too small to accommodate OTA.

                    Comment


                    • #11
                      Originally posted by zwolfpack View Post
                      Looks like I'm SOL with the Sparkfun boards. Apparently the flash on these is too small to accommodate OTA.
                      My understanding is you need twice as much memory as your sketch uses. I'm running only nodeMCUs which have enough memory.

                      Comment


                      • #12
                        Logbuilder,

                        Thank you for the info! I've fallen in love with the NodeMCU over the arduino. I wish I had more than one analog pin, but still a reliable, compact product.

                        With the OTA option I'm looking into using the Nextion serial touchscreen like this project uses:

                        https://community.home-assistant.io/...lacement/25464

                        This ends up being single gang with a customer 3D printed switch plate. If this works like I think I can replace my clunky UPB scene keypads with LCD touchscreens. The thing holding me back before was how to update .... OTA fixes that issue!

                        Thanks again, and I hope this ends up in the standard and API plugin sketches in the future.

                        Guy

                        Comment


                        • #13
                          FYI OTA update is available in Beta V.146 for normal and API sketches available in the updater.

                          Greig.
                          Zwave = Z-Stick, 3xHSM100� 7xACT ZDM230, 1xEverspring SM103, 2xACT HomePro ZRP210.
                          X10 = CM12U, 2xAM12, 1xAW10, 1 x TM13U, 1xMS13, 2xHR10, 2xSS13
                          Other Hardware = ADI Ocelot + secu16, Global Cache GC100, RFXtrx433, 3 x Foscams.
                          Plugings = RFXcom, ActiveBackup, Applied Digital Ocelot, BLDeviceMatrix, BLGarbage, BLLAN, Current Cost, Global Cache GC100,HSTouch Android, HSTouch Server, HSTouch Server Unlimited, NetCAM, PowerTrigger, SageWebcamXP, SqueezeBox, X10 CM11A/CM12U.
                          Scripts =
                          Various

                          Comment


                          • #14
                            Originally posted by enigmatheatre View Post
                            FYI OTA update is available in Beta V.146 for normal and API sketches available in the updater.

                            Greig.
                            That's great! Thanks!

                            Robert

                            Comment


                            • #15
                              Edit: I think I have it figured out. one question remains, how do I know which library I should install and which the program requires, I get this error when I compile the LCD program

                              WARNING: library LiquidCrystal_I2C claims to run on [avr] architecture(s) and may be incompatible with your current board which runs on [esp8266] architecture(s).



                              Edit: I was able to manage to update the boards ot at least one for now. I copied the old board code and replaced it with the new code by making sure I would not overwrite replace any of enigmatheatre code.
                              By the way, what do you suggest for the default location for libraries and board code, could I store the code on a NAS so every pc has access to the board code?

                              Can anyone please let me know how to update over the air with the new code when they have a chance?


                              By mistake I updated yesterday to the release Beta V.146 prematurely. Absolutely not an issue, unfortunately I can not find any documentation on what to do to update my boards. Also, how do I use the great new feature OTA?

                              Thanks,
                              Aldo
                              Last edited by aldo; December 19th, 2017, 12:44 PM.

                              Comment

                              Working...
                              X