asuro.h-Dateireferenz

Definitionen und Funktionen der ASURO Bibliothek. Mehr ...

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <inttypes.h>
#include <stdlib.h>

gehe zum Quellcode dieser Datei

Datenstrukturen

struct  my_t

Makrodefinitionen

#define FALSE   0
#define TRUE   1
#define OFF   0
#define ON   1
#define GREEN   1
#define RED   2
#define YELLOW   3
#define LEFT   0
#define RIGHT   1
#define GREEN_LED_ON   PORTB |= GREEN_LED
#define GREEN_LED_OFF   PORTB &= ~GREEN_LED
#define RED_LED_ON   PORTD |= RED_LED
#define RED_LED_OFF   PORTD &= ~RED_LED
#define FWD   (1 << PB5)
#define RWD   (1 << PB4)
#define BREAK   0x00
#define FREE   (1 << PB4) | (1 << PB5)
#define IRTX   (1 << PB3)
#define GREEN_LED   (1 << PB0)
#define RED_LED   (1 << PD2)
#define PWM   (1 << PB1) | (1 << PB2)
#define RIGHT_DIR   (1 << PB4) | (1 << PB5)
#define LEFT_DIR   (1 << PD4) | (1 << PD5)
#define SWITCHES   (1 << PD3)
#define SWITCH_ON   PORTD |= SWITCHES
#define SWITCH_OFF   PORTD &= ~SWITCHES
#define BATTERIE   (1 << MUX0) | (1 << MUX2)
#define SWITCH   (1 << MUX2)
#define IR_LEFT   (1 << MUX0) | (1 << MUX1)
#define IR_RIGHT   (1 << MUX1)
#define FRONT_LED   (1 << PD6)
#define ODOMETRIE_LED   (1 << PD7)
#define ODOMETRIE_LED_ON   PORTD |= ODOMETRIE_LED
#define ODOMETRIE_LED_OFF   PORTD &= ~ODOMETRIE_LED
#define WHEEL_LEFT   (1 << MUX0)
#define WHEEL_RIGHT   0

Funktionen

void Init (void)
 Initialisiert die Hardware: Ports, A/D Wandler, Serielle Schnittstelle, PWM
Die Init Funktion muss von jeden Programm beim Start aufgerufen werden.
unsigned long Gettime (void)
 Gibt die aktuelle Zeit in ms zurueck.
void Msleep (int dauer)
 Wartefunktion in ms.
void Sleep (unsigned char time36kHz)
 Wartefunktion.
void EncoderInit (void)
 Den Interrupt Betrieb der Odometriesensoren-Messung initialisieren und starten.
void EncoderSet (int setl, int setr)
 Interruptbetriebene Odometriesensoren Werte vorbelegen.
void EncoderStop (void)
 Den Interrupt Betrieb der Odometriesensoren-Messung anhalten.
void EncoderStart (void)
 Den Interrupt Betrieb der Odometriesensoren-Messung starten.
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.
void UartPutc (unsigned char zeichen)
 Sendet einen einzelnen Character über die serielle Schnittstelle.
void SerPrint (unsigned char *data)
 Sendet einen null-terminierten String ueber die serielle Schnittstelle.
void PrintInt (int wert)
 Ausgabe eines Integer Wertes als String ueber die serielle Schnittstelle.
void PrintLong (long wert)
 Ausgabe eines Long Wertes als String ueber die serielle Schnittstelle.
int Batterie (void)
 Liest die Batteriespannung und gibt sie zurueck.
Es erfolgt keine Konvertierung in einen Spannungswert.
void LineData (unsigned int *data)
 Liest die Daten der beiden Linienverfolgungssensoren.
Die Linien-Beleuchtungs-LED kann sowohl an- als auch ausgeschaltet sein.
void OdometrieData (unsigned int *data)
 Liest die Daten der beiden Odometriesensoren (Radsensoren).
Diese Funktion schaltet die Odometrie-LED's immer an.
Diese Funktion schaltet die Back-LED's immer aus.
void StatusLED (unsigned char color)
 Steuert die (lustige) mehrfarbige Status-LED.
void FrontLED (unsigned char status)
 Steuert die vorne, nach unten zeigende, Front-LED.
void BackLED (unsigned char left, unsigned char right)
 Steuert die beiden hinteren Back-LED's
Wenn diese Funktion aufgerufen wird, funktioniert die Odometriemessung
nicht mehr, da die gleichen Port-Pins (Port C:Pin 0 und 1) des Prozessors
hierfuer verwendet werden.
void MotorDir (unsigned char left_dir, unsigned char right_dir)
 Steuert die Drehrichtung der Motoren.
void MotorSpeed (unsigned char left_speed, unsigned char right_speed)
 Steuert die Geschwindigkeit der Motoren.
void SetMotorPower (int8_t leftpwm, int8_t rightpwm)
 Steuert die Motorgeschwindigkeit und Drehrichtung der Motoren.
void SerWrite (unsigned char *data, unsigned char length)
 Senden von Daten ueber die serielle Schnittstelle.
void SerRead (unsigned char *data, unsigned char length, unsigned int timeout)
 Lesen von Daten ueber die serielle Schnittstelle.
unsigned char PollSwitch (void)
 Tastsensor Abfrage im 'Polling-Betrieb'.
void StartSwitch (void)
 'Interrupt-Betrieb' zur Tastsensor Abfrage einschalten.
void StopSwitch (void)
 'Interrupt-Betrieb' zur Tastsensor Abfrage anhalten.
void Sound (uint16_t freq, uint16_t duration_msec, uint8_t amplitude)
 Soundausgabe ueber die Motoren.

Variablen

const char version [5]
int switched
 Flag, dass der Interrupt SIG_INTERRUPT1 durch eine gedrueckte Taste
ausgeloesst wurde. 0 = keine Taste, 1 = Taste gedrueckt.
Kann im eigenen Programm immer abgefragt werden.
int encoder [2]
 Odometriesensor Zaehler bei Interrupt Betrieb.
encoder[0] links, encoder[1] = rechts.
volatile unsigned char count36kHz
 Counter fuer 36kHz.
volatile unsigned long timebase
 Sytemzeit in ms.
volatile int autoencode
 Steuert, ob die Odometrie-Sensor Abfrage im Interrupt Betrieb laufen soll.
volatile my_t my


Ausführliche Beschreibung

Definitionen und Funktionen der ASURO Bibliothek.

Revision
2.70
Date
07. Januar 2007
Author
Jan Grewe, Robotrixer, Waste, Stochri, Andun, m.a.r.v.i.n

Toll, so kann man sich eine Mail sparen. Hallo Peter, ich bin mir ziemlich sicher, dass du schon das weitere Vorgehen fuer die ausge- lagerten asurotypischen Parameter hast. Ich habe hier mal einen Vorschlag fuer die Kommentare der benutzten Werte. Verpackt habe ich das hier in einer Daten- struktur my_t, die so natuerlich nicht benutzt werden muss.

Version:
V001 - 10.02.2007 - m.a.r.v.i.n
+++ Neue Datenstruktur
Datenstruktur fuer die Asuro-Hardwareabhaengigen Parameter die jeder User fuer seinen Asuro in der Datei myasuro.h selber einstellen kann um die Asuro-Typischen Eigenschaften zu definieren.

Definiert in Datei asuro.h.


Makro-Dokumentation

#define BATTERIE   (1 << MUX0) | (1 << MUX2)

ADC5 A/D Wandler Port fuer Batterie Abfrage

Definiert in Zeile 399 der Datei asuro.h.

#define BREAK   0x00

Motor bremsen

Definiert in Zeile 384 der Datei asuro.h.

#define FALSE   0

Definiert in Zeile 222 der Datei asuro.h.

#define FREE   (1 << PB4) | (1 << PB5)

Motor freilaufend

Definiert in Zeile 385 der Datei asuro.h.

#define FRONT_LED   (1 << PD6)

PD6 Port fuer Front LED

Definiert in Zeile 403 der Datei asuro.h.

#define FWD   (1 << PB5)

Motor vorwaerts

Definiert in Zeile 382 der Datei asuro.h.

#define GREEN   1

Definiert in Zeile 228 der Datei asuro.h.

#define GREEN_LED   (1 << PB0)

PB0 Port fuer Gruene Status LED

Definiert in Zeile 388 der Datei asuro.h.

#define GREEN_LED_OFF   PORTB &= ~GREEN_LED

Gruene Status LED aus

Definiert in Zeile 378 der Datei asuro.h.

#define GREEN_LED_ON   PORTB |= GREEN_LED

Gruene Status LED an

Definiert in Zeile 377 der Datei asuro.h.

#define IR_LEFT   (1 << MUX0) | (1 << MUX1)

ADC3 A/D Wandler Port fuer Linienfolger Fototransistor links

Definiert in Zeile 401 der Datei asuro.h.

#define IR_RIGHT   (1 << MUX1)

ADC2 A/D Wandler Port fuer Linienfolger Fototransistor rechts

Definiert in Zeile 402 der Datei asuro.h.

#define IRTX   (1 << PB3)

PB3 Port fuer Infrarot Transmitter LED

Definiert in Zeile 387 der Datei asuro.h.

#define LEFT   0

Definiert in Zeile 233 der Datei asuro.h.

#define LEFT_DIR   (1 << PD4) | (1 << PD5)

PD4, PD5 Ports fuer Drehrichtung linker Motor

Definiert in Zeile 393 der Datei asuro.h.

#define ODOMETRIE_LED   (1 << PD7)

PD7 Port fuer Odometrie LED

Definiert in Zeile 405 der Datei asuro.h.

#define ODOMETRIE_LED_OFF   PORTD &= ~ODOMETRIE_LED

Odometrie LED aus

Definiert in Zeile 407 der Datei asuro.h.

#define ODOMETRIE_LED_ON   PORTD |= ODOMETRIE_LED

Odometrie LED an

Definiert in Zeile 406 der Datei asuro.h.

#define OFF   0

Definiert in Zeile 225 der Datei asuro.h.

#define ON   1

Definiert in Zeile 226 der Datei asuro.h.

#define PWM   (1 << PB1) | (1 << PB2)

PB1, PB2 Ports fuer Pulsweitenmodulation der Motor Geschwindigkeit

Definiert in Zeile 391 der Datei asuro.h.

#define RED   2

Definiert in Zeile 229 der Datei asuro.h.

#define RED_LED   (1 << PD2)

PD2 Port fuer Rote Status LED

Definiert in Zeile 389 der Datei asuro.h.

#define RED_LED_OFF   PORTD &= ~RED_LED

Rote Status LED aus

Definiert in Zeile 380 der Datei asuro.h.

#define RED_LED_ON   PORTD |= RED_LED

Rote Status LED an

Definiert in Zeile 379 der Datei asuro.h.

#define RIGHT   1

Definiert in Zeile 234 der Datei asuro.h.

#define RIGHT_DIR   (1 << PB4) | (1 << PB5)

PB4, PB5 Ports fuer Drehrichtung rechter Motor

Definiert in Zeile 392 der Datei asuro.h.

#define RWD   (1 << PB4)

Motor rueckwaerts

Definiert in Zeile 383 der Datei asuro.h.

#define SWITCH   (1 << MUX2)

ADC4 A/D Wandler Port fuer Tastsensor

Definiert in Zeile 400 der Datei asuro.h.

#define SWITCH_OFF   PORTD &= ~SWITCHES

Definiert in Zeile 397 der Datei asuro.h.

#define SWITCH_ON   PORTD |= SWITCHES

Definiert in Zeile 396 der Datei asuro.h.

#define SWITCHES   (1 << PD3)

Definiert in Zeile 395 der Datei asuro.h.

#define TRUE   1

Definiert in Zeile 223 der Datei asuro.h.

#define WHEEL_LEFT   (1 << MUX0)

ADC1 A/D Wandler Port fuer Odometrie Sensor links

Definiert in Zeile 409 der Datei asuro.h.

#define WHEEL_RIGHT   0

ADC0 A/D Wandler Port fuer Odometrie Sensor rechts

Definiert in Zeile 410 der Datei asuro.h.

#define YELLOW   3

Definiert in Zeile 230 der Datei asuro.h.


Dokumentation der Funktionen

void BackLED ( unsigned char  left,
unsigned char  right 
)

Steuert die beiden hinteren Back-LED's
Wenn diese Funktion aufgerufen wird, funktioniert die Odometriemessung
nicht mehr, da die gleichen Port-Pins (Port C:Pin 0 und 1) des Prozessors
hierfuer verwendet werden.

Parameter:
[in] left Schaltet die linke LED an bzw. aus. [ ON | OFF ]
[in] right Schaltet die rechte LED an bzw. aus. [ ON | OFF ]
Rückgabe:
nichts
Hinweis:
Obwohl die uebergebenen Parameter nicht geprueft werden, treten hier keine
unerwarteten Reaktionen am Port C auf.
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // Linke LED aus; Rechte LED an
  BackLED (OFF, ON);

Definiert in Zeile 155 der Datei leds.c.

00158 {
00159   if (left || right)
00160   {
00161     PORTD &= ~(1 << PD7);               // Rad-LED's OFF
00162     DDRC |= (1 << PC0) | (1 << PC1);    // Port als Output => KEINE Odometrie
00163     PORTC |= (1 << PC0) | (1 << PC1);
00164   }
00165   if (!left)
00166     PORTC &= ~(1 << PC1);
00167   if (!right)
00168     PORTC &= ~(1 << PC0);
00169 }

int Batterie ( void   ) 

Liest die Batteriespannung und gibt sie zurueck.
Es erfolgt keine Konvertierung in einen Spannungswert.

Parameter:
keine 
Rückgabe:
10-Bit-Wert der Batteriespannung (Bereich 0..1023)
Fehler:
(Sternthaler) Die globale Variable autoencode muesste auch hier
temporaer auf FALSE gesetzt werden. Wie in LineData()
Die Spannung in Volt kann mit folgende Formel berechnet werden:
Umess[V] = (Uref / 2 ^ ADC-Bitsanzahl) * Batterie ()
Ubat[V] = ((R1 + R2) * Umess) / R2
Dabei sind:
Uref = 2.56 Volt
ADC-Bitsanzahl = 10 Bit
R1 = 12000 Ohm auf der ASURO-Platine
R2 = 10000 Ohm auf der ASURO-Platine
Oder einfach:
Ubat[V] = 0,0055 * Batterie ()
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // In Variable wert den 10-Bit-Bateriespannungswert lesen
  // und bei Unterschreitung von 810 eine alles_stop-Funktion
  // aufrufen.
  int wert;
  wert = Batterie ();
  if (wert < 810)             // 810 entsprechen ca. 4,455 Volt
    alles_stop ();            // Spannung zu klein, Akkus schonen

Definiert in Zeile 80 der Datei adc.c.

00082 {
00083   ADMUX = (1 << REFS0) | (1 << REFS1) | BATTERIE; // interne 2.56V Referenz
00084                                                   // Ref. mit ext. Kapazitaet
00085   ADCSRA |= (1 << ADSC);                // Starte AD-Wandlung
00086   while (!(ADCSRA & (1 << ADIF)))       // Ende der AD-Wandlung abwarten
00087     ;
00088   ADCSRA |= (1 << ADIF);                // AD-Interupt-Flag zuruecksetzen
00089   return ADCL + (ADCH << 8);            // Ergebnis als 16-Bit-Wert
00090 }

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 FrontLED ( unsigned char  status  )  [inline]

Steuert die vorne, nach unten zeigende, Front-LED.

Parameter:
[in] status Schaltet die LED an bzw. aus. [ ON | OFF ]
Rückgabe:
nichts
Hinweis:
Diese Funktion ist als 'inline'-Funktion definiert.
Achtung:
Der uebergeben Parameter wird nicht geprueft, und kann evl. zu unerwarteten
Reaktionen fuehren, da der Port D anhand dieses Wertes manipuliert wird.
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // schalte die Front-LED an.
  FrontLED (ON);

Definiert in Zeile 120 der Datei leds.c.

00122 {
00123   PORTD = (PORTD &~(1 << PD6)) | (status << PD6);
00124 }

unsigned long Gettime ( void   ) 

Gibt die aktuelle Zeit in ms zurueck.

Da der Asuro keine Atomuhr hat, ist es die vergangene Zeit seitdem er eingeschaltet wurde.
Genauer: nachdem der Interrupt Timer2 aktiviert wurde.

Parameter:
keine 
Rückgabe:
Einschaltzeit in Millisekunden (Bereich: unsigned long 0..286331153)
Das sind ca. 79.5 Stunden. Fuer die, die ihren Asuro also ohne Solarzellen
betreiben, reicht diese Zeitangabe bevor der Accu leer ist.
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // Alle 500 ms die Front-LED umschalten.
  unsigned long zeit;
  unsigned char on_off = TRUE;

  zeit = Gettime ();
  while (1)
  {
    if (Gettime () > zeit + 500)
    {
      zeit = Gettime ();
      FrontLED (on_off);
      on_off ^= 1;
    }
  }

Definiert in Zeile 78 der Datei time.c.

00079 {
00080   return ((timebase * 256) + count36kHz) / 36;
00081 }

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 Init ( void   ) 

Initialisiert die Hardware: Ports, A/D Wandler, Serielle Schnittstelle, PWM
Die Init Funktion muss von jeden Programm beim Start aufgerufen werden.

Parameter:
keine 
Rückgabe:
nichts
Siehe auch:
Die Funktionen Sleep() und Msleep() in time.c werden mit dem hier
eingestellten 36 kHz-Takt betrieben.
Funktionsweise der Zeitfunktionen:
Msleep() ruft Sleep() auf. In Sleep() wird die globale Variable count36kHz
zur Zeitverzoegerung benutzt. Diese Variable wird jedesmal im Interrupt
SIG_OVERFLOW2 um 1 hochgezaehlt.
Der Interrupt selber wird durch den hier eingestellten Timer ausgeloesst.
Somit ist dieser Timer fuer die Zeitverzoegerung zustaendig.
Siehe auch:
Die globale Variable autoencode fuer die automatische Bearbeitung der
Odometrie-ADC-Wandler wird hier auf FALSE gesetzt.
Hinweis zur 36 kHz-Frequenz vom Timer 2
Genau diese Frequenz wird von dem Empfaengerbaustein benoetigt und kann
deshalb nicht geaendert werden.
In der urspruenglichen, vom Hersteller ausgelieferten LIB, war diese
Frequenz allerdings auf 72 kHz eingestellt. Durch eine geschickte
Umkonfigurierung durch waste konnte diese aber halbiert werden.
Sinnvoll ist dies, da der durch diesen Timer2 auch ausgeloesste Timer-
Interrupt dann nur noch die Haelfte an Rechenzeit in Anspruch nimmt.
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // Die Init()-Funktion MUSS IMMER zu Anfang aufgerufen werden.
  int main (void)
  {
    int wert;

    Init ();

    while (1)
    (
        // Dein Programm
    }
    return 0;
  }

Definiert in Zeile 107 der Datei asuro.c.

00109 {
00110   /*
00111     Timer2, zum Betrieb mit der seriellen Schnittstelle, fuer die
00112     IR-Kommunikation auf 36 kHz eingestellt.
00113   */
00114   TCCR2 = (1 << WGM20) | (1 << WGM21) | (1 << COM20) | (1 << COM21) | (1 << CS20);
00115   OCR2  = 0x91;                         // duty cycle fuer 36kHz
00116   TIMSK |= (1 << TOIE2);                // 36kHz counter
00117 
00118   /*
00119     Die serielle Schnittstelle wurde waerend der Boot-Phase schon
00120     programmiert und gestartet. Hier werden die Parameter auf 2400 1N8 gesetzt.
00121   */
00122   UCSRA = 0x00;
00123   UCSRB = 0x00;
00124   UCSRC = 0x86; // 1 Stop Bit | No Parity | 8 Data Bit
00125   UBRRL = 0xCF; // 2400bps @ 8.00MHz
00126 
00127   /*
00128     Datenrichtung der I/O-Ports festlegen. Dies ist durch die Beschaltung der
00129     Asuro-Hardware nicht aenderbar.
00130     Port B: Seriell Senden; Richtungsvorgabe Motor links; Takt fuer die
00131             Geschwindigkeit beider Motoren; Grueneanteil-Status-LED
00132     Port D: Richtungsvorgabe Motor rechts; Vordere LED;
00133             Odometrie-LED (Radsensor); Rotanteil-Status-LED
00134   */
00135   DDRB = IRTX | LEFT_DIR | PWM | GREEN_LED;
00136   DDRD = RIGHT_DIR | FRONT_LED | ODOMETRIE_LED | RED_LED;
00137 
00138   /*
00139     PWM-Kanaele OC1A und OC1B auf 8-Bit einstellen.
00140     Sie werden fuer die Geschwindigkeitsvorgaben der Motoren benutzt.
00141   */
00142   TCCR1A = (1 << WGM10) | (1 << COM1A1) | (1 << COM1B1);
00143   TCCR1B = (1 << CS11);                 // tmr1-Timer mit MCU-Takt/8 betreiben.
00144 
00145   /*
00146     Einstellungen des A/D-Wandlers auf MCU-Takt/64
00147   */
00148   ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1);
00149 
00150   /*
00151     Sonstige Vorbereitungen.
00152     - Alle LED's ausschalten
00153     - Motoren stoppen und schon mal auf Vorwaerts einstellen.
00154     - Globale Variable autoencoder ausschalten.
00155   */
00156   ODOMETRIE_LED_OFF;
00157   FrontLED (OFF);
00158   BackLED (ON, ON);
00159   BackLED (OFF, OFF);
00160   StatusLED (GREEN);
00161 
00162   MotorDir (FWD, FWD);
00163   MotorSpeed (0, 0);
00164 
00165   autoencode = FALSE;
00166 
00167   /*
00168     Funktion zum ALLGEMEINEN ZULASSEN von Interrupts.
00169   */
00170   sei ();
00171 }

void LineData ( unsigned int *  data  ) 

Liest die Daten der beiden Linienverfolgungssensoren.
Die Linien-Beleuchtungs-LED kann sowohl an- als auch ausgeschaltet sein.

Parameter:
[out] data Zeiger auf die gelesenen Daten:
data[0] linker Sensor (Bereich 0..1023)
data[1] rechter Sensor (Bereich 0..1023)
Rückgabe:
nichts
Siehe auch:
Die globale Variable autoencode wird temporaer auf FALSE gesetzt und am Ende
der Funktion mit dem alten Wert restauriert.
Hinweis:
Die Linien-Beleuchtungs-LED kann vorher mit der Funktion FrontLED()
im aufrufenden Programmteil an- bzw. ausgeschaltet werden.
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  unsigned int data [2];
  FrontLED (ON);
  LineData (data);
  if (data [0] > 100)         // 0 ist der linke Sensor ...
    tu_diese ();              // linker Sensor > 100
  if (data [1] < 50)          // ... 1 ist der rechte Sensor
    tu_das ();                // rechter Sensor < 50

Definiert in Zeile 128 der Datei adc.c.

00130 {
00131   int   ec_bak = autoencode;            // Sichert aktuellen Zustand
00132 
00133   /*
00134      Autoencode-Betrieb vom ADC-Wandler unterbinden.
00135   */
00136   autoencode = FALSE;
00137 
00138   /*
00139      Linken Linien-Sensor lesen
00140   */
00141   ADMUX = (1 << REFS0) | IR_LEFT;       // Referenz mit externer Kapazitaet
00142   Sleep (10);
00143   ADCSRA |= (1 << ADSC);                // Starte AD-Wandlung
00144   while (!(ADCSRA & (1 << ADIF)))       // Ende der AD-Wandlung abwarten
00145     ;
00146   ADCSRA |= (1 << ADIF);                // AD-Interupt-Flag zuruecksetzen
00147   data [0] = ADCL + (ADCH << 8);        // Ergebnis als 16-Bit-Wert
00148 
00149   /*
00150      Rechten Linien-Sensor lesen
00151   */
00152   ADMUX = (1 << REFS0) | IR_RIGHT;      // Referenz mit externer Kapazitaet
00153   Sleep (10);
00154   ADCSRA |= (1 << ADSC);                // Starte AD-Wandlung
00155   while (!(ADCSRA & (1 << ADIF)))       // Ende der AD-Wandlung abwarten
00156     ;
00157   ADCSRA |= (1 << ADIF);                // AD-Interupt-Flag zuruecksetzen
00158   data [1] = ADCL + (ADCH << 8);        // Ergebnis als 16-Bit-Wert
00159 
00160   /*
00161      Autoencode-Betrieb vom ADC-Wandler wiederherstellen.
00162   */
00163   autoencode = ec_bak;
00164 }

void MotorDir ( unsigned char  left_dir,
unsigned char  right_dir 
) [inline]

Steuert die Drehrichtung der Motoren.

Parameter:
[in] left_dir Richtung des linken Motors [ FWD | RWD | BREAK | FREE ]
[in] right_dir Richtung des rechten Motors [ FWD | RWD | BREAK | FREE ]
Rückgabe:
nichts
Hinweis:
Diese Funktion ist als 'inline'-Funktion definiert.
Arbeitsweise:
Ueber die Parameter werden die Port-Pin's zu den H-Bruecken beider Motoren so
gesetzt, dass die jeweils 4 beteiligten Transitoren einer Bruecke den Strom
durch die Motoren entweder
  • FWD vorwaerts durchleiten
  • RWD rueckwaerts durchleiten
  • BREAK den Motor kurzschliessen (Bremswirkung)
  • FREE oder von der Stromversorgung trennen (Motor laeuft aus)
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // Setze die Richtung fuer den rechten Motor auf Rueckwaerts
  // und blockiert den linken Motor.
  MotorDir (BREAK, RWD);

Definiert in Zeile 127 der Datei motor.c.

00130 {
00131   PORTD = (PORTD &~ ((1 << PD4) | (1 << PD5))) | left_dir;
00132   PORTB = (PORTB &~ ((1 << PB4) | (1 << PB5))) | right_dir;
00133 }

