OpenSprinkler Forums Hardware Questions OpenSprinkler Controller lockups / crashes with wired Ethernet module Reply To: Controller lockups / crashes with wired Ethernet module

#67581

Ray
Keymaster

After 2 days of non-stop debugging, I think I am finally getting closer to the bottom of the issue. There are two main discoveries:

1) The UIPEthernet library for ENC28J60 does seem to have trouble when there are a constant influx of UDP broadcasts. On some networks, there aren’t that many broadcast traffic, so it works fine; but on other networks, there are lots of broadcast traffic, so eventually it goes into a corrupted state, which is the source of the hanging issue.

Stefan’s firmware (osefw2194_20200722.bin) uses a tweak of the UIPEthernet library that disables incoming broadcasts and that’s why it’s not prone to the issue. This probably explains why it has lasted much longer on your network. However, completely disabling UDP broadcasts has a downside, which is the second discovery below.

2) DHCP relies on UDP broadcasts, so if UDP broadcast is disabled, then DHCP renewal will fail, and that can lead to a stall. The reason this leads to a stall is because Ethernet.maintain() function is being called at every loop iteration:
https://github.com/OpenSprinkler/OpenSprinkler-Firmware/blob/master/main.cpp#L421
its main job is to handle DHCP renewal requests. When DHCP renewal fails, each call will stall for 60 seconds, but then when it comes back to the loop, it will call it again, which is another 60 seconds of non-responsiveness. The UIPEthernet library document never says how often Ethernet.maintain() should be called, it just says call it on a regular interval. So it wasn’t immediately clear to me the consequence of calling it at every loop iteration.

With these two discoveries, I’ve now modified the firmware and made firmware 2.1.9 revision(5). It has the following main changes:

A) Disable handling of UDP broadcast most of the time but only enable it temporarily during DHCP events. This way, most of the time the firmware is not affecting by influx of DHCP requests.

B) Change the code to call Ethernet.maintain() only once per hour to process DHCP renewal requests. This way, even in the case of renewal failure, it won’t go into an infinite loop of stalling.

C) There are also a few other improvements, such as improving DNS functionality, clean up send_http_request function, and for OS 3.x supporting LCD dimming or turn off LCD when the controller is idle (to help preserve the lifespan of OLED displays).

p.s. after I did A) above, I accidentally discovered that this is also what EtherCard library does:
https://github.com/njh/EtherCard/blob/master/src/dhcp.cpp#L421
that it only enables broadcast when processing DHCP. I am surprised that UIPEthernet doesn’t do this, but now I’ve added this feature.

D) If you are currently using Stefan’s firmware (osefw2194_20200722.bin), since it disables UDP broadcasts completely, you can either set static IP on OpenSprinkler, or set a DHCP reservation on your router, and then reboot your OpenSprinkler. This way it won’t incur DHCP renewal requests so need handling of broadcasts.

In any case, I’ve uploaded the current version of firmware 2.1.9(5) to the experimental firmware folder:
– for OS 3.2, it’s at: http://raysfiles.com/os_compiled_firmware/v3.0/experimental/ (note: the rev5_enc28j60 file, not the w5500 file!)
– for OS 2.3, it’s at: http://raysfiles.com/os_compiled_firmware/v2.3/experimental/

Feel free to give it a try and see if it addresses the hanging/locking issue. I’ve tested it myself for about 2 days now, but obviously it needs longer-term testing.

Notes: this firmware is largely meant for controllers with ENC28J60 ethernet module, which includes OS 2.3, and OS 3.2 with ENC28J60 wired Ethernet module. You do NOT need to try this firmware if you use WiFi only, or if you are using the experimental W5500 Ethernet module (so far only a very small number of users are trying out W5500 as far as I am aware).