Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
MT4v2 ESPHome yaml for home assistant without tuya
#1
Code:
esphome:
  name: mt4v2
  friendly_name: mt4v2


# ============================================================
# ESP32-S3
# ============================================================

esp32:
  board: esp32-s3-devkitc-1
  framework:
    type: arduino


# ============================================================
# Logger
# ============================================================

logger:
  hardware_uart: USB_SERIAL_JTAG


# ============================================================
# Home Assistant API
# ============================================================

api:


# ============================================================
# Ethernet - W5500
# ============================================================

ethernet:
  type: W5500
  clk_pin: GPIO1
  mosi_pin: GPIO2
  miso_pin: GPIO41
  cs_pin: GPIO42
  interrupt_pin: GPIO43
  reset_pin: GPIO44


# ============================================================
# I2C
# ============================================================

i2c:
  - id: bus_a
    sda: 8
    scl: 18
    scan: true
    frequency: 400kHz


# ============================================================
# PCF8574 - Digital Inputs
# ============================================================

pcf8574:
  - id: pcf8574_hub_in_1
    i2c_id: bus_a
    address: 0x24


# ============================================================
# UART
# ============================================================

uart:

  # RS485 UART
  - id: uart_1
    baud_rate: 9600
    tx_pin: 39
    rx_pin: 38
    debug:
      direction: BOTH
      dummy_receiver: true
      after:
        timeout: 10ms

  # ARM CPU Motor Control UART
  # ESP32-S3 TX GPIO16 -> ARM RX
  # ESP32-S3 RX GPIO15 <- ARM TX
  # MODBUS RTU 115200 / 8N1
  - id: uart_motor
    baud_rate: 115200
    tx_pin: 16
    rx_pin: 15
    data_bits: 8
    parity: NONE
    stop_bits: 1


# ============================================================
# Global Motor Speed Variables
#
# Positive = Forward
# Negative = Reverse
# 0        = Stop
# ============================================================

globals:

  - id: motor1_speed
    type: int
    restore_value: no
    initial_value: '100'

  - id: motor2_speed
    type: int
    restore_value: no
    initial_value: '100'

  - id: motor3_speed
    type: int
    restore_value: no
    initial_value: '100'

  - id: motor4_speed
    type: int
    restore_value: no
    initial_value: '100'


# ============================================================
# Motor MODBUS Scripts
# ============================================================

