PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Probleme mit meinen Programmen



Terran
10.11.2011, 21:03
Hi leute,

hab meine Asuro jezt scho ein jahr lag jezt die meiste zeit aber im schrank rum. Mittlerweile hab ich ihn wieder ausgepackt und wollt wieder los programmieren nur hab ich des problem dass er sich ständig aufhängt d.H. schon bei einfachen programmen (fahr stoß gegen wand und bleib stehn mit fehlerausgabe). In dem Fall fährt er los leuchtet grün bringt die fehlerausgabe crash und reagiert nimmer auf die knöpfe vorne er fährt einfach konstant weiter :P hab zum test mal den selftest wieder drauf gespielt da hat er von 3 versuchen sich direkt nachm motortest aufgehängt. Woran könnte des liegen?

#include "asuro.h"

int main(void)
{
Init();
int i;
int j;
StatusLED(RED);
SerWrite("Programm wird gestartet",30);
for (i=0; i<1000; i++)
{
Sleep(216);
}
SerWrite("GOO!!",10);
BackLED(ON,ON);
MotorDir(FWD,FWD);
MotorSpeed(255,230);
StatusLED(GREEN);


while (PollSwitch()==1)
{
MotorSpeed(0,0);
SerWrite("Shit happens",30);
StatusLED(RED);
Sleep(216);
StatusLED(YELLOW);

}


}

markusj
10.11.2011, 23:23
Der Code tut auch nicht was du willst.
Zuerst wartest du, dann gibst du Gas, und dann gehst du direkt NICHT in die Schleife, weil du prüfst PollSwitch()==1, das dürfte Anfangs nicht so sein, damit wird die Schleife übersprungen und dein ASURO fährt einfach weiter (weil das Programm fertig ausgeführt ist und damit einfach das fortsetzt was er zuletzt getan hat).

mfG
Markus

Terran
11.11.2011, 15:00
Hey danke für deine Antwort. kla des While hätt wohl mitm if getauscht gehört. Aber woran könnte des liegen, dass der sich einfach so mal erhängt? z.B. die Ausgabe bei dem Programm sieht wie folgt aus: Programm wird gestartet GOO!! dann die 3 Sekunden Pause durch den Sleep inner schleife danach GOO!! Shit ha (nein hab nich verplant auszuschreiben des schneidet jedes mal da ab)

außerdem noch ne allgemeine frage. Man kann sich ja diverse programme zum testen so herunterladen wenn ich des mache und mitm makefile zu ner .hex machen möchte schmeists mir immer Fehler. Woran liegt des? brauch ich da ein anderes oder modifiziertes makefile? Danke ;)

radbruch
11.11.2011, 15:44
Hallo


Aber woran könnte des liegen, dass der sich einfach so mal erhängt?Möglicherweise daran, dass du die Anzahl der Zeichen für SerWrite() falsch angegeben hast:


#include "asuro.h"

int main(void)
{
int i;

Init(); // nach Init() ist die StatusLED grün
// StatusLED(RED);
SerWrite("Programm wird gestartet\n\r", 25); // richtige Anzahl der Zeichen ist wichtig!
for (i=0; i<1000; i++)
{
Sleep(216);
}
SerWrite("GOO!!\n\r", 7); // \n\r bedeutet Neue Zeile und Wagenrücklauf
BackLED(ON,ON);
MotorDir(FWD,FWD);
MotorSpeed(255,230);
StatusLED(YELLOW); // Anzeige "Fahren"

while(1)
{
if(PollSwitch() > 0)
{
MotorSpeed(0,0);
SerWrite("Shit happens\n\r", 14);
StatusLED(RED); // Anzeige "
while(1); // endlos warten (oder Programmende)
}
}
return(0); // ohne meckert der Kompiler
}

Gruß

mic

Terran
11.11.2011, 17:23
danke hab jezt mal deinen programmvorschlag probiert (des unten mit while(1) und if pollswitch() > 0 hatte ich auch ma probiert jezt hab ich ma dei programm 1zu1 drauf gespielt jezt stimmt zwar die komplette text ausgabe nu geht er aber her startet des prog gibt für 1sek gas und bricht dann ab mit Shit happens

des is genau des was ich mit aufhängen meinte woran könnt des denn liegen?

radbruch
11.11.2011, 17:48
Die Tasterauswertung "lügt" gelegentlich:


#include "asuro.h"

int main(void)
{
int i;
char taste1, taste2;

Init(); // nach Init() ist die StatusLED grün
// StatusLED(RED);
SerWrite("Programm wird gestartet\n\r", 25); // richtige Anzahl der Zeichen ist wichtig!
for (i=0; i<1000; i++)
{
Sleep(216);
}
SerWrite("GOO!!\n\r", 7); // \n\r bedeutet Neue Zeile und Wagenrücklauf
BackLED(ON,ON);
MotorDir(FWD,FWD);
MotorSpeed(255,230);
StatusLED(YELLOW); // Anzeige "Fahren"
taste2=PollSwitch(); // ersten Vergleichswert einlesen

while(1)
{
taste1=PollSwitch(); // zweiten Wert einlesen
if((taste1 == taste2) && (taste1 > 0))
{
MotorSpeed(0,0);
MotorDir(BREAK, BREAK);
SerWrite("Shit happens\n\r", 14);
StatusLED(RED); // Anzeige "Stoppen"
while(1); // endlos warten (oder Programmende)
}
taste2=taste1; // letzten Wert merken für nächsten Vergleich
Sleep(255);
}
return(0); // ohne meckert der Kompiler
}

Meine Programmbeispiele für den asuro sind meist ungetestet, weil mein asuro eingemottet ist...

Terran
11.11.2011, 19:22
cool des funktioniert jezt heißt da war einfach die programmierung so daneben dass er sich erhangen hat ... zu dem programm paar fragen was macht des return(0) und wenn ich nach dem stoppen iwas weiter führen möchte muss ich des while(1) löschen und dann nach dem Sleep(255) zum beispiel weiter machen? der while(1) is immer ende vom programm?

radbruch
11.11.2011, 20:29
Na wunderbar. :)

