After ironing out the issues with my Modbus ESP32 Adapter board, the next stage was to test it worked.

When testing stuff like this, I find it helps to have a known *working* reference. To implement this, I put together a simple test. First, I used a YP-05 USB to UART adapter, which was connected to a HW-519 UART to Modbus adapter. The HW-519 then had its A & B wires connected to my PCB

YP-05 (top). HW-519 (middle). My PCB (bottom)

Testing the send (TX)

First thing I decided to try was to send a single byte from my PCB. I added some code to my firmware, which would just send one byte, every second.

I (557486) Modbus: TX 0x55
I (558486) Modbus: TX 0x55
I (559486) Modbus: TX 0x55
I (560486) Modbus: TX 0x55
I (561486) Modbus: TX 0x55
I (562486) Modbus: TX 0x55
I (563486) Modbus: TX 0x55
I (564486) Modbus: TX 0x55
I (565486) Modbus: TX 0x55
I (566486) Modbus: TX 0x55

On my PC, I had Claude create a simple Python script called receive_byte.py, which would open a connection to my YP-05 and log any bytes received. After a little tinkering, I discovered, to my annoyance, that my wiring was wrong.

GPIO 22 connected to RX and GPIO 23 connected to TX

I had my UART1 GPIOs the wrong way around. Thankfully, as this is all software defined, I just swapped the #defines in my firmware. TX to GPIO22 and RX to GPIO23. I dodged a bullet there. I made a note to update my firmware labels.

#define MODBUS_UART UART_NUM_1
#define TXD_PIN ((gpio_num_t)22)
#define RXD_PIN ((gpio_num_t)23)
#define DE_RE_PIN ((gpio_num_t)18)
#define MODBUS_SLAVE_ADDR 1

With both sides running, the Python script started to log the byte it was receiving!

[08:35:13] Received byte 0x55
[08:35:14] Received byte 0x55
[08:35:15] Received byte 0x55

I changed the firmware value to be sure

[08:41:34] Received byte 0x48
[08:41:35] Received byte 0x48
[08:41:36] Received byte 0x48

Amazing. My PCB was sending a byte over Modbus!

Testing receive (RX)

I fired up the inverse python script send_byte.py and put my firmware into the receive node. The python script started sending a byte

[08:55:21] Sent byte 0x55
[08:55:22] Sent byte 0x55
[08:55:23] Sent byte 0x55

Unfortunately, my firmware reporting nothing

W (31516) Modbus: RX idle (no bytes in 2000 ms)
W (33516) Modbus: RX idle (no bytes in 2000 ms)
W (35516) Modbus: RX idle (no bytes in 2000 ms)

After it ran for 30 seconds or so, I had a few of these messages:

I (120826) Modbus: RX 0x00 (0b00000000)
I (120836) Modbus: RX 0x00 (0b00000000)
I (120836) Modbus: RX 0x00 (0b00000000)

It had received something, just not what I wanted.

After a short diagnostics session with Claude, it suggested that I was missing a pull-up and pull-down resistor across the A & B terminals. I added 330Ω between B and GND and 330Ω between A and the 3V3 pin on the MAX3845.

As soon as I touched the resistor to the 3V3 pin, the logging confirmed the data was flowing in!

I (74026) Modbus: RX 0x55 (0b01010101)
I (75026) Modbus: RX 0x55 (0b01010101)
I (76026) Modbus: RX 0x55 (0b01010101)
I (77026) Modbus: RX 0x55 (0b01010101)

Claude suggested I only needed the bias resistors because I was using the HW-519, which had an auto-detect mechanism. This was sort of confirmed by the fact I had a MAX485 talk to an SDM120M meter without the bias resistors.

Something more complicated

Sending and receiving one byte is a good start, but hardly sufficient for a real-world application.

To give me something more substantial to test, I turned to the pymodbus library. This particular library is great because it has a simulator, which you can configure using JSON files. I had Claude whip me up a configuration based on the SDM120M electricity meter. Like the send_byte and receive_byte python scripts, this used the same YP-05 and HW-519 setup.

I put my custom firmware onto the PCB, setting it o its original operation (reading from the SDM120M) and tried it out. With the bias resistors in place, the communication worked perfectly!

I (3545608) SDM120M: Reading SDM120M...
I (3545608) Modbus: Requesting reg 0x0000
I (3545608) Modbus: 01 04 00 00 00 02 71 cb
I (3545658) Modbus: Received 9 bytes
I (3545658) Modbus: 01 04 04 43 66 80 00 6f df
I (3545658) Modbus: reg 0x0000 = 230.500000
I (3545658) SDM120M: Voltage: 230.50 V
I (3545658) Modbus: Requesting reg 0x0006
I (3545668) Modbus: 01 04 00 06 00 02 91 ca
I (3545718) Modbus: Received 9 bytes
I (3545718) Modbus: 01 04 04 3f 9d 70 a4 42 05
I (3545718) Modbus: reg 0x0006 = 1.230000
I (3545718) SDM120M: Current: 1.23 A
I (3545728) Modbus: Requesting reg 0x000C
I (3545728) Modbus: 01 04 00 0c 00 02 b1 c8
I (3545778) Modbus: Received 9 bytes
I (3545778) Modbus: 01 04 04 43 8d 99 9a 94 10
I (3545778) Modbus: reg 0x000C = 283.200012
I (3545778) SDM120M: Active Power: 283.20 W
I (3545788) Modbus: Requesting reg 0x001A
I (3545788) Modbus: 01 04 00 1a 00 02 50 0c
I (3545828) Modbus: Received 9 bytes
I (3545828) Modbus: 01 04 04 41 45 70 a4 da 16
I (3545828) Modbus: reg 0x001A = 12.340000
I (3545828) SDM120M: Total Energy: 12.34 kWh

The next step was to test the board with an actual SDM120M. Thankfully, I had one installed and waiting. It’s almost like I knew 🤣

The SDM120M that’s connected to my brand spanking new Heat Pump

When the electrician added the circuit for my new heat pump, I had him include an SDM120M.

My adapter is connected to the SDM via the twin and earth

I paired the sensor with my Heating Monitor and, after swapping A & B, it started to send readings!

The Electricity Sensor is sending data!

There is no power reading, since the heat pump is switched off at its isolator. Once it becomes fully operational, I hope to see some actual readings here!

All in all, I consider this a solid first test!

Next Steps

Now that my board is working (!), I need to think about the next steps. This board is something I think other hobbyists would find useful. It’s an ESP32-C6, so it can do WiFi, Thread and Zigbee. It can be programming with ESPHome, ESP-IDF or Arduino (I think).

Would you be interested in buying one? Drop me a comment if you would and I can get a batch made up.

Did you enjoy this post?

If you found this blog post useful and want to say thanks, you’re welcome to buy me a coffee.

Be sure to check out my YouTube Channel too – https://youtube.com/tomasmcguinness

Thanks,

Tom!

Fediverse reactions

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.