Archiv verlassen und diese Seite im Standarddesign anzeigen : Sonnenverfolger
Hallo,
ich habe jetzt mein erstes "sinvolles" Programm geschrieben, und zwar mitdem sich der Robby (auf einer Stelle drehend) immer zur Sonne bzw. zu einer Lichtquelle hin ausrichtet. Das Problem ist, wenn ich das Programm starte, dann dreht sich der Roboter sehr schnell auf der Stelle und gibt dann eine Fehlermeldung aus -> ich weiß das das was "mit task_motionControl()" zu tun hat, aber ich kann den Fehler einfach nicht finden. Ich hoffe ihr könnt mir helfen!
#include "RP6RobotBaseLib.h"
int main (void)
{
initRobotBase();
writeString("Ich beginne in 3sec. mit dem Test der Lichtsensoren!\n");
powerON; //Motorsysteme einschalten
mSleep(3000); //3sec. warten
startStopwatch1(); //Timer 1 starten
while (true)
{
uint16_t Licht_L = adcLSL; //linker Lichtsensor
uint16_t Licht_R = adcLSR; //rechter Lichtsensor
int16_t Diff = Licht_L - Licht_R; //Differenz berechnen
if (getStopwatch1() > 300) //Timer auslesen
{
writeString("Licht Links:"); //Lichtstärke links ausgeben
writeInteger(Licht_L, DEC);
writeString(" Licht Rechts:");//Lichtsensor rechts ausgeben
writeInteger(Licht_R, DEC);
writeString(" Differenz:"); //Lichtdifferenz ausgeben
writeInteger(Diff, DEC);
writeString("\n"); //neue Zeile
if (Licht_L > Licht_R) //wenn Licht Licht links stärker ist als rechts...
{
setLEDs(0b110000); //die linke LED-Reihe einschalten
rotate(20, RIGHT, 1, true);//nach rechts drehen
}
else if (Licht_L < Licht_R) //wenn Licht Licht rechts stärker ist als links...
{
setLEDs(0b000110); //die rechte LED-Reihe einschalten
rotate(20, LEFT, 1, true); //nach links drehen
}
else if (Licht_L = Licht_R) //wenn Licht auf beiden Sensoren gleich ist...
{
setLEDs(0b001001); //die grünen LEDs einschalten
}
setStopwatch1(0); //Timer stoppen
}
task_ADC(); //ADC Funktion aufrufen
task_motionControl(); //Motor Funktion aufrufen
}
}
Für Fragen steh ich immer zur Verfügung!
Danke im Voraus!!!
blenderkid
26.08.2008, 14:02
wie lautet denn der Fehler? Dann wär's einfacher den Fehler zu finden. :-)
Hallo,
natürlich, hier ist der Fehler, ich hab gedacht ihr kennt den Fehlercode, aber egal, hier ist er:
Terminal cleared!
Ich beginne in 3sec. mit dem Test der Lichtsensoren!
Licht Links:912 Licht Rechts:891 Differenz:21
##### EMERGENCY SHUTDOWN #####
##### ALL OPERATIONS STOPPED TO PREVENT ANY DAMAGE! #####
### ENCODER (OR MOTOR) MALFUNCTION! ###
Affected channel:LEFT!
(s. task_motorControl() function in RP6Lib!)
You need to check Encoder/Motor assembly (or your software).
The Robot needs to be resetted now.
[RP6BOOT]
[READY]
Hoffentlich könnt ihr mir helfen, danke!
radbruch
26.08.2008, 15:40
Hallo
Die RP6 haben gelegentlich Probleme mit den Motortreibern bzw. den Encodern. Als Einstieg kannst du mal nach "EMERGENCY AND SHUTDOWN" (ohne "") suchen und dich dann weiterhangeln...
Oder du suchst im RP6-Bereich nach Motor-/Encoderproblemen:
https://www.roboternetz.de/phpBB2/viewforum.php?f=49
Die Lösung des Problems ist meist eine Neujustage der Encoder, sehr selten ein Umtausch.
Gruß
mic
Hallo,
danke für die Antwort, weil der Selftest und die Beispielprogramme alle ordentlich funktionieren. Ich hab gedacht, da gibts einen ganz offensichtlichen Fehler im Programm?
Grüße
Oh, ich habe mich da wohl etwas unglücklich ausgedürckt?
Ich meine das es noch nicht funktioniert und hoffe das es ein Fehler im Programm ist.
Grüße
radbruch
26.08.2008, 18:11
Die Meldung kommt von ganz unten aus dem Motion-Control. Das kannst du mit einem "normalen" Programm nicht provozieren.
powerON;
Der Compiler sollte hier folgendes ausgeben:
RP6Base_Move_01.c:84: warning: statement with no effect
Und genau da liegt das Problem ;)
Das ist zwar ein Makro, aber richtig aufrufen muss Du das dennoch.
MfG,
SlyD
Endschuldigung, ich verstehe nicht?...
powerON; ---> powerON();
Du musst auch immer drauf achten, was der Compiler so an Warnungen ausgibt.
Die stehen immer etwas weiter oben in der Ausgabe - verhindern aber NICHT das erfolgreiche Compilieren des Programms.
powerOn(); schaltet die Drehgeber, Stromsensoren und die Power LED an. Ist eigentlich nur zum Energiesparen gedacht wenn diese nicht gebraucht werden.
MfG,
SlyD
Vieeeeeelen Dank es funktionirt nun!
Für alle die das Programm auch mal verwenden wollen, aufpassen:
ich hab die beiden rotier Anweisungen vertauscht! -> der Roboter dreht sich in die falsche Richtung!
Grüße
proevofreak
20.10.2008, 22:03
hallo, hab gerade ein ähnliches programm programmiert. bei mir sucht der roboter selbstständig in die hellste richtung. jetzt frag ich mich allerdings, warum die int_16t im programm nur die werte von -100 bis +100 annehmen kann, obwohl es ja ein 16 bit datentyp ist, der eigentlich von -32768 ... +32767 gehen sollte. ich hab es jetzt mal mit -200 und +200 ausprobiert, aber dann tut sich irgendwie gar nichts mehr. wer hat eine ahnung an was das liegt bzw. ich dieses problem lösen kann?
hier mein programm:
#include "RP6RobotBaseLib.h"
#define BATRANGE 500
#define RANGE 950
void task_LDRinfo(void)
{writeString_P("LDR_L: ");
writeIntegerLength(adcLSL,DEC,4);
writeChar('\n');
writeString_P("LDR_R: ");
writeIntegerLength(adcLSR,DEC,4);
writeChar('\n');
int16_t dif = ((int16_t)(adcLSL - adcLSR));
if(dif > 100) dif = 100;
if(dif < 100) dif = -100;
if(dif==100)
{setLEDs(0b000001);
moveAtSpeed(20,50);}
else if(dif==-100)
{setLEDs(0b000010);
moveAtSpeed(50,20);}
else{setLEDs(0b000000);
moveAtSpeed(0,0);}
}
void bumpersStateChanged(void)
{if(bumper_left)
{move(60,BWD,DIST_MM(150),true);
rotate(50,RIGHT,90,true);
changeDirection(FWD);
}
if(bumper_right)
{move(60,BWD,DIST_MM(150),true);
rotate(50,LEFT,90,true);
changeDirection(FWD);}
}
int main(void)
{initRobotBase();
powerON();
BUMPERS_setStateChangedHandler(bumpersStateChanged );
while(true)
{task_LDRinfo();
task_RP6System();
task_ADC();
}
return 0;
}
mfg
if(dif > 100) dif = 100; /* Obergrenze 100*/
if(dif < 100) dif = -100; /* Untergrenze -100*/
/* Wertebereich nun -100 ... 100 !!*/
if(dif==100) /* genau gleich 100 ?*/
...
else if(dif== -100) /* genau gleich -100?*/
...
else
/*tue nichts*/
Was macht das Programm bei z.B. 95, oder -43, oder ...?
Es ist doch seeehhhr unwahrscheinlich das die Werte genau erreicht werden. Ueberpruefe Deine Abfragen nochmal und sei nicht ganz so strikt mit den Forderungen.
Edit: ich sehe gerade, das Du ja nur die zwei Werte erreichen kannst. Ich sehs mir nochmal genauer an...
Edit2: RP6 dreht also immer entweder rechts oder links und findet nie eine Ruheposition...
if(dif < -100) dif = -100; /*so waers wohl besser*/
hth
Kay
proevofreak
21.10.2008, 16:46
hallo, verstehe jetzt leider nicht was du mir mit deinem post sagen willst.
meiner meinung nach ist dein verbesserungsvorschlag doch genau das, wie ich es programmiert habe.
mit +100 und -100 funktioniert das programm ja.
aber wenn ich diese werte mal mit +200 bzw. -200 ersetze geht nichts mehr.
mfg
if(dif > 100) dif = 100;
if(dif < 100 ) dif = -100;
Steht oben - da fehlt das Minus in der zweiten Abfrage.
Bei sowas rate ich immer: ALLE Zwischenergebnisse in einzelne Schritte aufdröseln und alles mit writeInteger ausgeben lassen! So lässt sich schnell feststellen wo es hakt.
MfG,
SlyD
proevofreak
21.10.2008, 17:31
macht es dann einen unterschied ob ich in meinem programm if(dif==100){} oder if(dif=100) {} schreibe?
mfg
Das macht einen gewaltigen Unterschied!
"==" ist eine Abfrage auf Gleichheit (kann wahr oder falsch sein)
"=" ist eine Zuweisung (veraendert Deine Variable!)
Das Problem war/ist nur das fehlende "-" in Deiner zweiten Abfrage.
proevofreak
21.10.2008, 17:56
ok, ja stimmt hab ich vorher übersehen. du hast natürlich recht gehabt.
danke nochmal
proevofreak
21.10.2008, 19:52
so, jetzt ist mein programm fertig. funktioniert einwandfrei. der rp6 findet nun jede lichtquelle zuverlässig.
#include "RP6RobotBaseLib.h"
#define BATRANGE 500
#define RANGE 1005
void task_LDRinfo(void)
{writeString_P("LDR_L: ");
writeIntegerLength(adcLSL,DEC,4);
writeString_P(" ; LDR_R: ");
writeIntegerLength(adcLSR,DEC,4);
writeChar('\n');
int16_t dif = ((int16_t)(adcLSL - adcLSR));
if(dif > 50) dif = 50;
if(dif < -50) dif = -50;
if(dif==50 && adcLSL<1005 & adcLSR<1005)
{setLEDs(0b000001);
moveAtSpeed(20,50);}
else if(dif==-50 && adcLSL<1005 & adcLSR<1005)
{setLEDs(0b000010);
moveAtSpeed(50,20);}
else if(adcLSL>1005 || adcLSR>1005)
{moveAtSpeed(0,0);
setLEDs(0b111111);
writeString_P("Lichtquelle gefunden");}
else{setLEDs(0b000000);
moveAtSpeed(50,50);}
}
void bumpersStateChanged(void)
{if(bumper_left)
{move(60,BWD,DIST_MM(150),true);
rotate(50,RIGHT,90,true);
changeDirection(FWD);
}
if(bumper_right)
{move(60,BWD,DIST_MM(150),true);
rotate(50,LEFT,90,true);
changeDirection(FWD);}
}
int main(void)
{initRobotBase();
powerON();
BUMPERS_setStateChangedHandler(bumpersStateChanged );
while(true)
{task_LDRinfo();
task_RP6System();
task_ADC();
}
return 0;
}
die werte sind auf einen schwach beleuchteten raum ausgelegt, nur für den fall, dass es jemand ausprobieren will.
mfg
carlitoco
21.10.2008, 20:29
mein Edit zu Drivers ursprünglicher Variante
else if ((Licht_L + 1 <= Licht_R) && (Licht_L - 1 >= Licht_R)) //wenn Licht auf beiden Sensoren gleich ist...
gruss
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.