void MotorSpeed ( unsigned char  left_speed,
unsigned char  right_speed 
) [inline]

Steuert die Geschwindigkeit der Motoren.

Parameter:
[in] left_speed Geschwindigkeit linker Motor (Bereich 0..255)
[in] right_speed Geschwindigkeit rechter Motor (Bereich 0..255)
Rückgabe:
nichts
Siehe auch:
Die Initialisierung der PWM-Funktionalitaet erfolgt in der Funktion Init().
Hinweis:
Diese Funktion ist als 'inline'-Funktion definiert.
Arbeitsweise:
Ueber die Parameter werden die beiden Kanaele der PWM-Funktionalitaet im
Prozessor angesteuert. Diese Art der Geschwindigkeitsreglung beruht darauf,
dass ein digitaler Output-Pin in schneller Folge an- und ausgeschaltet wird.
Mit dem Parameter wird nun gesteuert wie lange der Strom im Verhaeltniss
zur Zykluszeit angeschaltet ist.
Wird z.B. ein Wert von 150 fuer einen Parameter uebergeben, dann wird fuer
150 / 255-tel der Zykluszeit der Port auf 1 geschaltet und somit ist die
Motorleistung entsprechend reduziert.
Daraus ergibt sich auch dass der Asuro noch nicht bei einem Wert von
20 fahren wird, da diese Leistung nicht ausreicht ihn 'anzuschieben'.
(PWM = Pulsweitenmodulation)
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // Setzt die Geschwindigkeit fuer den linken Motor
  // auf 150 und stoppt den rechten Motor.
  MotorSpeed (150, 0);

Definiert in Zeile 84 der Datei motor.c.

00087 {
00088   OCR1A = left_speed;
00089   OCR1B = right_speed;
00090 }

void Msleep ( int  dauer  ) 

Wartefunktion in ms.

Diese Funktion nutzt die Sleep()-Funktion um mit dem uebergeben Parameter
Pausen in ms-Einheiten zu erhalten.

Parameter:
[in] dauer Wartezeit in Millisekunden.
Rückgabe:
nichts
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // 1.5 Sekunde warten
  Msleep (1500);

Definiert in Zeile 143 der Datei time.c.

00145 {
00146   int z;
00147   for (z = 0; z < dauer; z++)
00148     Sleep (36);
00149 }

void OdometrieData ( unsigned int *  data  ) 

Liest die Daten der beiden Odometriesensoren (Radsensoren).
Diese Funktion schaltet die Odometrie-LED's immer an.
Diese Funktion schaltet die Back-LED's immer aus.

Parameter:
[out] data Zeiger auf die gelesenen Daten:
data[0] linker Sensor,
data[1] rechter Sensor. (Bereich 0..1023)
Rückgabe:
nichts
Fehler:
(Sternthaler) Die globale Variable autoencode muesste auch hier
temporaer auf FALSE gesetzt werden. Wie in LineData()
Hinweis:
Die Odometrie-Beleuchtungs-LED's muessen zur Messung der Odometrie-
sensoren wegen der Hardware im ASURO immer eingeschaltet sein.
Die Hardware ist so ausgelegt, dass dadurch allerdings die hinteren
Back-LED's ausgeschaltet werden.
Da die Odometrie-Beleuchtungs-LED's in dieser Funktion EIN-geschaltet
werden, funktionieren dann die Back-LED's nicht mehr. Sie koennen im
Programm nach dieser Funktion mit BackLED() bei Bedarf wieder
eingeschaltet werden.
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  unsigned int data [2];
  OdometrieData (data);
  if (data [0] > data [1])    // 0 linker Sensor; 1 ist rechter Sensor
    fahre_links ();           // Ein bisschen nach links fahren
  if (data [0] < data [1])
    fahre_rechts ();          // Ein bisschen nach rechts fahren
  BackLED (ON, OFF);          // linke Back-LED mal wieder anschalten

Definiert in Zeile 208 der Datei adc.c.

00210 {
00211   /*
00212      Vorbereitung zum lesen der Odometrie-Sensoren.
00213   */
00214   DDRC &= ~((1 << PC0) | (1 << PC1));   // Port auf Input=>Back-LEDs gehen aus
00215   ODOMETRIE_LED_ON;                     // Odometrie-LED's einschalten
00216 
00217   /*
00218      Linken Odometrie-Sensor lesen
00219   */
00220   ADMUX = (1 << REFS0) | WHEEL_LEFT;    // Referenz mit externer Kapazitaet
00221   ADCSRA |= (1 << ADSC);                // Starte AD-Wandlung
00222   while (!(ADCSRA & (1 << ADIF)))       // Ende der AD-Wandlung abwarten
00223     ;
00224   ADCSRA |= (1 << ADIF);                // AD-Interupt-Flag zuruecksetzen
00225   data [0] = ADCL + (ADCH << 8);        // Ergebnis als 16-Bit-Wert
00226 
00227   /*
00228      Rechten Odometrie-Sensor lesen
00229   */
00230   ADMUX = (1 << REFS0) | WHEEL_RIGHT;   // Referenz mit externer Kapazitaet
00231   ADCSRA |= (1 << ADSC);                // Starte AD-Wandlung
00232   while (!(ADCSRA & (1 << ADIF)))       // Ende der AD-Wandlung abwarten
00233     ;
00234   ADCSRA |= (1 << ADIF);                // AD-Interupt-Flag zuruecksetzen
00235   data [1] = ADCL + (ADCH << 8);        // Ergebnis als 16-Bit-Wert
00236 }

unsigned char PollSwitch ( void   ) 

Tastsensor Abfrage im 'Polling-Betrieb'.

Parameter:
keine 
Rückgabe:
Tastenwert bitorientiert, K1 = Bit5, K2 = Bit4, K3 = Bit3, K4 = Bit2, K5 = Bit1, K6 = Bit0
Siehe auch:
Die globale Variable autoencode wird temporaer auf FALSE gesetzt und am Ende
der Funktion mit dem alten Wert restauriert.
Hinweis:
In dieser Funktion sind 2 Sleep() Aufrufe vorhanden. Sie werden benoetigt
damit der Kondensator an der AD-Wandlereinheit genuegend Zeit hat geladen
zu werden.
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  uint8_t t1, t2;
  unsigned char text [16];

  while (1)
  {
    t1 = PollSwitch ();
    t2 = PollSwitch ();
    // 2x PollSwitch aufrufen und beide Rueckgabewerte auf Gleichheit ueberpruefen
    if (t1 && t2 && t1 == t2)           // irgendeine Taste gedrueckt 
    {
      itoa (t1, text, 10);              // Tastenwert senden 
      SerPrint (text);
      SerPrint ("\r\n");                // Zeilenvorschub 
    }
    Msleep (500);                       // 0,5 sek warten
  }

