When instructed to move forward the Euro RPy-Rover will do so obligingly, like a lemming in the game, even when facing a rock. To prevent this senseless behavior we used a distance sensor to detect obstacles and know when to stop the rover forward motion.
There are multiple choices available for distance sensors, including infrared and sonar. Sonars will output the distance as a digital signal whose pulse duration corresponds to the distance measured, which we thought would be difficult to convert into a number, so we decided to use an analog sensor with an analog to digital converter (ADC).
In this module we used:
- Raspberry Pi B+
- Pololu Carrier with Sharp GP2Y0A60SZLF Analog Distance Sensor 10-150cm, 3V
- MCP3008 – 8-Channel 10-Bit ADC With SPI Interface
We used a 8 channel ADC to be able to add other analog sensors to the rover in the future, but the 1 channel MCP3001 would do just as well for this purpose.
|Ranger Out||MCP 1||Ranger out / ADC in|
|MCP 12||RPi 21||RPi MISO /ADC MOSI|
|MCP 11||RPi 19||RPi MOSI /ADC MISO|
|MCP 13||RPi 23||SCLK|
The ranger we used outputs an analog voltage. The Raspberry Pi doesn’t have analog inputs so we used an ADC to get the digital reading from the sensor. The ADC used, the MCP3008, has a SPI bus, so we used the spidev Python library.
To use the SPI bus we wrote:
spi = spidev.SpiDev() # Create object spi.open(0, 0) # Open SPI port 0 on (CS) 0
Since the converter is a 10 bit ADC, we need to send two bytes and do some bit shifting on the two bytes returned, for which we resorted to some come by Scruss (thanks!).
r = spi.xfer2([1, 8 + adcnum &lt;&lt; 4, 0]) adcout = ((r &amp;amp; 3) &lt;&lt; 8) + r
When we saw the output of the ranger/ADC we realized that the readings had large errors and varied immensely. To get a more accurate reading we made 100 consecutive readings and used the average.
adcaverage = 0 for averagenum in range(0,100): r = spi.xfer2([1, 8 + adcnum &lt;&lt; 4, 0]) adcout = ((r &amp;amp; 3) &lt;&lt; 8) + r adcaverage += adcout adcaverage = adcaverage/100
Looking at the obstacle distance/output voltage graph below (reproduced from Sharp GP2Y0A60SZLF Analog Distance Sensor data sheet) we see that the voltage decreases as the distance increases.
After some tests we decided to use 300 as the reference value to consider that there is an obstacle ahead, so the rover forward movement will stop whenever the average value read from the ranger is larger that this.
Previous tutorial: Capturing images from the rover
First tutorial: Controlling the RPy-Rover’s motors