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 4596 8

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.
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
📢 Listen (AI):
  • 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:
    WXDM2 dual dimmer - reverse engineering - strange UART protocol
    The dimmer cost PLN 80, which is quite a lot, but at least it supports two light bulbs and two switches.
    Description from seller:
    WXDM2 dual dimmer - reverse engineering - strange UART protocol
    Important note - in the original firmware it dims by pressing the button, so the monostable button is preferred:
    WXDM2 dual dimmer - reverse engineering - strange UART protocol
    assembly diagram:
    WXDM2 dual dimmer - reverse engineering - strange UART protocol
    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 dual dimmer - reverse engineering - strange UART protocol WXDM2 dual dimmer - reverse engineering - strange UART protocol WXDM2 dual dimmer - reverse engineering - strange UART protocol WXDM2 dual dimmer - reverse engineering - strange UART protocol WXDM2 dual dimmer - reverse engineering - strange UART protocol
    WXDM2 dual dimmer - reverse engineering - strange UART protocol

    WXDM2 interior, module pins and PCB analysis
    Just pry the cover:
    WXDM2 dual dimmer - reverse engineering - strange UART protocol WXDM2 dual dimmer - reverse engineering - strange UART protocol
    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.
    WXDM2 dual dimmer - reverse engineering - strange UART protocol
    WXDM2 dual dimmer - reverse engineering - strange UART protocol
    We look further - the WiFi module is not signed, it is not WB3S:
    WXDM2 dual dimmer - reverse engineering - strange UART protocol
    Let's desolder the upper PCB:
    WXDM2 dual dimmer - reverse engineering - strange UART protocolWXDM2 dual dimmer - reverse engineering - strange UART protocol WXDM2 dual dimmer - reverse engineering - strange UART protocol
    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?
    WXDM2 dual dimmer - reverse engineering - strange UART protocol
    WXDM2 dual dimmer - reverse engineering - strange UART protocol
    Now you need to unsolder the screen from the WiFi module to see what's inside.
    WXDM2 dual dimmer - reverse engineering - strange UART protocol
    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.
    WXDM2 dual dimmer - reverse engineering - strange UART protocol WXDM2 dual dimmer - reverse engineering - strange UART protocol
    WXDM2 dual dimmer - reverse engineering - strange UART protocol

    WXDM2 dual dimmer - reverse engineering - strange UART protocol WXDM2 dual dimmer - reverse engineering - strange UART protocol
    Finally, I developed a sketch:
    WXDM2 dual dimmer - reverse engineering - strange UART protocol
    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.
    WXDM2 dual dimmer - reverse engineering - strange UART protocol
    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:
    WXDM2 dual dimmer - reverse engineering - strange UART protocol WXDM2 dual dimmer - reverse engineering - strange UART protocol
    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:
    WXDM2 dual dimmer - reverse engineering - strange UART protocol





    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.

    Cool? Ranking DIY
    Helpful post? Buy me a coffee.
    About Author
    p.kaczmarek2
    Moderator Smart Home
    Offline 
    p.kaczmarek2 wrote 14649 posts with rating 12660, helped 655 times. Been with us since 2014 year.
  • ADVERTISEMENT
  • #2 20635642
    Torx75
    Level 11  
    Posts: 67
    Rate: 9
    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.
    Attachments:
    • LMB54-Users-Manual-Shenzhen-Lingan-Intelligent-2ajk8-lmb54-ex-1-1.pdf (602.01 KB) You must be logged in to download this attachment.
  • #3 20635703
    pedropaislopes
    Level 4  
    Posts: 5
    Rate: 1
    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 support for two dimmer circuits: L1 and L2. They can be controlled independently on the APP and on an external wall push button (S1 and S2). S1 and S2 should be connected on AC voltage, what is a great deal specially if the dimmer module is installed on the ceiling, for example.

    Here are some photos.

    WXDM2 dual dimmer - reverse engineering - strange UART protocol

    It opens easily on the back side.

    WXDM2 dual dimmer - reverse engineering - strange UART protocol

    Here are the pins of the CB3S controller that are soldered on the back green board.

    WXDM2 dual dimmer - reverse engineering - strange UART protocol

    So it has a TX only communication to (another) controlled or chip, that exists on the back of this little green board.

    WXDM2 dual dimmer - reverse engineering - strange UART protocol

    On the back side the controller is a HK32F030MF4P6.

    The main difference, in my point of view, is that this module uses only one ARM chip to control the dimmer. The Original Post (OP) module uses two chips, one for each dimmer circuit.

    After some desoldering and sniffing on the UART protocol I've came with the same findings that the OP get. Sending on TX pin, at a baud rate of 9600 8n1, specially coded hex strings changes the dimmer. The rule is:

    - 0a ff 55 01_or_02 L1brightness L2brightness Dimmer_ramp Dimmer_ramp 0a

    Explained a little more, byte-per-byte:

    - 0a ff 55: start of message. Can't find a explanation (TuyaMCU related?)
    - 01_or_02: sending 01 changes L1 brightness. Sending 02 changes L2 brightness.
    - L1brightness: the dimmer brightness of L1. 00 is 0 brightness (off, on my understand), FF is 255 brightness (maximum brightness)
    - L2brightness: the same of L1brightness
    - Dimmer_ramp (two bytes): original message of my module is "05 dc", that presents a smooth brightness change (around half a second). Changing both to 00 produces an immediate change of brightness. On my tests I can't change L1 and L2 smooth brightness change independently.
    - 0a: last byte

    After flashing OpenBEKEN on the CB3S, soldering back things, was time to configure it.

    The CB3S pins are as described on the following picture.

    WXDM2 dual dimmer - reverse engineering - strange UART protocol

    But I've asked: can OpenBEKEN be configured to enable dimmer change with S1 and S2 pins? Of course!

    Here is my autoexec.bat with comments explained easy line (only for L1, as L2 is very similar):

    
    // Enabling and setting ntp driver
    startDriver ntp
    ntp_setServer 200.160.0.8
    ntp_timeZoneOfs -3:00
    // TuyaMCU driver that permits sending hex coding on TX pin to communicate with dimmer controller
    startDriver TuyaMCU
    // Clearing any handler that was used on debugging
    clearAllHandlers
    // Starts with both dimmers at 0 brightness (off state)
    uartSendHex 0A FF 55 01 00 00 05 DC 0A
    uartSendHex 0A FF 55 02 00 00 05 DC 0A
    //
    //
    // L1 channels and configurations
    // Dimmer256 has 0 to 255 range
    setChannelType 11 dimmer256
    // Channel 21 will act as a "variable"...
    setChannelType 21 TextField
    // ... initialized with 1.
    setChannel 21 1
    // Channel 21 represents the long press of S1. If S1 is long pressed the brightness will change 15 points. It will increase
    // brightness if channel 21 is 1, and decrease brightness if channel 21 is -1
    // So this way I could mimic the original Tuya firmware behavior.
    //
    // A label for channel 11, that represents L1 brightness state
    SetChannelLabel 11 Espelho_Sala 0
    // Clamping channel 11 to its values. I think that this command is redundant...
    ClampChannel 11 0 255
    // Channel 11 starts with 0, reflecting L1 state (see first uartSendHex above)
    setChannel 11 0
    //
    // Events with S1 (Botton switch that links to L1)
    // If a fast click is captured on PIN 8 (S1 module AC connector), and channel 11 is 0 (off), set its brightness (channel value) to 255 (max)
    // if not, set to 0 (off)
    // BUT, at the same time, changes channel 21 value. If dimmer is switched on, long press on S1 will (of course) decrease brightness.
    // If dimmer is switched off, long press on S1 will (of course) increase.
    addEventHandler OnClick 8 if $CH11==0 then "backlog setChannel 11 255; setChannel 21 -1" else "backlog setChannel 11 0; setChannel 21 1"
    // The OnHold event. Observe that the conditional is based do $CH21.
    addEventHandler OnHold 8 if $CH21==1 then "addChannel 11 15 0 255" else "addChannel 11 -15 0 255"
    // And, after release of a OnHold (long press) event, changes the direction of the next long press.
    addEventHandler OnRelease 8 if $CH21==1 then "setChannel 21 -1" else "setChannel 21 1"
    // Finally sends the hex string to the dimmer controller, based on Channel 11 value
    addEventHandler OnChannelChange 11 uartSendHex 0A FF 55 01 $CH11$ 00 05 DC 0A
    
    // channel 12 links to module L2
    setChannelType 12 dimmer256
    setChannelType 22 TextField
    setChannel 22 1
    SetChannelLabel 12 Espelho_Sala 0
    ClampChannel 12 0 255
    setChannel 12 0
    addEventHandler OnClick 9 if $CH12==0 then "backlog setChannel 12 255; setChannel 22 -1" else "backlog setChannel 12 0; setChannel 22 1"
    addEventHandler OnHold 9 if $CH22==1 then "addChannel 12 15 0 255" else "addChannel 12 -15 0 255"
    addEventHandler OnRelease 9 if $CH22==1 then "setChannel 22 -1" else "setChannel 22 1"
    addEventHandler OnChannelChange 12 uartSendHex 0A FF 55 02 00 $CH12$ 05 DC 0A
    


    Amazing what OpenBEKEN can do!!!!!

    Now the home assistant part, that will communicate with the dimmer module by MQTT. On OpenBEKEN the MQTT Client Topic is DM02.

    
    mqtt:
      light:
        - name: "Espelho Sala"
          # Defines the HASS entity
          unique_id: dm02_espelho_sala
          schema: template
          # Defines light entity online/offline based on the whole module state
          availability_topic: "DM02/connected"
          # State definition. 11 is the channel of L1
          state_topic: "DM02/11/get"
          state_template: '{{ "off" if value | int == 0 else "on" }}'
          # Command to switch on/off
          command_topic: "DM02/11/set"
          # This "brightness" is a variable that reflects the click on the HASS web/app interface light slide
          # But the button bellow this slide should turn ON the light, too. Turn on on maximum brightness.
          command_on_template: "{%- if brightness is defined -%}
            {{ brightness }}
            {%- else -%}
            {{ 255 }}
            {%- endif -%}"
          # Zero brightness is off, as OpenBEKEN configuration
          command_off_template: "0"
          # Brightness value (that comes from the "get" topic)
          brightness_template: "{{value}}"
          # Details of MQTT
          qos: 1
          retain: true
          # We infer state based on brightness so optimistic can be disabled
          optimistic: false
    


    And it works! I am absolutely admired how powerful and simple OpenBEKEN is!

    I have some other ideas. I plan to use arithmetic operations with channel 21 (or 22, in case of L2 dimmer) to take out some conditionals on Events, and put on another channel (lets say, channel 31 and 32) the brightness step value for each dimmer, so an user can change it's step on the web interface. And put some names on those auxiliary channels. If I implement these ideas I could send the new autoexec.bat.

    I hope to help someone with this explanation that has a similar dimmer module, the same way that the Original Post helped me.

    And, changing this last dimmer module to OpenBEKEN, the Tuya integration is officially switched off on my Home Assistant! No more cloud dependency!

    Cheers!
  • ADVERTISEMENT
  • #4 20635728
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14649
    Help: 655
    Rate: 12660
    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 is similar to one in TuyaMCU. Maybe it's just that Tuya likes to use that constant to mark the beginning of their data packets.

    I am surprised that 0a at the end is not a checksum. If I were to design that protocol, I'd included a simple checksum in the packet data.

    Anyway, good job! Thank you for a detailed addition to my work.
    Helpful post? Buy me a coffee.
  • #5 20680315
    ferbulous
    Level 18  
    Posts: 419
    Help: 8
    Rate: 56
    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?
  • ADVERTISEMENT
  • #6 20680356
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14649
    Help: 655
    Rate: 12660
    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 is momentary and holding it adjusts the brightness.

    Are you interested in buying that particular device, considering that now OBK can support it?
    Helpful post? Buy me a coffee.
  • #7 20680378
    ferbulous
    Level 18  
    Posts: 419
    Help: 8
    Rate: 56
    Yes, I just don't quite understand how to use it with momentary switch.

    p.kaczmarek2 wrote:
    the button is momentary and holding it adjusts the brightness.

    Indeed, but which action increase or decrease the brightness if you recall

    I have the usual smart dimmer with knobs to adjust the brightness by rotating clockwise or counterclockwise.
  • #8 21369907
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14649
    Help: 655
    Rate: 12660
    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/topic3975542.html#21369813
    (post #15, 30 Dec 2024 22:23 by @danielberglund1977 )
    Helpful post? Buy me a coffee.
  • ADVERTISEMENT
  • #9 21716540
    mortadella16
    Level 1  
    Posts: 1
    >>20635703
    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 of course, since my device does not have it.

    Good job, guys!
    Wi-Fi dimmer module with voltage specs and wiring diagram
📢 Listen (AI):

Topic summary

✨ The discussion centers on the reverse engineering of the WXDM2 dual dimmer, which uses an unusual UART protocol distinct from the common TuyaMCU communication. The device is based on an LMB54 (BK7231N) Wi-Fi module and two HC32F003 microcontrollers. Unlike typical Tuya dimmers, this model employs a unidirectional, simpler UART communication protocol with a packet header resembling Tuya's "magic" constant (0a ff 55) but without a conventional checksum. The dimmer supports two independent dimmer circuits (L1 and L2) controllable via the Tuya Smart app and external momentary push buttons (S1 and S2) connected to AC voltage. The momentary switches adjust brightness by holding the button, though the exact method to increase or decrease brightness was questioned. OpenBeken firmware support has been developed for this device, enabling custom programming through scripting. Additional technical insights include pinouts of the CB3S controller and the presence of TX-only communication lines between the Wi-Fi module and microcontrollers. The device was purchased on a Polish auction site for approximately PLN 80 and is also available in other markets like Brazil for around $20. A linked discussion provides further user experiences with the same device.

FAQ

TL;DR: This FAQ gives OpenBeken users 15 practical answers for WXDM2 dual dimmers; the core finding is “one-way UART”: brightness uses 0A FF 55 … 0A, not full TuyaMCU, solving BK7231N/CB3S flashing, scripting, switch dimming, and Home Assistant MQTT setup. [#20631683] Why it matters: WXDM2-style dimmers can be taken off the Tuya cloud while keeping two independent 0–255 dimmer channels.

Alternative WiFi module Dimmer MCU layout Protocol finding Practical change
WXDM2 unit LMB54 with BK7231N 2 × HC32F003 TX-only UART Use OpenBeken uartSendHex scripts
Similar Brazilian unit CB3S 1 × HK32F030MF4P6 9600 8N1 TX-only UART Same packet idea, clearer L1/L2 bytes
Single-channel AliExpress unit CB3S Rev. C 1 channel Same template adapted Remove L2 logic

Key insight: The WiFi module only transmits dimming commands. Each dimmer controller selects packets by the 01 or 02 channel byte, so OpenBeken can replace the original firmware with scripts.

Quick Facts

  • WXDM2 cost 80 PLN, supports 2 bulbs and 2 switches, and originally dims by holding a momentary button. [#20631683]
  • The PCB analysis found 3.3 V logic power, BK7231N, 2 × HC32F003, 2 × 7N65C MOSFETs, 8 × S3M diodes, and a PN8016 converter controller. [#20631683]
  • The working OpenBeken brightness range is 0–255, matching the Dimmer256 channel type and the one-byte brightness field. [#20631683]
  • The CB3S-based variant uses 9600 baud, 8N1 UART and packet bytes 0A FF 55 01_or_02 L1 L2 ramp ramp 0A. [#20635703]
  • The reported Home Assistant setup used MQTT client topic DM02, qos: 1, retained messages, and brightness state from channel 11. [#20635703]

How do you flash OpenBeken onto a WXDM2 dual dimmer with a BK7231N or CB3S WiFi module?

Flash OpenBeken through the WiFi module UART pads, using BK7231GUIFlashTool for BK7231N or CB3S devices.
  1. Open the dimmer and identify 3.3 V, GND, RX, and TX.
  2. Connect a UART programmer to the exposed pads.
  3. Flash OpenBeken, then test dimming with uartSendHex.
The author found desoldering was unnecessary because only the WiFi module talks on UART. Do not power the mains side while using a low-voltage programmer. [#20631683]

What UART packet format controls brightness on the WXDM2 dual dimmer using OpenBeken?

The brightness packet uses a Tuya-style header, a channel byte, one or two brightness bytes, ramp bytes, and final 0A. The CB3S variant used 0A FF 55 01_or_02 L1brightness L2brightness Dimmer_ramp Dimmer_ramp 0A at 9600 8N1. Brightness runs from 00 to FF, so OpenBeken maps it cleanly to 0–255. For the WXDM2 test, uartSendHex 0A FF 55 02 00 9F 00 00 0A controlled channel 2. [#20635703]

How can I configure OpenBeken autoexec.bat to control both L1 and L2 dimmer channels independently?

Use separate OpenBeken Dimmer256 channels and separate OnChannelChange handlers for L1 and L2. One working setup used channel 11 for L1 and channel 12 for L2. It sent 0A FF 55 01 $CH11$ 00 05 DC 0A for L1. It sent 0A FF 55 02 00 $CH12$ 05 DC 0A for L2. Auxiliary channels 21 and 22 stored long-press direction. This keeps both outputs independent in OpenBeken and MQTT. [#20635703]

What does the UART command `0A FF 55 02 00 9F 00 00 0A` mean on a Tuya-style dual dimmer?

The command sets dimmer channel 02 to brightness 9F, which is 159 on a 0–255 scale. 0A FF 55 acts as a fixed header. 02 selects the second dimmer. 00 9F maps channel values, with 9F used as the active brightness byte in the author’s test. 00 00 gives an immediate transition instead of the smoother 05 DC ramp. The final 0A terminates the packet, not a confirmed checksum. [#20631683]

How do momentary wall switches control brightness increase and decrease on the WXDM2 or similar Tuya dimmer?

A momentary switch toggles on short press and changes brightness while held. In the shared OpenBeken script, a click on pin 8 toggles L1 between 0 and 255. Holding the switch changes brightness by 15 steps per event. A helper channel stores direction as 1 or -1. On release, the script reverses that direction, so the next hold dims the other way. The same logic applies to S2 on pin 9. [#20635703]

What is the purpose of the `05 DC` ramp bytes in the WXDM2 dimmer UART protocol?

The 05 DC bytes define a smooth brightness ramp of about half a second on the tested CB3S dimmer. Replacing both ramp bytes with 00 00 produced an immediate brightness change. The tester could not change L1 and L2 ramp behavior independently. That means the ramp likely applies globally inside the dimmer MCU for each received command. [#20635703]

What is TuyaMCU, and how is this WXDM2 dimmer protocol different from the normal TuyaMCU protocol?

“TuyaMCU is a serial device-control protocol that lets a Tuya WiFi module exchange structured commands with a separate MCU, usually using bidirectional UART frames and defined datapoints.” This WXDM2 protocol differs because the analyzed unit used only TX from the WiFi module. The dimmer MCUs did not send data back. The author saw Tuya-like bytes FF 55, but concluded it was not normal TuyaMCU. There was also no confirmed checksum. [#20631683]

What is OpenBeken, and why is it useful for replacing Tuya cloud firmware on BK7231N and CB3S devices?

“OpenBeken is open firmware for Beken-based smart devices that provides local control, scripting, MQTT integration, and Tuya-firmware replacement without cloud dependency.” It helped here because BK7231N and CB3S modules could send custom UART bytes with uartSendHex. OpenBeken channels also expose 0–255 dimmer controls. One user reported that after converting this dimmer, Tuya integration was officially switched off in Home Assistant. [#20635703]

BK7231N vs CB3S dimmer modules — what changes when reverse engineering and flashing OpenBeken?

BK7231N and CB3S both work with OpenBeken, but their boards expose different module layouts and MCU arrangements. The WXDM2 used an LMB54 module with BK7231N and 2 × HC32F003 controllers. The similar Brazilian dimmer used CB3S and 1 × HK32F030MF4P6 controller. Reverse engineering therefore focuses on finding each board’s UART pads and button pins. The dimming packet concept stayed the same: TX-only control with 01 and 02 channel selection. [#20635703]

How can I use Home Assistant MQTT with an OpenBeken-flashed dual dimmer?

Configure Home Assistant MQTT lights against OpenBeken channel topics. The shared example used MQTT client topic DM02. L1 state came from DM02/11/get, and commands went to DM02/11/set. The YAML used schema: template, qos: 1, retain: true, and optimistic: false. It mapped brightness 0 to off and nonzero values to on. For L2, repeat the pattern with channel 12. [#20635703]

Which pins on the WXDM2 or CB3S dimmer are used for UART flashing, TX dimmer control, and S1/S2 button inputs?

The key pins are 3.3 V, GND, RX, TX, S1, S2, dimmer outputs, and zero-cross detection. On the WXDM2, TX from the WiFi module goes to both HC32F003 dimmer controllers. S1 and S2 connect to the WiFi module. R1 and R2 drive the dimmer outputs. ZC carries zero-cross detection through a transistor to both dimmer controllers. In the CB3S OpenBeken script, S1 used pin 8 and S2 used pin 9. [#20631683]

Why does the WXDM2 dual dimmer use one-way UART communication from the WiFi module to HC32F003 or HK32F030 microcontrollers?

The design uses one-way UART because the dimmer MCUs only need brightness commands from the WiFi module. In the WXDM2, both HC32F003 controllers share one TX line from the BK7231N module. Each controller filters packets by channel byte, 01 or 02. The WiFi module does not need return status for basic dimming. This simplifies the protocol, but it also removes feedback and error reporting. [#20631683]

How can I add long-press dimming behavior for S1 and S2 buttons in OpenBeken scripts?

Add click, hold, release, and channel-change handlers for each switch. For L1, the shared script used OnClick 8 to toggle channel 11 between 0 and 255. It used OnHold 8 to add or subtract 15 brightness points. It used channel 21 as the direction variable. OnRelease 8 flipped that variable. L2 repeated the same pattern on pin 9, channel 12, and direction channel 22. [#20635703]

What safety issues should I check before wiring a WXDM2 dimmer, especially if the seller diagram swaps N and L?

Check the markings on the dimmer housing before wiring live and neutral. The seller diagram showed N and L reversed for the shipped product. The author warned that the housing markings have the “last word.” This is a mains-voltage dimmer, and S1/S2 in the similar module connect to AC voltage. Do not trust only the auction diagram. Verify L, N, load outputs, and switch inputs before energizing the circuit. [#20631683]

Can the OpenBeken configuration from a dual-channel Tuya dimmer be adapted for a single-channel AliExpress CB3S dimmer?

Yes, remove the second channel logic and keep the matching single-channel UART command. A later tester confirmed the proposed template and autoexec.bat worked on a single-channel AliExpress dimmer with CB3S Rev. C. They removed L2 configuration because the device had only one dimmer output. This is the main edge case: dual-channel scripts will reference missing channels unless you delete the unused L2 handlers. [#21716540]
ADVERTISEMENT