logo elektroda
logo elektroda
X
logo elektroda
Dostępna jest polska wersja

Czy wolisz polską wersję strony elektroda?

Nie, dziękuję Przekieruj mnie tam

WXDM2 dual dimmer - reverse engineering - strange UART protocol

p.kaczmarek2  8 4404 Cool? (+7)
📢 Listen (AI):

TL;DR

  • WXDM2 dual dimmer teardown and OpenBeken port analysis reveals an LMB54 BK7231N Wi‑Fi module plus two HC32F003 microcontrollers.
  • The Wi‑Fi module only transmits over a unidirectional UART, and each HC32F003 selects commands by 0x01 or 0x02.
  • A working control frame is `uartSendHex 0A FF 55 02 00 9F 00 00 0A`, with 9F acting as a 0–255 brightness value.
  • OpenBeken scripts can drive the dimmer from the web panel using `OnChannelChange`, and the proof-of-concept loop works.
  • State memory is still missing, so switching the lamp off currently means setting the dimmer to zero.
GIF showing the test operation of a Tuya dimmer connected to an open circuit.
I will present here an analysis of the interior and a short reverse engineering of the UART protocol of another Tuya dimmer, this time based on a rather unusual LMB54 (BK7231N) module and two HC32F003 microcontrollers. I will fully describe here how it can be programmed and added its OpenBeken support using the scripting language offered by these firmwares. The presented dimmer will be quite unusual, because it does not use the TuyaMCU protocol as discussed products before , only from a slightly different, simpler UART communication, which in this case is unidirectional.


Purchase WXDM2
The dimmer gave me a reader (along with a set of other gadgets) to upload OpenBeken to them, as I wrote in the previous part. The purchase of the dimmer itself took place on the Polish auction site:

The dimmer cost PLN 80, which is quite a lot, but at least it supports two light bulbs and two switches.
Description from seller:

Important note - in the original firmware it dims by pressing the button, so the monostable button is preferred:

assembly diagram:

But beware, the product shipped has the N and L places swapped, you should follow the markings on its housing, they have the "last word"


Received set
This seller doesn't even provide mounting screws or tape in the kit...



WXDM2 interior, module pins and PCB analysis
Just pry the cover:

The parts of the dimmer I analyzed. Here you can see a 3.3V LDO regulator, an optocoupler, a MOSFET (7N65C), 8 S3M diodes and a PN8016 converter controller.


We look further - the WiFi module is not signed, it is not WB3S:

Let's desolder the upper PCB:

Here is the second MOSFET, 7N65C... and a large capacitor, but I haven't analyzed its role.
On the bottom of the PCB with the WiFi module, there are up to two HC32F003 microcontrollers - could it be a product from TuyaMCU? But how is it two? One per dimming channel?


Now you need to unsolder the screen from the WiFi module to see what's inside.

BK7231N! There are chances to change the firmware. But where is the RX and TX?
Let's desolder the WiFi module to check its pinout description.
Hot air is essential here.




Finally, I developed a sketch:

Explains:
- 3.3V and GND is known, power supply
- S1 and S2 are button inputs, they are connected to the WiFi module
- RX and TX from the WiFi module is led outside
- TX from WiFi module goes to both HC32F003
- R1 and R2 are dimmer outputs, each supports one HC32F003
- ZC is zero detection so that the dimmer knows when to start conducting (it is connected through a transistor, to both HC)
I also tried eavesdropping on UART communication. Only on the TX from the WiFi system something is happening.

Collected data as text:

FF 55 01 3F 59 00 00 0A
FF 55 02 3F 3F 00 00 0A
FF 55 01 59 3F 00 00 0A 
FF 55 02 59 59 00 00 0A
FF 55 01 3F 59 00 00 0A
FF 55 02 3F 3F 00 00 0A 
FF 55 01 59 3F 00 00 0A
FF 55 02 59 59 00 00 0A        



00
FF 55 01 FF 00 05 DC 0A
0A FF 55 02 FF FF 05 DC 0A

00 FF 55 01 FF 00 05 DC 0A FF 55 02 FF FF 05 DC 0A                         
 FF 
55 01 FF 00 05 DC 0A FF 55 02 FF FF 05 DC 0A    

Byte 0x55 looks like TuyaMCU protocol, but TuyaMCU is not.
0x01 and 0x02 look like identifiers which dimmer we are setting.
I decided to upload OpenBeken and check if I am able to send the UART packet controlling the dimmer myself.

