Da gab es gerade einen Thread darüber: http://www.roboternetz.de/phpBB2/vie...=467705#467705
Druckbare Version
Da gab es gerade einen Thread darüber: http://www.roboternetz.de/phpBB2/vie...=467705#467705
Irgendwas mache ich immer noch falsch!
main.cCode:funktionen.c: In function ‘Beschleunige’:
funktionen.c:51: error: ‘abgebrochen’ undeclared (first use in this function)...
funktionen.c (Auszug)Code:#include "asuro.h"
extern int abgebrochen;
#include "funktionen.h"
int main(void)
{
// Initialisierung
Init();
sei();
StartSwitch();
// hier kommt der Hauptteil des Programms
StatusLED(RED);
while (1)
{
/*
** Nach einem erfolgreichen Beschleunigungsvorgang soll so lange weitergefahren
** werden, wie kein Hindernis kommt. Ansonsten wird an den Anfang der Schleife
** zurückgesprungen und wieder von 0 beschleunigt.
*/
if (Beschleunige(120, 150, 3))
{
while (abgebrochen == 0);
abgebrochen = 0;
}
}
return 0;
}
funktionen.hCode:#include "asuro.h"
int Beschleunige(int start, int end, int zeit)
{
StatusLED(GREEN);
int momentan;
int durchlaeufe = end - start;
float zeitschritt = (float) zeit / (float) durchlaeufe * 1000;
for(momentan=start; momentan<end; momentan++)
{
// wenn die Geschwindigkeit von einem Interrupt verändert wurde, wird der Vorgang unterbrochen
if (abgebrochen == 1)
{
abgebrochen = 0;
return 0;
}
Geschwindigkeit(momentan, momentan);
Warte(zeitschritt);
}
return 1;
}
Code:int Beschleunige(int, int, int);
Das extern int abgebrochen; gehört in die funktionen.h
In dem *.c in dem main ist, musst du dann noch int abgebrochen definieren.
Dein Stoppen und wieder beschleunigen sollte eher so aussehenIn deiner ISR setzt du abgebrochen auf 1.Code:if(abgebrochen)
abgebrochen =0;
Beschleunige(120, 150, 3);
}
Damit wird dein Beschleunigen nur einmal durchlaufen, oder wieder nach einer ISR.
Achso. Gut, jetzt kompiliert er schonmal durch. Nach dem ersten Hindernis will er aber nicht mehr weiterfahren, er kommt anscheinend aus der while-if-Schleife nicht mehr raus. Meine Vermutung war, dass durch Compiler-Optimierung die Schleife in ein while(1); "umgewandelt" wird, da das abgebrochen ja normalerweise währenddessen nicht verändert werden kann, also habe ich es mit int volatile abgebrochen probiert, aber das Ergebnis ist das gleiche. Ich verzweifel hier langsam ](*,)
So sieht meine main.c jetzt aus:
Code:#include "asuro.h"
#include "funktionen.h"
// Standardmäßig auf 1, da am Anfang von 0 beschleunigt werden soll
volatile int abgebrochen = 1;
int main(void)
{
// Initialisierung
Init();
sei();
StartSwitch();
// hier kommt der Hauptteil des Programms
StatusLED(RED);
while (1)
{
/*
** Bei einer Kollision soll wieder von 0 beschleunigt werden und nicht
** beim vorherigen Beschleunigungsvorgang weiter gemacht werden
*/
if (abgebrochen)
{
abgebrochen = 0;
Beschleunige(120, 150, 3);
}
}
return 0;
}
Hallo
Wenn du die Variable mit 0 initialisierst und mit dem Beschleunigen startest wird der Compiler auf keinen Fall optimieren:
Fehlt hier nicht noch ein Start_Switch())Code:...
volatile int abgebrochen = 0;
...
Beschleunige(120, 150, 3);
while (1)
{
...
GrußCode:if (abgebrochen)
{
abgebrochen = 0;
Beschleunige(120, 150, 3);
}
mic
Was machst du denn in deiner ISR, fährt er kurz zurück?
Kann man mit Beschleunigen weitermachen oder braucht man noch eine Startsequenz dazu.
@radbruch: Hab ich alles eingebaut - immer noch das gleiche Ergebnis...
In der ISR wird angehalten und dann 2s gewartet:Zitat:
Zitat von Hubert.G
Ich bau gleich mal ein bisschen Debug-Ausgabe ein (via LEDs, hehe)Code:ISR(INT1_vect)
{
abgebrochen=1;
StopSwitch();
HalteAn();
Warte(2000);
}
Habe das Programm nochmal etwas vereinfacht und mit den LEDs rausgefunden: Er kommt aus dem Interrupt gar nicht mehr raus, und zwar liegt es da an dem Warte(2000); . Im normalen Programm funktioniert die Warte funktion aber, und wenn ich das Warte in der ISR durch Sleep ersetze, bleibt er auch hängen. Wenn ich Warte bzw. Sleep da ganz rausnehme, klappt es, allerdings hält er dann bei einem Hindernis nicht mehr an bzw. fährt direkt weiter.
So sieht das ganze aus:
Die Status LED wird nicht mehr Yellow. Wenn ich das Warte rausnehme aber schon.Code:ISR(INT1_vect)
{
StatusLED(RED);
abgebrochen=1;
StopSwitch();
HalteAn();
Warte(2000);
StatusLED(YELLOW);
}
Hier noch die Warte Funktion
Code:void Warte(int msek)
{
int i;
for (i=msek; i>0; i--)
{
Sleep(85);
}
}
In der ISR sollst du auch nicht warten.
Ist warten überhaupt sinnvoll?
Wäre es nicht besser wenn er zurück fährt oder dreht?
Sonst in der ISR ein Flag für warten, eine eigene Funktion für Warten und dort dann das Flag für Beschleunigen setzen.
Das ganze war ja auch nur zu Testzwecken. Außerdem impliziert das zurückfahren ja auch wieder ein Warten, nämlich so lange wie er zurück fahren soll:Zitat:
Zitat von Hubert.G
So geht es nämlich auch nicht, er kommt aus dem "Warte" nicht mehr raus und fährt nur noch zurück.Code:void FahreZurueck(int speed, int msek)
{
MotorDir(RWD, RWD);
Geschwindigkeit(speed, speed);
Warte(msek);
MotorDir(FWD, FWD);
HalteAn();
}
ISR(INT1_vect)
{
StatusLED(RED);
abgebrochen=1;
StopSwitch();
HalteAn();
FahreZurueck(120, 1000);
StatusLED(YELLOW);
}
Das verstehe ich nicht ganz. Mit "Flag" meinst du wieder eine globale Variable, die dann in der Beschleunigen-Funktion abgefragt wird und dann wird in der Beschleunigen Funktion gewartet? Das ist doch irgendwie nicht ganz der Sinn der Sache. Ich dachte, das Behandeln der Kollision wäre Sinn der ISR?Zitat:
Zitat von Hubert.G
Sorry, das ich hier so pingelig bin, aber es muss doch möglich sein, in eine ISR ein Sleep einzubauen!
Mal so nebenbei: Könnte es sein, dass mein Problem mit der Start bzw. StopSwitch zu tun hat? Was machen diese Funktionen eigentlich, das habe ich noch nicht verstanden.
Achja, hier meine vereinfachte main.c:
Code:#include "asuro.h"
#include "funktionen.h"
volatile int abgebrochen = 0;
int main(void)
{
// Initialisierung
Init();
sei();
StartSwitch();
// hier kommt der Hauptteil des Programms
while (1)
{
StatusLED(GREEN);
Beschleunige(120, 150, 3);
}
return 0;
}