Definiert in Zeile 77 der Datei switches.c.

00078 {
00079   unsigned int i;
00080   int ec_bak = autoencode;              // Sichert aktuellen Zustand
00081 
00082   /*
00083      Autoencode-Betrieb vom ADC-Wandler unterbinden.
00084   */
00085   autoencode = FALSE;
00086 
00087   DDRD |= SWITCHES;                     // Port-Bit SWITCHES als Output
00088   SWITCH_ON;                            // Port-Bit auf HIGH zur Messung
00089   ADMUX = (1 << REFS0) | SWITCH;        // AVCC reference with external capacitor
00090   Sleep (10);
00091 
00092   ADCSRA |= (1 << ADSC);                // Starte AD-Wandlung
00093   while (!(ADCSRA & (1 << ADIF)))       // Ende der AD-Wandlung abwarten
00094     ;
00095   ADCSRA |= (1 << ADIF);                // AD-Interupt-Flag zuruecksetzen
00096 
00097   i = ADCL + (ADCH << 8);               // Ergebnis als 16-Bit-Wert
00098 
00099   SWITCH_OFF;                           // Port-Bit auf LOW
00100   Sleep (5);
00101 
00102   /*
00103      Autoencode-Betrieb vom ADC-Wandler wiederherstellen.
00104   */
00105   autoencode = ec_bak;
00106 
00107   /*
00108     Die Original Umrechenfunktion von Jan Grewe - DLR wurder ersetzt durch
00109     eine Rechnung ohne FLOAT-Berechnungen.
00110   return  ((unsigned char) ((( 1024.0/(float)i - 1.0)) * 61.0 + 0.5));
00111 
00112     Wert 61L evtl. anpasssen, falls fuer K1 falsche Werte zurueckgegebn werden.
00113   */
00114   return ((10240000L / (long)i - 10000L) * 61L + 5000L) / 10000;
00115 }

void PrintInt ( int  wert  ) 

Ausgabe eines Integer Wertes als String ueber die serielle Schnittstelle.

Parameter:
[in] wert Auszugebender Integer Wert (16Bit)
Autor:
Robotrixer, marvin
Version:
beta - 31.03.2005 - Robotrixer
first implementation

2.60 - 28.09.2005 - m.a.r.v.i.n
strlen verwenden, anstelle fester Laenge

2.61 - 20.11.2006 - m.a.r.v.i.n
Initialisierung text String kann zu Fehler
beim Flashen mit RS232/IR Adapter fuehren
(Bug report von francesco)

2.70b- 07.01.2007 - m.a.r.v.i.n
SerPrint Funktion anstelle SerWrite verwenden

2.70rc2- 09.02.2007 - m.a.r.v.i.n
Text Laenge auf 7 erhoeht, fuer Ausgabe negativer Werte (Bug Report von HermannSW)

Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // Beispiel fuer zeilenweise Ausgabe der Encoder Werte
  EncoderInit();
  While(1)
  {
    PrintInt (encoder [0]);
    SerWrite ("   ", 3);
    PrintInt (encoder [1]);
    SerPrint ("\n\r");
    MSleep (500); //0,5sek. warten
  }

Definiert in Zeile 92 der Datei print.c.

00094 {
00095   char text [7];                        // "-12345"
00096 
00097   itoa (wert, text, 10);
00098   SerPrint (text);
00099 }

void PrintLong ( long  wert  ) 

Ausgabe eines Long Wertes als String ueber die serielle Schnittstelle.

Parameter:
[in] wert Auszugebender Long Wert (32Bit)
Autor:
HermannSW, marvin
Version:
2.70rc2 - 09.02.2007 m.a.r.v.i.n
first implementation (Idee von HermannSW)
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // Beispiel fuer Ausgabe der Batterie Werte
  long data;
  While(1)
  {
    data = Batterie ();
    PrintLong (data);
    SerPrint ("\n\r");
    MSleep (500); //0,5sek. warten
  }

Definiert in Zeile 131 der Datei print.c.

00133 {
00134   char text [12];                       // '-'1234567891'\0'
00135 
00136   ltoa (wert, text, 10);
00137   SerPrint (text);
00138 }

void SerPrint ( unsigned char *  data  ) 

Sendet einen null-terminierten String ueber die serielle Schnittstelle.

Parameter:
[in] data null-terminierter String
Autor:
stochri
Version:
sto1 - 07.01.2007 - stochri
first implementation
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // Beispiel fuer SerPrint
  SerPrint ("Hallo ASURO!\r\n");

Definiert in Zeile 200 der Datei print.c.

00202 {
00203   unsigned char i = 0;
00204 
00205   while (data [i] != 0x00)
00206     UartPutc (data [i++]);
00207 }

void SerRead ( unsigned char *  data,
unsigned char  length,
unsigned int  timeout 
)

Lesen von Daten ueber die serielle Schnittstelle.

Die empfangenen Daten werden in der als Pointer uebergeben Variable data
dem Aufrufer zur verfuegung gestellt.
Der Aufrufer bestimmt ueber den Parameter Timeout, ob diese Funktion im
'blocking'- oder im 'nonblocking'-Mode laufen soll. Im 'blocking'-Mode
bleibt diese Funktion auf alle Faelle so lange aktiv, bis die, uber den
Parameter length, geforderte Anzahl Zeichen empfamgen wurde.

Parameter:
[out] data Zeiger auf die einzulesenden Daten
[in] length Anzahl der zu lesenden Zeichen
[in] timeout 0 = blockierender Mode
Wird hier ein Wert groesser 0 uebergeben, wird nur eine gewisse Zeit
lang versucht ein weiteres Zeichen ueber die Schnittstelle zu empfangen.
Kommt in dieser Zeit kein weiteres Zeichen, wird im zurueckgegeben
Parameter date das erste Zeichen auf 'T' gesetzt und die Funktion
kehrt zum Aufrufer zurueck.
Ansonsten wird die Funktion auf alle Faelle verlassen, wenn die als
Parameter length geforderte Anzahl Zeichen empfangen werden konnten.
Rückgabe:
nichts
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // Empfangen von 5 Zeichen. Aber spaetestens nach 20 Versuchen wieder
  // im Programm weiter machen.
  char emfangene_daten [10];

  SerRead (emfangene_daten, 5, 20);
  if (emfangene_daten [0] == 'T')
    SerWrite ("Mist, timeout", 13);
  else
    SerWrite ("5 Zeichen empfangen", 19);

