PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Rolf Simulation-Programm Problem



Hardest
10.04.2008, 21:18
Hallo :D

Ich hab meinen Asuro ROLF genannt ^^
Ich bin momentan dabei, ihn etwas leben einzuhauchen indem ich erm selbständig irgenetwas machen lasse, aber da das ganze noch in seinem anfangsstadium ist... und ich erst seit kurzem in C programmiere... ist mein Quellcode auch dementsprechend schlecht ^^

Ich möchte alles in funktionen aufteilen, die ich abrufen kann wann mir gerade lustig ist. Ich möchte auch später einen zufallsgenerator einbaun, der diese funktionen zu unterschiedlichen zeiten und zu unterschiedlichen längen ausführt. Um etwas Leben einzubringen ^^

Somit habe ich angefangen eine funktion zu schreiben die es Rolf erlaubt eine gewisse zeit auf Kollisionskurs zu gehen... nur scheinbar gibt es probleme mit der forschleife die kontrolliert, ob rolf noch rumspielen darf...

Der Wartemode (led rumblinken lassen) funktioniert noch :)

Vielleicht kann ich auch keine funktionen in funktionen einbinden, wie gesagt, kenn mich in C überhaupt nicht aus ^^

Hier ersteinmal der Code:

#include "asuro.h"

void erwarten(unsigned char male); //Rufe Wartemodus ab
void collusion(unsigned int lang); //Rufe Collusion ab

int main(void)
{
Init();
//Ab hier beginnt Rolf zu "Leben"
//Morgenmassage senden
SerPrint("\r\nMuah... muss ich aufstehen?\r\n");

//Rolf wartet erstmal ab
erwarten(1);

//Rolf startet Kollusionsfahrt
collusion(10000);

return 0;
}

//Funktionen
//Rolf wartet auf etwas
void erwarten(unsigned char male) {
unsigned int i;
for (i = 0; i <= male; i++)
{
Msleep(500);
StatusLED(GREEN);
Msleep(10);
BackLED (OFF, ON);
Msleep(500);
StatusLED(OFF);
Msleep(10);
BackLED (ON, OFF);
Msleep(500);
BackLED (OFF, ON);
Msleep(500);
BackLED (ON, OFF);
if (i == male) BackLED (OFF, OFF); //Schalte Alles ab wenn am ende
}
}

//Rolf vorwaerts
void FWARD(void)
{
FrontLED (ON); //Kuendige Anfahren an
Msleep(300);
FrontLED (OFF);
Msleep(150);
FrontLED (ON);
Msleep(300);
FrontLED (OFF);
MotorDir(FWD,RWD); //Beide Motoren vorwaerts
MotorSpeed(150,150); //Los gehts
}

//Rolf rueckwaerts
void RWARD(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(120,120); //Los gehts
}

//Rolf rueckwaerts links
void RWDL(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(120,0); //Los gehts
}

//Rolf rueckwaerts rechts
void RWDR(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(0,120); //Los gehts
}

//Rolf stoppen
void STOP(void)
{
MotorSpeed(0,0);

}

//Rolf kollusionsprogramm
void collusion(unsigned int lang)
{
unsigned char t1, t2;
unsigned long zeit;
t1 = PollSwitch();
t2 = PollSwitch();

for (zeit = Gettime(); zeit > zeit + lang;)
{

if (t1 == 0 && t2 == 0) //Keine Taste gedrueckt, Rolf feahrt vorwaerts
{
FWARD(); //Auf gehts
}
else if (t1 && t2 && t1 == t2)
{
STOP(); //Stoppen
if (t1 & 0x07) //Linke tasten beruehrt
{
RWDL(); //LinksRueckwaerts ausweichen
}
if (t1 & 0x38) //Rechte tasten beruehrt
{
RWDR(); //RechtsRueckwearts ausweichen
}
Msleep(1000); //Eine Sekunde rueckwarts fahren
}
}
}



Würde mich für Ratschläge wirklich freuen... da ich glaube auf keinen gescheiten Pfad zu kommen ^^

Mit freundlichen Güßen
Hardy

H3llGhost
10.04.2008, 21:26
Hallo,

also mir gefällt deine Funktion erwarten nicht ...
Ich würde sagen das muss ein int sein, aber da bin ich mir nicht sicher ...

Hardest
11.04.2008, 12:31
nun ja, die funktion erwarten funktioniert ja... is doch egal wie man eine variabel deklariert... solangs nurn paar zahlen sind oder? schwieriger wirds wenn buchstaben oder zahlen in einer bestimmten länge dazukommen.

