PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Asuro, bestimmte Zeit einstellen (z.b. beim Rückwärtsfahren)



Ollowain
09.10.2009, 09:19
Hallo zusammen.
Vorweg muss gesagt werden, dass ich ein absoluter Anfäger bin was programmieren angeht. Hab zwar schon einige kleinere Programme geschrieben aber jetzt steh ich vor einer größeren Herausforderung:

Wie schaffe ich es, dass mein Roboter nur z.b. eine halbe Sekunde rückwärts fährt, sich umdreht und dann vorwärts weiter fährt (Natürlich erst wenn er an einer Wand anstößt)
Vielleicht kann auch jemand mein Programm durchschaun, das zwar syntaktisch korrekt ist aber trotzdem nicht das macht was ich will =)
Speziell die Sache mit "for" erschließt sich mir nicht.


#include "asuro.h"

int main()
{
Init();
int i;
while(1)
{
if (PollSwitch()==0) /* Keine Kollision */
{
StatusLED(GREEN);
MotorDir(FWD,FWD);
MotorSpeed(155,155);
}

else if (PollSwitch()==1) /* Taster rechts-außen wird gedrückt */
{
StatusLED(RED);
MotorDir(RWD,RWD); /* Rückwärtskurve rechts*/
MotorSpeed(100,20);
for (i=0; i<250;i++)

{Sleep(216);}

MotorDir(FWD,FWD); /* Vorwärtskurve links*/
MotorSpeed(20,100);
for (i=0; i<250;i++)

{Sleep(216);}
}

else if (PollSwitch()>31) /* Taster Links-außen wird gedrückt */
{
StatusLED(YELLOW);
MotorDir(RWD,RWD); /* Rückwärtskurve links */
MotorSpeed(20,100);
for (i=0; i<250;i++)

{Sleep(216);}

MotorDir(FWD,FWD); /* Vorwärtskurve rechts */
MotorSpeed(100,20);
for (i=0; i<250;i++)

{Sleep(216);}
}

else /* Andere Taster werden gedrückt */
{
BackLED(ON,ON);
MotorDir(RWD,RWD); /* Rückwärts fahren */
MotorSpeed(100,100);
for (i=0; i<250;i++)

{Sleep(216);}

MotorDir(RWD,FWD); /* Drehung gegen UZS */
MotorSpeed(100,100);
for (i=0; i<250;i++)

{Sleep(216);}
}
}
return 0;
}

Seid nicht zu streng mit mir ;)
lg Ollowain

Valen
09.10.2009, 10:55
Vielleicht kann auch jemand mein Programm durchschaun, das zwar syntaktisch korrekt ist aber trotzdem nicht das macht was ich will =)Auf ersten sicht sieht das gut aus. Aber das problem ist das du nicht erzählst hast was er macht, nur was du wölltest er macht. Bitte gib eine genaue beschreibung wie die motoren drehen wenn du einer der taster eindruckt. Und die farbe der Statusled.

Und das ist nicht bösse gemeint. Sicherlich nicht persönlich. Viele anfanger mit problehmen machen ein thread mit versuchen fur hilfe, aber vergessen mit zu teilen was er (asuro) mit das Program macht. Leider haben wir keine Magische Glass-Kügel im Forum-suchfunktion.

Ollowain
09.10.2009, 11:43
ok, hab das programm nochmal kurz überarbeitet (i<10 auf i<250)
Das ist auf jeden fall schonmal ein fortschritt denn nun "ruckeln" die motoren nicht mehr so wie es vorher war. (i war wahrscheinlich zu klein).
Im Moment leutet die StatusLED grün. außerdem fährt er rückwärts, bleibt stehn, dreht rechts, fährt rückwärts, bleibt stehn, dreht rechts, usw... Also eine Art kreis gegen den Uhrzeigersinn allerdings rückwärts. Außerdem leuchten beide hinteren LEDs. Auf Tasterdruck reagiert er nicht.

the.speciali
09.10.2009, 13:58
Hi,
dass Problem bei dem PollSwitch ist meistens das auch mal ein paar Bytes einfach so kommen obwohl keine Taste gedrückt worden ist und deswegen er unkontrollierte Bewegungen macht. Also einfach ein Sleep reingebaut damit er warten muss^^

Habs mal überarbeit:


#include "asuro.h"

