Ett ganska stort problem att lösa vid sumo-robotbyggande är sensorerna. För en vanlig digitalnörd kan det vara lite irriterande att inse att sensorerna varken är speciellt linjära eller okänsliga för yttre elektromagnetiska fält. Dessutom finns en massa mekaniska krav på att sensorn ska vara riktad åt rätt håll och mäta något som är på rätt avståndsintervall. Sen drar vissa av dom en hel del ström så med för klena spänningsmatningar uppstår spikar på mätsignalen som inte får misstolkas som riktigt data.

Meanytime, 10:a i SM 2010, undergår nu en grundkontroll och jag kollar störningar med oscilloskop och nivåer med voltmeter. Dessutom kör jag ett testprogram på en annan styrdator, en Orangutan X2, för den har en display ansluten där jag skriver ut min, max och medelvärde en gång i sekunden för två analoga ingångar. Displayen har bara 8×2 tecken så jag får byta mellan sensorerna vartefter jag testar av dem. Jag bifogar testprogrammet nedan.

Pololu QTR-1A Reflectance Sensor

Pololu QTR-1A Reflectance Sensor

Meanytime har två stycken av Parallax QTI linjesensorer monterade längst fram på sidorna alldeles bakom plogen. På SM fick jag aldrig dessa att fungera speciellt bra och nu upptäcker jag varför. Vitt ligger på kanske 50% av maxvärdet som minst men borde vara 0%. Eftersom jag inte hann mäta ordentligt innan SM innebär detta att Meanytime inte hade en chans att se kanten ordentligt då jag antagit att upp till 33% skulle vara vitt och resten svart. Genom att byta pull-up motstånd på QTI sensorerna från 4.7K Ohm till 10K Ohm så får jag ner värdet till 5% för vitt, så blir det enklare.

Sharp GP2D120 Distance Measuring Sensor

Sharp GP2D120 Distance Measuring Sensor

För att kunna tracka motståndaren, eller upptäcka den på ren svenska, är Meanytime utrustad med 2 st Sharp  GP2D120 infraröda sensorer. Sharps sensorer är kända för att generera spikar vilket jag validerade med oscilloskopet. En 4.7 uF elektrolytkondensator mellan plus och minus på varje sensor tog hand om det värsta spikandet och resten hanterar jag i mjukvara genom att helt enkelt sampla in ett antal mätvärden och plocka bort det högsta och det lägsta innan jag räknar ut medelvärdet. Samplefrekvensen måste då ligga på minst en spikbredds mellanrum men det var ju lätt uppmätt med skåpet.

Nästa uppgift blir att kolla upp motorerna så att de mår bra och drivs optimalt.

Jocke

/*
* ADC tester, a small polled program that display on a LCD values from two 
* ADC ports on the Orangutan X2 controller. The program uses functions from 
* Pololus library which needs to be downloaded in addition to the AVR 
* compiler: http://www.pololu.com/docs/0J20
*
* Author: Joakim Larsson, Stockholm Robotförening, 
* joakim@bildrulle.nu, 2010
*/

#include <stdio.h>
#include <pololu/orangutan.h>
#include "device.h"

/* Setup the AD converter */
void setup_adc()
{
// Enable it
ADCSRA |= (1 << ADEN);

// Setup prescaler (110 == 64)
ADCSRA &= ~((1 << ADPS0) | (1 << ADPS2) | (1 << ADPS1));
ADCSRA |=  (1 << ADPS2) | (1 << ADPS1);

// Enable interrupt
// ADCSRA |= (1 << ADIE); // No interrupts in this example

// Left shifted 10 bit (8 high  bits in ADCH)
ADMUX = (1 << ADLAR);
}

/* start_adc() sets up the ADC mux for a specific channel */
void start_adc(unsigned int chan)
{
ADMUX  &= ~((1 << MUX0) |(1 << MUX1) |(1 << MUX2) |(1 << MUX3) |(1 << MUX4));
ADMUX  |= (chan & ((1 << MUX0) |(1 << MUX1) |(1 << MUX2)));
ADCSRA |= ( 1 << ADSC );         // start conversion
}

/*
* Polled ADC value retrival. Takes 13-260 us to complete according to the AVR datasheet
*
* chan is 0 to 7 and supports 8 muxed channels for PA0 to PA7
*/
unsigned int poll_adc(unsigned int chan)
{
start_adc(chan);
while ( ADCSRA & ( 1 << ADSC )); // wait while converting, aka busy wait
return ADCH;
}

int main(int argc, char **argv)
{
unsigned int min, max, avg;
unsigned int data0[10], data1[10], i;
char buf[32];

setup_adc();

i = 1;
clear();

while(1){
data0[i % 10] = poll_adc(0);
data1[i % 10] = poll_adc(1);

/* Each sample takes up to 250 uS = 0.25 mS ==> 2-3 mS for 10 samples */
/* When we got 10 samples do the calculations and display the result  */
if ((i % 10) == 0){
min = 0xff; max = 0; avg = 0;
for (i = 0; i < 10; i++){
min = data0[i] < min ? data0[i] : min;
max = data0[i] > max ? data0[i] : max;
avg += data0[i];
}

/* Display the result for the first ADC channel */
clear();
lcd_goto_xy(0, 0);
snprintf(buf, sizeof(buf), "%02x-%02x~%02x", min, max, (avg - max - min) / 8);
print(buf);

/* Do the calculations for the other ADC and display the result */
min = 0xff; max = 0; avg = 0;
for (i = 0; i < 10; i++){
min = data1[i] < min ? data1[i] : min;
max = data1[i] > max ? data1[i] : max;
avg += data1[i];
}
lcd_goto_xy(0, 1);
snprintf(buf, sizeof(buf), "%02x-%02x~%02x", min, max, (avg - max - min) / 8);
print(buf);



 /* Since the sharp sensors outputs new value only each 40-60 mS we can wait a while here */
delay_ms(100);
}
i++;
}
}
 

2 Responses to Finjustera sensorer

  1. Erik Sternå says:

    Skulle den där samplingen och medelvärdesbildningen fungera i en sumo-robot? Jag menar, givet en samplingshastighet på 40 ms och 10 samplingar så skulle det (i bästa fall) ta 400 ms innan värdet ändras. En snabb sumo hinner långt på en halv sekund.

    Och bra med { på nästa rad. 🙂 Sånt gillar vi!

  2. Jocke says:

    Givetvis inte, men man kan ju tänka sig ett rullande fönster om 10 värden för filtret och 3 senaste värdena för medelvärdet så uppdaterar man 8-10 ggr per sekund. Det ska nog räcka. Interrupt och digitalt i/o för linjesensorerna hjälper också, men för att hinna se mätvärdena blinka förbi så funkade 2 ggr per skund bra.

    Får jobba med måsvingarna lite, inte glad över formatet. Dessutom tappade jag bilderna vid flytten av forumet. Allt kan bli bättre! 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *

Set your Twitter account name in your settings to use the TwitterBar Section.