Close
0%
0%

Samsung Dryer IoT Hack

I wanted to get notifications on my phone when my Samsung Dryer finishes the cycle.

Similar projects worth following
224 views
0 followers
After making the washing machine IoT using a smart plug, I wanted to do achieve a similar thing for the dryer.

We all do it. Leave our laundry in the washer or dryer wayyy after the machine is done (and the clothes get smelly). The machine has a chime when the cycle finished, but if you dont grab the laundry immediately, you forget about it and it sits there forever. 

It was a significant life improvement when I made our washing machine IoT connected to Home Assistant. There are multiple YouTube videos out there on how to make your washing machine IoT using just a smart plug, power monitoring thresholds and some timing checks. I then set the system up to send Signal messages (using signal-cli) to my wife and I when the washer was done. 

But, because the dryer is 240V, you cant just buy off-the-shelf smart plugs for them. This makes it more difficult to automate. But I was determined to make it work, so I tore the dryer apart. 

After some reverse engineering, I found out that the front control panel board is kinda just a dumb board that watches the status of the buttons and sends the status back to a main controller (somewhere else in the dryer) via UART at 38400 baud. This UART is continuously transmitting, even when the machine is off. The dryer main power is 12 VDC and the control board runs at 5V.

By connecting up an ESP8266, I was able to continuously monitor the UART and react to specific messages. I captured a message when the board is first turned on and another when it is first turned off. Then I created an ESPHome image with a Custom UART Component which was a Binary Sensor that just updates its state when the UART receives those specific messages.

With that, I now have an IoT Samsung Dryer without having to mess around with 240V 50A circuits. See the instructions for details.

  • 1
    Get Access to Control Board

    First we need to gain access to the front panel control board.

    Disconnect the power from the machine before doing anything!

    First, undo the two screws at the back of the dryer in order to remove the top panel. The top panel will slide forward then lift off once the two screws are removed.

    Once the top is off, there are four screws along the front of the machine that hold the front panel piece on. Undo them, then carefully pop the front panel forward a bit. Behind the panel are two wires with connectors that clip on. Grab and squeeze the clips while removing the wires. 

    Once the wires are disconnected, the whole front panel pieces comes off and can be taken elsewhere.

    Unclip the last wire from the control board (comes from the encoder), then you have to pop off all the clips.

    Finally, after a few more clips and one last screw we have access to the control board. 

  • 2
    Reverse Engineering the Board

    I spent some time reverse engineering the board to figure out where to connect to. There is conformal coating which makes soldering a bit more tricky, but definitely possible.

    You can see the wires I ended up with. I connected to 12V, GND and RX3 (which comes from the central controller.

    You need an ESP-based board that manages to fit within the cover of the board.

  • 3
    ESP8266 Software

    Make software in ESPHome that listens to the UART traffic and changes the state of a switch based on specific messages that happen when the dryer is first turned on or off.

    The code I used is based on a Custom UART Component in ESPHome and a Custom Binary Switch.

    # dryer.yaml
    esphome:
      name: dryer
      includes:
        - dryer.h
    
    esp8266:
      board: esp12e
    
    wifi:
      ssid: wifi_ssid
      password: wifi_password
    
    api:
      password: ""
    
    ota:
      password: ""
    
    logger:
      baud_rate: 0 # disable logging over uart
    
    web_server:
      port: 80
      local: true
    
    uart:
      id: uart_bus
      tx_pin: GPIO1
      rx_pin: GPIO3
      baud_rate: 38400
    
    binary_sensor:
      - platform: custom
        lambda: |-
          auto my_dryer_sensor = new DryerUartSensor(id(uart_bus));
          App.register_component(my_dryer_sensor);
          return {my_dryer_sensor};
        binary_sensors:
          name: "Dryer State"
    

    And dryer.h:

    // dryer.h
    #include "esphome.h"
    #include <string.h>
    
    static const uint8_t on_message[] =  {0x5a, 0xa5, 0xc0, 0x1e, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x01, 0x00, 0x01, 0xe6, 0x80, 0xdb, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x91, 0xef};
    static const size_t on_message_len = sizeof(on_message);
    static const uint8_t off_message[] = {0x5a, 0xa5, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x52, 0x34};
    static const size_t off_message_len = sizeof(off_message);
    
    class DryerUartSensor : public Component, public UARTDevice, public BinarySensor {
        protected:
            int pos_;
            uint8_t buffer_[256];
            uint8_t dryer_state_;
        public:
        DryerUartSensor(UARTComponent *parent) : UARTDevice(parent) {}
    
        void setup() override {
        }
    
        void loop() override {
            uint8_t newData;
            int read_count = 50; //Set max read amount to prevent blocking too long
            while (this->available() && read_count--) {
                if(this->read_byte(&newData)) {
                    if((newData == 'Z') || (pos_ == 254)) {
                        if(dryer_state_) {
                            if(!memcmp(buffer_, off_message, off_message_len-2)) {
                                publish_state(false);
                                dryer_state_ = false;
                            }
                        }
                        else {
                            if(!memcmp(buffer_, on_message, on_message_len-2)) {
                                publish_state(true);
                                dryer_state_ = true;
                            }
                        }
    
                        pos_ = 0;
                    }
                    buffer_[pos_] = newData;
                    pos_ += 1;
                    buffer_[pos_] = 0;
                }
            }
        }
    };

View all 5 instructions

Enjoy this project?

Share

Discussions

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates