encoder.c-Dateireferenz

Radencoder und Odometrie Funktionen.
Funktionen zur Vorgabe von Fahrstrecken und Drehungen. Mehr ...

#include "asuro.h"

gehe zum Quellcode dieser Datei

Funktionen

void EncoderInit (void)
 Den Interrupt Betrieb der Odometriesensoren-Messung initialisieren und starten.
void EncoderStop (void)
 Den Interrupt Betrieb der Odometriesensoren-Messung anhalten.
void EncoderStart (void)
 Den Interrupt Betrieb der Odometriesensoren-Messung starten.
void EncoderSet (int setl, int setr)
 Interruptbetriebene Odometriesensoren Werte vorbelegen.
void Go (int distance, int speed)
 Faehrt eine bestimmte Strecke mit einer bestimmten Geschwindigkeit. (Autor: stochri)
Benutzt die Odometrie Sensoren im Interrupt Betrieb.
Vor dem ersten Aufruf muss deshalb EncoderInit() aufgerufen werden.
void Turn (int degree, int speed)
 Dreht um einen bestimmten Winkel mit einer bestimmten Geschwindigkeit. (Autor: stochri)
Benutzt die Odometrie Sensoren im Interrupt Betrieb.
Vor dem ersten Aufruf muss deshalb EncoderInit() aufgerufen werden.


Ausführliche Beschreibung

Radencoder und Odometrie Funktionen.
Funktionen zur Vorgabe von Fahrstrecken und Drehungen.

Siehe auch:
Defines zum setzen von Port's und Konfigurationen in asuro.h
TRUE, FALSE, LEFT, RIGHT
Version:
V--- - KEINE original Version von der ASURO CD vom DLR

V--- - bis zum 07.01.2007 -
Bitte in Datei CHANGELOG nachsehen.
Das Grundgeruest dieser Funktionen wurde von stochri erstellt.

V001 - 13.01.2007 - m.a.r.v.i.n
+++ Alle Funktionen
Zerlegte Sourcen in einzelne Dateien fuer eine echte Library.

V002 - 27.01.2007 - Sternthaler
+++ Alle Funktionen
Kommentierte Version (KEINE Funktionsaenderung)

Definiert in Datei encoder.c.


Dokumentation der Funktionen

void EncoderInit ( void   ) 

Den Interrupt Betrieb der Odometriesensoren-Messung initialisieren und starten.

Parameter:
keine 
Rückgabe:
nichts
Siehe auch:
autoencode, encoder
Funktionsweise:
Schaltet die Back-LED's aus und die Odometrie-LED's ein.
Initialisiert den AD-Wandler und startet ihn fuer eine Messung des linken
Rad-Sensors.
Wichtig ist nun das setzen der globalen Variablen autoencode auf TRUE.
Diese Funktion wird nun verlassen und das aufrufende Hauptprogramm arbeit
weiter. In der Zwischenzeit ist der AD-Wandler beschaeftigt um das Mess-
ergebniss zu ermitteln.
Ist der Wandler fertig, wird der Interrupt zum AD-Wandler aufgerufen und in
der dazu vorhandene Interrupt-Funktion aus asuro.c berabeitet.
Dort wird nun AUTOMATISCH das Messergebnis ausgewertet, ein erkannter
Hell- Dunkel-Wechsel an der Encoderscheibe erkannt und dadurch der Zaehler
in der globalen Variablen encoder[] weitergezaehlt.
Ausserdem wird dort dann der AD-Wandler fuer die andere Seite gestartet.
Da dies dann ab nun immer Wechsel laeuft, kann das Hauptprogramm, ohne
weiters Zutun von nun ab auf die Zaehlerwerte in encoder[] zugreifen.
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  int main (void)
  {
    Init ();

    EncoderInit ();

    MotorDir (FWD, FWD);
    MotorSpeed (150, 150);
    while (1)
    (
      // Dein Programm

      if (encoder [0] > 500)
      {
        EncoderStop ();
        MotorSpeed (0, 0);
      }
    }
    return 0;
  }

Definiert in Zeile 91 der Datei encoder.c.

