Reading Serial data from arduino to esphome

Home Assistant automation projects, questions, etc. go here.
horrorchris
LED-Curious
LED-Curious
Reactions:
Posts: 3
Joined: Wed Nov 11, 2020 2:58 pm

Hey all.. been lurking for a while, first time posting. Im stuck trying to read serial data in from an arduino into an esphome configured esp32. Id like to keep the main control unit in esphome so that I can easily call pumps, switches, etc. I had to move the hx711 scale over to an arduino because I could not get a solid reading at all configuring the sensor through esphome. Scale works great now, but getting data back to the esphome esp32 is now the challenge.

Any thoughts or suggestions?
Morbidbystander
LED Enthusiast
LED Enthusiast
Reactions:
Posts: 40
Joined: Wed Sep 16, 2020 4:12 am

I've been mulling over this same question. I'm mostly commenting to tag this thread because I know very little.
User avatar
LEDG
Site Admin
Reactions:
Posts: 1599
Joined: Sun Jun 04, 2017 8:15 pm

I'm pretty sure the answer lies in creating a custom UART component, though this looks tricky. https://esphome.io/custom/uart.html

I'm going to give this a try and will report back if successful.
Want to Support the Site?

Use this Amazon referral link and any purchase you make within 24 hrs will earn LEDgardener a commission at no cost to you!
horrorchris
LED-Curious
LED-Curious
Reactions:
Posts: 3
Joined: Wed Nov 11, 2020 2:58 pm

LEDG wrote:
Wed Nov 18, 2020 3:54 pm
I'm pretty sure the answer lies in creating a custom UART component, though this looks tricky. https://esphome.io/custom/uart.html

I'm going to give this a try and will report back if successful.
Awesome, I was thinking something along the same lines with a custom uart text sensor.. ill tinker with it and post my findings here as well, thanks homie!
User avatar
LEDG
Site Admin
Reactions:
Posts: 1599
Joined: Sun Jun 04, 2017 8:15 pm

I got the custom uart text sensor working this morning. I just programmed another esp to publish messages over serial every second to my esphome node and they showed up in home assistant. You'll just have to set your arduino up at the same baud rate and program it to do a Serial.println("<whatever your data is>") at whatever interval you want the data to come through. If it's weight, I'd just have it print the numeric value of the reading and nothing else.

I'm not sure this is the proper way to do it since you can't do stuff like give it a unit of measurement in the esphome yaml, but it works... you can probably add these customizations in home assistant itself though for that sensor. I was able to trigger automations based on the state of this sensor so this should work for you. I think the proper way would be setting it up as a custom uart device rather than text_sensor, but I wasn't able to get it working that way. Anyway, here's what I did to get text_sensor working:

Go to file editor, then go to the config/esphome folder and create a new file called whateveryouwant.h

I called mine test_uart_component.h

Paste this code into the file and save:

Code: Select all

#include "esphome.h"

class UartReadLineSensor : public Component, public UARTDevice, public TextSensor {
 public:
  UartReadLineSensor(UARTComponent *parent) : UARTDevice(parent) {}

  void setup() override {
    // nothing to do here
  }

  int readline(int readch, char *buffer, int len)
  {
    static int pos = 0;
    int rpos;

    if (readch > 0) {
      switch (readch) {
        case '\n': // Ignore new-lines
          break;
        case '\r': // Return on CR
          rpos = pos;
          pos = 0;  // Reset position index ready for next time
          return rpos;
        default:
          if (pos < len-1) {
            buffer[pos++] = readch;
            buffer[pos] = 0;
          }
      }
    }
    // No end of line has been found, so return -1.
    return -1;
  }

  void loop() override {
    const int max_line_length = 80;
    static char buffer[max_line_length];
    if (available() && readline(read(), buffer, max_line_length) > 0) {
      publish_state(buffer);
    }
  }
};
If you already have a node set up in esphome, edit it and under the esphome: heading at the top, add a line to include the file you created (name has to match) like this:

Code: Select all

esphome:
  name: <whatever your node is named>
  platform: ESP32
  board: esp-wrover-kit
  includes:
    - test_uart_text_component.h
Then, add this yaml as well (tx/rx pins are set for RX0 and TX0 pins on an ESP32):

Code: Select all

uart:
  id: uart_bus
  tx_pin: GPIO1
  rx_pin: GPIO3
  baud_rate: 9600