Nur die collusions funktion funtkioniert nicht :(

Valen
11.04.2008, 13:14
Hallo Hardest,

Mein deutsch is leider nicht so gut. Aber ich habe nicht verstanden was das problem ist. Also was tut deiner 'Rolf' denn nicht was tun soll. Was erwartest du von ihnen wenn du siest das Rolf nicht mehr die 'Erwarten' funktion ablauft. Fährt er nun gerade aus und stoßt irgend etwas an? Was macht er? Gerne ein genaue beschreibung.

Jedenfalls muß dus mal die FWARD und RWARD funktionen anschauen:
void RWARD(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(120,120); //Los gehts
}Drehen die räder nicht gegeneinander in? Öder hast du die motoren falsch angelöted?

Hardest
11.04.2008, 13:25
Hi

Die erwarten funktion funktioniert... nur darauf soll er die void collusion(unsigned int lang) aufrufen... jedoch passiert rein gar nichts... er fährt nicht los

Richtig, scheinbar hab ich die Rädermotoren falsch angelötet ^^

EDIT:
Dein Deutsch ist gut :D

Valen
11.04.2008, 13:43
Hallo wieder,

Ich denke dat is verstehe warum deine Rolf 'hängt'. Ich muß mall erkennen das ich auch wenig oder eigentlich keine schreib-erfarung habe mit C. Doch lesen geht schön bei mir.

Deine for-schleife in die collusion funktion kan nicht weiter gehen weil die zeit nicht hochgezählt wurde.



void collusion(unsigned int lang)
{
unsigned char t1, t2;
unsigned long zeit;
t1 = PollSwitch();
t2 = PollSwitch();

for (zeit = Gettime(); zeit > zeit + lang; ETWAS VERGESSEN )
...


Sehe mall an wie die For-schleife in die Asuro manual beschrieben wird (bei mir auf seite 61; englisher version):

for (i = 0; i < n; i++)

Buggie
11.04.2008, 13:52
Hallo Hardest,
das Problem liegt in Deiner for-Schleife begraben.
Die For-Schleife wird solange ausgeführt, wir die angegebene Bedingung erfüllt ist. Deine Bedingung
zeit > zeit + lang
ist nun aber leider NIE erfüllt, da immer gilt
zeit == zeit.
Wenn Du also - wie ich vermute - die Schleife solange ausführen willst, bis die als Parameter in die Funktion übergebene Zeitspanne überschritten ist mußt zum Beispiel folgende Konstruktion verwenden:


[...]
unsigned long startzeit = Gettime();
for ( zeit = Gettime(); zeit < startzeit + lang;)
{
[...]
}

Es gibt aber - wie immer - sicherlich noch 2 Milliarden andere Lösungsmöglichkeiten. :-k
Mag sein, dass es da noch weitere Probleme gibt, aber ich hab's nur überflogen.

Gruß
Burkhard

Valen
11.04.2008, 13:55
Ich meine was Buggie schreibt

Hardest
11.04.2008, 13:59
Danke ihr beiden ^^

Werde die for-schleife dementsprechend ausbessern und abwarten was bassiert :D

Buggie
11.04.2008, 14:05
Deine for-schleife in die collusion funktion kan nicht weiter gehen weil die zeit nicht hochgezählt wurde.

Sorry, das habe ich natürlich auch übersehen. Du musst natürlich an zeit bei jedem Durchlauf einen neuen Wert zuweisen, also anstelle des Inkrements in Valens Beispiel wieder zeit = Gettime().
Insgesamt wäre hier wahrscheinlich eine while-Schleife sinnvoller. Die for-Schleife wird traditionell angewandt, wenn man eine bestimmte Anzahl Durchläufe benötigt O:)
Du möchtest aber die Schleife ausführen, solange eine Bedingung erfüllt ist.



[...]
unsigned int startzeit = Gettime();
while ( Gettime() < startzeit + lang )
{
[...]
}


In der Hoffnung, Dich nicht verwirrt zu haben noch viel Spass!

Gruß
Buggie

Hardest
11.04.2008, 15:53
Hi!

Er fährt schonmal, reagiert auch auf buttons u.s.w... aber er hält sich nicht an seine zeit... er hört also nicht auf zu fahren... versteh nicht ganz warum... hab auch entsprechende änderungen am code vorgenommen, jedoch ohne erfolg.
Teilweise fängt auch die Gelbe StatusLED zum blinken an. Kann jedoch nicht erkennen woran das liegt.

Hier noch einmal der Code


#include "asuro.h"

void erwarten(unsigned int male); //Rufe Wartemodus ab
void collusion(unsigned int lang); //Rufe Collusion ab

int main(void)
{
Init();
//Ab hier beginnt Rolf zu "Leben"
//Morgenmassage senden
SerPrint("\r\nMuah... muss ich aufstehen?\r\n");

//Rolf wartet erstmal ab
erwarten(1);

//Rolf startet Kollusionsfahrt
collusion(10000);

return 0;
}

//Funktionen
//Rolf wartet auf etwas
void erwarten(unsigned int male) {
unsigned int i;
for (i = 0; i <= male; i++)
{
Msleep(500);
StatusLED(GREEN);
Msleep(10);
BackLED (OFF, ON);
Msleep(500);
StatusLED(OFF);
Msleep(10);
BackLED (ON, OFF);
Msleep(500);
BackLED (OFF, ON);
Msleep(500);
BackLED (ON, OFF);
if (i == male) BackLED (OFF, OFF); //Schalte Alles ab wenn am ende
}
}

//Rolf vorwaerts
void FWARD(void)
{
FrontLED(ON); //Kuendige Anfahren an
Msleep(300);
FrontLED(OFF);
Msleep(150);
FrontLED(ON);
Msleep(300);
FrontLED(OFF);
MotorDir(FWD,RWD); //Beide Motoren vorwaerts
MotorSpeed(150,150); //Los gehts
}

//Rolf rueckwaerts
void RWARD(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(120,120); //Los gehts
}

//Rolf rueckwaerts links
void RWDL(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(120,0); //Los gehts
}

//Rolf rueckwaerts rechts
void RWDR(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(0,120); //Los gehts
}

//Rolf stoppen
void STOP(void)
{
MotorSpeed(0,0);
FrontLED(OFF);
}

//Rolf kollusionsprogramm
void collusion(unsigned int lang)
{
unsigned long startzeit = Gettime();
unsigned char t1;
unsigned char t2;
unsigned long zeit;
zeit = startzeit + lang;

while ( startzeit < zeit ) //Fahre so lange wie zeit gegeben ist
{
t1 = PollSwitch();
t2 = PollSwitch();

if (t1 == 0 && t2 == 0 && startzeit < zeit) //Keine Taste gedrueckt, Rolf feahrt vorwaerts
{
FWARD(); //Auf gehts
}
else if (t1 && t2 && t1 == t2)
{
STOP(); //Stoppen
if (t1 & 0x07 && startzeit < zeit) //Linke tasten beruehrt
{
RWDL(); //LinksRueckwaerts ausweichen
}
if (t1 & 0x38 && startzeit < zeit) //Rechte tasten beruehrt
{
RWDR(); //RechtsRueckwearts ausweichen
}
Msleep(1000); //Eine Sekunde rueckwarts fahren
}
else STOP();
}
STOP();
}



Hat jemand einen gut gemeinten rat für mich? ^^

Valen
11.04.2008, 16:40
Er hält nicht an seiner zeit weil er nimmer eines zweites mal die zeit abfragt und benutzt. Nur beim einstieg von deine collusion funktion (initialisierung von startzeit) tüt er das. Jedenfalls wurde 'startzeit' immer kleiner sein als 'zeit' und deshalb wurde Rolf niemals aus die while-schleife herauskommen ... denke ich.

[Edit] Wechsel mall startzeit mit Gettime() im start der while schleife. Dan söllte er mal ein bisschen rühe nehmen. ;) Aber ich verstehe nich wozu du die 'startzeit < zeit' auch ins If-stelle(n) gesteckt hat. Das ist überflussig nach meiner meinung.

