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