Using Arduino Ultrasonic Sensor with Pyfirmata

1.2k Views Asked by At

I'm trying to use pyfirmata to use an Arduino Ultrasonic sensor. I used Arduino Uno board and HC-SR04 Ultrasonic sensor. Here is the code I'm using. The code ran smoothly, it's just that it seems the echo pin failed to get an impulse from the trigger ultrasonic sound, so it keeps on getting False (LOW reading) and thus giving me false distance reading. Does anyone have a solution for this problem?

import pyfirmata
import time

board = pyfirmata.Arduino('COM16')

start = 0
end = 0

echo = board.get_pin('d:11:i')
trig = board.get_pin('d:12:o')
LED = board.get_pin('d:13:o')

it = pyfirmata.util.Iterator(board)
it.start()

trig.write(0)
time.sleep(2)

while True:
    time.sleep(0.5)

    trig.write(1)   
    time.sleep(0.00001)
    trig.write(0)
    
    print(echo.read())
    while echo.read() == False:
        start = time.time()

    while echo.read() == True:
        end = time.time()
    
    TimeElapsed = end - start
    distance = (TimeElapsed * 34300) / 2

    print("Measured Distance = {} cm".format(distance) )

I've tried changing the time.sleep() to several value and it still doesn't work. It works just fine when I'm using Arduino code dirrectly from Arduino IDE.

3

There are 3 best solutions below

0
On

I haven't done the exact math but given a range of 50cm you're at about 3ms travel time. That would mean you need to turn off the pulse and poll the pin state within that time.

That's not going to happen. The echo probably arrives befor you have turned off the emitter through PyFirmata. You should do the delay measurement on the Arduino.

0
On

I solve this false data problem by counting. I observe that false data comes after 2 or 3 sec. So if it takes More than 2 or 3 sec I clear count and restarts it from 0;

Sudo code:

cnt = 0;

if sensorvalue <= 20 && sensorvalue <= 30:
   cnt++;
if cnt>=5:
  detected = true;
  cnt =0;

if cnt<5 && lastDecttime>2 (2 sec):
  cnt = 0; // Here we handle the false value and clear the data
0
On

I'm currently trying to work this exact problem out. I can get the sensor to work using the Arduino IDE directly, but not with python and pyfirmata. I am getting some output, but its mostly non-sensical. Here's an example output I'm getting, while keeping the sensor at the same distance from my object:

817.1010613441467
536.828875541687
0.0
546.0820078849792
0.0
0.0
1060.0213408470154

Regarding your code, the only thing I can see that you could do differently is to use the board.pass_time function instead of time.sleep(). Let me know if you get anywhere!

import pyfirmata as pyf
import time

def ultra_test():

board = pyf.Arduino("COM10")
it = pyf.util.Iterator(board)
it.start()
trigpin = board.get_pin("d:7:o")
echopin = board.get_pin("d:8:i")
while True:
    trigpin.write(0)
    board.pass_time(0.5)
    trigpin.write(1)
    board.pass_time(0.00001)
    trigpin.write(0)
    limit_start = time.time()
    
    while echopin.read() != 1:
        if time.time() - limit_start > 1:
            break
        pass
    
    start = time.time()
    while echopin.read() != 0:
        pass
    stop = time.time()
    time_elapsed = stop - start
    print((time_elapsed) * 34300 / 2)
    board.pass_time(1)