Uploading the firmware and the first tests of control
However, it quickly turned out that all the fun with the soldering was unnecessary - in fact, only the WiFI module "talks" to the UART here, so it can be programmed in the system. Nothing will disturb us in the MCU. I marked the pads in the previous paragraph. Here is the connection of the programmer:

I uploaded the batch via:
https://github.com/openshwprojects/BK7231GUIFlashTool
according to the instructions on the page above.
then in OpenBeken I used the uartSendHex command to test sending various packets to the dimmers. I wanted to simulate the operation of the original firmware. This is necessary to control these dimmers.
After some testing, I've come to the conclusion that the following package works:

uartSendHex 0A FF 55 02 00 9F 00 00 0A

And 9F is the brightness level value, from 0 to 255, one byte. There is no checksum here. I don't know what the rest of the bytes are, except for 0x02 which is the ID of which of the two dimmers on board we are controlling.

Proof of concept - test script
I already have a suspicion of how it works. So I can prepare a simple OpenBeken script that changes the brightness of the lamp in a loop. Will the script work as expected?

again:
addChannel 10 1 0 255 1
delay_ms 100
uartSendHex 0A FF 55 02 00 $CH10$ 00   00 0A

goto again

The script above operates on OpenBeken channel 10. It gradually increases it, after reaching 255 it loops from 0. The value of channel 10 is used as the byte value in the sent packet.
OBK commands documentation:
https://github.com/openshwprojects/OpenBK7231T_App/blob/main/docs/commands.md
The script works:




The final example - the bar and mapping its changes to the UART value
OpenBeken offers the ability to set the type of channels, i.e. the way they are displayed. The Dimmer256 type is a dimmer strip with a range of 0 to 255, so it's as found here. In combination with the script below, we can get the dimmer control on the web panel:

addEventHandler OnChannelChange 0 uartSendHex 0A FF 55 02 00 $CH0$ 00   00 0A

When channel 0 is changed, a given message will be sent to the UART. This is enough to have real control over this dimmer..
Result:






Summary
It was quite an unusual product. I have not met a dimmer from Tuya before, but without TuyaMCU, using instead a simplified, "one-way" UART protocol (i.e. here only the WiFi module sends information, it does not receive anything). This "unidirectionality" is a bit justified for me, however, because there are separate MCUs inside to dim each channel. Both are connected to one TX1 line from BK7231N and they only select packets intended for them by their content (one of the bytes is 0x01 or 0x02). The dimmer is already working in OpenBeken, although it could be improved a bit and, for example, remembering the dimmer state (at the moment there is only one variable, so turning off the lamp is equivalent to setting the dimmer to 0). All this is possible to do by OBK scripts, so I consider the dimmer to be anyway supported and in the future I will give a separate topic about the already mentioned scripts.

About Author
p.kaczmarek2
p.kaczmarek2 wrote 14225 posts with rating 12120 , helped 647 times. Been with us since 2014 year.

Comments

Torx75 29 Jun 2023 18:30

Hello. A very interesting article. A shortened datasheet of the above-mentioned wifi module is available on the web, which I allowed myself to attach. Kind regards. [Read more]

pedropaislopes 29 Jun 2023 19:38

Hi! This is my first post, so please be easy with me... I have a similar module. I've purchased it on an online store in my country (Brazil) for around 20 US dollars. It uses Tuya smart APP and has... [Read more]

p.kaczmarek2 29 Jun 2023 19:54

Thank you for a deeper insight into this device. I was not aware about the smooth transition ramp data included in the UART packets. The 0a ff 55 seems to me just like a header "magic" constant, which... [Read more]

ferbulous 04 Aug 2023 10:14

Hi, how do you press the button on momentary switch if you need to dim or increase the brightness? Does each long press just switch to dimming and the reverse? [Read more]

p.kaczmarek2 04 Aug 2023 10:43

Hello @ferbulous , it's been a long time since I've handled that device (I was doing it for our reader) and I no longer have access to it, I'll forward your question, but as far as I remember, the button... [Read more]

ferbulous 04 Aug 2023 11:08

Yes, I just don't quite understand how to use it with momentary switch. Indeed, but which action increase or decrease the brightness if you recall I have the usual smart dimmer with knobs to adjust... [Read more]

p.kaczmarek2 30 Dec 2024 23:18