hai1991
11.04.2008, 17:08
hallo hardest

ich bin mir nicht sicher, aber ich würde es mal so probieren


void collusion(unsigned int lang)
{
unsigned long startzeit = Gettime();
unsigned char t1;
unsigned char t2;
unsigned long zeit;


while (gettime() < (startzeit + lang) ) //Fahre so lange wie zeit gegeben ist
{
t1 = PollSwitch();
t2 = PollSwitch();

//Rest deines Progammes
}

Hardest
11.04.2008, 17:53
argh,... richtig, is sollte doch die for schleife nehmen...

so sollte es ja funktionieren richtig?

unsigned long startzeit= Gettime();
for (zeit = 0; zeit > startzeit + lang; startzeit = startzeit)

Valen
11.04.2008, 17:59
Nein, weil startzeit=startzeit kein inkrementierung is. Zeit wird nie großer. Wechsel das mit zeit++. Has du das ende meiner 2er bericht im diesem topic gelesen?

damaltor
11.04.2008, 18:05
wenn die gelbe status led blinkt, dann halte mal den transceiver drüber. wenn du in hyperterminal jetzt VLVLVL esen kannst, dann sind die batterien leer.

Hardest
11.04.2008, 21:00
hmmh... danke für die batterie info...

Ich dachte das ich mit startzeit = startzeit einfach die Gettime() funtkion nochmals abfrage, die nun einen neuen wert beeinhaltet... obwohl... ich muss die funktion live abfragen... da sie ja ausserhalb der for schleife nicht aktuell ist

also:
startzeit = Gettime();
for (zeit = 0; zeit > startzeit + lang; zeit = Gettime())

so sollte es funktionieren nicht?

Buggie
12.04.2008, 09:44
Hallo Hardest,



...
also:
startzeit = Gettime();
for (zeit = 0; zeit > startzeit + lang; zeit = Gettime())

so sollte es funktionieren nicht?
...

Also nochmal: Diese For-Schleife wird nie durchlaufen, weil zeit immer kleiner als startzeit + lang sein wird.
Du musst also zeit mit Gettime() initialisieren und die Bedingung auf zeit < (startzeit+lang) ändern.
Merke: Die Bedingung in einer For-Schleife ist ein Eintritts- bzw. Wiederholungskriterium, kein Abbruchkriterium.

Aber das wird schon. Es ist noch kein Meister vom Himmel gefallen.

Gruß
Buggie

Hardest
14.04.2008, 12:41
Ups :D entschuldige ... manchmal bin ich recht schwer vom begriff ^^

Habs nun einwandfrei hinbekommen... funzt supergut :D
Naja fast... manchmal geht er einfach aus ^^ aber da hab ich irgendein faktor missachtet... muss ich noch genauer darauf eingehen...

Ansonsten... vielen dank Buggie

Buggie
14.04.2008, 12:53
Naja fast... manchmal geht er einfach aus ^^ aber da hab ich irgendein faktor missachtet... muss ich noch genauer darauf eingehen...


Was genau bedeutet das? Geht er wirklich aus oder führt er nur keine erkennbaren Aktionen aus?

Gruß
Buggie

Hardest
14.04.2008, 15:28
Also es leuchtet dann rein gar nichts mehr, als wär er aus ^^ also eingentlich "keine erkennbaren Aktionen" ^^

Hardest
16.04.2008, 14:32
So...

Habs nun schon mal so hinbekommen, dass es ohne probleme funktioniert... nur teilweise hat er seinen spinnenden momente wo er einfach neustartet, oder einfach einen gedrückten button simuliert und dementsprechend reagiert. Oder manchmal blingt die Statusled gelb grün (abwechselnd) und er sendet unlesbare zeichen ^^

Teilweise aber funktioniert es wieder tadelos... müsste ein hardwarefehler sein oder? Vll mischen sich auch alte programmteile ein?

Vll ist es aber doch mein Code... wer ihn mal anguggen will :)


