UART distance sensor code?

Guys,
Looking for some help please.

I have a UART Ultrasonic distance sensor - one of these:
DFRobot UART distance sensor

I have been running this on a PICOW via Python scripting for a couple of years without problems. It works well but the POE / wifi connnection isnt the most reliable and when it looses connection the sensor doesnt come back online without a reboot, so Id like to migrate it over to ESPHOME, running on the same PICOW - this seems a much more stable platform in real life on the farm.

My question then is how do I convert my python script that currently does the bit-banging over to ESPHOME?

Here is my python code:

from utime import sleep_ms

PICO_UART = 1			# Can use UART0 or UART1 (UART0 uses Tx Pin1 & Rx Pin2 whereas UART1 uses Tx Pin6 & Rx Pin7).  Use 0 for UART0 or 1 for UART1.
                        # Note that using UART0 conflicts with using the USB for connectivity via Thonny.  Always try to use UART1.
PICO_rx_High = 7		# Use 2 is using UART0 or 7 if using UART1

# Create an LED object that we can turn on and off
led = machine.Pin("LED",machine.Pin.OUT)
avg_pin = machine.Pin(PICO_rx_High, machine.Pin.OUT, value=1) # tell sensor to average data in hardware by driving RX pin on sensor high

# Initialise UART
uart = UART(PICO_UART, 9600)
uart.init(bits=8, parity=None, stop=1) # Defaults from DFrobot wiki page: https://wiki.dfrobot.com/A01NYUB%20Waterproof%20Ultrasonic%20Sensor%20SKU:%20SEN0313


def read_distance():
    uart.read() # clear buffer (could contain many measurements)
    while (uart.any() == 0): # wait for the sensor to send a packet
        pass # pass and check again if you didn't get one
    data_buff = uart.read(4) # read the 4 bytes it sent
    checksum = (data_buff[0] + data_buff[1] + data_buff[2]) & 0xFF # checksum seems to be header + data H + data L, masked to a single byte
    if (checksum == data_buff[3]):
        measurement = ((data_buff[1] << 8) + data_buff[2]) # shift data H left 8 bits, and add with data low
        if measurement == 250:
            return(-1) # return -1 if "250" (invalid measurement) is recieved, consider adding 0 too, as it's usually not accurate
        else:
            return(measurement)
    else:
        return(-2) # if checksum fails (normally because minimum range has been exceeded, return -1)

while True:
    print(str(read_distance()) + " mm") # convert to string (int can't concatenate) and append mm
#    sleep_ms(2000)


The bit that confuses me is how I parse the UART stream and extract the relvant data before passing over to a sensor. I guess its going to be in a lamda call, but I have no idea.

Any thoughts would be grately appreciated.

Thanks
Jon

A quick search revealed this:

2 Likes