int main()
{
Init();

int i;


while(1)
{
if (PollSwitch()==0) /* Keine Kollision */
{
StatusLED(GREEN);

MotorDir(FWD,FWD);
MotorSpeed(155,155);

for (i=0; i<50;i++)
{
Sleep (72);
}
}


else if (PollSwitch()==1) /* Taster rechts-außen wird gedrückt */
{
StatusLED(RED);

MotorDir(RWD,RWD); /* Rückwärtskurve rechts*/
MotorSpeed(100,20);

for (i=0; i<1000;i++) /*1sekunde rückwärts fahren (1000mls)*/
{
Sleep(72);
}


MotorDir(FWD,FWD); /* Vorwärtskurve links*/
MotorSpeed(20,100);

for (i=0; i<500;i++)
{
Sleep(72);
}
}


else if (PollSwitch()>31) /* Taster Links-außen wird gedrückt */
{
StatusLED(YELLOW);

MotorDir(RWD,RWD); /* Rückwärtskurve links */
MotorSpeed(20,100);

for (i=0; i<1000;i++)
{
Sleep(72);
}


MotorDir(FWD,FWD); /* Vorwärtskurve rechts */
MotorSpeed(100,20);

for (i=0; i<500;i++)
{
Sleep(72);
}
}


else /* Andere Taster werden gedrückt */
{
BackLED(ON,ON);

MotorDir(RWD,RWD); /* Rückwärts fahren */
MotorSpeed(100,100);

for (i=0; i<1000;i++)
{
Sleep(72);
}


MotorDir(RWD,FWD); /* Drehung gegen UZS */
MotorSpeed(100,100);

for (i=0; i<500;i++)
{
Sleep(72);
}
}
}

return 0;
}

Die Sleeps hab ich auf 72 gestellt das entspricht einer Millisekunde, so kann man nämlich ganz leicht eine Sekunde einstellen ;) (Schleife mit 1000 durchläufen). Auch war ich mal so frech und hab es bissi übersichtlicher gestaltet ;)

beste Grüße
the.speciali

Ollowain
09.10.2009, 14:34
super danke the.speciali das hilft mir total weiter und ich hab wieder was dazu gelernt. Allerdings wird das bei weitem nich das letzte Problemchen gewesen sein aber ich weiß ja jetzt wohin ich mich wenden kann.
grüße Ollowain

Valen
09.10.2009, 15:40
Ich habe noch etwas langer daruber gedacht, und da fehlt etwas in deiner taster logik. Kein problem, binaire zahlen ist auch nicht einfach fur anfanger.


else if (PollSwitch()>31) /* Taster Links-außen wird gedrückt */

Pollswitch()>31 meinst nicht nur 'gleich 32', oder 'das muss meiner linker taster sein'. Aber auch vieleicht 'gleich 43 oder 50, 58, 63, 64, 128, 201 usw. bis 255'. Pollswitch gibt einer wert zuruck als char typ. Das könnte im prinzip werte sein von 0 bis 255 (inklussif). Asuro hat aber nur 6 taster. Dafur braucht man auch nur 6 bits in einer variabele speicherplatz. Deshalb gibt Pollswitch nur werte zwischen 0 bis 63 (inkl.) zuruck. Aber fur den werten 32 bis und inklusief 63, gibt es eine menge von 32 kombinationen mit nur eins (den ganz linker) oder jeder taster.
Also, wenn Asuro irgendwie die meist links-ausen taster eingedruckt kriecht, aber auch einer oder mehr von den andere Taster wird diesen If-stellung war sein. Du wunscht aber nur den ganz links-aussen taster. Dazu muss es "=32" sein. Weil 32 ist gleich "100000" in binaire zahlung. ">31 ist gleich wie '001xxxxx' in binair zahlung. Wo 'x' heist 'kan 1 oder 0 sein', oder 'machts nicht was es ist'.

Ich hoffe das obene macht sinn fur dich, weil es ganz wichtig ist wenn mann sich mit mircocontroller oder programieren beschaftigen möchtest. Leider habe ich viele schwierigkeiten das deutlich zu erklären auf Deutsch.

Valen
09.10.2009, 16:59
Hier ist meiner (bearbeiteten) code:


#include "asuro.h"