#include "asuro.h"

void erwarten(unsigned int male); //Rufe Wartemodus ab
void collusion(unsigned int lang); //Rufe Collusion ab

int main(void)
{
Init();
//Ab hier beginnt Rolf zu "Leben"
//Morgenmassage senden
SerPrint("\r\nMuah... muss ich aufstehen?\r\n");

//Rolf wartet erstmal ab
erwarten(1);

//Rolf startet Kollusionsfahrt
collusion(10000);

//miau
RWARD();
Msleep(1000);
STOP();
return 0;
}

//Funktionen
//Rolf wartet auf etwas
void erwarten(unsigned int male) {
unsigned int i;
for (i = 0; i <= male; i++)
{
Msleep(500);
StatusLED(GREEN);
Msleep(10);
BackLED (OFF, ON);
Msleep(500);
StatusLED(OFF);
Msleep(10);
BackLED (ON, OFF);
Msleep(500);
BackLED (OFF, ON);
Msleep(500);
BackLED (ON, OFF);
if (i == male) BackLED (OFF, OFF); //Schalte Alles ab wenn am ende
}
}

//Rolf vorwaerts
void FWARD(void)
{
FrontLED(ON); //Kuendige Anfahren an
Msleep(300);
FrontLED(OFF);
Msleep(150);
FrontLED(ON);
Msleep(300);
FrontLED(OFF);
MotorDir(FWD,RWD); //Beide Motoren vorwaerts
MotorSpeed(150,150); //Los gehts
}

//Rolf rueckwaerts
void RWARD(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(120,120); //Los gehts
}

//Rolf rueckwaerts links
void RWDL(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(120,0); //Los gehts
}

//Rolf rueckwaerts rechts
void RWDR(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(0,120); //Los gehts
}

//Rolf stoppen
void STOP(void)
{
MotorSpeed(0,0);
FrontLED(OFF);
}

//Rolf kollusionsprogramm
void collusion(unsigned int lang)
{
unsigned long zeit = 0;
unsigned long startzeit = Gettime();
unsigned char t1;
unsigned char t2;

while (zeit < (startzeit+lang)) //Fahre so lange wie zeit gegeben ist
{
zeit = Gettime();
t1 = PollSwitch();
t2 = PollSwitch();

if (t1 == 0 && t2 == 0 && zeit < (startzeit+lang)) //Keine Taste gedrueckt, Rolf feahrt vorwaerts
{
FWARD(); //Auf gehts
}
else if (t1 && t2 && t1 == t2 && zeit < (startzeit+lang))
{
STOP(); //Stoppen
if (t1 & 0x07 && zeit < (startzeit+lang)) //Linke tasten beruehrt
{
RWDL(); //LinksRueckwaerts ausweichen
SerPrint("\r\n Hab links was beruehrt, weiche aus...\r\n");
}
if (t1 & 0x38 && zeit < (startzeit+lang)) //Rechte tasten beruehrt
{
RWDR(); //RechtsRueckwearts ausweichen
SerPrint("\r\n Hab rechts was beruehrt, weiche aus...\r\n");
}
Msleep(1000); //Eine Sekunde rueckwarts fahren
}
SerPrint("\r\nWiederhohle Schleife fuer Collisionsfahrt\r\n");
PrintLong(zeit);
}
STOP();
SerPrint("\r\nVerlasse Collisionsschleife.\r\n");
}

Sternthaler
16.04.2008, 22:25
Hallo Rolf, äh meine natürlich Hardest,

erst einmal ein herzliches Willkommen im Forum.


Vll ist es aber doch mein Code... wer ihn mal anguggen will :)
anguggen hab ich getan.

Die while()-Geschichte habt ihr ja schon zusammenbekommen.
Die 'spinnerten Momente', ja da liegst du richtig, es ist dein main()-Programm, welches das Problem erzeugt. Die Hardware können wir bestimmt ausschliessen.

