Distance Sensor

Published on 2016-12-31 in µBob biped robot.

For the first time µBob has a working distance sensor on board (you might recall I tried to give it a distance sensor earlier, but it didn’t work). So let’s make use of it.

The sensor I’m using is a SHARP GP2Y0A60SZLF on a breakout board from Pololu. It’s an analog sensor, which is good, because I can use only a single pin for it. All I have to do is get the ADC to work. A bit of googling for examples, and a little bit of cross-checking with the datasheet, and I had the basic procedure:\

ADCSRA = 1<<ADEN | 1<<ADPS2 | 1<<ADPS1 | 0<<ADPS0; // Pre-scaler 64.
ADMUX = 0<<ADLAR | 0<<REFS1 | 0<<REFS0 | pin & 0x03;
ADCSRA |= 1<<ADSC;
while (ADCSRA & (1<<ADSC)) {
    // Pass.
}
return ADCH << 8 | ADCL;

However, that didn’t work. I spent half a day trying to figure out why it would keep returning the same number all the time, changing only on reset. Everything was exactly the same as in the datasheet, the examples, even the Arduino cores that I checked. What did I miss? After asking around a bit on IRC and robotics forums, someone pointed out to me that the order in which you read ADCH and ADCL is important – there is a latch there, that makes sure the values won’t change in the middle of your reading. Sure enough, I had the order wrong. The fix is very simple – I can defer to the compiler to do the right thing by just doing:

return ADC;

That’s it. Suddenly I started getting changing values, as expected. However, the changes still weren’t in any way correlated with the voltage on the pin… Back to the drawing board. Four re-readings of the datasheet later I just tried the same program on a different chip, and it worked fine. Turns out the ATtiny85 that I have soldered to a breakout board some 2 years ago and used since for all sorts of uncanny experiments must have gotten the ADC broken somehow – possibly by applying higher voltage than it should get.

In any case, the next step is checking the range of the sensor. I don’t have any way to display the readings from the robot (and I want to check the readings in the robot, not on a separate circuit, because the voltages would be different), so I wrote a simple program that basically moves a servo depending on the value read from the sensor. Since I know the servo’s range, I can guess what the reading was.

That worked pretty well, now I just need to fine-tune the walking algorithm to make the robot go straight, add some animations for turning and going backwards, and make a simple state machine switching between those animations depending on the sensor readings. Should fit in the ~400 bytes of program space I have left.