Tl/Dr: It’s on the network! But in my analysis, I fell victim to my own bias.
Picking up from last weekend, I play with the ESP32-POE-EA board from Olimex using the Espressif FreeRTOS ESP-IDF Framework.
Before I get started, I want to give an unsolicited plug to Mair Seartz for his excellent video tutorial on ESP32 programming. It’s on sale for $49 and it’s worth it. I’ve got books and read web pages and even built some things, but dang, a few hours with his videos and I am vastly more knowledgable. And he showed me some thing I flat out did not know that changed my development. If you want to do ESP32, go watch his courses. That’s my heartfelt advice. He has no idea I’m plugging him, either.
Here’s the gadget:
And here it’s on the network:
I (1913) eth_example: Ethernet Started
I (1913) eth_example: Ethernet Link Up
I (1913) eth_example: Ethernet HW Addr 08:3a:f2:13:4c:4f
I (2873) esp_netif_handlers: eth ip: 192.168.42.164, mask: 255.255.255.0, gw: 192.168.42.1
I (2873) eth_example: Ethernet Got IP Address
I (2873) eth_example: ~~~~~~~~~~~
I (2873) eth_example: ETHIP:192.168.42.164
I (2883) eth_example: ETHMASK:255.255.255.0
I (2883) eth_example: ETHGW:192.168.42.1
I (2893) eth_example: ~~~~~~~~~~~
This is using the vanilla code from Olimex., specifically here.
Getting Started Really Understanding
I got it to compile and run, but to really grok how it works I decided to build a clean new app based off the official samples. ESP32 has example code for Ethernet, geared towards their Ethernet Kit. One of the nifty things I learned from learn32.com was how to create a sample app easily in Visual Code.
Inside Visual Code, hit F1 and search for “ESP-IDF: Show Example Projects” and select your installed ESP-IDF folder as the source. You can pick any of them and create a sample app directly from it.
So I did that and then started to compare it to the Olimex example. My process on this included opening an issue in the Olimex git repo that has a bad link… and basically says nothing useful. It does compile and run, assuming you use the right version of the ESP-IDF framework.
But How is This Different?
Oof. It’s very different. Right off I compared the sdkconfig files and painstakingly changed them on the new side. I’m unclear on a few things, like this difference:
CONFIG_EXAMPLE_ETH_PHY_LAN8720=y |CONFIG_EXAMPLE_ETH_PHY_LAN87XX=y
(that was created with ‘diff -wy’ by the way). Probably chalk it up to improvements in making the official code more generic, and the Olimex code is a snapshot in time of the official code.
I think I got all the changes to match, but alas, it just crashes:
I (382) system_api: read default base MAC address from EFUSE
E (402) lan87xx: lan87xx_init(499): wrong chip ID
E (402) esp_eth: esp_eth_driver_install(215): init phy failed
ESP_ERROR_CHECK failed: esp_err_t 0xffffffff (ESP_FAIL) at 0x40085548
0x40085548: _esp_error_check_failed at /home/gherlein/esp/esp-idf/components/esp_system/esp_err.c:42
file: "../main/ethernet_example_main.c" line 122
func: app_main
expression: esp_eth_driver_install(&config, ð_handle)
abort() was called at PC 0x4008554b on core 0
0x4008554b: _esp_error_check_failed at /home/gherlein/esp/esp-idf/components/esp_system/esp_err.c:43
Digging Deeper, and Exposing a Bias
I stupidly thought that the source code would be the same as the example code, but on reflection that does not make sense. Of course it’s different. This isn’t Linux! On a real OS all the hardware is abstracted completely away from you. Swap a NIC card, no worries. The CODE is the same.
That exposed a bias on my part: I am so used to Linux that I didn’t think to look at the source. Configs sure, since those tell the system what the hardware is. But alas, at the level of the real-time OS your code has to change too, to match the new hardware. A quick diff and oh my. There’s some stuff to unpack.
The Olimex board is using the onboard EMAC but an external LAN8720 transceiver. Looks like it uses 3 GPIO to control it and SPI for the data.
I’m not in a crazy rush to build something on a deadline. I’m doing this because it’s fun, and it scratches a deep itch inside me to code, to learn, to hack, to build stuff. So my next step is to really dig into this code and understand what it is doing. I love networking - been doing it my whole career - and now instead of hacking on packets I’m going to hack on the PHY layer!
Where Might This Go?
Olimex has an example WiFi Access Point using this hardware. Now, that’s the last thing I need to build. I have a box full of them in my basement, left over from when I replaced my OpenWRT system with Ubiquity Unifi equipment. But, the goal here is not really to understand it at a deep level. You know, to HACK!
Where Might This Have All Come From?
History! Even those who understand history might be doomed to repeat it. Way back, way way WAY back, I did something similar. Back when dinosaurs where still around. You know, in 1996 or so. Here is an article I wrote for the Linux Journal where we used a spread-spectrum radio well before we had WiFi standards. It worked fantastic! When I built that I submitted bug fixes to the Linux kernel (for RS-485 drivers) and was completely comfortable with how every component in the system worked at a deep level. Those days are behind me in my day job now (for now, at least) so the chance to dive that deep on a hobby project is really satisfying.
But What Are You Building?
I have an underground cistern without a water gauge. If the cistern gets low the pump float switch will prevent it from running (to save the pump). So when I have no water pressure, is it due to low water level (e.g. someone used it faster than the city water pressure could refill it) or do I have some other problem? What I really need is a water level gauge!
I have a drawer full of HC-SR04 Ultrasonic Ranging Modules from robotics.
The cover of the cistern is concrete and steel. I very much doubt that I can get WiFi down there. But I can run an Ethernet cable and do POE and data over it!
I already tried someone elses example code and found it pretty easy. Calibration will be a big deal though.
Goal established. Learn. Hack. Oh, and get a notice if the water level drops below a certain point so I can tell folks to go easy unless they want to be thirsty!
Update
I had an older Olimex ESP32 Gateway board in my parts bin. I found it while looking to see if I had a suitable JTAG adapter (I don’t, so I ordered this one). I built the same code and installed it.
AND IT WORKED.
So I pulled out the new ESP32=EVB-EA-IND board that I bought with the POE board and tried it.
AND IT WORKED. Which is not too surprising. Olimex has a standard design and they are sticking to it. Good to see. Now I have three boards that have the same hardware! And they are readily available, and the hardware is open source. That’s really remarkable.