script:

  # ----------------------------------------------------------
  # Motor Master Enable
  # Coil 503 = ON
  # ----------------------------------------------------------

  - id: motor_enable
    then:
      - lambda: |-
          uint8_t data[6] = {
            0x01, 0x05,
            0x01, 0xF7,
            0xFF, 0x00
          };

          uint16_t crc = 0xFFFF;

          for (int p = 0; p < 6; p++) {
            crc ^= data[p];

            for (int i = 0; i < 8; i++) {
              crc = (crc & 1)
                    ? (crc >> 1) ^ 0xA001
                    : crc >> 1;
            }
          }

          id(uart_motor).write_array(data, 6);

          uint8_t crc_data[2] = {
            (uint8_t)(crc & 0xFF),
            (uint8_t)(crc >> 8)
          };

          id(uart_motor).write_array(crc_data, 2);


  # ----------------------------------------------------------
  # Motor 1 - Register 2000
  # ----------------------------------------------------------

  - id: motor1_write
    mode: restart
    then:
      - lambda: |-
          int16_t speed = id(motor1_speed);

          uint8_t data[6] = {
            0x01, 0x06,
            0x07, 0xD0,
            (uint8_t)(speed >> 8),
            (uint8_t)speed
          };

          uint16_t crc = 0xFFFF;

          for (int p = 0; p < 6; p++) {
            crc ^= data[p];

            for (int i = 0; i < 8; i++) {
              crc = (crc & 1)
                    ? (crc >> 1) ^ 0xA001
                    : crc >> 1;
            }
          }

          id(uart_motor).write_array(data, 6);

          uint8_t crc_data[2] = {
            (uint8_t)(crc & 0xFF),
            (uint8_t)(crc >> 8)
          };

          id(uart_motor).write_array(crc_data, 2);


  # ----------------------------------------------------------
  # Motor 2 - Register 2001
  # ----------------------------------------------------------

  - id: motor2_write
    mode: restart
    then:
      - lambda: |-
          int16_t speed = id(motor2_speed);

          uint8_t data[6] = {
            0x01, 0x06,
            0x07, 0xD1,
            (uint8_t)(speed >> 8),
            (uint8_t)speed
          };

          uint16_t crc = 0xFFFF;

          for (int p = 0; p < 6; p++) {
            crc ^= data[p];

            for (int i = 0; i < 8; i++) {
              crc = (crc & 1)
                    ? (crc >> 1) ^ 0xA001
                    : crc >> 1;
            }
          }

          id(uart_motor).write_array(data, 6);

          uint8_t crc_data[2] = {
            (uint8_t)(crc & 0xFF),
            (uint8_t)(crc >> 8)
          };

          id(uart_motor).write_array(crc_data, 2);


  # ----------------------------------------------------------
  # Motor 3 - Register 2002
  # ----------------------------------------------------------

  - id: motor3_write
    mode: restart
    then:
      - lambda: |-
          int16_t speed = id(motor3_speed);

          uint8_t data[6] = {
            0x01, 0x06,
            0x07, 0xD2,
            (uint8_t)(speed >> 8),
            (uint8_t)speed
          };

          uint16_t crc = 0xFFFF;

          for (int p = 0; p < 6; p++) {
            crc ^= data[p];

            for (int i = 0; i < 8; i++) {
              crc = (crc & 1)
                    ? (crc >> 1) ^ 0xA001
                    : crc >> 1;
            }
          }

          id(uart_motor).write_array(data, 6);

          uint8_t crc_data[2] = {
            (uint8_t)(crc & 0xFF),
            (uint8_t)(crc >> 8)
          };

          id(uart_motor).write_array(crc_data, 2);


  # ----------------------------------------------------------
  # Motor 4 - Register 2003
  # ----------------------------------------------------------

  - id: motor4_write
    mode: restart
    then:
      - lambda: |-
          int16_t speed = id(motor4_speed);

          uint8_t data[6] = {
            0x01, 0x06,
            0x07, 0xD3,
            (uint8_t)(speed >> 8),
            (uint8_t)speed
          };

          uint16_t crc = 0xFFFF;

          for (int p = 0; p < 6; p++) {
            crc ^= data[p];

            for (int i = 0; i < 8; i++) {
              crc = (crc & 1)
                    ? (crc >> 1) ^ 0xA001
                    : crc >> 1;
            }
          }

          id(uart_motor).write_array(data, 6);

          uint8_t crc_data[2] = {
            (uint8_t)(crc & 0xFF),
            (uint8_t)(crc >> 8)
          };

          id(uart_motor).write_array(crc_data, 2);


# ============================================================
# Motor Speed Sliders
#
# 0   = Stop
# 100 = Full Speed
#
# Slider changes motor speed immediately.
# Current direction is retained.
# ============================================================

number:

  - platform: template
    name: "Motor 1 Speed"
    id: motor1_speed_slider
    min_value: 0
    max_value: 100
    step: 1
    initial_value: 100
    optimistic: true
    mode: slider
    set_action:
      - lambda: |-
          if (id(motor1_speed) < 0)
            id(motor1_speed) = -(int)x;
          else
            id(motor1_speed) = (int)x;
      - script.execute: motor1_write


  - platform: template
    name: "Motor 2 Speed"
    id: motor2_speed_slider
    min_value: 0
    max_value: 100
    step: 1
    initial_value: 100
    optimistic: true
    mode: slider
    set_action:
      - lambda: |-
          if (id(motor2_speed) < 0)
            id(motor2_speed) = -(int)x;
          else
            id(motor2_speed) = (int)x;
      - script.execute: motor2_write


  - platform: template
    name: "Motor 3 Speed"
    id: motor3_speed_slider
    min_value: 0
    max_value: 100
    step: 1
    initial_value: 100
    optimistic: true
    mode: slider
    set_action:
      - lambda: |-
          if (id(motor3_speed) < 0)
            id(motor3_speed) = -(int)x;
          else
            id(motor3_speed) = (int)x;
      - script.execute: motor3_write


  - platform: template
    name: "Motor 4 Speed"
    id: motor4_speed_slider
    min_value: 0
    max_value: 100
    step: 1
    initial_value: 100
    optimistic: true
    mode: slider
    set_action:
      - lambda: |-
          if (id(motor4_speed) < 0)
            id(motor4_speed) = -(int)x;
          else
            id(motor4_speed) = (int)x;
      - script.execute: motor4_write