text_sensor:
- platform: custom
  lambda: |-
    auto uartHX711 = new UartReadLineSensor(id(uart_bus));
    App.register_component(uartHX711);
    return {uartHX711};
  text_sensors:
    id: "uartHX711"
    name: "hx711_custom_uart"


You can change "uartHX711" you see in 3 places in the lambda to whatever you want and you can change the id and name under text_sensors as well. After uploading this, I just had to go back to home assistant configuration-->integrations and then click on my node in the ESPHome integration box, then the three dots in bottom right, then "System options", then "Update" to be able to see my new sensor. You might not need to do this step.
Want to Support the Site?

Use this Amazon referral link and any purchase you make within 24 hrs will earn LEDgardener a commission at no cost to you!
horrorchris
LED-Curious
LED-Curious
Reactions:
Posts: 3
Joined: Wed Nov 11, 2020 2:58 pm

that is freakin awesome. thanks man!
User avatar
LEDG
Site Admin
Reactions:
Posts: 1599
Joined: Sun Jun 04, 2017 8:15 pm

horrorchris wrote:
Wed Nov 18, 2020 10:15 pm
that is freakin awesome. thanks man!
You bet. I got it working as a sensor as well... I think it could be better this way. You'll need to hook up your Arduino to the UART1 set of pins (TX = GPIO17, RX = GPIO16) rather than UART0 if you want to be able to see the values in the logger window.

Put the code below in the ".h" file you created instead of the code from my previous post... You can change the "PollingComponent(1000)" value to how often you want to publish an updated value for the sensor to home assistant in milliseconds E.g. PollingComponent(500) would be every half second:

Code: Select all

#include "esphome.h"

class scaleSensor : public PollingComponent, public UARTDevice, public sensor::Sensor{
 public:
  scaleSensor(UARTComponent *parent) : PollingComponent(1000), UARTDevice(parent) {}
  float weight = 0;
  
  void setup() override {
    // nothing to do here
  }
  
  void loop() override {
    while (available()) {
      String line = readStringUntil('\n');
      weight = line.toFloat();
    }
  }
  
  void update() {
    publish_state(weight);
  }
};


Put this into your esphome yaml:

Code: Select all

esphome:
  name: whateverName
  platform: ESP32
  board: esp-wrover-kit
  includes: whateverFileName.h

wifi:
  ssid: "yourSSID"
  password: "yourPass"

captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

uart:
  id: uart_bus
  tx_pin: GPIO17
  rx_pin: GPIO16
  baud_rate: 9600
  
sensor:
  - platform: custom
    lambda: |-
      auto hx711scale = new scaleSensor(id(uart_bus));
      App.register_component(hx711scale);
      return {hx711scale};
    sensors:
      name: "Weigh Scale"
      unit_of_measurement: Kg
      accuracy_decimals: 2
And don't forget to connect your arduino to TX/RX 1 on your ESP instead of TX/RX 0. You could try playing with the interval at which the arduino spits out data to the ESP as well if you find the ESP is publishing duplicate values. Maybe set the Arduino to send data every half second or something and the ESP every second.
Want to Support the Site?

Use this Amazon referral link and any purchase you make within 24 hrs will earn LEDgardener a commission at no cost to you!
Morbidbystander
LED Enthusiast
LED Enthusiast
Reactions:
Posts: 40
Joined: Wed Sep 16, 2020 4:12 am

Tips from the master. Thanks for finding the fix.
User avatar
LEDG
Site Admin
Reactions:
Posts: 1599
Joined: Sun Jun 04, 2017 8:15 pm

I’m far from a master... definitely learning this stuff too. I just google the shit out of it and then hack at it until it works.
Want to Support the Site?

Use this Amazon referral link and any purchase you make within 24 hrs will earn LEDgardener a commission at no cost to you!
Morbidbystander
LED Enthusiast
LED Enthusiast
Reactions:
Posts: 40
Joined: Wed Sep 16, 2020 4:12 am

I tried and failed. Possibly because I was trying to smash the code with the Ruuvi sensor that is steaming temp and humidity. Idk, it said failed during the up load with a arrow pointing at the "s" in scale after new.

auto hx711scale = new scaleSensor(id(

And the final } was also tagged as an error. But I did get the spacing correct. Yaml kicks my butt. For some reason I can understand c++ way better.

Edit: missed the part about adding the yaml config to file editor
Last edited by Morbidbystander on Thu Nov 19, 2020 10:35 pm, edited 1 time in total.
Post Reply