Das main() läuft bei dir einmal von oben nach unten durch. Startet zwischendurch deine Funktionen und endet unten bei der }.
Das ist nicht gut, da die CPU dann Langeweile bekommt und ein bisschen rumspinnt.

2 Möglichkeiten führen zu einer Besserung.

1) Dein main() wird genau ein mal durchlaufen:

int main(void)
{
Init();
//Ab hier beginnt Rolf zu "Leben"
.
.
//miau
RWARD();
Msleep(1000);
STOP();

while (1); // <<<<<------ Hier wird die CPU geparkt. KOMA-Zustand
// Wiederbeleben von Rolf nur noch mit aus- und einschalten moeglich.

return 0; // Sieht ueberfluessig aus, verhindert aber ein waring beim Compiler.
}

2) Oder Rolf wird senil und wiederholt immer alles:

int main(void)
{
Init();
//Ab hier beginnt Rolf zu "Leben"
//Morgenmassage senden
SerPrint("\r\nMuah... muss ich aufstehen?\r\n");

while (1) // <<<<---- die Schleife der Wiederholung beginnen ...
{

//Rolf wartet erstmal ab
erwarten(1);
.
.
STOP();

} // <<<<---- ... und natürlich die Schleife zumachen.

while (1); // Das ist zwar nun ueberfluessig, aber schuetzt vor
// 'spinnenden Momenten', falls die Schleife oben durch einen
// Programmfehler verlassen wird.
return 0;
}

Ob dies schon ausreicht alle von dir beschriebenen Sonderlebensfunktionen zu beheben, weiss ich nicht genau. Vor allem die Taster-Funktion hat im Rolf so ihr Eigenleben. Aber ist es nicht genau das was du mit deinem Programm erreichen wolltest? ;-) Ist es so nicht schon fertig? ;-)

Weiter viel Erfolg, vor allem Spaß und viel Geduld mit Rolf
wünscht euch Sternthaler

Hardest
19.04.2008, 11:24
Ach so ist das :D

Die Programmiersprache C liegt quasie direkt an der substanz... nicht läuft von selbst... hat vor und nachteile :D

Aber eher vorteile weil es den Programmierer nervt bis er sich beugt und intelligenz "fressen" muss ^^

Wunderbar... vielen dank... werd ich gleich mal ausprobieren hehe

damaltor
20.04.2008, 23:36
hrhr... fang mal assembler an. DAS liegt dann wirklich an der substanz... da geht überhaupt nix mehr von allein. allerdings kann man mit assembler auch die absolut kleinsten und schnellsten programme schreiben. wenn man den überblick behält.

Hardest
26.04.2008, 09:31
also kann ich assembler gleich mal vergessen ^^


Also ich habe nun Rolfs ablauf in eine unendliche schleife gepackt... und darunter auch eine die den Atmega am laufen hält, wenn er aus der ersten schleife ausbrechen sollte.

Jedoch spinnt er so genauso... hmmh.. sagen wir mal... sogar noch einwenig mehr ^^

Hier der geänderte code:


#include "asuro.h"

void erwarten(unsigned int male); //Rufe Wartemodus ab
void collusion(unsigned int lang); //Rufe Collusion ab

int main(void)
{
Init();
//Ab hier beginnt Rolf zu "Leben"
//Morgenmassage senden
SerPrint("\r\nMuah... muss ich aufstehen?\r\n");

//Rolfs ablaufchema in eine unendliche schleife setzen
while (1)
{

//Rolf wartet erstmal ab
erwarten(1);

//Rolf startet Kollusionsfahrt
collusion(10000);

//miau
RWARD();
Msleep(1000);
STOP();
}

//Rolfs durchdrehverhinderungsschleife
while (1);
return 0;
}

//Funktionen
//Rolf wartet auf etwas
void erwarten(unsigned int male) {
unsigned int i;
for (i = 0; i <= male; i++)
{
Msleep(500);
StatusLED(GREEN);
Msleep(10);
BackLED (OFF, ON);
Msleep(500);
StatusLED(OFF);
Msleep(10);
BackLED (ON, OFF);
Msleep(500);
BackLED (OFF, ON);
Msleep(500);
BackLED (ON, OFF);
if (i == male) BackLED (OFF, OFF); //Schalte Alles ab wenn am ende
}
}

//Rolf vorwaerts
void FWARD(void)
{
FrontLED(ON); //Kuendige Anfahren an
Msleep(300);
FrontLED(OFF);
Msleep(150);
FrontLED(ON);
Msleep(300);
FrontLED(OFF);
MotorDir(FWD,RWD); //Beide Motoren vorwaerts
MotorSpeed(150,150); //Los gehts
}

//Rolf rueckwaerts
void RWARD(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(120,120); //Los gehts
}

//Rolf rueckwaerts links
void RWDL(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(120,0); //Los gehts
}

//Rolf rueckwaerts rechts
void RWDR(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(0,120); //Los gehts
}

//Rolf stoppen
void STOP(void)
{
MotorSpeed(0,0);
FrontLED(OFF);
}