Definiert in Zeile 135 der Datei uart.c.

00139 {
00140   unsigned char i = 0;
00141   unsigned int  time = 0;
00142 
00143   UCSRB = 0x10;                         // Empfaenger einschalten
00144 
00145   if (timeout != 0)
00146   {
00147     /*
00148       Die Funktion wird auf alle Faelle, auch ohne empfangene Daten, wieder
00149       verlassen. --> nonblocking mode
00150     */
00151     while (i < length && time++ < timeout)
00152     {
00153       if (UCSRA & 0x80)
00154       {
00155         data [i++] = UDR;
00156         time = 0;
00157       }
00158     }
00159     if (time > timeout)
00160       data [0] = 'T';
00161   }
00162   else
00163   {
00164     /*
00165       Die Funktion wird auf alle Faelle erst nach dem Empfang von der
00166       vorgegebenen Anzahl Zeichen verlassen. blocking mode
00167     */
00168     while (i < length)
00169     {
00170       if (UCSRA & 0x80)
00171         data [i++] = UDR;
00172     }
00173   }
00174 }

void SerWrite ( unsigned char *  data,
unsigned char  length 
)

Senden von Daten ueber die serielle Schnittstelle.

Die zu senden Daten werden nicht als 0-terminierter C-String erwartet, sondern
es werden grundsaetzlich so viele Zeichen gesendet wie im 2.ten Parameter
angegeben werden.

Parameter:
[in] data Zu sendende Daten
[in] length Die Anzahl der zu sendenden Zeichen.
Rückgabe:
nichts
Siehe auch:
Die Initialisierung vom Timer 2-Interrupt erfolgt in der Funktion Init().
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // Senden eines 'wunderbaren Textes' ueber die Schnittstelle.
  SerWrite ("Hello world", 11);

Definiert in Zeile 68 der Datei uart.c.

00071 {
00072   unsigned char i = 0;
00073 
00074   UCSRB = 0x08;                         // Sender einschalten
00075   while (length > 0)                    // so lange noch Daten da sind
00076   {
00077     if (UCSRA & 0x20)
00078     {                                   // warten, bis der Sendebuffer leer ist
00079       UDR = data[i++];
00080       length --;
00081     }
00082   }
00083   while (!(UCSRA & 0x40))               // abwarten, bis das letzte Zeichen
00084     ;                                   // uebertragen wurde.        
00085 
00086   for (i = 0; i < 0xFE; i++)            // warten auf irgendwas; keiner weiss
00087     for (length = 0; length < 0xFE; length++);  // wofuer
00088 }

void SetMotorPower ( int8_t  leftpwm,
int8_t  rightpwm 
)

Steuert die Motorgeschwindigkeit und Drehrichtung der Motoren.

Parameter:
[in] leftpwm linker Motor (-rückwaerts, + vorwaerts) (Wertebereich -128...127)
[in] rightpwm rechter Motor (-rückwaerts, + vorwaerts) (Wertebereich -128...127)
Rückgabe:
nichts
Hinweis:
Da der Wertebereich dieser Funktion nur von -128 bis +127 reicht, aber die
urspruengliche Funktion MotorSpeed() einen Wertebereich bis +255 hat, werden
die hier uebergebene Parameter als Absolutwert mit 2 multipliziert weitergegeben.
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // Setzt die Geschwindigkeit fuer den linken Motor auf 60 (vorwaerts),
  // und für den rechten Motor auf -60 (rueckwaerts)
  // Asuro soll auf der Stelle drehen.
  SetMotorPower (60, -600);

Definiert in Zeile 183 der Datei motor.c.

00186 {
00187   unsigned char left, right;
00188 
00189   if (leftpwm < 0)                      // Ein negativer Wert fuehrt ...
00190   {
00191     left = RWD;                         // ... zu einer Rueckwaertsfahrt, ...
00192     leftpwm = -leftpwm;                 // aber immer positiv PWM-Wert
00193   }
00194   else
00195     left = FWD;                         // ... sonst nach vorne, ...
00196   if (leftpwm == 0)
00197     left = BREAK;                       // ... oder bei 0 zum Bremsen.
00198 
00199   if (rightpwm < 0)
00200   {
00201     right = RWD;
00202     rightpwm = -rightpwm;
00203   }
00204   else
00205     right = FWD;
00206   if (rightpwm == 0)
00207     right = BREAK;
00208 
00209   MotorDir (left, right);                 // Drehrichtung setzen
00210 
00211   /*
00212     Die Geschwindigkeitsparameter mit 2 multiplizieren, da der Absolutwert
00213     der Parameter dieser Funktion nur genau die Haelfte von der MotorSpeed()-
00214     Funktion betraegt.
00215   */
00216   MotorSpeed (leftpwm * 2, rightpwm * 2);
00217 }

void Sleep ( unsigned char  time36kHz  ) 

Wartefunktion.

Die maximale Wartezeit betraegt 7ms. Fuer laengere Wartezeiten siehe Msleep().
Diese Funktion nutzt den Timer 2-Interrupt um ein 'zeitgefuehl' zu erhalten.
Der Interrupt wird mit 36 kHz, durch die Init()-Funktion initialisiert,
aufgerufen und zaehlt dort die globale Variablen count36kHz weiter.
Diese Funktion nutzt diesen Zaehler und berechnet daraus mit dem uebergeben
Parameter den Zeitpunkt wann die Pausenzeit erreicht ist, Danach bricht sie
ab, und im Hauptprogramm ist eben eine Wartezeit eingelegt worden.

Parameter:
[in] time36kHz Wartezeit x/36kHz (sec)
Rückgabe:
nichts
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // 1 Millisekunde warten
  Sleep (36);

Definiert in Zeile 111 der Datei time.c.

00113 {
00114   unsigned char ziel = (time36kHz + count36kHz) & 0x00FF;
00115 
00116   while (count36kHz != ziel)
00117     ;
00118 }

void Sound ( uint16_t  freq,
uint16_t  duration_msec,
uint8_t  amplitude 
)

Soundausgabe ueber die Motoren.

Parameter:
[in] freq Frequenz in Hz
[in] duration_msec Laenge in Millisekunden
[in] amplitude Amplitude
Autor:
stochri
Version:
sto2 - 1.09.2006 stochri
first version
   // Laesst den Asuro einen Ton von 1kHz für eine 1/2 Sekunde mit max. Amplitude spielen
   Sound(1000, 500, 255);

Definiert in Zeile 46 der Datei sound.c.

