ESPHome Ultrasonic sensor SR04T via UART

Ok,
I’m going to solder a 47KΩ at R19 for activating the “Low Power Serial Mode” and reverting with results.

What code should be changed if remaining into “Automatic Serial Mode”?

Edit1.This link is for the specific model that I have in my hands, labeled AJ-SR04M and resistors value is different than JSN-SR04T. I’m highlighting this for the sake of clarity.

Edit2. After the soldering of the 47KΩ at R19 the blue led is flashing every 5-6 seconds
I have try

      write(0x00); not any indication in logs or in esphome
      write(0x55); not any indication in logs or in esphome
      write(0x01); not any indication in logs or in esphome


History2– Home Assistant

The two screen shots are the debug logs and the integration. the theird one is the history of the sensor. As you can see yesterday after soldering the resistor and trying x55 amd x00 was visible some measurements althouth with lag which situation I can reproduce anymore.

If is the same module from the link you should send 0x01

void loop() {
    jsnSerial.write(0x01);
    delay(50);
  if(jsnSerial.available()){
    getDistance();
  }
}

Try write(0x01)

I’m trying various things,
first finding is that your config is different than tuxflo’s,
with yours I’m receiving distance athought with lag (does not matter if it is 47kΩ or 120)

Now recompilling with 01, reverting

Edit1. with 47kΩ, your posted config, with 0x01 is working, updating fast. Accuracy is a question, sometimes 10cm plus , other time ok.
** Edit2. If I’ll unplug the esp32 board from power supply then I have to reinstall/recompile the settings before having readings!!! Alternatively unlpug the Tx or Rx pin (very weird) **

See screenshot, 1)anything to improve it? 2) how to add a sensor with the quantity and %

Any help on the reset issue?

  tx_pin: GPIO14
  rx_pin: GPIO12

Change the pins, the pins you chose interfere with the boot.

I have changed to

uart:
  id: uart_bus
  tx_pin: GPIO19
  rx_pin: GPIO18
  baud_rate: 9600
  stop_bits: 1

but still having same behavior. I’m going to try more couples of pins from the recommended list.

Other thing tried was separate power supply for sensor, it didn’t work.

Edit2. Same with 16,17!!!

Edit3. As I have a second identical sensor but only a 8266 spare board, Could anybody advise me how to setup that board for further testing?

framework:
    type: arduino

is not working with that board, so I cant perform a comparison test

I use this pins:

uart:
  id: uart_bus
  tx_pin: GPIO17 # echo/RX do SR04M 
  rx_pin: GPIO18 #trigger/TX do SR04M 
  baud_rate: 9600
  stop_bits: 1
  rx_buffer_size: 4

Change the board:

esp8266:
  board: d1_mini

I have spent this afternoon doing trials:

  1. no any chance to test the esp8266 board, the board type or the framework is not passing the validation, therefore no time or knowledge from my side for this anymore.

  2. I went to the basement and removed one ESP32-cam for testing . I used the second sensor with this board and it was working flawlessly ! responding immediately after reboot, used pins

  tx_pin: GPIO3
  rx_pin: GPIO1

This made me suspicious for the pins of the initial board.

  1. I have tried any combination of pins ESP32-WROOM-32U but the results were the same. No responding after a reboot unless remove the pin tx or rx of the sensor.

  2. I have removed the dallas sensors from the ESP32-WROOM-32U but no change, issues after reboot is there.

  3. I have removed everything related to dallas sensors from config. I have recompiled it, its working immediately after it (as usual) but not after reboot. WTF is the matter with this board?

No idea what else to try!

You need to change pins to 8266.

Maybe your esp32 is faulty or the first sensor.
To be sure you would have to use the first sensor on the ESP32-cam and vice versa.

Thanks for your patience!
I have exchange the sensors to the boards. Reboot issue only with ESP32-WROOM-32U.
The issue occuring with the particular board and I have no idea what could be!

The only reason that Im insisting with that board is the external antena that could be used with it due to the poor wifi coverage at the place of installation

Edit1. I got by express courier and on high price a D1 mini, delivered while ago, I did the same setup as ESP32-cam, in selected GPIO, in connections, in config file etc still have same results.

  • D1 min (as ESP32-WROOM-32U) when rebooting is not communicating with sensor unless remove the tx or Rx pin as kick start.

  • ESP32-cam is NOT working fine (anymore) after reboot!!! Not any more!

I’m giving up on this project!