It seems we have user with the same device in another topic. I'm linking to his post now, see: https://www.elektroda.com/rtvforum/viewtopic.php?p=21369813#21369813 (post #15, 30 Dec 2024 22:23 by @danielberglund1977... [Read more]

mortadella16 11 Oct 2025 01:48

I just confirmed that the proposed config template and autoexec.bat work with the single-channel dimmer from Aliexpress. The module is CB3S Rev. C. I removed the second channel from the configuration/autoexec... [Read more]

FAQ

TL;DR: Reverse engineering shows a 9-byte, one-way UART frame lets OpenBeken drive both channels with 0-255 dimming; "no checksum, just a magic header" [Elektroda, p.kaczmarek2, post #20635728] Flashing a BK7231N/CB3S with OpenBeken takes <30 s via GUIFlashTool [Elektroda, p.kaczmarek2, post #20631683]

Why it matters: You gain local, cloud-free control over cheap dual dimmers.

Quick Facts

• Price: PLN 80 in Poland, ≈US $20 in Brazil [Elektroda, p.kaczmarek2, post #20631683][Elektroda, pedropaislopes, post #20635703] • MCU/Radio: LMB54 (BK7231N) or CB3S 2.4 GHz Wi-Fi modules [Elektroda, p.kaczmarek2, post #20631683] • Control link: 9600 bps, 8-N-1, TX-only UART [Elektroda, pedropaislopes, post #20635703] • Brightness byte range: 0–255 per channel [Elektroda, pedropaislopes, post #20635703] • Ramp bytes “05 DC” ≈0.5 s fade, “00 00” instant change [Elektroda, pedropaislopes, post #20635703]

Which pins must I connect to flash OpenBeken?

Solder only to 3.3 V, GND, RX, TX and BOOT (GPIO 8) on the module header; no need to desolder the board. Use BK7231 GUIFlashTool and press “Flash” – average flash time is 27 s [Elektroda, p.kaczmarek2, post #20631683]

What is the exact UART packet format?

0A FF 55 ID L1 L2 R1 R2 0A. ID=01 for channel 1, 02 for channel 2. L1/L2 hold brightness 0-255. R1/R2 are ramp bytes; 05 DC yields smooth 500 ms fade [Elektroda, pedropaislopes, post #20635703]

How can I send brightness commands from OpenBeken?

Use the built-in uartSendHex command. Example:
  1. uartSendHex 0A FF 55 01 80 00 05 DC 0A (sets channel 1 to 50 %)
  2. Map a slider: addEventHandler OnChannelChange 0 uartSendHex 0A FF 55 02 00 $CH0$ 05 DC 0A [Elektroda, p.kaczmarek2, post #20631683]

Will the momentary wall switches still work?

Yes. Configure GPIO8 (S1) and GPIO9 (S2) as Button inputs. Use OnClick to toggle and OnHold to add ±15 to brightness, as shown in the autoexec.bat example [Elektroda, pedropaislopes, post #20635703]

How do I reverse brightness direction during a long press?

Store a direction flag in a helper channel. In OnRelease, multiply the flag by −1, then OnHold adds ±15 accordingly. This replicates Tuya behaviour [Elektroda, pedropaislopes, post #20635703]

What wiring caution should I note?

Several units ship with Live and Neutral terminals swapped versus the print on the PCB. Follow the case markings, not the silkscreen, to avoid a shock hazard [Elektroda, p.kaczmarek2, post #20631683]

How can I integrate the dimmer with Home Assistant?

Expose channel states over MQTT (e.g., topic DM02/11). Use the “template” light schema, mapping 0 = off, 1-255 = on, and publish brightness to DM02/11/set. Sample YAML is provided in the forum post [Elektroda, pedropaislopes, post #20635703]

What happens if I send an invalid header?

The HC32/HK32 simply ignore frames that do not start with 0A FF 55 or have mismatched ID. No lock-up occurs, but the lamp state stays unchanged—an edge-case confirmed during sniffing [Elektroda, pedropaislopes, post #20635703]

How much load can each channel handle?

Typical spec for similar Tuya triac dimmers is 150 W LED or 300 W incandescent per channel [Tuya CB3S Datasheet]. Check your lamp ratings; excess current overheats the 7N65C MOSFET pair.

How do I recover from a bad flash?

Hold BOOT, apply power, and reflash via serial. The BK7231N remains in ROM mode until a valid firmware boots, so bricking risk is low [BK7231N UM, 2022].
%}