Ich fang mal hinten beim return() an: Programme in C sind eigentlich für Rechner mit Betriebssystem gedacht und bilden für diese Betriebssysteme eine weitere Funktion. Das Betriebssystem ruft das Programm auf und übergibt dabei gegebenenfalls auch ein paar Parameter und das Programm übergibt beim Beenden irgendwelche Rückgabewerte an das Betriebssystem zurück, z.b. eventuelle Fehlercodes. Um das Programm zu starten ruft das Betriebssystem die Funktion main() als Unterprogramm auf und legt die Rücksprungadresse auf den Stapel. Wenn die Funktion main() beendet werden soll, wird die Funktion return() aufgerufen und der Rückgabewert an das Betriebssystem weitergegeben. Dieses holt die Rücksprungadresse vom Stapel und setzt dort seine Arbeit fort. (Alles stark vereinfacht)

Beim Microkontroller existiert aber kein übergeordnetes Betriebssystem, der Anfang der Funktion main() wird einfach direkt nach dem Einschalten angesprungen. Deshalb gibt es auch keine Parameter die beim Start mitgeteilt werden können und auch niemand der sich für den Rückgabewert interessiert. Da auch GCC ein echtes C ist sieht der korrekte Aufbau von main() immer so aus:

int main(void) // Rückgabewert ist(muss!) ein Integer (int) sein und kein Parameter wird übergeben (void)
{
// Funktionskörper

return(0); // weil C für eine Funktion den Rückgabewert verlangt motzt auch GCC beim Kompilieren ein Fehlen des Returns an.
}

Was passiert, wenn die Funktion main() beendet wird? Das weiß eigentlich niemand genau, denn es geschieht unkontrollierbares. Mit Return holt sich der Kontroller irgendwas vom Stapel und interpretiert dies als die Adresse des nächsten Befehls. Ohne Return macht der Kontroller hinter der }-Klammer weiter, egal was da im Speicher steht. Beidesmal ist es reiner Zufall welchen Inhalt die Speicherstellen besitzen die jetzt abgearbeitet werden und welche Maschinenbefehle hinter den einzelnen Bitmustern stecken. Von "Der Kontroller macht endlos weiter" über "Ausgangspins werden verändert und können Hardware beschädigen" bis hin "zum Überschreiben der Watchdogeinstellungen" ist eigentlich alles möglich (, aber zum Glück nicht gleich wahrscheinlich).

Deshalb darf weder das return() noch die letzte }-Klammer je erreicht werden. Wer sicher ist, dass er immer eine Endlosschleife programmiert, der kann das return() auch weglassen (und die Kompilierwarnung ignorieren). Ängstliche (so wie ich auch) machen im Zweifel immer ein while(1); vor dem return(). Ächz, Ende return().

Zu while(1): Beim Abarbeiten des Programm wird meist eine einmalige Initialisierung von Hardware und Daten ausgeführt und dann der Rest als Schleife endlos wiederholt. Diese Endlosschleife kann zwar immer wieder unterschiedlich verzweigen, wird aber nie verlassen (von goto und break mal abgesehen). Ob das nun als while(1), while(1==1), while(true) oder gar als for(;;) umgesetzt wird ist egal.

Zu Sleep(255): Die endlose Schleife sah erst etwa so aus:

while(1)
{

if(PollSwitch()==1)
{
}

}

Ohne Tastendruck wird if() nie erfüllt und die Schleife rast unglaublich schnell vor sich hin. Lediglich PollSwitch() bremst durch die AD-Wandelzeit (und ein paar unerklärliche Sleeps) etwas. Aber eigentlich wird nach dem Wandeln sofort der nächste Wert gewandelt, das könnte eventuell zu Wandelfehlern führen. Deshalb erzwingt Sleep(255) einen kurzen Abstand zwischen den Lesungen. Zudem werden so auch deutlich weniger Werte und damit auch Fehler gelesen.

Zu Weiterfahren: Wenn anstelle des Stops ein Zurückfahren mit Ausweichen programmiert wird, kann man das "while(1); // Programmende" entfernen.

Bei aller Begeisterung solltest du aber daran denken, dass der Resttastenhub der Taster nach dem Schaltpunkt deutlich kürzer als der Anhalteweg des asuro nach Erkennen des Tastendrucks ist. Rausgeschleuderte Mega8s sind noch die harmlosesten Folgen solcher Kollisionsschaltertests...

Gruß

mic

Terran
12.11.2011, 01:37
Danke für deine Hilfe :D im groben hatte ich bereits programmieren inner berufsschule damals nur war des java was wir hatten nich wirklich auf irgend einen nutzen bezogen eher bisschen logisch.

Nachdem ich nun weiß dass an meinem Asuro wohl kein defekt liegt und des auf meine Dummheit zurückzuführen war kann ich jezt ja mit ruhigem gewissen weiter experimentieren :D

Gruß

Terran/Freddy