# ============================================================
# Motor Control Buttons
# ============================================================

button:

  # Motor 1
  - platform: template
    name: "Motor 1 Forward"
    on_press:
      - script.execute: motor_enable
      - delay: 50ms
      - lambda: |-
          id(motor1_speed) =
            abs((int)id(motor1_speed_slider).state);
      - script.execute: motor1_write

  - platform: template
    name: "Motor 1 Reverse"
    on_press:
      - script.execute: motor_enable
      - delay: 50ms
      - lambda: |-
          id(motor1_speed) =
            -abs((int)id(motor1_speed_slider).state);
      - script.execute: motor1_write

  - platform: template
    name: "Motor 1 Stop"
    on_press:
      - lambda: |-
          id(motor1_speed) = 0;
      - script.execute: motor1_write


  # Motor 2
  - platform: template
    name: "Motor 2 Forward"
    on_press:
      - script.execute: motor_enable
      - delay: 50ms
      - lambda: |-
          id(motor2_speed) =
            abs((int)id(motor2_speed_slider).state);
      - script.execute: motor2_write

  - platform: template
    name: "Motor 2 Reverse"
    on_press:
      - script.execute: motor_enable
      - delay: 50ms
      - lambda: |-
          id(motor2_speed) =
            -abs((int)id(motor2_speed_slider).state);
      - script.execute: motor2_write

  - platform: template
    name: "Motor 2 Stop"
    on_press:
      - lambda: |-
          id(motor2_speed) = 0;
      - script.execute: motor2_write


  # Motor 3
  - platform: template
    name: "Motor 3 Forward"
    on_press:
      - script.execute: motor_enable
      - delay: 50ms
      - lambda: |-
          id(motor3_speed) =
            abs((int)id(motor3_speed_slider).state);
      - script.execute: motor3_write

  - platform: template
    name: "Motor 3 Reverse"
    on_press:
      - script.execute: motor_enable
      - delay: 50ms
      - lambda: |-
          id(motor3_speed) =
            -abs((int)id(motor3_speed_slider).state);
      - script.execute: motor3_write

  - platform: template
    name: "Motor 3 Stop"
    on_press:
      - lambda: |-
          id(motor3_speed) = 0;
      - script.execute: motor3_write


  # Motor 4
  - platform: template
    name: "Motor 4 Forward"
    on_press:
      - script.execute: motor_enable
      - delay: 50ms
      - lambda: |-
          id(motor4_speed) =
            abs((int)id(motor4_speed_slider).state);
      - script.execute: motor4_write

  - platform: template
    name: "Motor 4 Reverse"
    on_press:
      - script.execute: motor_enable
      - delay: 50ms
      - lambda: |-
          id(motor4_speed) =
            -abs((int)id(motor4_speed_slider).state);
      - script.execute: motor4_write

  - platform: template
    name: "Motor 4 Stop"
    on_press:
      - lambda: |-
          id(motor4_speed) = 0;
      - script.execute: motor4_write


# ============================================================
# RS485 Test Switch
# ============================================================

switch:

  - platform: uart
    uart_id: uart_1
    name: "RS485 Button"
    data: [0x11, 0x22, 0x33, 0x44, 0x55]


# ============================================================
# Digital Inputs
# ============================================================