00092 {
00093   /*
00094     Alle definierten Interrupts im Asuro sperren.
00095   */
00096   cli();
00097 
00098   /*
00099     Port C als Input => dadurch gehen die Back-LED aus ...
00100   */
00101   DDRC &= ~ ((1<<PC0) | (1<<PC1));
00102   /*
00103     ... aber nun koennen die LED's am Rad eingeschaltet werden, und die
00104         Sensoren koennen gemessen werden.
00105   */
00106   ODOMETRIE_LED_ON;
00107 
00108   /*
00109     AD-Wandler einschalten, Parameter einstellen und Starten. (clk/128)
00110   */
00111   ADCSRA = (1<<ADEN) | (1<<ADFR) | (1<<ADIE) | (1<<ADSC) | (1<<ADPS0) | (1<<ADPS1) | (1<<ADPS2);
00112 
00113   /*
00114     Linken Odometrie-Sensor auswaehlen. (AVCC ref. with external capacitor)
00115   */
00116   ADMUX = (1<<ADLAR) | (1<<REFS0) | WHEEL_LEFT;
00117 
00118   /*
00119     Odometrie im Interruptbetrieb weiter bearbeiten.
00120   */
00121   autoencode = TRUE;
00122 
00123   /*
00124     Alle definierten Interrupts im Asuro wieder zulassen.
00125   */
00126   sei();
00127 
00128   /*
00129     Die Odometrie Hell-/Dunkel-Zaehler zuruecksetzen/initialisieren.
00130   */
00131   EncoderSet (0, 0);
00132 }

void EncoderSet ( int  setl,
int  setr 
)

Interruptbetriebene Odometriesensoren Werte vorbelegen.

Parameter:
[in] setl Wert fuer links
[in] setr Wert fuer rechts
Rückgabe:
nichts
Hinweis:
Initialisiert die beiden Werte in der globalen Variable encoder.
Normalerweise werden die Zaehlerwerte mit 0 initialisiert. Fuer einige
Anwendungen kann es sinnvoll sein auch schon bestimmte Werte vorzubelegen.
Siehe auch:
Die globale Variable encoder wird hier initialisiert.
Beispiel:
(siehe unter den examples)

Definiert in Zeile 221 der Datei encoder.c.

00224 {
00225   encoder [LEFT]  = setl;
00226   encoder [RIGHT] = setr;
00227 }

void EncoderStart ( void   ) 

Den Interrupt Betrieb der Odometriesensoren-Messung starten.

Parameter:
keine 
Rückgabe:
nichts
Fehler:
(Sternthaler) Wurde die Automatik gestoppt, und ist der ADC-Interrupt
erfolgt, dann wurde keine weitere Wandlung mehr angestossen.
Nur das setzen der globalen Variablen autoencode startet somit nicht mehr
die Automatik. Sie kann ueber die Funktion EncoderInit() neu gestartet werden.
Siehe auch:
Die globale Variable autoencode hier auf TRUE gesetzt.
Beispiel:
(siehe unter EncoderInit bzw. in den examples)

Definiert in Zeile 189 der Datei encoder.c.

00190 {
00191   autoencode = TRUE;
00192 }

void EncoderStop ( void   ) 

Den Interrupt Betrieb der Odometriesensoren-Messung anhalten.

Parameter:
keine 
Rückgabe:
nichts
Siehe auch:
Die globale Variable autoencode hier auf FALSE gesetzt.
Funktionsweise:
Durch das setzen der globalen Variablen autoencode auf FALSE wird in
der AD-Wandler-Interruptfunktion der Teil zur Bearbeitung uebersprungen.
Dadurch wird der Wandler nicht mehr neu gestartet und somit stopp die
Automatik.
Beispiel:
(siehe unter EncoderInit bzw. in den examples)

Definiert in Zeile 159 der Datei encoder.c.

00160 {
00161   autoencode = FALSE;
00162 }

void Go ( int  distance,
int  speed 
)

Faehrt eine bestimmte Strecke mit einer bestimmten Geschwindigkeit. (Autor: stochri)
Benutzt die Odometrie Sensoren im Interrupt Betrieb.
Vor dem ersten Aufruf muss deshalb EncoderInit() aufgerufen werden.

Parameter:
[in] distance Distanz in mm (- rueckwaerts, + = vorwaerts)
[in] speed Geschwindigkeit (Wertebereich 0...255)
Rückgabe:
nichts
Siehe auch:
In der globale Variable encoder, werden die Hell-/Dunkelwechsel der Encoder-
scheiben im Interruptbetrieb gezaehlt.
Funktionsweise:
Anhand des Vorzeichens der zu fahrenden Strecke wird ueber MotorDir() die
Richtung gesetzt.
Die zu fahrende Strecke wird in Hell-/Dunkelwechsel (Ticks) umgerechnet.
Die Geschwindigkeit wird mit MotorSpeed() eingestellt.
In einer Programmschleife werden nun die Ticks der linken Seiten gezaehlt.
Wird die berechnete Vorgabe erreicht, werden die Motoren gestoppt, und die
Funktion wird beendet.
Damit die Fahrt auch gerade ausgefuehrt wird, werden in der Schleife immer
die Ticks der rechten und linken Seite verglichen und die Geschwindigkeit
einer Seite so angepasst, dass der Asuro geradeaus faehrt. Dabei wird
darauf geachtet, dass die vorgegebene Geschwindigkeit moeglichst
eingehalten wird.
Hinweis:
Die Berechnung der zu fahrenden Ticks beruht auf der Annahme, dass die
Anzahl der schwarzen Teilstuecke und die Raddurchmesser wie bei stochri sind.
(Sternthaler) Vermutung, dass der Hersteller unterschiedlich grosse Raeder
ausgeliefert hat, da die Berechnung in dieser Form bei Sternthaler nicht
funktioniert.
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // Laesst den Asuro ein Quadrat von 200 mm fahren,
  // bei einer Geschwindigkeit von 150.
  EncoderInit ();
  for (int i = 0; i < 4; i++)
  {
    Go (200, 150);
    Turn (90, 150);
  }