int main()
{
Init();

int i;

char t1,t2,tasterzustand;


while(1)
{
t1=PollSwitch();
t2=PollSwitch(); /* zwei mal tasterwert messen fur stabiele wert */
if (t1==t2) /* sind die taster eindrucken stabiel? */
{
tasterzustand=t1; /* ja ist es, tasterzustand ist erste messung */
}
else
{
tasterzustand=0; /* nee, ist es nicht, tasterzustand ist 'kein taster' */
}

if (tasterzustand==0) /* Keine Kollision: 00000000 im binaire zahlung */
{
StatusLED(GREEN);

MotorDir(FWD,FWD);
MotorSpeed(155,155);
BackLED(OFF,OFF); /* Ich gehe voraus, vieleicht sind die LEDs schon aus, aber tu es sonnst */

for (i=0; i<50;i++)
{
Sleep (72);
}
}


else if (tasterzustand==1) /* Taster rechts-außen wird gedrückt: 00000001 im binaire zahlung */
{
StatusLED(RED);

MotorDir(RWD,RWD); /* Rückwärtskurve rechts*/
MotorSpeed(100,20);
BackLED(ON, OFF); /* Meiner linken Rad dreht (schneller) rückwärts */

for (i=0; i<1000;i++) /*1sekunde rückwärts fahren (1000mls) */
{
Sleep(72);
}

MotorDir(FWD,FWD); /* Vorwärtskurve links*/
MotorSpeed(20,100);
BackLED(OFF, OFF); /* Gehe wieder vorwärts */

for (i=0; i<500;i++)
{
Sleep(72);
}
}


else if (tasterzustand=32) /* Taster Links-außen wird gedrückt: 00100000 im binaire zahlung */
/* '>31' is xx1xxxxx im binaire zahlung, und nicht nur die ganz linker taster*/
{
StatusLED(YELLOW);

MotorDir(RWD,RWD); /* Rückwärtskurve links */
MotorSpeed(20,100);
BackLED(OFF, ON); /* Meiner Rechter Rad dreht (schneller) rückwärts */



for (i=0; i<1000;i++)
{
Sleep(72);
}


MotorDir(FWD,FWD); /* Vorwärtskurve rechts */
MotorSpeed(100,20);
BackLED(OFF, OFF); /* Ich gehe wieder vorwärts*/

for (i=0; i<500;i++)
{
Sleep(72);
}
}


else /* Andere Taster werden gedrückt: 00xxxxxx im binaire zahlung */
{

MotorDir(RWD,RWD); /* Rückwärts fahren */
MotorSpeed(100,100);
BackLED(ON,ON); /* Beider Rädern drehen zurück */

for (i=0; i<1000;i++)
{
Sleep(72);
}



MotorDir(RWD,FWD); /* Drehung gegen UZS */
MotorSpeed(100,100);
BackLED(OFF,OFF); /* Ich fahre nicht mehr zurück */

for (i=0; i<500;i++)
{
Sleep(72);
}
}
}

return 0;
}

Edit von radbruch: if (t1==t2)

Ollowain
09.10.2009, 20:42
was ich mir bei der Funktion gedacht habe ist folgendes. In der Anleitung steht:

Bit0 (1) -> K6
Bit1 (2) -> K5
Bit2 (4) -> K4
Bit3 (8) -> K3
Bit4 (16) -> K2
Bit5 (32) -> K1

Wenn ich jetz die werte von K6 bis K2 zusammen zähl komm ich auf 31.
Deshalb meine überlegung -> alles was über 31 ist muss K1 sein. (selbst wenn alle anderen gleichzeitig gedrückt sind).
Bin ich soweit richtig?

Außerdem versteh ich diesen Teil noch nicht ganz, insbesondere das mit dem stabilen wert:

===============================================

char t1,t2,tasterzustand;


