0
votes

I've connected an ultrasonic distance sensor to a raspberry pi 2. When triggered the sensor is supposed to send the following 6 parameters back via serial:

  1. frame header: 0xFF
  2. data 1: 0x07
  3. data 2: 0xD0
  4. data 3: 0x01
  5. data 4: 0x19
  6. checksum: 0xF0

However when I'm trying to read the output I get something like this: ['\x00\xff\x01V\x00\xce']

Here are some information about the serial frame format of the sensor:

sensor output information

The checksum is calculated like this:

SUM =( Frame header + Data_H+ Data_L+ Temp_H+ Temp_L)&0x00FF Note: The checksum keeps the low accumulative value of 8 bits only;

And this is the code I've written so far:

import RPi.GPIO as GPIO
import time
from serial import Serial

GPIO.setmode(GPIO.BCM) #GPIO mode
GPIO_TRIGGER = 18      #assign GPIO pins
GPIO.setup(GPIO_TRIGGER, GPIO.OUT) #direction of GPIO-Pins (IN / OUT)

data_output=[]

def uss_funct():
    ser = Serial('/dev/ttyAMA0', baudrate=9600, bytesize=8, parity='N', stopbits=1)

    # set trigger HIGH, sensor is waiting for falling edge
    time.sleep(0.01000)
    GPIO.output(GPIO_TRIGGER, True)

    # set trigger LOW after 10ms -> Falling Edge
    time.sleep(0.01000)
    GPIO.output(GPIO_TRIGGER, False)

    # set trigger back HIGH after 2ms, as LOW is supposed to be between 0.1-10ms
    time.sleep(0.00200)
    GPIO.output(GPIO_TRIGGER, True)

    #read from rx
    data_output.append(ser.read(6))
    ser.close()

    #clean up GPIO pins
    GPIO.cleanup()

    print (data_output)

if __name__ == '__main__':
    uss_funct()
1

1 Answers

0
votes

The checksum can be calculated quite easily, but your problem is that the data is out of sync. The first byte needs to be 0xff. Here is some code to find the front of the data (0xff), then calculate the temperature, distance and checksum:

data_output = ser.read(6)

# the first byte should be 0xff
if len(data_output) == 6 and \
        data_output[0] != 0xff and 0xff in data_output:

    # find where 0xff is in the data stream
    still_needed = data_output.index(0xff)

    # read more data, we are out of sync
    data_output = data_output[still_needed:] + ser.read(still_needed)

# must get 6 bytes, and the first needs to be 0xff
if len(data_output) != 6 or data_output[0] != 0xff:
    good_data = False
else:
    # verify the checksum
    good_data = (0 == (sum(data_output) & 0xff))

if good_data:
    distance = data_output[1] * 256 + data_output[2] 
    temperature = data_output[3] * 256 + data_output[4]

Be sure to initialize the serial object with a timeout:

from serial import Serial
ser = Serial(..., timeout=1)

I have no way to test this, so buyer beware.