Trials and Tribulations of Ultrasonic Sensors
Apr 4
3 min read
0
42
For navigation during the autonomous phases of the competition, the rover will utilise HC-SR04 ultrasonic distance sensors. These are driven by 4 pins - V in, Ground, Echo and Trigger. A pulse is sent to the trigger pin (i.e. it is set high) and for the duration of the pulse the ultrasound speaker is activated. 40 ms is a standard pulse. The receiver then listens for the echo and records the time spent between pulse being sent and received. The echo pin is then set to high for the same time.
The rover is going to use four US sensors to navigate, forwards, backwards, left and right (F,B,L,R.) The intended logic will be along the lines of if F>10cm drive forwards, else turn in the direction of the greater of L or R. It wont be pretty but hopefully it will be enough for simple mazes at Pi Wars!
However an issue came from operating 4 sensors. There is a risk that the sensors could here returns off the others. It was thought that firing the sensors all at once would alleviate this as logically the first return they would hear would be a reflection off their own emitter, as this is the shortest path. I charged ahead with this notion and made a custom harness up that combines the 4 Vcc, GND and TRIG leads into one header pin, with the ECHO lines being left independent. I then soldered up a little potential divider boar that split the incoming 5V echo return lines into 3.3V inputs to the Raspberry Pi GPIO pins.
Then I started coding (big mistake.) Turns out, the simple DistanceSensor function in gpiozero allocates unique TRIG pins to each sensor. I.e I couldn't have 4 sensor objects, each sharing the same GPIO TRIG number. I had to resort to another custom built function to handle it instead.
This also proved tricky to implement. The pseudo code is as follows:
1) trigger the ultrasound sensors by switching GPIO TRIG high for 40 ms
2) Concurrently wait for each ECHO pin to switch to high, then start a timer until it reverts to low
3) wait until the last pin has reverted to low and then send the next pulse
Sounds simple enough, right? But unlike the prebuilt DistanceSensor code, this all needs to be built and tested by hand. Frequent issues were encountered involving no echos being heard or interreference stalling the code. As such the attempt to fire all at once was temporarily suspended until the code worked reliably, and so I reverted to a one-at-a-time "for" loop. The result of this was fairly slow, needed debugging, and most pressing of all the prototype board had some issues that meant it was currently jumper-wired together.
By this point I was wishing I could use the prebuilt functions and get testing the actual control logic, and not just writing code to cater to a board that needed fixing anyway. But then I discovered that some HC-SR04 boards can operate of 3.3V, and so remove the need for the potential divider on the return line. I quickly tested mine and thankfully mine work on 3.3V!
So I cut open my harness, and respliced the TRIG lines to separate pins, scrapped the potential divider board and am now back to running 4 sensors using the generic DistanceSensor libraries. I'd still like to resolve this as at the moment I am using up a lot of my GPIO pins to operate this, although thankfully I don't need them for Pi Wars
Now with my final wheels printing, hopefully we can do some driving this weekend...