Hallo
Die whiles gefallen dir wohl sehr. Wenn ich richtig verstehe, willst du messen, wie lange der asuro frei geradeaus fährt um dann, bei einer Kollision, die Dauer der Drehung abhängig von dieser Messung zu machen.
Dazu sehe ich eigentlich zwei Ansätze:
1.: Man misst die Zeit (z.B. über die Anzahl der Schleifendurchgänge oder mit Gettime(); )
2.: Man misst die Wegstrecke (und auch die Drehung) mit der Odometrie
Wobei die Zeitmessung "ungenauer" sein wird.
Zeitmessung mit Schleifenzähler: Du verwendet eine Zählvariable. Diese wird zu Beginn des Programms und jeweils nach dem Drehen auf 0 gesetzt. Bei Geradeausfahrt wird der Zähler dann hochgezählt und beim Drehen ausgewertet. Das Problem dabei ist der schnelle ATMega8, der Zähler wird rasend schnell riesige Werte annehmen. Deshalb verzögere ich den Ablauf etwas (um je eine 1/1000stel Sekunde, deshalb Geradeauszeit ungefähr gleich Drehzeit). Man könnte auch eine größere Zählvariable verwenden (int long) und später den Wert runterteilen:
Code:
#include <asuro.h>
#define taste (!(PINC & (1<<PC4)))// Tastenabfrage
#define keine_taste (PINC & (1<<PC4))
unsigned int zaehler; //Schleifenzaehler
int main(void)
{
int zeit;
Init();
zaehler=0; //Schleifenzaehler zuruecksetzen
while(1)
{
BackLED(OFF,OFF); //BackLED beide aus und
StatusLED(GREEN); //StatusLED grün also alles Okay
MotorDir(FWD,FWD);//Also kann man auch schön gradeaus fahren
MotorSpeed(200,220);
Sleep(36); // Ablauf etwas verzoegern, weil ATMega8 so schnell ist
if (zaehler < 5000) zaehler++; //Schleifenzaehler hochzaehlen mit Begrenzung!
if(taste)
{
BackLED(ON,ON);//BackLED beide an und
StatusLED(RED);//StatusLED ROT also Kollision
MotorDir(RWD,RWD);//also erst ein Stück zurück
MotorSpeed(200,220);
for(zeit=0;zeit<500;zeit++)//(0,5 Sekunde zurück)
{
Sleep(36);
}
StatusLED(YELLOW);//StatusLED orange
BackLED(ON,ON);//BachLED ROT also Besserung in Sicht
MotorDir(RWD,FWD);//Drehung
MotorSpeed(200,220);
for(zeit=0;zeit<zaehler;zeit++) //abhaengig von gerader Fahrt drehen
{
Sleep(36);
}
zaehler=0; //Ende der Drehung, Schleifenzaehler zuruecksetzen
}
}
while(1);
return 0;
}
Die Drehung kann man dann noch z.B. mit
for(zeit=0;zeit<(zaehler/2);zeit++)
beeinflussen.
Mit Gettime() würde es so ähnlich funktionieren. Anstatt den Zähler zurückzusetzen müsste man sich die aktuelle Zeit merken und beim Drehen den aktuellen Zeitunterschied auswerten. Das alles ist aber sehr ungenau und hat auch eigentlich keinen Sinn. Außer eben, dass man übt.
Ich würde dir aber raten, das über die Odometrie zu lösen. Dann bist auch erstmal beschäftigt, denn die Odometrie hat einige Tücken und ist nicht einfach zu beherrschen. Zusätzlich zur optimierten Mechanik (axiales Spiel der Codescheiben, Abdeckung der Sensoren) must du auch die Min-/Maxwerte kennen(mit PrintInt(); zum Terminal schicken) um eine vernünftige Funktion programmieren zu können. Es gibt noch viel zu tun und zu entdecken.
Aus dem Datenblatt kann man gut die Beispielcodes verwenden, z.B. das Schreiben und Lesen des EEProms. Ich mische aber im Moment auch die Libary mit einigen direkten Portzugriffen (z.B. Tastenabfrage). Die Libary ist eben bequem, weil man sich um nichts kümmern muss und schnell zu einem Ergebniss kommt. Je nach Interesse kann man sich eben mehr Richtung KI oder Richtung Hardware orientieren.
Bitte verstehe das jetzt nicht falsch. Ich habe nicht die Zeit und auch keine Lust dich bei jedem Schritt zu unterstützen. Du hast jetzt den Einstieg geschafft, alles weitere kommt von alleine, es braucht eben etwas Zeit und Mühe. Vieles wurde hier schon besprochen und erklärt. Da solltest du einfach mal etwas im Forum stöbern. Wenn's dann mal wirklich wieder klemmt, helfe ich dir natürlich weiter, wenn ich kann. Auch meine Möglichkeiten und Kenntnisse sind begrenzt. Aber es gibt ja auch noch andere asuro-Besitzer die sich gut auskennen und dir helfen können.
Gruß
mic
Lesezeichen