while(1)
{
t1=PollSwitch();
t2=PollSwitch(); /* zwei mal tasterwert messen fur stabiele wert */
if (t1==t2) /* sind die taster eindrucken stabiel? */
{
tasterzustand=t1; /* ja ist es, tasterzustand ist erste messung */
}
else
{
tasterzustand=0; /* nee, ist es nicht, tasterzustand ist 'kein taster' */
}

if (tasterzustand==0) /* Keine Kollision: 00000000 im binaire zahlung */

===============================================

radbruch
09.10.2009, 21:04
Hallo

Durch schlechte Kalibierung und Störungen durch z.B. die Motoren "lügt" PollSwitch() recht häufig. Deshalb ist es empfehlenswert die Funktion mehrfach aufzurufen und die eingelesenen Werte auf Gleichheit zu überprüfen.

In der Datei asuro.c findet man am Ende der Funktion PollSwitch() (beim return) eine Formel mit der die Tasten kalibriert werden können. Wenn diese Formel halbwegs stimmt wird nie ein Wert über 32 auftreten. Infos dazu findet man u.A. im asurowiki:

http://www.asurowiki.de/pmwiki/pmwiki.php/Main/Tasten

Gruß

mic

Ollowain
09.10.2009, 22:24
okay so langsam komm ich mit immerhin beschäftige ich mich erst seit ca. einer woche mit asuro und vom programmieren hatte ich auch nicht gerade viel ahnung.
mit kalibrieren meinst du sicherlich diese zeile?

return ((unsigned char) ((( 1024.0/(float)i - 1.0)) * 63.0 + 0.5));

woher weiß ich jetzt, was ich wie verändern muss?

Mittlerweile stoße ich auch immer öfter auf modifizierte bibliotheken (Asuro Lib). Da gibts ja dann auch wieder verschiedene... :-s
Inwiefern ist es ein "Muss" (bewusst in Anführungszeichen) diesen Schritt zu machen? Vielleicht kann mir das mal jemand in einfachen Worten erklären ;-)

Valen
10.10.2009, 03:10
Edit von radbruch: if (t1==t2) ](*,)

Valen
10.10.2009, 03:29
was ich mir bei der Funktion gedacht habe ist folgendes. In der Anleitung steht:

Bit0 (1) -> K6
Bit1 (2) -> K5
Bit2 (4) -> K4
Bit3 (8) -> K3
Bit4 (16) -> K2
Bit5 (32) -> K1

Wenn ich jetz die werte von K6 bis K2 zusammen zähl komm ich auf 31.
Deshalb meine überlegung -> alles was über 31 ist muss K1 sein. (selbst wenn alle anderen gleichzeitig gedrückt sind).
Bin ich soweit richtig?Nein, leider nicht ganz. Weil wenn K1,K2 und
K3 gleichzusammen eingedruckt sind (asuro stosst gegen ein weiches objekt an auf seiner linker seite) ist das gleich an 8+16+32=56. Das ist auch grosser als 31, aber nicht nur K1. Oder zb. K1 mit K6 als störungsignal (K6 ist nicht wirklich eingedrukt aber der analog-digital converter ADC hat ein wenig falsch gemessen wegen den motorrausch) ist das auch grosser als 31: 32+1=33.

Ollowain
10.10.2009, 11:19
okay jetz hab ichs verstanden. Wie läuft das mit der kalibrierung der Taster?

Valen
10.10.2009, 14:15
Diesen thread habe ich gefunden durch suchen auf 'kalibrieren' im asuro abteilung:

https://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=29263&highlight=kalibrieren

Im dritten bericht steht ein beispiel wie mann das machen kan beim orginalem lib. Die erweiterte lib had einer andere funktion fur PollSwitch, und speichert den kalibrier wert in einer bestimmte datei ("myasuro.h" wenn ich mich nicht irre) Den orginale lib ist gut genug fur anfanger mit Asuro. Den erweiterten lib ist keinen 'muss' wie du sagst. Aber es ist was besser documentiert, und hat einiger fehler im code aufgelost. Den code erweiterungen machen die code aber etwas schwieriger zu verstehen. Weil die code uber mehrere dateien verteilt ist. Ich wurde das nur emphelen wenn du die orginal lib c-code richtig lesen unt verstehen kannst.

mayokleckz
15.10.2009, 14:14
So, ich hab mich heut endlich mal ran gemacht das mit dem Programmieren etwas zu blicken.
Geradeaus fährt er schonmal, an der Wand setzt er auch minimal zurück, aber eben nur minimal.
Die Taster Funktionieren einwandfrei. Solange man sie gedrückt hält fährt er rückwärts und sofort beim loslassen wieder vorwärts.

Jetzt wollt ich die Schleife
for(i=0;i<1000;i++){
Sleep (72);
}
ins Programm bringen und auf einmal fährt er nur noch rückwerts im Kreis.
Linkes Rad flüssig, rechtes Rad stotternd, sobald ich den Taster drück macht er dann das was er soll. (zurücksetzen für ne Zeit)
Aber warum fährt er dauernd rückwärts ??
Weiß jemand Rat, oder wie ich die Zeit des Rückwärtsfahrens mit MSleep und ohne schleife hinbekomme?
Hab schon versucht etwas in die asuro.h zu schreiben, is aber wohl nicht so einfach mit reinschreiben . :-k