Definiert in Zeile 307 der Datei encoder.c.

00310 {
00311   uint32_t enc_count;
00312   int tot_count = 0;
00313   int diff = 0;
00314   int l_speed = speed, r_speed = speed;
00315 
00316   // calculation tics/mm
00317   enc_count=abs(distance)*10000L;
00318   enc_count/=19363L;
00319 
00320   EncoderSet(0,0); // reset encoder
00321 
00322   MotorSpeed(l_speed,r_speed);
00323   if (distance<0) MotorDir(RWD,RWD);
00324   else MotorDir(FWD,FWD);
00325 
00326   while (tot_count<enc_count)
00327   {
00328     tot_count += encoder[LEFT];
00329     diff = encoder[LEFT] - encoder[RIGHT];
00330     if (diff > 0)
00331     { //Left faster than right
00332       if ((l_speed > speed) || (r_speed > 244)) l_speed -= 10;
00333       else r_speed += 10;
00334     }
00335     if (diff < 0)
00336     { //Right faster than left
00337       if ((r_speed > speed) || (l_speed > 244)) r_speed -= 10;
00338       else l_speed += 10;
00339     }
00340     EncoderSet(0,0); // reset encoder
00341     MotorSpeed(l_speed,r_speed);
00342     Msleep(1);
00343   }
00344   MotorDir(BREAK,BREAK);
00345   Msleep(200);
00346 }

void Turn ( int  degree,
int  speed 
)

Dreht um einen bestimmten Winkel mit einer bestimmten Geschwindigkeit. (Autor: stochri)
Benutzt die Odometrie Sensoren im Interrupt Betrieb.
Vor dem ersten Aufruf muss deshalb EncoderInit() aufgerufen werden.

Parameter:
[in] degree Winkel (- rechts, + links)
[in] speed Geschwindigkeit (Wertebereich 0...255)
Rückgabe:
nichts
Siehe auch:
Funktion Go(), mit dem Unterschied, dass hier anhand des Vorzeichens der
uebergebenen Geschwindigkeit mal eine rechts- bzw. links-Drehung erzeugt wird.

In der globale Variable encoder, werden die Hell-/Dunkelwechsel der
Encoderscheiben im Interruptbetrieb gezaehlt.

Hinweis:
Die Berechnung der zu fahrenden Ticks beruht auf der Annahme, dass die
Anzahl der schwarzen Teilstuecke und die Raddurchmesser wie bei stochri sind.
(Sternthaler) Vermutung, dass der Hersteller unterschiedlich grosse Raeder
ausgeliefert hat, da die Berechnung in dieser Form bei Sternthaler nicht
funktioniert.
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // Laesst den Asuro ein Quadrat von 200 mm fahren,
  // bei einer Geschwindigkeit von 150.
  EncoderInit ();
  for (int i = 0; i < 4; i++)
  {
    Go (200, 150);
    Turn (90, 150);
  }

Definiert in Zeile 411 der Datei encoder.c.

00414 {
00415   long enc_count;
00416   enc_count=abs(degree)*177L;
00417   enc_count /= 360L;
00418 
00419   int tot_count = 0;
00420   int diff = 0;
00421   int l_speed = speed, r_speed = speed;
00422 
00423 
00424   EncoderSet(0,0);              // reset encoder
00425 
00426   MotorSpeed(l_speed,r_speed);
00427   if (degree<0) MotorDir(RWD,FWD);
00428   else MotorDir(FWD,RWD);
00429 
00430   while (tot_count<enc_count)
00431   {
00432     tot_count += encoder[LEFT];
00433     diff = encoder[LEFT] - encoder[RIGHT];
00434     if (diff > 0)
00435     { //Left faster than right
00436       if ((l_speed > speed) || (r_speed > 244)) l_speed -= 10;
00437       else r_speed += 10;
00438     }
00439     if (diff < 0)
00440     { //Right faster than left
00441       if ((r_speed > speed) || (l_speed > 244)) r_speed -= 10;
00442       else l_speed += 10;
00443     }
00444     EncoderSet(0,0);            // reset encoder
00445     MotorSpeed(l_speed,r_speed);
00446     Msleep(1);
00447   }
00448   MotorDir(BREAK,BREAK);
00449   Msleep(200);
00450 }


Erzeugt am Wed Feb 14 16:10:02 2007 für ASURO Library von  doxygen 1.5.1-p1