Which pins did you use?
Look at the link below, there is a table with the pins and a note with possible problems.

If you tested with pins 1 and 3, change to whatever has OK on the input and output and nothing on the note.

I did it again, no difference. It should be disconnect/reconect the tx or rx pin before resuming measurements. Its a mystery for me!
Other observation is the need for common source of power/grounding for a responsive sensor (before reboot).

Edit: finally I did it with UART method, see here for my case

I received the same sensor (AJ-SR04M) and I can’t get it to work. It shows no distance readings. I have been following this thread but to no avail. Can someone enlighten me where to put the AJ_SR04M_Sensor.h file. I was hoping to use it withou any resistor (to work just like the HC-SR04). Are there any changes to the code?

Hello - I found this post interesting - I’m starting to connect AJ-SR04M to my HA via esphome board : esp32 or wemos D1 mini

Have You considered voltages ?

I assume that You get 5v for AJ-SR04M from the board (esp32 or D1mini) but as far as I know TX/RX pins on these boards are working with 3.3v.
So If You connect TX/RX from SR04M You get 5v signal … and connecting it to 3.3v pins can cause damage or malfunction.
There is an instruction how to connect and there is a film presenting it is working but this example is based on Arduino UNO - there are 5v pin !
instructions
film - arduino UNO working with AJ-SR04M

So … did You noticed this “voltage question” ?

Hello everyone,
I am trying to reproduce this configuration on my Home Assistant via ESPHOME.
However, I have errors, and I’m more than new to Arduino.

My setup is a “Wemos D1 mini” with “JSN-SR04T” (AJ-SR04M) and 47KΩ residence on R19

In /homeassistant/esphome/
Here is my file AJ_SR04M_Sensor.h

#include "esphome.h"
 
class AJ_SR04M_Sensor : public PollingComponent, public UARTDevice, public Sensor {
 public:

  AJ_SR04M_Sensor(UARTComponent *parent) : PollingComponent(5000), UARTDevice(parent) {}

// AJ_SR04M_Sensor format:
// Trigger: 0x00
// Response: Byte1          Byte2  Byte3  Byte4               Byte5
//           Start Byte=FF  MSB    LSB    Checksum (LSB+MSB)  00

  void update() override {
  
    char frame[5];
    int pos = 0;


    float value = 0.0;

    write(0x01);
    while (available()) {


      frame[pos] = read();
      pos++;
      if(pos==5) {
        if ((frame[0] == 0xFF) && (frame[4] == 0x00) && ((frame[1]+frame[2])==frame[3])) {
          value = ((frame[1]<<8) + frame[2]) / 10.0;
          publish_state(value);
        }
        break;
      }
    }
  }
};

and my esp-cuve.yaml file

esphome:
  name: esp-cuve
  friendly_name: esp-cuve
  includes:
    - AJ_SR04M_Sensor.h

uart:
  id: uart_bus
  tx_pin: D1
  rx_pin: D2
  baud_rate: 9600
  stop_bits: 1
  rx_buffer_size: 4
  debug:

esp8266:
  board: d1_mini

# Enable logging
logger:
  baud_rate: 0

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

captive_portal:

web_server:
  port: 80

# Time: https://esphome.io/components/time.html
time:
  - platform: homeassistant
    timezone: "Europe/Paris"
    id: homeassistant_time

# Status Binary Sensor: https://esphome.io/components/binary_sensor/status.html
binary_sensor:
  - platform: status
    name: "Status"

# Restart Button: https://esphome.io/components/button/restart.html
button:
  - platform: restart
    name: "Restart"


sensor:

  - platform: custom
    lambda: |-
      auto my_sensor = new AJ_SR04M_Sensor(id(uart_bus));
      App.register_component(my_sensor);
      return {my_sensor};
    sensors:
     unit_of_measurement: cm
     accuracy_decimals: 1
     name: "Distance"

No error on compilation but here are the logs

[20:21:22][D][uart_debug:114]: >>> 01
[20:21:27][D][uart_debug:114]: >>> 01
[20:21:32][D][uart_debug:114]: >>> 01
[20:21:37][D][uart_debug:114]: >>> 01
[20:21:42][D][uart_debug:114]: >>> 01

Do you have any idea where the problem could come from?
Thank you again for your help

Just curious, did you get it working? I’m in the same situation.

Did you figure this one out? I’m very new to esphome so I’m really just trying anything an everything, but I’ve just got it working by removing the checksum comparison.

