OTA firmware update with external MQTT broker
-
@yd Sure, I will add this. Kindly create feature request on https://github.com/mycontroller-org/mycontroller/issues
-
@yd, Would you be willing to share how you got the bootloader loaded to your nodes and got OTA firmware updates working with MyController?
I've been trying for days now and every guide, or forum post I've found is way over my head. I'm confused with all the fuse settings etc that people are discussing and just want to load MYSBootloader to my nodes so I can push the updates from the Controller. All the other jargon is bogging me down.
I'm running MySensors 2.0 on a Serial Gateway and the nodes, and My Controller v0.0.3-FINAL2
Thanks,
-
@imedia You don't need to change fuse for OTA. It's mostly for low battery.
I've use mysensors boot loader from MYSController 0_1_2_282.
However you need usbasp bootloader burning cable and also I use avrdudess s/w to burn boot loader.
I don't know why but I was unable to burn bootloader from arduino or any other s/w.
Only problem is after you use mysensors bootloader, you can't use arduino to burn firmware on it.
Ah I use arduino pro mini 3.3V version.After you load firmware on MYController, you have to reset node to start burn firmware from controller.
Hope this save your time.
Thanks.
-
Thanks for the info @yd, going to give this a try shortly..
Just to confirm, I export the sketch (firmware) using Sketch > Export compiled binary in the Arduino IDE correct? I then import that file into MySensors on the Firmware page. However, on that page it says "Nothing Selected" for both the Type and Version. There is also nothing appearing in the drop downs to select something and you cannot save and upload the firmware without selecting both these drope downs. Maybe @jkandasa can advise on that?
So Let's assume I can get the firmware loaded into MyController. How does the node know to connect this specific Gateway / MyController and download it's specific firmware? There needs to be a relationship between the two created correct? If so how is that created and ensure the correct node is getting the correct firmware from the correct controller?
Thanks,
-
Well you'd better see following link to get HEX file.
https://www.mysensors.org/about/ota (search "How to upload a new sketch just with OTA")
Then you can find hex file in build.pathIn MyController, you have to create new type and version first then you can select the type and version then upload HEX file.
Once you upload firmware, you can go Resources => Node then you can select any node which you want to uplpad firmware. Then edit node and select firmware.
Don't forget reset node to get new firmware.
Cheers,
YD -
@imedia One more thing you need to know.
Once you got New boot loader, you are unable to use arduino sketch to put new firmware.
You have to use OTA. It took 5-10minutes;; Not sure what's wrong with this but it looks like mysensors boot loader bug or how it works.Cheers~
-
@yd I'm not sure where you create the new "type" and "version" you are referring to? Can you please be more specific?
Also, I understand that the firmwares will need to be loaded to the nodes via MyController once the node is running the MYSBootloader. My question is, how does the node with just a bootloader installed know where to find its firmware? What tells a newly loaded node with only the bootloader on it where and what firmware it should be running?
Let's say I get a brand new Pro Mini, I flash it with the bootloader. Then what? Is there some type of configuration I need to do on the bootloader before loading it so it has a unique ID or something? How does it find home when it doesn't know where home is?
-
@imedia
Add type
Utilities => Firmwares => Click "Types" on right top => click "Add firmware type" right next => add new record
Add version
Utilities => Firmwares => Click "Versions" on right top => click "Add firmware version" right next => add new recordAfter you flash MYSBootLoader, you will see the node ID in MYController node list.
You can select the node and click action then you can edit node.
From that screen, you will be able to select one of firmware which you have uploaded in utilities.Once you upload MYSBootloader, Once you have new bootloader, the node doesn't have firmware so keep sending request to controller to get firmware. Obviously your gateway should work as expected.
Hope this help you.Cheers~
-
Thank you so much. I feel dumb for not figuring out the adding of the Types and Versions.. I guess when I saw those buttons there I thought they were for sorting rather than managing sub-lists. Maybe some UI improvements needed here, or maybe I'm just tired. Eiter way, thanks for clarifying on that.
I think I have a better idea what to do now. We should get a WIKI going as I can't seem to come up with much in terms of documentation other than the forum? +1?
-
@imedia
Seem you are on the right track. If you make a simple wiki document for newbie after you success, it will be huge help for the community.
English is my second language so it will take long time for me and afraid not crystal clear for everyone^^; -
I would be more than happy to do the writing, I am quite new to the platform however so I'm still discovering the system myself as you can see...
With your help I can write the documentation once I understand what exactly it is I'm documenting. I see @jkandasa has already an outline created on GIT hub, we just need to add moer specifics to that. Hotlinking to support right in the application will also be a huge help to users.
-
@imedia Have you checked user manual? Which is available on http://www.mycontroller.org/files/docs/0.0.3.Alpha2.pdf for the last released version. I hope this manual will help you to understand more on configuration.
How node gets new firmware from Controller?
Once you installed and turned on brand new node, following actions done.
- Requests node id from controller, Controller gives next available node for the new node. Node id will be stores on eeprom, So this is permanent node id for this node(Until we trigger
Erase configuration
from controller). - By default brand new node has type id as
65535
and version id as65535
. node sends this information to MyController. - If you have enabled and configured, Support default firmware on MyController, default firmware will be sent to node. Otherwise controller will not respond for the firmware request, as controller does not know which firmware have to send.
- Once node appeared on nodes list. You have to select your firmware for that node and trigger reboot.
- Now your node will request with
65535
as version id and type id. However controller has different type id and version id for this node. Controller will send configured firmware type id and version id. Now node takes the controller configuration and requests firmware for that configuration. - New firmware will be loaded on your node.(Which is configured on controller's node page)
Hope this will help you to understand more depth about firmware update on node.
- Requests node id from controller, Controller gives next available node for the new node. Node id will be stores on eeprom, So this is permanent node id for this node(Until we trigger
-
Great, thanks again @jkandasa!
I tried this and got it to work, however, some clarification is still needed as my results are inconsistent.
First thing I noticed is, when the .hex file is generated by the Arduino IDE two .hex files are created:
-
SketchName.ino.hex
-
SketchName.ino.with_bootloader.hex
Which one should be uploaded to the MyController Firmware section? Does it matter?
Next, a little more clarification on the update process...
Once a new version of the firmware is uploaded into MyController, how do we push that out to the node?
I know there is an option to select the node and then from the Actions Menu choose "Upload firmware". Does that initiate the upload immediately and refresh refresh the node or must a "Reboot" be selected after pushing "Upload firmware"?
If a reboot is needed, can it be done immediately after choosing "Upload firmware"? If not how long should we wait before clicking "Reboot"?
I'm able to get the updates out eventually but that is just because I keep clicking reboot and upload, and even resetting the node manually. That seems like a poor way to achieve what I am doing. There must be a certain order to doing this with consistent results. I would like to know what part of what I am doing is actually necessary and what is not.
Can you please provide a step by step guide.
Also, is there any way we could monitor the Firmware Upload progress in MyController? That would be very helpful. Should I add that feature request to GitHub?
-
-
@imedia First I would explain supported boot-loaders. For now AFAIK MySensors supports two type of boot-loaders,
MYSBootloader:
This boot-loader does not required any external memory. This boot-loader occupies approx 2K of memory on chip. It is isolated completely from actual program. When you reboot your node(Arduino board with MYSBootloader) It sends current available version of Users firmware to controller. Controller checks locally and respond with what firmware node should have. If node do not see any different on controller response. Boot-loader changes control to users program. Now boot-loader goes away from actions, all the control goes to users program. Boot-loader gets control only on next reboot of node.
DualOptiboot:
This boot-loader comes along with users program. This boot-loader needs external memory. This boot-loader never request firmware configuration from controller. If controller sends firmware configuration, it reads local configuration and if the received one is different receives the firmware from controller and stores on external memory. Once it receives all the firmware bytes successfully. Reboots the node, on reboot node checks external memory with some flag. If there is a flag enabled, copies firmware from external memory to actual program memory space and starts with new firmware.
This is how both boot-loader works.
- When we use
MYSBootloader
, we need to reboot the node to update new firmware. - When we use
DualOptiboot
, we need to clickUpdate firmware
for the node.
You have to use always use the firmware without boot-loader (SketchName.ino.hex). I hope now you I have cleared your confusions.
- When we use
-
Thank you for your explain. I didn't know how DualOptiboot works.
However if your node is battery powered and has sleep mode, it may work differently.
Mysensors 2.0.0 library has smartSleep() when it wake up, wait 500ms to get command from controller. (You can change wait time from config)
You can place reboot command when node send heartbeat.
I use node-Red to send reboot command because MyController current official version doesn't support this.I'm not sure how firmware update function work battery powered node with DualOptiboot.
-
@yd in SNAPSHOT version we have smartSleep support. If you issue reboot, command will be on queue. When it receives heartbeat from node, sends queued commands to that node.
-
@jkandasa Is there any easy update Snapshot version. Just overwrite all files?
-
@yd SNAPSHOT build is available here with upgrade instruction.
-
I loaded your latest snapshot, I am not getting the following error, OTA firmware update no longer seems to work either.
ERROR [Thread-5] [org.mycontroller.standalone.message.MessageMonitorThread:123] Throws exception while processing!, [RawMessage(gatewayId=1, data=1;255;4;0;2;010001007E04, subData=null, isTxMessage=false, networkType=MY_SENSORS, timestamp=1478706446658)]
java.lang.IndexOutOfBoundsException: Index: 18400, Size: 1024
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.get(ArrayList.java:429)
at org.mycontroller.standalone.message.McMessageEngine.procressFirmwareRequestMySensors(McMessageEngine.java:552)
at org.mycontroller.standalone.message.McMessageEngine.streamSubMessageTypeSelector(McMessageEngine.java:489)
at org.mycontroller.standalone.message.McMessageEngine.execute(McMessageEngine.java:136)
at org.mycontroller.standalone.message.McMessageEngine.run(McMessageEngine.java:1148)
at org.mycontroller.standalone.message.McMessageUtils.sendToMcMessageEngine(McMessageUtils.java:616)
at org.mycontroller.standalone.provider.mysensors.MySensorsProviderBridge.executeRawMessage(MySensorsProviderBridge.java:58)
at org.mycontroller.standalone.message.McMessageUtils.sendToProviderBridge(McMessageUtils.java:562)
at org.mycontroller.standalone.message.MessageMonitorThread.processRawMessage(MessageMonitorThread.java:112)
at org.mycontroller.standalone.message.MessageMonitorThread.run(MessageMonitorThread.java:191)
at java.lang.Thread.run(Thread.java:745)
2016-11-09 10:47:30,960 ERROR [Thread-5] [org.mycontroller.standalone.message.MessageMonitorThread:123] Throws exception while processing!, [RawMessage(gatewayId=1, data=1;255;4;0;2;010001007E04, subData=null, isTxMessage=false, networkType=MY_SENSORS, timestamp=1478706450936)]
java.lang.IndexOutOfBoundsException: Index: 18400, Size: 1024
at java.util.ArrayList.rangeCheck(ArrayList.java:653)
at java.util.ArrayList.get(ArrayList.java:429)
at org.mycontroller.standalone.message.McMessageEngine.procressFirmwareRequestMySensors(McMessageEngine.java:552)
at org.mycontroller.standalone.message.McMessageEngine.streamSubMessageTypeSelector(McMessageEngine.java:489)
at org.mycontroller.standalone.message.McMessageEngine.execute(McMessageEngine.java:136)
at org.mycontroller.standalone.message.McMessageEngine.run(McMessageEngine.java:1148)
at org.mycontroller.standalone.message.McMessageUtils.sendToMcMessageEngine(McMessageUtils.java:616)
at org.mycontroller.standalone.provider.mysensors.MySensorsProviderBridge.executeRawMessage(MySensorsProviderBridge.java:58)
at org.mycontroller.standalone.message.McMessageUtils.sendToProviderBridge(McMessageUtils.java:562)
at org.mycontroller.standalone.message.MessageMonitorThread.processRawMessage(MessageMonitorThread.java:112)
at org.mycontroller.standalone.message.MessageMonitorThread.run(MessageMonitorThread.java:191)
at java.lang.Thread.run(Thread.java:745) -
@imedia Thanks to report this. Let me have a look.