0

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.

  • 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
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.

  • 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.