#include "asuro.h"

int main(void)
{

unsigned char t1, t2;
int i;

Init();
while(1)
{
t1 = PollSwitch();
t2 = PollSwitch();

if (t1 == 0 && t2 == 0)
{
MotorDir(FWD,FWD);
MotorSpeed(175,180);
BackLED(OFF,OFF);
FrontLED(ON);
}

else if( t1 && t2 && t1 == t2)
{


MotorSpeed(0,0);
StatusLED(RED);




if( t1 & 0x07 ) //Tasten links gedrückt??
{

FrontLED(OFF);
BackLED(ON,OFF);
MotorDir(RWD,RWD);
MotorSpeed(100,0); // linkes rad rückwärts


}

if( t1 & 0x38) //Tasten rechts gedrückt ??
{

FrontLED(OFF);
BackLED(OFF,ON);
MotorDir(RWD,RWD);
MotorSpeed(0,100); //rechtes Rad Rückwärts

}

***********hier hatte ich mal die Schleife drin ********************




}
return 0;
}

Valen
15.10.2009, 17:10
Wie hasst du das compiliert gekriegen. Die while-schleife braucht noch einer klammer zum ende. Die anzahl von "{" sind nicht gleich and die anzahl von "}". Auf welchem platz hast du ihn in einer alter version deiner program gesteckt?

the.speciali
15.10.2009, 17:19
Hachja wieso einfach wenns auch kompliziert geht :D

Sorry, aber irgendwie macht ihr das alles viel zu kompliziert^^ Erstmal zum MsSleep Hier mal eine Selbstgebaute Funktion die im Grunde genommen das Selbe macht:



void pause (int zeit)
{
int t;

for (t=0; t<zeit; t++)
{
Sleep (72);
}
}

Einfach die Funktion in dein Programm schreiben (weis nicht ob man das auch einfach so in die "asuro.h" schreiben kann, ich habe dies immer als zusätzliche Datei gespeichert und binde sie dann ein als "pause.h"). Also nach dem include in die nächste Zeile ein

void Pause (int zeit);
und nach dem Hauptprogramm den oben genannten code Einfügen schon kannst du einfach "pause (1000)" in dein Hauptprogramm eingeben und es wartet 1sek ohne irgendwelche Schleifen ;)

Zu den Problem mit den Tastern:


#include "asuro.h"

void pause (int zeit);

int main(void)
{
Init();
int a;

while (1)
{

while (PollSwitch () == 0)
{
StatusLED (GREEN);

MotorDir (FWD, FWD);
MotorSpeed (150, 150);

pause (50);
}


if ((PollSwitch()==1)||(PollSwitch==2))
{
BackLed (ON,OFF);

MotorDir (RWD, RWD);
MotorSpeed (120,120);

pause (1000);

MotorDir (FWD,FWD);
MotorSpeed (120, 0);

pause (500);

MotorSpeed (0,0);
}

//Das selbe spiel mit PollSwitch==16/32 nur diesmal andersherum mit den Geschwindigkeiten und den Backleds

BackLED (OFF, OFF);
}

StatusLED (RED);
return 0;
}


void pause (int zeit)
{
int t;

for (t=0; t<zeit; t++)
{
Sleep (72);
}
}

So sollte es eigentlich funktionieren^^ Hab aber wie so oft das Problem ich kanns hier nicht testen... Sollte es nicht Funktionieren passt mit dem if und deren Klammersetzung etwas nicht und es muss ein while rein. Bin mir aber nicht ganz sicher dessen^^

Das Problem bei deinem Programm ist: du hast kein Sleep drinn weswegen der Prozessor nicht eine bestimmte Zeit rückwärts fährt nur eben dann wenn einer der Tasten gedrückt worden ist^^ Aber im grunde genommen sollte dein Programm auch funktionieren fällen eben nur ein paar Pausen drinn ;)

beste Grüße
the.speciali

EDIT: Init hat gefehlt, return 0...
Und stimmt das mit der While Schleife ist mir garnicht aufgefallen Valen.