//Rolf kollusionsprogramm
void collusion(unsigned int lang)
{
unsigned long zeit = 0;
unsigned long startzeit = Gettime();
unsigned char t1;
unsigned char t2;

while (zeit < (startzeit+lang)) //Fahre so lange wie zeit gegeben ist
{
zeit = Gettime();
t1 = PollSwitch();
t2 = PollSwitch();

if (t1 == 0 && t2 == 0 && zeit < (startzeit+lang)) //Keine Taste gedrueckt, Rolf feahrt vorwaerts
{
FWARD(); //Auf gehts
}
else if (t1 && t2 && t1 == t2 && zeit < (startzeit+lang))
{
STOP(); //Stoppen
if (t1 & 0x07 && zeit < (startzeit+lang)) //Linke tasten beruehrt
{
RWDL(); //LinksRueckwaerts ausweichen
SerPrint("\r\n Hab links was beruehrt, weiche aus...\r\n");
}
if (t1 & 0x38 && zeit < (startzeit+lang)) //Rechte tasten beruehrt
{
RWDR(); //RechtsRueckwearts ausweichen
SerPrint("\r\n Hab rechts was beruehrt, weiche aus...\r\n");
}
Msleep(1000); //Eine Sekunde rueckwarts fahren
}
SerPrint("\r\nWiederhohle Schleife fuer Collisionsfahrt\r\n");
PrintLong(zeit);
}
STOP();
SerPrint("\r\nVerlasse Collisionsschleife.\r\n");
}



Er macht nur das was er soll wenn ich auf keinen taster drücke... warum bringen die taster alles durcheinander? Eine sehr sehr nervige angelegenheit.. grml

Gibt es noch eine möglichkeit, die rolf das machen lässt was man ihn auch vorschreibt? ;)

Valen
26.04.2008, 17:47
Hallo Hardest,

Erstmall, was mir auffällt ist das du in jeder If-schleife testet ob die zeit schön passiert ist (... && zeit < (startzeit+lang)... ). Das is nicht nötig weil das schön beim eintrit die while-schleife sicher ist. Dieser test wird immer die selbe antwort geben im selben durchlauf. Fur deine asuro ist das nur sinlose arbeit. Und persönlich wurde ich die zeit = Gettime(); am ende die while-schleife platzen, sondern nützt die while-schleife (testen fur einer neue eintrit) eine veralterte zeit. Das werde dein program nicht besser laufen lassen (ich meine dein taster problem auflösen) sondern wurde es etwas netter machen.

Deine taster-testen problem liegt vielleicht an t1 & 0x38. 38=32+4+2. Also ich bin nicht ganz sicher welcher bestimmte taster das sind aber ich denke taster 6, 3 und 2. Das sind taster an die linker (6?) und rechter seite (3,2?). Versuche mall mit 0x46 (=32+16+8, oder taster 6, 5 und 4 wenn ich ´s recht habe). 0x07 stimmt wenn es taster 1,2 und 3 meinen söllte. Wenn 's nicht (besser) geht wechsel dieser zahlen mal fur die linke und rechter fahrt.

Valen
30.04.2008, 00:20
Hmm, ich habe mir geirrt. 0x38 ist ein hexadecimal nummer, nicht decimal. Also 0x38=3*16+8=32+16+8, und so stimmt mit taster 4,5,6. Vergesse mein 0x46.

Hardest
01.05.2008, 10:10
#include "asuro.h"

void erwarten(unsigned int male); //Rufe Wartemodus ab
void collusion(unsigned int lang); //Rufe Collusion ab

int main(void)
{
Init();
//Ab hier beginnt Rolf zu "Leben"
//Morgenmassage senden
SerPrint("\r\nMuah... muss ich aufstehen?\r\n");

//Rolfs ablaufchema in eine unendliche schleife setzen
while (1)
{

//Rolf wartet erstmal ab
erwarten(1);

//Rolf startet Kollusionsfahrt
collusion(10000);

//miau
RWARD();
Msleep(1000);
STOP();
}

//Rolfs durchdrehverhinderungsschleife
while (1);
return 0;
}

//Funktionen
//Rolf wartet auf etwas
void erwarten(unsigned int male) {
unsigned int i;
for (i = 0; i <= male; i++)
{
Msleep(500);
StatusLED(GREEN);
Msleep(10);
BackLED (OFF, ON);
Msleep(500);
StatusLED(OFF);
Msleep(10);
BackLED (ON, OFF);
Msleep(500);
BackLED (OFF, ON);
Msleep(500);
BackLED (ON, OFF);
if (i == male) BackLED (OFF, OFF); //Schalte Alles ab wenn am ende
}
}

//Rolf vorwaerts
void FWARD(void)
{
FrontLED(ON); //Kuendige Anfahren an
Msleep(300);
FrontLED(OFF);
Msleep(150);
FrontLED(ON);
Msleep(300);
FrontLED(OFF);
MotorDir(FWD,RWD); //Beide Motoren vorwaerts
MotorSpeed(150,150); //Los gehts
}

//Rolf rueckwaerts
void RWARD(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(120,120); //Los gehts
}