binary_sensor:

  - platform: gpio
    name: "mt4v2-input01"
    id: mt4v2_input01
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 0
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "mt4v2-input02"
    id: mt4v2_input02
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 1
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "mt4v2-input03"
    id: mt4v2_input03
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 2
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "mt4v2-input04"
    id: mt4v2_input04
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 3
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "mt4v2-input05"
    id: mt4v2_input05
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 4
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "mt4v2-input06"
    id: mt4v2_input06
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 5
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "mt4v2-input07"
    id: mt4v2_input07
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 6
      mode: INPUT
      inverted: true

  - platform: gpio
    name: "mt4v2-input08"
    id: mt4v2_input08
    pin:
      pcf8574: pcf8574_hub_in_1
      number: 7
      mode: INPUT
      inverted: true


  # GPIO inputs with pull-up resistors on PCB

  - platform: gpio
    name: "mt4v2-W1-io47"
    pin:
      number: 47
      inverted: true

  - platform: gpio
    name: "mt4v2-W1-io48"
    pin:
      number: 48
      inverted: true

  - platform: gpio
    name: "mt4v2-W1-io17"
    pin:
      number: 17
      inverted: true

  - platform: gpio
    name: "mt4v2-W1-io40"
    pin:
      number: 40
      inverted: true


  # ==========================================================
  # DRV8262 Fault Status
  #
  # Register 2020 = DRV8262 #1
  # Register 2021 = DRV8262 #2
  #
  # OFF = Normal
  # ON  = Problem
  # ==========================================================

  - platform: template
    name: "DRV8262-1 Fault"
    id: drv8262_1_fault
    device_class: problem

  - platform: template
    name: "DRV8262-2 Fault"
    id: drv8262_2_fault
    device_class: problem


# ============================================================
# ADS1115
# ============================================================

ads1115:
  - address: 0x48


# ============================================================
# Sensors
# ============================================================

sensor:

  # ADS1115 Channel 1
  - platform: ads1115
    multiplexer: A0_GND
    gain: 6.144
    resolution: 16_BITS
    name: "ADS1115 Channel A0-GND"
    update_interval: 5s

  # ADS1115 Channel 2
  - platform: ads1115
    multiplexer: A1_GND
    gain: 6.144
    name: "ADS1115 Channel A1-GND"
    update_interval: 5s

  # ADS1115 Channel 3
  - platform: ads1115
    multiplexer: A2_GND
    gain: 6.144
    name: "ADS1115 Channel A2-GND"
    update_interval: 5s

  # ADS1115 Channel 4
  - platform: ads1115
    multiplexer: A3_GND
    gain: 6.144
    name: "ADS1115 Channel A3-GND"
    update_interval: 5s


  # ==========================================================
  # Motor Current
  #
  # ARM MODBUS Registers:
  # 2010 = Motor 1 Current
  # 2011 = Motor 2 Current
  # 2012 = Motor 3 Current
  # 2013 = Motor 4 Current
  #
  # Values are displayed as raw register values.
  # ==========================================================

  - platform: template
    name: "Motor 1 Current"
    id: motor1_current
    accuracy_decimals: 0
    update_interval: never

  - platform: template
    name: "Motor 2 Current"
    id: motor2_current
    accuracy_decimals: 0
    update_interval: never

  - platform: template
    name: "Motor 3 Current"
    id: motor3_current
    accuracy_decimals: 0
    update_interval: never

  - platform: template
    name: "Motor 4 Current"
    id: motor4_current
    accuracy_decimals: 0
    update_interval: never


# ============================================================
# MODBUS Status Polling
#
# Every 2 seconds:
#
# Read 2010-2013 -> Motor Current
# Read 2020-2021 -> DRV8262 Fault
# ============================================================

