Archiv verlassen und diese Seite im Standarddesign anzeigen : Einsteiger bräuchte kleine Hilfestellung in C für Asuro
travell0r
16.06.2009, 11:38
Tag!
In dem Asuro-Subforum befinden sich wirklich einige Dinge die mir schon ziemlich geholfen haben und mir den Einstieg ziemlich erleichtert haben - toll Community!
Hab erst Gestern angefangen mich mit dem Asuro UND mit C-Programmierung zu beschäftigen, d.h. hab ich einige Grundlegende fragen und ich hoffe, das sich hier jemand findet der sie mir kurz und knapp beantworten kann. ;)
Dann frag ich mal drauf los:
Das C-Kommando "for" - was bewirkt es und wie benutze ich es?
Das C-Kommando "do" - was bewirkt es und wie benutze ich es?
Wie bekomm ich den Asuro dazu, eine gewisse Aktion (z.b. Vorwärtsfahren) für eine BESTIMMBARE Zeit zu tun?
Diesbezüglich hab ich schon was im Zusammenhang mit dem Sleep Befehl gelesen, allerdings erscheint mir das unlogisch da laut dem Asuro Manual ja der Sleep Befehl den Prozessor warten, also nichts tuen, lässt.
](*,)
So das wars vorerst, werden hier sicherlich noch mehr Fragen mit der Zeit dazu kommen. ;)
Danke schonmal an alle, die sich Gedanken über meine Fragen machen!
Grüße
Andree-HB
16.06.2009, 12:23
Wenn es vielleicht nur darum geht, nach vorne zu fahren (vielleicht so 10m) und dann zu drehen.... ;-)
...dann evtl. : http://www.arexx.com/arexx.php?cmd=goto&cparam=p_asuro_rovipro.dat
021aet04
16.06.2009, 12:33
Die Befehle Do und for sind beides Befehle für Schleifen.
Der Do Befehl wird folgenderweiße angewandt:
do
{
Anweisung1;
Anweisung2;
Anweisung3;
.....
.....
}
while (Bedingung)
Die Do Schleife (besser Do-While) wird mindestens 1 mal ausgeführt, da am Ende die Bedingung überprüft wird.
Die For Schleife wird so verwendet.
for(Startwert; Endwert; Schrittweite)
{
Anweisung1;
Anweisung2;
Anweisung3;
.....
.....
}
Der For Befehl wird nur ausgeführt, wenn die Bedingung erfüllt ist, es kann auch sein, dass sie nie ausgeführt wird.
Als Beispiel für den For Befehl. Eine Zählschleife
for(i=0; i<10; i++);
Startwert ist 0, Wenn die Variable "i" kleiner als 10 ist, wird sie um 1 erhöht. Statt "i++" kann an auch "i=i+1" schreiben, aber i++ ist kürzer
021aet04 hat schon alles super erklärkt ^^
Und wenn du ein countdown haben willst schreibst einfach so
for (i=10; i>0;i--)
Ich hab dir noch ne PM geschrieben^^
travell0r
16.06.2009, 13:38
@Andree-HB: Danke! Das Tool kannte ich bereits und würde es nur ungern benutzen, da ich mich doch gerne etwas intensiver mit dem Code und dem ganzen Kram beschäftigen möchte.
@021aet04: Danke! Kurz und Knapp so wie ichs wollte, wunderbar. :)
@Leachim: Das versteh ich noch nicht ganz - was ist "i"?
Und wenn das ein Countdown sein soll, auf was bezieht er sich dann beim runterzählen? Also Sekunden? Millisekunden? *allgemeineverwirrung*
Ich möchte das der ASURO Beispielsweise 5 Sekunden geradeaus fährt, dann 2 Sekunden eine leichte Linkskurve etc.
Das möchte ich halt am liebsten via Zeit verwirklichen, da die Odometrie noch ziemlich unklar für mich ist. :)
Help?
EDIT: Die SuFu hat was ausgespuckt das ziemlich nah an das ran kommt (Achter fahren):
#include "asuro.h"
#define kurve 1000
#define gerade 200
#define schnell 150 // Außenkurve
#define langsam 5 // Innenkurve und Gerade
unsigned int i;
int main(void)
{
Init();
while(1)
{
MotorSpeed(langsam, langsam);
for(i=0; i<gerade; i++) Sleep(36); // Sleep(72) bei orginaler CD-Library
MotorSpeed(langsam, schnell);
for(i=0; i<kurve; i++) Sleep(36);
MotorSpeed(langsam, langsam);
for(i=0; i<gerade; i++) Sleep(36);
MotorSpeed(schnell, langsam);
for(i=0; i<kurve; i++) Sleep(36);
}
return(0);
}
Allerdings, wie gesagt, ist mir der Sinn des for Kommandos in dem Zusammenhang nicht ganz klar, genau so bräuchte ich bitte eine Erläuterung des Sleep-Kommandos in dem Zusammenhang.
Entschuldigt meine Unwissenheit, aber wie gesagt, bin absoluter Neuling. :)
Und wenn das ein Countdown sein soll, auf was bezieht er sich dann beim runterzählen? Also Sekunden? Millisekunden? *allgemeineverwirrung*
Mit Countdown ist diesmal gemeint, dass i (eine Variable, z.b. von Typ int) bei jedem Schleifendurchgang runter anstatt hochgezählt wird. Eine for-Schleife ist in C ein Spezialfall der while-Schleife, ganau genommen ist for(a; b; c ; ) { d } dasselbe wie a; while(b) {d; c ;} . Das erste Statement in der Klammer der for-Schleife wird also nur einmal bedingungslos ausgeführt. Solange das zweite Statement wahr (true) ist, wird das, was nach der for-Schleife steht, sowie das dritte Statement ausgeführt.
Bespiel: Du hast ein int-Arry mit 10 Elementen, und du möchtest dass in dem Array nacheinander die Zahlen 0-9 stehen. Das kann man z.b. so machen
int array[10];
array[0] = 0;
array[1] = 1;
...
array[9] = 9;
oder mit einer while-Schleife
int array[10];
int i;
i = 0;
while(i<10)
{
array[i] = i;
i++;
}
oder eben mit einer for-Schleife
int array[10];
int i;
for(i=0; i<10; i++)
array[i] = i;
Letzteres hat einfach den Vorteil, dass es übersichtlicher ist.
In dem Code, dan Du gepostet hast wird in einer Endlosschleife while(1) zuerst jeweils die Geschwindigkeit eingestellt, mit der ASURO fahren soll und dann eine gewisse Zeit mit Sleep abgewartet (während dieser Zeit faäht ASURO weiter). Weil die Sleep-Funktion keine übergroßen Werte annimmt, furt man sie in einer for-Schleife mehrmals nacheinander auf.
Mal ehrlich, arbeite erstmal ein gutes C-Tutorial durch oder kauf Dir ein C-Buch, bevor Du mit ASURO weitermachst. Es ist doch viel zu schade, dass gute Ideen einfach nur deshalb scheitern, weil man die Programmiersprache nicht beherrscht. Es ist wie beim Schreiben eines Romans: nicht die Beherrschung der Grammatik, sondern die Phantasie ist das wichtigste. Aber selbst die größte Phantasie nutzt einem nichts, wenn man Analphabet ist.
MfG Mark
travell0r
17.06.2009, 10:12
@p_mork: Erstmal danke für deine ausführliche Antwort.
Leider versteh ich noch immer nicht Ganz wie mir diese Geschichte mit dem int-Arry jetzt bei meiner Problemstellung (s. o.) helfen kann. Kanns das überhaupt? Oo
Ich dachte das Sleep-Kommando lässt den Prozessor eine Weile gar nichts tun - wie kann das also jetzt sein das er währenddessen weiterfährt? Leuchtet mir nicht ganz ein...
Und ja, ich bin wie gesagt erst seit 2 Tagen an C dran und versuch mein Bestes - unter Anderem versuch ich halt auch mit diesem Topic mir etwas auf die Sprünge helfen zu lassen! ;)
Da bis jetzt noch keine wirklich für mich Umsetzbaren Vorschläge kamen, wiederhole ich nochmal meine Problemstellung;
Ich möchte den Asuro so programmieren, dass er in eine gewisse Richtung für eine gewisse Zeit fährt, und nach dieser Zeit wieder in eine andre Richtung. Um z.b. gewisse Figuren fahren zu können. (Odometrie möchte ich hierbei erstmal vernachlässigen.)
@travell0r
Das mit dem Array war nur als Beispiel gemeint, um die Funkionsweise der for-Schleife zu erklären.
Ich dachte das Sleep-Kommando lässt den Prozessor eine Weile gar nichts tun - wie kann das also jetzt sein das er währenddessen weiterfährt? Leuchtet mir nicht ganz ein...
Mit garnichts tun ist gemeint, dass die CPU selbst eine bestimmte Zeit lang nichts tut. Intern wird eine Variable einfach ständig runtergezählt, bis es 0 ist. Das Runterzählen sowie das Abfragen, ob es bereits 0 ist, benötigt eine bestimmte Anzahl von Takten, und wenn man es ein paar tausend mal gemacht hat, ist eine gewisse Zeitspanne vergangen. Die PWM-Signale für die Motoren werden von zusäztlicher Hardware, die an der CPU dranhängt, erzeugt und werden durch die Aktivitäten der CPU nicht beeinflusst.
MfG Mark
radbruch
17.06.2009, 15:44
Hallo
Das Runterzählen sowie das Abfragen, ob es bereits 0 ist, benötigt eine bestimmte Anzahl von Takten, und wenn man es ein paar tausend mal gemacht hat, ist eine gewisse Zeitspanne vergangen.
In der asuro-Library wird die interne Variable von Sleep() mit einem Timerinterrupt runtergezählt. Das geschieht 36000 mal in der Sekunde (orginale CD-Lib: 72000), deshalb dauert Sleep(36) beim asuro ziemlich genau 1/1000 Sekunde. Mit einer einfachen Schleife kann man die Wartezeit deutlich verlängern:
int i;
for(i=0; i<1000; i++) Sleep(36); // wartet eine Sekunde
Gruß
mic
Hier ist eine sehr billiges einstieg C-Buch. ;) Aber ein richtiges Buch wird das manchmal etwas weiter erklären.
http://www.rn-wissen.de/index.php/C-Tutorial
[qoute="Radbruch"]In der asuro-Library wird die interne Variable von Sleep() mit einem Timerinterrupt runtergezählt[/quote]
Oh, tut mir leid, dass wusste ich nicht, da ich selbst keinen ASUORO habe. Da es meistens durch Runterzählen realsisiert wird, dachte ich, dass es auch beim ASURO zutrifft.
MfG Mark
radbruch
17.06.2009, 21:50
Da es meistens durch Runterzählen realsisiert wird, dachte ich, dass es auch beim ASURO zutrifft.
Da der asuro die 36kHz für seine IR-Kommunikation erzeugt ist es naheliegend diesen Takt auch für andere Funktionen zu verwenden.
Gruß
mic
travell0r
22.06.2009, 15:28
Erstmal danke für eure Antworten, das hat mir schon etwas auf die Beine geholfen und ich hab mein erstes selbstgeschriebenes Programm entwickelt...es funktioniert nur leider nicht so ganz, welch Überraschung! :D
#include "asuro.h"
int main(void)
{
int x; // Motorgeschwindigkeit links //
int y; // Motorgeschwindigkeit rechts //
int l;
int r;
int i;
x = 150;
y = 150;
Init();
unsigned int data[2];
// Anfangsmitteilungen //
SerWrite("\n\r VORWAERTS MEIN KAISER! \n\r",33);
SerWrite("\n\r Volle Kraft Voraus! \n\r",29);
SerWrite("\n\r Mit Synchronisation! \n\r",30);
// Gerade aus fahren //
while(1)
{
if(PollSwitch()==0)
{
OdometrieData(data);
BackLED(OFF,OFF);
FrontLED(ON);
StatusLED(GREEN);
MotorDir(FWD,FWD);
MotorSpeed(x+l,y+r);
}
if(data[0]<data[1])
{l = 50;}
if(data[0]>data[1])
{r = 50;}
if(data[0]==data[1])
{r = 0;}
if(data[0] >= 1023)
{
data[0] = 0;
data[1] = 0;
}
if(PollSwitch()==32)
{
for(i=0; i<200; i++) Sleep(72);
{
MotorDir(FWD,RWD);
MotorSpeed(170,200);
BackLED(ON,ON);
StatusLED(YELLOW);
FrontLED(OFF);
}
}
if(PollSwitch()==1)
{
for(i=0; i<200; i++) Sleep(72);
{
MotorDir(RWD,FWD);
MotorSpeed(200,170);
BackLED(ON,ON);
StatusLED(YELLOW);
FrontLED(OFF);
}
}
if(PollSwitch()==18)
{
for(i=0; i<300; i++) Sleep(72);
{
MotorDir(FWD,RWD);
MotorSpeed(170,200);
BackLED(ON,ON);
StatusLED(YELLOW);
FrontLED(OFF);
}
}
if(PollSwitch()==12)
{
for(i=0; i<300; i++) Sleep(72);
{
MotorDir(FWD,RWD);
MotorSpeed(170,200);
BackLED(ON,ON);
StatusLED(YELLOW);
FrontLED(OFF);
}
}
if(PollSwitch()==6)
{
for(i=0; i<350; i++) Sleep(72);
{
MotorDir(FWD,RWD);
MotorSpeed(170,200);
BackLED(ON,ON);
StatusLED(YELLOW);
FrontLED(OFF);
}
}
if(PollSwitch()==2)
{
for(i=0; i<200; i++) Sleep(72);
{
MotorDir(FWD,RWD);
MotorSpeed(170,200);
BackLED(ON,ON);
StatusLED(YELLOW);
FrontLED(OFF);
}
}
if(PollSwitch()==16)
{
for(i=0; i<200; i++) Sleep(72);
{
MotorDir(RWD,FWD);
MotorSpeed(200,170);
BackLED(ON,ON);
StatusLED(YELLOW);
FrontLED(OFF);
}
}
}
return (0);
}
Der Asuro soll also gerade aus fahren, solange keine Taste gedrückt ist, und zwar wirklich GERADE aus! Allerdings gibts da noch Probleme mit der OdometrieData und damit, das ich nicht raffe wie ich sie "zurücksetzen" kann, das was ich da zusammengeschustert habte funzt nich so wirklich glaube ich...
Dann hab ich noch die Grundroutinen fürs Ausweichen bei Kollisionen reingemacht, funktioniert beim K1 z.b. wunderbar, bei K6 allerdings hängt sich der Asuro auf - hilfe?
Wär sehr dankbar wenn sich jemand meinen Code mal durchlesen könnte und mir ein paar Tipps gibt! :)
Grüße
radbruch
22.06.2009, 19:24
Hallo
Die Werte der Odometrie geben die Helligkeit an mit der die Phototransistoren T11/12 angestrahlt werden. Mit diesen Werten kann der asuro die Segmente auf der Codescheibe unterscheiden und zählen. Ein direkter Vergleich mit z.B. "if(data[0]<data[1]) " bedeutet " links heller als rechts?" (großer Wert bedeutet dunkel) und hat nichts mit der zurückgelegten Wegstrecke zu tun.
PollSwitch() lügt häufig!
Gruß
mic
Und den odometrie werten sehen aus wie eine sinus kurve. Den linken und rechter seite haben aber unterschiedliche amplituden und mittelwerten. Und das ist auch manchmal abhängich von umgebungslicht wenn die odometrie sensoren nicht abgeschirmt sind .
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.