Hallo
Hier mein Versuch das Problem der Wegspeicherung und Wiederholung über die Zeit zu lösen, die zwischen den gesendeten Kommandos vergeht.
Code:
#include "asuro.h"
#define wegteile 50
#define pow1 150 // Langsame Geschwindigkeit
#define pow2 200 // Schnelle Geschwindigkeit
#define taste (!(PINC & (1<<PC4))) // Tastenabfrage
#define keine_taste (PINC & (1<<PC4))
unsigned int count, temp; // Zaehler, IR-Kommando
unsigned char daten[14], ir_status; // IR-datenspeicher, IR-Eingangsegel
unsigned int wegspeicher[wegteile], wegabschnitt, wegkommando;
unsigned long int startzeit;
void fahre(unsigned char kommando) {
/* asuro steuern.
Mit dem 10er-Block der Fernbedienung kann der asuro nun gesteuert werden:
Alle anderen Tasten stoppen den asuro
*/
switch (kommando) {
case 1: MotorDir(FWD,FWD); MotorSpeed(pow1,pow2); break;
case 2: MotorDir(FWD,FWD); MotorSpeed(pow2,pow2); break;
case 3: MotorDir(FWD,FWD); MotorSpeed(pow2,pow1); break;
case 4: MotorDir(BREAK,FWD); MotorSpeed(0,pow1); break;
case 5: MotorDir(BREAK,BREAK); MotorSpeed(0,0); break;
case 6: MotorDir(FWD,BREAK); MotorSpeed(pow1,0); break;
case 7: MotorDir(RWD,BREAK); MotorSpeed(pow1,0); break;
case 8: MotorDir(RWD,RWD); MotorSpeed(pow1,pow1); break;
case 9: MotorDir(BREAK,RWD); MotorSpeed(0,pow1); break;
default: MotorDir(BREAK,BREAK); MotorSpeed(0,0); break;
}
}
int main(void) {
Init();
for (count=0;count<wegteile; count++) wegspeicher[count]=0;
wegabschnitt=0;
wegkommando=0;
startzeit=0;
do{
temp=0;
while (PIND & (1 << PD0)) //warten auf die Flanke des Startbits
StatusLED(RED); // Alarmstufe ROT: ein Zeichen ist im Anflug
for (count=0; count<14; count++) { // im Gesammten warten wir auf 14 bits
Sleep(48); // Information einlesen nach 3/4 der Bitlaenge
ir_status=(PIND & (1 << PD0)); // Pegel Speichern
if (ir_status) daten[count]='1'; else daten[count]='0'; // und merken
if (ir_status) temp |= (1 << (13-count)); // das MSB(=mostsuefikantbit) zuerst
while (ir_status == (PIND & (1 << PD0))); // Bit gelesen, warten auf naechste Flanke
}
temp=temp/2 & 0xf; // Die Info steht in den Bits 1-4
StatusLED(YELLOW); // Daten gelesen
//Msleep(2000); // Zeit um der IR-Transceifer ueber den asuro zu bringen
//SerWrite("\n\r",2);
//SerWrite(daten,14); // Bitmuster zum PC senden
//SerWrite("-",1);
//PrintInt(temp); // erkannte Daten zum PC senden
//fahre(temp);
if ((temp > 0) && (temp <= 9)) fahre(temp);
if (temp == 0){
count=0;
BackLED(ON,ON);
Msleep(1000);
while (wegspeicher[count]) {
fahre(wegspeicher[count] & 0xf);
Msleep(wegspeicher[count]/16);
count++;
}
BackLED(OFF,OFF);
}
if (temp == 12) {
BackLED(ON,ON);
for (count=0;count<wegteile; count++) wegspeicher[count]=0;
wegabschnitt=0;
wegkommando=0;
startzeit=0;
Msleep(300);
BackLED(OFF,OFF);
}
if (wegkommando) {
startzeit=Gettime()-startzeit;
while (startzeit > 2000) {
wegspeicher[wegabschnitt]=2000*16+wegkommando;
wegabschnitt++;
startzeit-=2000;
}
wegspeicher[wegabschnitt]=startzeit*16+wegkommando;
wegabschnitt++;
wegkommando=0;
}
if ((temp > 0) && (temp <= 9)) {
startzeit=Gettime();
wegkommando=temp;
}
StatusLED(GREEN); //endlos
//Msleep(1000);
}while (1);
return 0;
}
Die Zeit wird mit Gettime() in Millisekunden gemessen und in den oberen 12 Bits zusammen mit dem Kommandocode in den unteren 4 Bits in einem Integer-Feld gespeichert. So können Zeiten bis ca. 2000 Millisekunden (2^11=204 plus das Kommando in zwei Bytes gespeichert werden.
Nach dem Einschalten und dem Senden eines ersten Startzeichens beginnt die Aufzeichnung. Mit "0" wird das bisher Aufgezeichnete wiederholt, mit "12" (ist bei mir die Teletexttaste) wird die Aufzeichnung gelöscht und der asuro kann was neues aufnehmen.
Achtung! Die Aufzeichnung endet nie! Das muss ich noch ändern um zu verhinderen, dass ein Speicherüberlauf auftritt. Ein kleines Video werde ich noch nachreichen.
Bild hier
Mit der Odometrie geht das sicher genauer, wenn auch deutlich aufwendiger. Aber auch meine Lösung macht Spass und verblüfft die Zuschauer.
Gruß
mic
Lesezeichen