Wish I could say why that would be causing errors for me, but its the only way I’m getting any readings, and have been consistent and very accurate.

I’m having issues getting this working - see

on a D1 mini is an 8266 so there are only 2 UARTs and the second is transmit-only. You have to use the default hardware UART0 on GPIO01 and GPIO03 per the UART Bus documentation UART Bus — ESPHome

Using the debug example to see whether there’s data going back and forth is also super useful.

Additionally, I had to take out the frame[4] == 0x00 check, because for some reason that byte always has a value on mine even though the uart debug log only shows 4 bytes being received. Now it works fine.

Edit: ended up tweaking it a bit so that it’s a little more flexible, and doesn’t block while waiting for a response.

  # AJ_SR04M custom component
  - platform: custom
    lambda: |-
      auto my_sensor = new AJ_SR04M_Sensor2(id(uart_bus),60000,0x01);
      App.register_component(my_sensor);
      return {my_sensor};
    sensors:
      name: "Distance"
      icon: mdi:arrow-expand-vertical
      unit_of_measurement: cm 
      accuracy_decimals: 1
      state_class: measurement
#pragma once

#include <vector>

#include "esphome/core/component.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/uart/uart.h"

#include "esphome/core/helpers.h"
#include "esphome/core/log.h"

#include "esphome.h"

//namespace esphome {
//namespace aj_sr04m {

static const char *const TAG = "aj_sr04m.sensor";
    
class AJ_SR04M_Sensor2 : public sensor::Sensor, public PollingComponent, public uart::UARTDevice {
  public:
    //constructors
    AJ_SR04M_Sensor2(UARTComponent *parent, uint32_t polling_period, uint8_t read_trigger) : PollingComponent(polling_period), UARTDevice(parent) {
        read_trigger_ = read_trigger;
    }
    
    //void setup() override {
    //  ESP_LOGCONFIG(TAG,"Setup of Custom AJ_SR04M_Sensor Finished.");
    //}
    
    void update() override {
        //this->write_byte(0x00); // Try this
        //this->write_byte(0x55); // Try this
        //this->write_byte(0x01); // Try this
        //ESP_LOGV(TAG,"Sent read request to sensor");
        
        this->write_byte(read_trigger_);
        ESP_LOGV(TAG,"Sent read request to sensor using %02x", read_trigger_);
    }

    void loop() override {
        while (this->available() > 0) {
            uint8_t data;
            this->read_byte(&data);
        
            ESP_LOGV(TAG, "Read byte from sensor: %x", data);
        
            if (this->buffer_.empty() && data != 0xFF)
              continue;
        
            this->buffer_.push_back(data);
            if (this->buffer_.size() == 4)
              this->check_buffer_();
        }
    }
    
    void dump_config() override {
      LOG_SENSOR("","AJ_SR04M Sensor",this);
      LOG_UPDATE_INTERVAL(this);
    }
    
  protected:
    std::uint8_t read_trigger_;
    std::vector<uint8_t> buffer_;
    void check_buffer_() {
        // AJ_SR04M_Sensor format:
        // Trigger: 0x01 (some use 0x00 or 0x55)
        // Response: Byte0          Byte1  Byte2  Byte3               Byte4
        //           Start Byte=FF  MSB    LSB    Checksum (LSB+MSB)  00 (not always?)
        //The Byte4 description might be a lie 2024.06.09 ejb
    
        uint8_t checksum = this->buffer_[0] + this->buffer_[1] + this->buffer_[2];
        if (this->buffer_[3] == checksum) {
            uint16_t distance = encode_uint16(this->buffer_[1], this->buffer_[2]);
            if (distance > 200) {
                float scaled_distance = distance / 10.0f;
                ESP_LOGV(TAG, "Distance from sensor: %umm, %.1fcm", distance, scaled_distance);
                this->publish_state(scaled_distance);
            } else {
                ESP_LOGW(TAG, "Invalid data read from sensor: %s", format_hex_pretty(this->buffer_).c_str());
            }
        } else {
            ESP_LOGW(TAG, "Checksum failed: %02x != %02x", checksum, this->buffer_[3]);
        }
        this->buffer_.clear();
    }
};//class AJ_SR04M_Sensor2

//}//namespace aj_sr04m
//}//namespace esphome

Have any recent updates made this not work? I’m trying to copy all of this but it’s not working for me. Just gives me unknown state and nothing in the logs.

Any help is appreciated.