//Rolf rueckwaerts links
void RWDL(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(120,0); //Los gehts
}

//Rolf rueckwaerts rechts
void RWDR(void)
{
MotorDir(RWD,FWD); //Beide Motoren rueckwearts
MotorSpeed(0,120); //Los gehts
}

//Rolf stoppen
void STOP(void)
{
MotorSpeed(0,0);
FrontLED(OFF);
}

//Rolf kollusionsprogramm
void collusion(unsigned int lang)
{
unsigned long zeit = 0;
unsigned long startzeit = Gettime();
unsigned char t1;
unsigned char t2;

while (zeit < (startzeit+lang)) //Fahre so lange wie zeit gegeben ist
{
t1 = PollSwitch();
t2 = PollSwitch();

if (t1 == 0 && t2 == 0) //Keine Taste gedrueckt, Rolf feahrt vorwaerts
{
FWARD(); //Auf gehts
}
else if (t1 && t2 && t1 == t2)
{
STOP(); //Stoppen
if (t1 & 0x07) //Linke tasten beruehrt
{
RWDL(); //LinksRueckwaerts ausweichen
SerPrint("\r\n Hab links was beruehrt, weiche aus...\r\n");
}
if (t1 & 0x38) //Rechte tasten beruehrt
{
RWDR(); //RechtsRueckwearts ausweichen
SerPrint("\r\n Hab rechts was beruehrt, weiche aus...\r\n");
}
Msleep(1000); //Eine Sekunde rueckwarts fahren
}
zeit = Gettime();

SerPrint("\r\nWiederhohle Schleife fuer Collisionsfahrt\r\n");
PrintLong(zeit);
}
STOP();
SerPrint("\r\nVerlasse Collisionsschleife.\r\n");
}



So ich habe die änderungen vorgenommen... teilweise funktioniert es... nur teilweise spinnt er wieder völlig, schaltet sich manchmal sogar ab, oder startet einfach von neu. Ich hab wirklich keine ahnung ^^ warum er so ein eigenleben entwickelt ^^ ist ja auch irgendwie beabsichtigt, nur irgendwie kontrollierter ^^

Valen
01.05.2008, 11:06
...
So ich habe die änderungen vorgenommen... teilweise funktioniert es... nur teilweise spinnt er wieder völlig, schaltet sich manchmal sogar ab, oder startet einfach von neu. Ich hab wirklich keine ahnung ^^ warum er so ein eigenleben entwickelt ^^ ist ja auch irgendwie beabsichtigt, nur irgendwie kontrollierter ^^Wie bist du sicher das er abschaltet und von neu startet? Kanst du die output von serielen schnittstellen auf ihren rechner sehen? Sagt er "Muah... muss ich aufstehen?" mit einiger regelmäß? Dann denke ik mall an eine hardware-reset das passiert, oder ähnliches. Weil er das nur einmall ausgeben sollte am start. Ich denke zu viel spannungsabfall durch bremsenden motoren oder etwas. Dein programm seht ganz gut aus.

Vieleicht kannst du versuchen mehr 'debug-messages' in dein programm einzufügen und uber serielen schittstelle ubertragen. Dan kannst du besser sehen wenn und was er eigentlich tut, und wenn er etwas nicht söllte. Also wie "Ich gehe nach links" oder "t1 ist: xx, und t2 ist: xx".

Sternthaler
01.05.2008, 15:07
Hey Hardest,
Valen schreibt ja schon, dass dein Programm gut aussieht.
Es funktioniert auch gut.

Fahre für 10 Sekunden ohne Hindernis, dann 1 Sec zurück. --> OK

Fahre, und wenn Hindernis rechts/links auftaucht, weiche rückwärts links/rechts aus. --> OK

Wenn ein Hindernis erkannt wurde, die Rückwärtsfahrt gerade beendet ist, und dann auch noch die 10 Sekunden abgelaufen ist, dann sieht es sehr Merkwürdig aus, da nach dem rückwärtigen Ausweichen mit Drehung ja noch ein Stück gerade rückwärts gefahren wird. --> Aber das ist auch OK


Du solltest die beiden Strippen an deinem rechten Motor mal tauschen, dann muss nicht jeder in deinem Programm das RWD und FWD auf einen korrekten Motoranschluss anpassen. ;-)

Valen hat den Spannungsabfall angesprochen.
Wichtig ist der Jumper neben dem Ein-/Ausschalter in Kombination mit der Stromversorgung.
Akku -> Jumper gesteckt
Batterie -> Jumper weglassen

Beide Fälle sind nur so sinnvoll.

Akkus bringen nur 4 * 1,2V = 4,8V. Der Jumper überbrückt eine Diode, so dass die 4,8 V als Betriebspannung da sind. --> Saft reicht gerade noch.

Batterien haben 4 * 1,5V = 6,0V. Ohne Jumper ist nun die Diode noch in Reihe mit der Stromversorgung und reduziert nun die 6,0V um 0,7V auf 5,3V. --> CPU bleibt heile.

Hier nochmal eine von mir 'aufgeräumte' Version von deinem Programm:
#include "asuro.h"