00047 {
00048   uint16_t n,k,wait_tics;
00049   uint32_t period_usec,dauer_usec;
00050 
00051   period_usec=1000000L/freq;
00052   dauer_usec=1000*duration_msec;
00053   k=dauer_usec/period_usec;
00054 
00055 //IR Interuptfreq=36KHz
00056 //Wavefreq=18KHz
00057 
00058   wait_tics=18000/freq;
00059 
00060   MotorSpeed(amplitude,amplitude);
00061 
00062   for (n=0;n<k;n++)
00063   {
00064     MotorDir(FWD,FWD);
00065     Sleep(wait_tics);
00066     MotorDir(RWD,RWD);
00067     Sleep(wait_tics);
00068   }
00069   MotorSpeed(0,0);
00070 }

void StartSwitch ( void   ) 

'Interrupt-Betrieb' zur Tastsensor Abfrage einschalten.

Parameter:
keine 
Rückgabe:
nichts
Fehler:
(Sternthaler) Die globale Variable switched sollte schon in der Funktion
mit FALSE initialisiert werden.
Hinweis:
Ueber die globale Variable switched kann nach diesem Funktionsaufruf im
Hauptprogramm geprueft werden, ob eine Taste gedrueckt wurde und kann dann
bei Bedarf die Funktion PollSwitch() aufrufen.
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  Start_Switch ();
  while (!switched)         // wartet auf Tastendruck
    ;
  // an dieser Stelle kann mit Pollswitch geprüft werden
  // welche Taste gedrückt wurde, wenn nötig.
  switched = FALSE;         // für eine neuen Aufruf von StartSwitch()

Definiert in Zeile 150 der Datei switches.c.

00151 {
00152   SWITCH_OFF;                           // Port-Bit auf LOW
00153   DDRD &= ~SWITCHES;                    // Port-Bit SWITCHES als INPUT
00154   MCUCR &= ~((1 << ISC11) | (1 << ISC10));  // Low level erzeugt Interrupt
00155   GICR |= (1 << INT1);                  // Externen Interrupt 1 zulassen
00156 }

void StatusLED ( unsigned char  color  )  [inline]

Steuert die (lustige) mehrfarbige Status-LED.

Parameter:
[in] color Zu setzende Farbe. [ OFF | GREEN | RED | YELLOW ] Bei einem nicht definierten Wert von 'color' aendert sich nichts an der LED.
Rückgabe:
nichts
Hinweis:
Diese Funktion ist als 'inline'-Funktion definiert.
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // Schaltet die Status-LED abwechselnd auf gruen und rot. 
  while (1)
  { 
    StatusLED (GREEN);
    Msleep (500);
    StatusLED (RED);
    MSleep (500);
  }

Definiert in Zeile 68 der Datei leds.c.

00070 {
00071   if (color == OFF)
00072   {
00073     GREEN_LED_OFF;
00074     RED_LED_OFF;
00075   }
00076   if (color == GREEN)
00077   {
00078     GREEN_LED_ON;
00079     RED_LED_OFF;
00080   }
00081   if (color == YELLOW)
00082   {
00083     GREEN_LED_ON;
00084     RED_LED_ON;
00085   }
00086   if (color == RED)
00087   {
00088     GREEN_LED_OFF;
00089     RED_LED_ON;
00090   }
00091 }

void StopSwitch ( void   ) 

'Interrupt-Betrieb' zur Tastsensor Abfrage anhalten.

Parameter:
keine 
Rückgabe:
nichts
Hinweis:
Die globale Variable switched wird nicht mehr automatisch bei einem
Tastendruck gesetzt.
Beispiel:
(Nicht vorhanden)

Definiert in Zeile 179 der Datei switches.c.

00180 {
00181   GICR &= ~(1 << INT1);                 // Externen Interrupt 1 sperren
00182 }

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 }

void UartPutc ( unsigned char  zeichen  ) 

Sendet einen einzelnen Character über die serielle Schnittstelle.

Parameter:
[in] zeichen auszugebendes Zeichen
Autor:
stochri
Version:
sto1 - 07.01.2006 stochri
first implementation
Beispiel:
(Nur zur Demonstration der Parameter/Returnwerte)
  // 'wunderbaren' Text als einzelne Zeichen senden.
  UartPutc ('H');
  UartPutc ('e');
  UartPutc ('l');
  UartPutc ('l');
  UartPutc ('o');

Definiert in Zeile 166 der Datei print.c.

00168 {
00169   UCSRB  = 0x08;                        // enable transmitter
00170   UCSRA |= 0x40;                        // clear transmitter flag
00171   while (!(UCSRA & 0x20))               // wait for empty transmit buffer
00172     ;
00173   UDR = zeichen;
00174   while (!(UCSRA & 0x40))               // Wait for transmit complete flag (TXC)
00175     ;
00176 }


Variablen-Dokumentation

volatile int autoencode

Steuert, ob die Odometrie-Sensor Abfrage im Interrupt Betrieb laufen soll.

Siehe auch:
Interruptfunktion SIGNAL (SIG_ADC) in asuro.c
EncoderInit(), EncoderStart(), EncoderStop() in encoder.c

Definiert in Zeile 95 der Datei globals.c.

volatile unsigned char count36kHz

Counter fuer 36kHz.

Siehe auch:
Interruptfunktion SIGNAL (SIG_OVERFLOW2) in asuro.c
Gettime(), Sleep() in time.c

Definiert in Zeile 69 der Datei globals.c.

int encoder[2]

Odometriesensor Zaehler bei Interrupt Betrieb.
encoder[0] links, encoder[1] = rechts.

Siehe auch:
Interruptfunktion SIGNAL (SIG_ADC) in asuro.c
EncoderInit(), EncoderStop(), EncoderStart(), EncoderSet(), Go(),
Turn() in encoder.c

Definiert in Zeile 56 der Datei globals.c.

volatile my_t my

int switched

Flag, dass der Interrupt SIG_INTERRUPT1 durch eine gedrueckte Taste
ausgeloesst wurde. 0 = keine Taste, 1 = Taste gedrueckt.
Kann im eigenen Programm immer abgefragt werden.

Siehe auch:
Interruptfunktion SIGNAL (SIG_INTERRUPT1) in asuro.c
StartSwitch(), StopSwitch(), PollSwitch() in switches.c

Definiert in Zeile 41 der Datei globals.c.

volatile unsigned long timebase

Sytemzeit in ms.

Siehe auch:
Interruptfunktion SIGNAL (SIG_OVERFLOW2) in asuro.c
Gettime() in time.c

Definiert in Zeile 82 der Datei globals.c.

const char version[5]

Asuro Lib Versions String

Definiert in Zeile 193 der Datei version.c.


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