-1

I have an HRLV-EZ4 ultrasonic sensor hooked up to my RPi 3 B+ like so:

Serial output --> pi RX (pin 10)

V+ --> pi 5V

GND --> pi GND

I've already gotten it to work with an analog voltage output and an analog-digital converter, but it was not as accurate as I would have liked it to be.

I'd like to write a script that uses serial to read the incoming data from the sensor, but I am new at this and unsure of where to go from here. The sensor is currently configured to use TTL (9600 baud, 8-bit), but I can change it to RS232 if needed. Here's the datasheet for more information. Any help is appreciated.

EDIT: I've tried using this module and script I found before, but to no avail.

# Filename: maxSonarTTY.py
# Reads serial data from Maxbotix ultrasonic rangefinders
# Gracefully handles most common serial data glitches
# Use as an importable module with "import MaxSonarTTY"
# Returns an integer value representing distance to target in millimeters

from time import time
from serial import Serial

serialDevice = "/dev/ttyAMA0" # default for RaspberryPi
maxwait = 3 # seconds to try for a good reading before quitting

def measure(portName):
    ser = Serial(portName, 9600, 8, 'N', 1, timeout=1)
    timeStart = time()
    valueCount = 0

    while time() < timeStart + maxwait:
        if ser.inWaiting():
            bytesToRead = ser.inWaiting()
            valueCount += 1
            if valueCount < 2: # 1st reading may be partial number; throw it out
                continue
            testData = ser.read(bytesToRead)
            if not testData.startswith(b'R'):
                # data received did not start with R
                continue
            try:
                sensorData = testData.decode('utf-8').lstrip('R')
            except UnicodeDecodeError:
                # data received could not be decoded properly
                continue
            try:
                mm = int(sensorData)
            except ValueError:
                # value is not a number
                continue
            ser.close()
            return(mm)

    ser.close()
    raise RuntimeError("Expected serial data not received")

if __name__ == '__main__':
    measurement = measure(serialDevice)
    print("distance =",measurement)

The 'raise runtime error' close to the bottom kept giving me trouble, and even if I commented it out, the module wouldn't pick up a reading (IE distance would be 0).

EDIT2: Here's a sample of the output from a script that just reads the data using .read(). It continually updates at 9600 baud.

R
0
4
5
1

R
0
4
5
1 

R
0
4
5
1 

This is the distance of an object from the sensor in mm that will be used to control a robot. My goal right now is to have that be a single updating entity that can be easily referenced in other modules/scripts. Once the reading falls below a threshold, it will trigger an event/action. The ultimate goal is to have this be differential, so that the robot can respond to it as it changes, and not just past a certain threshold. I'd settle for the first goal for now, though.

Adam M.
  • 1
  • 3
  • start by writing a program to display serial data as it streams in .... do not try to parse the data stream, do that after you can actually receive valid data – jsotola Jul 23 '18 at 19:12
  • Alright, I went ahead and made a real simple program that does just that. Any suggestions for parsing it? This is where my knowledge is lacking, and I can't find a whole lot of resources for it online. – Adam M. Jul 23 '18 at 19:43
  • You can use minicom or another serial program on the Raspberry Pi to see how the communication works. One note: TTL-level and RS-232 are electrical standards rather than serial protocols. TTL-level is 0-5V and RS-232 can be up to 15V if I remember correctly. I've never heard a definitive name for the UART serial protocol, so I just call it that and try to use specific names like 8N1. – NomadMaker Jul 23 '18 at 19:46
  • @AdamM. It would help us if you could paste several lines of this output into your question. In addition, please include a small section on what the data is supposed to be, please. – NomadMaker Jul 23 '18 at 19:48
  • Sure thing. Just added it. – Adam M. Jul 23 '18 at 20:19
  • The module uses 5V. The Raspberry Pi expects 3.3V at the serial interface and on its GPIO pins. You should use a logic level converter (google for "logic level converter 3.3 5"), some soldering may be necessary. Using GPIOs rather than the serial interface may make life easier for you as well. – PiEnthusiast Jul 24 '18 at 07:38

1 Answers1

1

/dev/ttyAMA0 IS NOT the default serial UART for RaspberryPi

See How-do-i-make-serial-work-on-the-raspberry-pi3

In Raspbian ALL code on all models should use /dev/serial0 which is the default (assuming serial is enabled).

NOTE the serial interface (in common with other GPIO pins) is NOT 5V - it is 3.3V.

Milliways
  • 59,890
  • 31
  • 101
  • 209
  • Thanks, that helped me solve one problem. I went ahead and enabled it in the /boot/config.txt and now it works fine. Saved me another headache. EDIT: Scratch that, I used /dev/serial0 like you said. – Adam M. Jul 23 '18 at 19:41
  • Isn't /dev/serial0 just a symlink to /dev/ttyAMA0 (or /dev/ttyS0?)? – Geremia Jan 09 '24 at 03:46