/*----------------------------------------------------------------------------
Funktionsdeclarationen
----------------------------------------------------------------------------*/
void erwarten (
unsigned int male);
void FWARD (
void);
void RWARD (
void);
void RWDL (
void);
void RWDR (
void);
void STOP (
void);
void collision (
unsigned int lang);

/*----------------------------------------------------------------------------
Hauptprogramm
----------------------------------------------------------------------------*/
int main (
void)
{
Init ();

/*
Ab hier beginnt Rolf zu "Leben"
Morgenmassage senden
*/
SerPrint ("\r\nMuah... muss ich aufstehen?\r\n");

/*
Rolfs Ablaufchema in eine unendliche Schleife setzen.
*/
while (1)
{
/*
Rolf wartet erstmal ab.
*/
erwarten (1);

/*
Rolf startet Kollisionsfahrt.
*/
collision (10000);

/*
miau
*/
RWARD ();
Msleep (1000);
STOP ();
}

/*
Rolfs Durchdrehverhinderungsschleife
*/
while (1);
return 0;
}

/*----------------------------------------------------------------------------
Funktion erwarten()
Rolf wartet auf etwas
----------------------------------------------------------------------------*/
void erwarten (
unsigned int male)
{
unsigned int i;

for (i = 0; i <= male; i++)
{
Msleep (500);
StatusLED (GREEN);
Msleep (10);
BackLED (OFF, ON);
Msleep (500);
StatusLED (OFF);
Msleep (10);
BackLED (ON, OFF);
Msleep (500);
BackLED (OFF, ON);
Msleep (500);
BackLED (ON, OFF);
}
StatusLED (OFF);
BackLED (OFF, OFF); // Schalte alles ab
}

/*----------------------------------------------------------------------------
Funktion FWARD()
Rolf vorwaerts
----------------------------------------------------------------------------*/
void FWARD (
void)
{
FrontLED (ON); // Kuendige Anfahren an
Msleep (300);
FrontLED (OFF);
Msleep (150);
FrontLED (ON);
Msleep (300);
FrontLED (OFF);
MotorDir (FWD, FWD); // Beide Motoren vorwaerts
MotorSpeed (150, 150); // Los gehts
}

/*----------------------------------------------------------------------------
Funktion RWARD()
Rolf rueckwaerts
----------------------------------------------------------------------------*/
void RWARD (
void)
{
MotorDir (RWD, RWD); // Beide Motoren rueckwearts
MotorSpeed (120, 120); // Los gehts
}

/*----------------------------------------------------------------------------
Funktion RWDL()
Rolf rueckwaerts links
----------------------------------------------------------------------------*/
void RWDL (
void)
{
MotorDir (RWD, RWD); // Beide Motoren rueckwearts
MotorSpeed (120, 0); // Los gehts
}

/*----------------------------------------------------------------------------
Funktion RWDR()
Rolf rueckwaerts rechts
----------------------------------------------------------------------------*/
void RWDR (
void)
{
MotorDir (RWD, RWD); // Beide Motoren rueckwearts
MotorSpeed (0, 120); // Los gehts
}

/*----------------------------------------------------------------------------
Funktion STOP()
Rolf stoppen
----------------------------------------------------------------------------*/
void STOP (
void)
{
MotorSpeed (0, 0); // Feierabend
FrontLED (OFF); // Nix Licht
}


/*----------------------------------------------------------------------------
Funktion collision()
Rolf Kollisionsprogramm
----------------------------------------------------------------------------*/
void collision (
unsigned int lang)
{
unsigned long zeit = 0;
unsigned long startzeit = Gettime ();
unsigned char t1;
unsigned char t2;

while (zeit < (startzeit + lang)) // Fahre so lange wie zeit gegeben ist
{
t1 = PollSwitch ();
t2 = PollSwitch ();

/*
Nur dann die Tasten auswerten, wenn beide Abfragen identische Werte
geliefert haben. Sonst gehen wir von Schrottdaten aus.
*/
if (t1 == t2)
{
if (t1 == 0) // Keine Taste gedrueckt, vorwaerts
{
FWARD (); // Auf gehts (dauert 750 ms)
}
else
{
STOP (); // Stoppen
if (t1 & 0x07) // Linke tasten beruehrt
{
RWDL (); // LinksRueckwaerts ausweichen
SerPrint ("\r\n Hab links was beruehrt, weiche aus...\r\n");
}
if (t1 & 0x38) // Rechte tasten beruehrt
{
RWDR (); // RechtsRueckwearts ausweichen
SerPrint ("\r\n Hab rechts was beruehrt, weiche aus...\r\n");
}
Msleep (1000); // Eine Sekunde rueckwarts fahren
}
}
zeit = Gettime ();

SerPrint ("\r\nWiederhole Schleife fuer Collisionsfahrt\r\n"); // 44*5ms= 200 ms
PrintLong (zeit);
}
STOP ();
SerPrint ("\r\nVerlasse Collisionsschleife.\r\n");
}Leider musst du nun RWD und FWD wieder tauschen. Oder besser löten.

Gruß Sternthaler