Hallo m.a.r.v.in,
nichts leichter als das:
Code:
/****************************************************************************/
/*
\brief
Interrupt-Funktion fuer den AD-Wandler. Kann ueber autoencode gesteuert\n
die Odometrie-Zaehler in encoder hochzaehlen.
\param
keine
\return
nichts
\see
Die globale Variable autoencode wird hier ausgewertet. Ist sie nicht FALSE,\n
dann wird der AD-Wandler-Wert zum Zaehlen der Odometriewerte in der globalen\n
Variablen encoder benutzt.\n
Es wird auch der AD-Wandler-Kanal auf die 'andere' Seite der Odometrie\n
umgeschaltete und der AD-Wandler neu gestartet.\n
Somit wird erreicht, dass zumindest die Odometriemessung automatisch erfolgt.
\par Beispiel:
int main(void) {
int lSoll=60, rSoll=30, lPwm=lSoll, rPwm=rSoll, delta=50;
Init();
EncoderInit();
EncoderStart();
while(1) {
int lIst=encoder[LEFT], rIst=encoder[RIGHT];
EncoderSet(0, 0);
lPwm+=(delta*lSoll - 1000*lIst)/300;
rPwm+=(delta*rSoll - 1000*rIst)/300;
SetMotorPower(lPwm, rPwm);
Msleep(delta);
}
}
*****************************************************************************/
SIGNAL (SIG_ADC)
{
const static unsigned char admux[]={
(1 << ADLAR) | (1 << REFS0) | WHEEL_LEFT,
(1 << ADLAR) | (1 << REFS0) | WHEEL_RIGHT};
static int tmp [2], flag [2]={1,1};
static unsigned char toggle = 0;
if (autoencode)
{
// Aktuellen Sensorwert vom AD-Wandler entnehmen (hier nur high-order-byte).
int sensor = ADCH;
// Der AD-Wandler wird schon mal auf den übernächsten Analogkanal eingestellt.
ADMUX = admux[toggle];
// In tmp wird ein gleitender Mittelwert mitgeführt.
tmp[toggle] += (sensor-tmp[toggle])>>2;
// Weicht der aktuelle Sensorwert um mehr als +/- 2 vom gleitenden Mittel ab?
if (flag[toggle]*(sensor-tmp[toggle]) > 2)
{
// Dann zähle einen Tick weiter.
// Und nächster Tick erst wieder bei -/+ 2 Abweichung vom gleitenden Mittel.
encoder[toggle]++;
flag[toggle] = -flag [toggle];
}
toggle ^= 1;
}
}
Besser so? Auf jeden Fall deutlich besser kommentiert als das Lib-Orginal
Lesezeichen