interval:

  - interval: 2s
    then:

      # ======================================================
      # Read Motor Current
      #
      # FC03
      # Start Register = 2010
      # Quantity       = 4
      # ======================================================

      - lambda: |-

          // Clear old UART receive data
          while (id(uart_motor).available()) {
            uint8_t c;
            id(uart_motor).read_byte(&c);
          }

          // MODBUS request:
          // Slave 1
          // Function 03
          // Start address 2010 = 0x07DA
          // Read 4 registers

          uint8_t data[6] = {
            0x01, 0x03,
            0x07, 0xDA,
            0x00, 0x04
          };

          uint16_t crc = 0xFFFF;

          // Calculate MODBUS RTU CRC16
          for (int p = 0; p < 6; p++) {
            crc ^= data[p];

            for (int i = 0; i < 8; i++) {
              crc = (crc & 1)
                    ? (crc >> 1) ^ 0xA001
                    : crc >> 1;
            }
          }

          // Send MODBUS request
          id(uart_motor).write_array(data, 6);

          // Send CRC
          uint8_t crc_data[2] = {
            (uint8_t)(crc & 0xFF),
            (uint8_t)(crc >> 8)
          };

          id(uart_motor).write_array(crc_data, 2);


      # Wait for ARM CPU response
      - delay: 50ms


      # ======================================================
      # Process Motor Current Response
      # ======================================================

      - lambda: |-

          uint8_t rx[32];
          int len = 0;

          // Read UART response
          while (id(uart_motor).available() && len < 32) {
            id(uart_motor).read_byte(&rx[len]);
            len++;
          }

          // Expected response:
          //
          // 01 03 08
          // M1_H M1_L
          // M2_H M2_L
          // M3_H M3_L
          // M4_H M4_L
          // CRC_L CRC_H
          //
          // Total = 13 bytes

          if (len >= 13 &&
              rx[0] == 0x01 &&
              rx[1] == 0x03 &&
              rx[2] == 0x08) {

            uint16_t m1 =
              ((uint16_t)rx[3] << 8) | rx[4];

            uint16_t m2 =
              ((uint16_t)rx[5] << 8) | rx[6];

            uint16_t m3 =
              ((uint16_t)rx[7] << 8) | rx[8];

            uint16_t m4 =
              ((uint16_t)rx[9] << 8) | rx[10];

            // Publish values to ESPHome
            id(motor1_current).publish_state(m1);
            id(motor2_current).publish_state(m2);
            id(motor3_current).publish_state(m3);
            id(motor4_current).publish_state(m4);
          }


      # ======================================================
      # Read DRV8262 Fault Status
      #
      # FC03
      # Start Register = 2020
      # Quantity       = 2
      # ======================================================

      - lambda: |-

          // Clear UART receive buffer
          while (id(uart_motor).available()) {
            uint8_t c;
            id(uart_motor).read_byte(&c);
          }

          // MODBUS request:
          // Slave 1
          // Function 03
          // Start address 2020 = 0x07E4
          // Read 2 registers

          uint8_t data[6] = {
            0x01, 0x03,
            0x07, 0xE4,
            0x00, 0x02
          };

          uint16_t crc = 0xFFFF;

          // Calculate MODBUS RTU CRC16
          for (int p = 0; p < 6; p++) {
            crc ^= data[p];

            for (int i = 0; i < 8; i++) {
              crc = (crc & 1)
                    ? (crc >> 1) ^ 0xA001
                    : crc >> 1;
            }
          }

          // Send MODBUS request
          id(uart_motor).write_array(data, 6);

          // Send CRC
          uint8_t crc_data[2] = {
            (uint8_t)(crc & 0xFF),
            (uint8_t)(crc >> 8)
          };

          id(uart_motor).write_array(crc_data, 2);


      # Wait for ARM CPU response
      - delay: 50ms


      # ======================================================
      # Process DRV8262 Fault Response
      # ======================================================

      - lambda: |-

          uint8_t rx[16];
          int len = 0;

          // Read UART response
          while (id(uart_motor).available() && len < 16) {
            id(uart_motor).read_byte(&rx[len]);
            len++;
          }

          // Expected response:
          //
          // 01 03 04
          // Fault1_H Fault1_L
          // Fault2_H Fault2_L
          // CRC_L CRC_H
          //
          // Total = 9 bytes

          if (len >= 9 &&
              rx[0] == 0x01 &&
              rx[1] == 0x03 &&
              rx[2] == 0x04) {

            uint16_t fault1 =
              ((uint16_t)rx[3] << 8) | rx[4];

            uint16_t fault2 =
              ((uint16_t)rx[5] << 8) | rx[6];

            // 0 = Normal
            // Non-zero = Fault
            id(drv8262_1_fault).publish_state(
              fault1 != 0
            );

            id(drv8262_2_fault).publish_state(
              fault2 != 0
            );
          }


# ============================================================
# Web Server
# ============================================================

web_server:
  port: 80


# ============================================================
# OLED Font
# ============================================================

font:
  - file: "gfonts://Roboto"
    id: roboto
    size: 20


# ============================================================
# OLED Display
# ============================================================

display:

  - platform: ssd1306_i2c
    i2c_id: bus_a
    model: "SSD1306 128x64"
    address: 0x3C

    lambda: |-
      it.printf(
        0,
        0,
        id(roboto),
        "KinCony MT4v2"
      );
ESPHome yaml file download:

.txt   MT4v2-HA-Motor-Current-Without-Tuya.txt (Size: 22.74 KB / Downloads: 8)
Reply


Forum Jump:


Users browsing this thread:
1 Guest(s)