logo elektroda
logo elektroda
X
logo elektroda

Reverse engineering of the unusual protocol of the Tuya FS-05R dimmer based on UART

p.kaczmarek2 7014 36
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
📢 Listen (AI):
  • #31 21488398
    @GUTEK@
    Level 31  
    Posts: 1561
    Help: 163
    Rate: 367
    I checked, running the tmSensor driver in addition does not change anything. What helps is adding at the end of the script that the command should be sent several times. Although this is not a very elegant solution.
    ...
    refresh:
    // channel 5 is temporary variable, from 0 to 255*3, multiplied also by toggle value
    setChannel 5 $CH2*3*$CH1
    // split into two bytes
    setChannel 3 $CH5/256
    setChannel 4 $CH5%256
    // send the two bytes
    tuyaMcu_sendCmd 0x30 00$CH3$$CH4$
    delay_ms 3
    tuyaMcu_sendCmd 0x30 00$CH3$$CH4$
    delay_ms 3
    tuyaMcu_sendCmd 0x30 00$CH3$$CH4$
    .
  • ADVERTISEMENT
  • #32 21640037
    jahara
    Level 4  
    Posts: 4
    Rate: 3
    Every few months the MCU stops controlling the dimmer and only power on/off works. The only way to get the dimmer to work is with a complete power cycle. Has anyone found a way to resolve this?
  • ADVERTISEMENT
  • #33 21703784
    jbornema
    Level 2  
    Posts: 2
    >>20986793
    Great work! I almost threw that device into trash, because Tuya firmware disconnected from cloud almost daily and I had to power-cycle. My device only need to send the commands twice (no clue why), and anything below dimmer value 65 was "off" for my LED, so I've added a min value. Here my autoexec.bat:

    
    // this is not really tuyaMCU but we will treat it as such
    startDriver TuyaMCU
    // set baud rate
    tuyaMcu_setBaudRate 115200
    
    // create a toggle and a dimmer
    setChannelType 1 toggle
    setChannelType 2 dimmer256
    
    // invoke refresh on change
    addEventHandler OnChannelChange 1 startScript autoexec.bat refresh
    addEventHandler OnChannelChange 2 startScript autoexec.bat refresh
    
    // restore states after reboot
    setStartValue 1 -1
    setStartValue 2 -1
    
    // min value
    setChannel 6 65
    
    refresh:
    if $CH2==0 then "setChannel 5 0" else "setChannel 5 ($CH6+($CH2-1)*(255-$CH6)/254)*3*$CH1"
    setChannel 3 $CH5/256
    setChannel 4 $CH5%256
    tuyaMcu_sendCmd 0x30 00$CH3$$CH4$
    tuyaMcu_sendCmd 0x30 00$CH3$$CH4$
    
  • ADVERTISEMENT
  • #34 21703814
    sp4rk1e
    Level 10  
    Posts: 37
    Help: 3
    Rate: 5
    great work definitively. Somewhat naively I first tried to get the FS-05R running with Tasmota. With not much success. Searching for a solution I discovered 'OpenBK' and this thread. Tasmota does not provide an equivalent for 'tuyaMcu_sendCmd'. Basically this dimmer works with Tasmota:

    
    template:
    {"NAME":"FS-05R","GPIO":[0,2272,0,2304,0,0,0,0,0,0,0,0,0,0],"FLAG":0,"BASE":54}
    
    SetOption97 1                                                 # set 115200 bps
    SerialSend5 55AA0030000300000A3C      # dim to brightness 0x0a
    SerialSend5 55AA0030000300000032       # dim to brightness 0
    SerialSend5 55AA0030000300009DCF      # dim to brightness 0x9d
    


    For a productive solution in Tasmota you would have to resort to Berry :-(

    But in OpenBK I've got the same problem left as 'jbornema' and '@GUTEK@'. To be on the safe side I do have to issue the 'tuyaMcu_sendCmd' twice. Even without delay between the two is sufficient.

    jbornema wrote:
    tuyaMcu_sendCmd 0x30 00$CH3$$CH4$
    tuyaMcu_sendCmd 0x30 00$CH3$$CH4$


    Easily reproducible also on the console. About every other 6th 'tuyaMcu_sendCmd' is ignored by the device for some unknown reason...

    Any information that may help to find a solution is very welcome.
  • #35 21710909
    sp4rk1e
    Level 10  
    Posts: 37
    Help: 3
    Rate: 5
    the Tuya FS-05R dimmers are quite nice. They allow a decent control of dimming and even support 3 separate buttons. E.g. one for on/off, one for up, one for down

    attached a script currently supporting one button (as commonly used):

    features:
    - short press: switches on/off
    - double click: reverse dim direction (ping pong shortcut)
    - long press if device is on: dim either up or down
    - long press if device is off: turn on at brightness zero, continue from there with dim up
    - if brightness reaches the upper or lower bound: reverse dim direction (ping pong)
    - wifi LED reflects channel 1 state (on/off)

    
    startDriver TuyaMCU
    tuyaMcu_setBaudRate 115200
    tuyaMcu_defWiFiState 4
    PowerSave 1
    SetFlag 10 0                // Flag 10 - [MQTT] Broadcast self state on MQTT connect DONT CLUTTER LOG
    SetButtonTimes 2 3 2        // provides fast response and low lag
    SetChannel 14 40            // define dim stepsize
    
    // button o (connected in parallel to WiFi button)
    SetPinChannel 7 10
    SetPinRole 7 Btn
    // button -
    SetPinChannel 24 11
    SetPinRole 24 Btn
    // button +
    SetPinChannel 26 12
    SetPinRole 26 Btn
    // LED
    SetPinChannel 8 13
    SetPinRole 8 Rel
    
    alias reverse_dim_dir setChannel 14 -$CH14
    alias check_bounds if $CH2==1000||$CH2==0 then reverse_dim_dir
    alias turn_on_at_zero backlog SetChannel 1 1; SetChannel 2 1
    alias dim_step backlog if $CH2==1000||$CH2==0 then reverse_dim_dir; addChannel 2 $CH14 0 1000
    alias calc_sndcmd backlog setChannel 13 !$CH1; setChannel 5 $CH2*$CH1; setChannel 3 $CH5/256; setChannel 4 $CH5%256
    
    setChannelType 1 toggle
    setChannelType 2 dimmer
    addEventHandler OnChannelChange 1 startScript autoexec.bat refresh
    addEventHandler OnChannelChange 2 startScript autoexec.bat refresh
    addEventHandler OnClick    7 toggleChannel 1
    addEventHandler OnHold     7 if $CH1==0 then turn_on_at_zero else dim_step
    addEventHandler OnDblClick 7 reverse_dim_dir
    
    refresh:
    calc_sndcmd
    tuyaMcu_sendCmd 0x30 00$CH3$$CH4$
    tuyaMcu_sendCmd 0x30 00$CH3$$CH4$
    
  • ADVERTISEMENT
  • #36 21716229
    p.kaczmarek2
    Moderator Smart Home
    Posts: 14612
    Help: 655
    Rate: 12630
    This could be adjusted for new ping pong mode in addChannel
    Helpful post? Buy me a coffee.
  • #37 21716555
    sp4rk1e
    Level 10  
    Posts: 37
    Help: 3
    Rate: 5
    p.kaczmarek2 wrote:
    could be adjusted

    now a version for the new firmware commands:
    
    // device: Tuya FS-05R
    //
    // features:
    // short press: switches on/off
    // long press if device is on: dim either up or down
    // long press if device is off: turn on at brightness zero, continue from there with dim up
    // if brightness reaches the upper or lower bound: reverse dim direction (ping pong)
    // after long press: reverse dim direction
    // wifi LED reflects state (on/off)
    
    startDriver TuyaMCU
    tuyaMcu_setBaudRate 115200
    tuyaMcu_defWiFiState 4
    PowerSave 1
    SetFlag 10 0                // Flag 10 - [MQTT] Broadcast self state on MQTT connect DONT CLUTTER LOG
    SetButtonTimes 2 3 2        // provides fast response and low lag
    SetChannel 14 40            // define dim stepsize
    
    // button o (connected in parallel to WiFi button)
    SetPinChannel 7 10
    SetPinRole 7 Btn
    // button -
    SetPinChannel 24 11
    SetPinRole 24 Btn
    // button +
    SetPinChannel 26 12
    SetPinRole 26 Btn
    // LED
    SetPinChannel 8 13
    SetPinRole 8 Rel
    
    alias turn_on_at_zero backlog SetChannel 8 1; SetChannel 9 1
    alias calc_sndcmd backlog setChannel 13 !$CH8; setChannel 5 $CH9*$CH8; setChannel 3 $CH5/256; setChannel 4 $CH5%256
    
    setChannelType 8 toggle     // arbitrary channel possible for this dimmer
    setChannelType 9 dimmer     // arbitrary channel possible for this dimmer
    addEventHandler OnChannelChange 8 startScript autoexec.bat refresh
    addEventHandler OnChannelChange 9 startScript autoexec.bat refresh
    
    addEventHandler OnClick   24 toggleChannel 8
    addEventHandler OnHold    24 if $CH8==0 then turn_on_at_zero else "addChannel 9 $CH14 0 1000 2" // with ping-pong
    addEventHandler OnRelease 24 addChannel 9 $CH14 0 1000 3        // indicate reverse direction to the firmware
    
    refresh:
    calc_sndcmd
    tuyaMcu_sendCmd 0x30 00$CH3$$CH4$  
    tuyaMcu_sendCmd 0x30 00$CH3$$CH4$    // cmd gets ignored often if sent only once
    
📢 Listen (AI):

Topic summary

✨ The discussion focuses on reverse engineering the UART communication protocol of the Tuya FS-05R dimmer, which differs from typical TuyaMCU-based dimmers like the EDM-01AA-EU. The FS-05R uses a non-standard protocol between its WiFi module and the microcontroller responsible for dimming. Users successfully flashed the dimmer with OpenBK firmware and scripted it to work with Home Assistant, though some encountered issues with dimming smoothness and responsiveness. Problems included limited dimming range depending on the bulb type, delayed or inconsistent command responses, and the presence of a heartbeat signal (55 AA 00 00 00 00 FF) potentially interfering with communication. Solutions involved updating to the latest OpenBK firmware, adjusting baud rates, sending repeated commands to ensure reception, and disabling or working around the heartbeat. Some users replaced the original WiFi module with ESP-based boards and noted differences in baud rates and frame formats. The dimmer’s smooth transition effect is handled by the MCU, but slowing it further requires custom scripting. Compatibility varies with bulb types; not all bulbs are dimmable or suitable for this dimmer. The discussion also covers scripting techniques to map dimming ranges and attempts to integrate the device with ESPhome. Hardware variations and firmware batches affect behavior, and UART captures helped analyze the protocol. Overall, the thread provides detailed insights into the FS-05R’s unique UART protocol, firmware customization, and practical integration challenges and solutions for smart home automation.
Generated by the language model.

FAQ

TL;DR: At 115200 baud, “This is a TuyaMCU compatible package” became the key clue: the Tuya FS-05R uses a simplified UART dimmer protocol, not full TuyaMCU. This FAQ helps OpenBeken, ESPHome, and Tasmota users capture packets, flash the CB2S safely, script dimming, and fix variants that ignore single commands. [#20986793]

Why it matters: The FS-05R looks like a normal Tuya dimmer, but its non-standard UART behavior changes how you flash, script, troubleshoot, and integrate it.

Approach What the thread shows Best use case
OpenBeken Native scripting, HA discovery, proven working on multiple units Best documented path for Wi-Fi retrofits
ESPHome Reported working through a Home Assistant forum configuration Good if you already standardize on ESPHome
Tasmota Basic serial control works, but no tuyaMcu_sendCmd equivalent; Berry needed for production Useful for experiments, weaker fit for this dimmer

[#21283485]

Key insight: The hardest part is not brightness math. It is that some FS-05R variants accept the same dimming packet only when it is sent two or three times, especially when heartbeat traffic interferes.

Quick Facts

  • The original reverse-engineered FS-05R used 115200 baud, and the dimmer MCU reacted to command 0x30 with a 2-byte brightness value packed after the 55 AA header. [#20986793]
  • The board could be analyzed safely off-mains by powering it from 3.3 V, which let the UART RX/TX traffic be captured with a Sigrok analyzer. [#20986793]
  • The Wi-Fi module JSON exposed four GPIO roles: bt_pin=7, display_led1_pin=8, lightminus_sw_pin=24, and lightplus_sw_pin=26, showing the module handles local inputs too. [#20986793]
  • A later hardware variant used 9600 baud and 5-byte frames: FF 00 V1 V2 CK, with checksum (V1 + V2 - 1) & 0xFF, so not every FS-05R speaks the same protocol. [#21402422]
  • Real-world load limits matter: one user saw unstable strip behavior below dimmer value 40, another needed a minimum usable value of 65, and a different user found the issue was the bulb, not the script. [#21703784]

How was the UART protocol of the Tuya FS-05R dimmer reverse engineered, and what tools were used to capture the RX/TX traffic?

It was reverse engineered by intercepting the serial link between the CB2S Wi-Fi module and the dimmer MCU. The setup used a Sigrok analyzer on the RX/TX lines, and the board was powered from 3.3 V instead of mains so the capture could be done safely. The captured traffic showed the MCU sending short idle packets and the Wi-Fi module sending control frames when buttons were pressed. [#20986793]

What is TuyaMCU, and how is the FS-05R's simplified UART protocol different from a standard TuyaMCU implementation?

“TuyaMCU” is a UART control protocol that links a Tuya Wi-Fi module to a separate microcontroller, using framed commands, checksums, heartbeats, and datapoint-style exchanges. The FS-05R only reuses part of that model. It sends a checksum-valid 55 AA control packet, but it does not show normal TuyaMCU heartbeats or dpID exchanges. In this dimmer, one simplified brightness packet drives the MCU directly. [#20986793]

Why does the Tuya FS-05R JSON dump show both a 115200 baud rate and GPIO roles like bt_pin, display_led1_pin, and lightplus_sw_pin?

Because this dimmer is not a normal full-TuyaMCU design. The JSON shows baud_rate=115200 for UART communication, but it also lists local GPIO roles such as P7, P8, P24, and P26. That matters because the Wi-Fi module still handles buttons and LED functions, which is unusual for classic TuyaMCU devices where the external MCU usually owns those signals. [#20986793]

How do you flash OpenBeken onto a Tuya FS-05R with a CB2S module when the PCB pin labels for 3.3V and GND are wrong?

You must ignore the PCB silkscreen and follow the CB2S catalog pinout. 1. Desolder the CB2S, because the UART lines are shared with the dimmer MCU. 2. Connect programming wires by the datasheet pinout, not the reversed board labels for 3.3 V and GND. 3. Flash with BK7231GUIFlashTool, then solder the module back. The thread explicitly warns that the board’s CB2S marking is incorrect. [#20986793]

What does the 55 AA header mean in the FS-05R UART packets, and how was the checksum verified as TuyaMCU-compatible?

The 55 AA header marks a frame that looks like a TuyaMCU command. The captured button-triggered packet was checked with a TuyaMCU analyzer, and the author confirmed that the checksum matched the TuyaMCU calculation correctly. That proved the FS-05R packet format is TuyaMCU-compatible at the frame level, even though the overall protocol is simplified. [#20986793]

How can I write an autoexec.bat script in OpenBK to control the FS-05R as a dimmer with on/off and brightness channels?

Use one toggle channel and one dimmer256 channel, then convert brightness into two bytes for command 0x30. The published script sets channel 1 as on/off, channel 2 as brightness, multiplies the dimmer value by 3, splits it into high and low bytes, and sends tuyaMcu_sendCmd 0x30 00$CH3$$CH4$. That gives on/off memory plus slider control in OpenBK and Home Assistant. [#20986793]

Which OBK pin roles and event handlers should be used to make the FS-05R's P7, P24, and P26 buttons work for toggle and dimming?

Set P24 and P26 to Btn_ScriptOnly if you want the script to own dimming behavior. For the main button on P7, use either Btn_ScriptOnly with addEventHandler OnClick 7 toggleChannel 1 or assign the standard Btn role to channel 1. For brightness, the thread suggests addEventHandler OnHold 26 addChannel 2 10 0 255 on one button and the same command with -10 on the other. [#20986793]

Why does an FS-05R bulb jump to full brightness in OpenBeken instead of dimming smoothly, even though it works in the Tuya app?

The usual cause is the load, not the UART math. One user reported that the bulb only switched full on in OpenBeken, but after changing to a different bulb the same script worked “perfectly.” The follow-up conclusion was clear: not every lamp behaves well with this dimmer, and some bulbs have only a very small dimming range even under Tuya firmware. [#21008260]

What kinds of bulbs are actually dimmable, and how can I tell whether an LED bulb will work properly with the Tuya FS-05R dimmer?

Only bulbs explicitly designed for dimming should be assumed compatible. The thread states the safe rule bluntly: assume a bulb is not dimmable unless the packaging says so. In practice, users in this thread saw three outcomes: some bulbs worked smoothly, some dimmed only across a small range, and some loads behaved oddly below certain brightness values. That makes label verification essential before blaming OBK or the dimmer. [#21014440]

How can I remap the FS-05R dimming range in OpenBK so Home Assistant still uses a 0-100 slider while the real output stays between a higher minimum and maximum value?

Map the slider into a higher internal minimum, then send zero only when the slider is zero. A working example used minimum value 65 and this logic: if the slider equals 0, send 0; otherwise scale 1..255 into 65..255 before multiplying for the packet. That preserves normal Home Assistant off behavior while avoiding the unusable lower dimming range. [#21703784]

What controls the fade speed in the FS-05R dimmer, and what options exist if I want a slower or instant transition on the device itself?

The dimmer MCU controls the fade speed, not the Wi-Fi module. The thread states that the smooth transition is handled inside the MCU, and no built-in OpenBK command was given to slow it further or make it instant. A custom C snippet on OBK was mentioned as a possible workaround, but it could look jerky because MCU smoothing would still remain underneath. [#21015455]

ESPHome vs OpenBeken vs Tasmota for the Tuya FS-05R dimmer: which approach works best when the device uses custom UART commands?

OpenBeken is the best-documented fit in this thread. It already has working scripts, Home Assistant discovery, and direct tuyaMcu_sendCmd support. ESPHome was later reported working through a Home Assistant forum example, so it is viable. Tasmota can send raw serial frames like SerialSend5 55AA0030000300009DCF, but one user noted it lacks a direct tuyaMcu_sendCmd equivalent and would need Berry for a polished setup. [#21703814]

What is the CB2S module in Tuya devices, and why does its incorrect silkscreen labeling matter when powering or programming the FS-05R?

“CB2S” is a Tuya Wi‑Fi radio module that hosts the BK7231-family firmware, exposes UART and GPIO pins, and serves as the network side of many Tuya devices. The bad silkscreen matters because the FS-05R board reversed the labels for 3.3 V and GND. If you trust the board print instead of the official CB2S pinout, you can mis-power or mis-wire the module during flashing. [#20986793]

Why do some FS-05R hardware variants ignore every few TuyaMCU commands unless the same brightness packet is sent two or three times?

Because some variants appear to reject or miss single packets when the TuyaMCU driver keeps sending heartbeat traffic. One user captured repeated 55 AA 00 00 00 00 FF frames, identified them as heartbeat-like traffic, then showed that raw uartSendHex commands worked every time while tuyaMcu_sendCmd did not. A practical fix was to send the same brightness packet two or three times, sometimes with a 3 ms delay. [#21488398]

How can the MCU firmware or behavior be changed on an FS-05R variant that uses a different 9600-baud 0xFF 00 V1 V2 CK protocol and adds an unwanted 1-second smooth transition?

The thread does not provide a working way to reflash that MCU or disable its transition effect. That variant used 9600 baud and 5-byte frames FF 00 V1 V2 CK, with checksum (V1+V2-1) & 0xFF, and the user reported about a 1 s smooth on/off delay. The only concrete takeaway is that this is a different FS-05R-family protocol, so the original 115200-baud OpenBK script will not directly solve it. [#21402422]
Generated by the language model.
ADVERTISEMENT