PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programmierung C - Asuro



brandy_000
03.01.2012, 15:21
Hallo!

Ich bin versiert im Umgang mit Programmiersprachen, doch auf dem Gebiet C bin ich ein Neuling. Jetzt hab ich mir ein einfaches Programm für den Asuro gebastelt, aber es will und will nicht funktionieren. Er überspringt mir ständig meine Schleife, von der das Fahren abhängig ist - hier mal ein Code (hab ihn vereinfacht, aber vielleicht könnt ihr mir mal Tipps geben, wie er mir die Schleife mitnimm)


#include "asuro.h"

int main(void)
{
Init();
int i;
i=1;
while(i<300)
{
MotorDir(FWD,FWD);
MotorSpeed(200,200);
i++;
}
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
}

Che Guevara
03.01.2012, 15:24
Hallo,

ich selbst kann zwar kein (oder nur sehr sehr wenig) C, aber was glaubst du, wielange der µC braucht, deine while(i<300) Schleife abzuarbeiten? Das geht so schnell, dass die Motoren nicht einmal drauf reagieren können.
Du könntest z.b. einen Wait-Befehl einbauen, in C heißt das glaube ich Delay(x). Aber da kenne ich mich zuwenig aus.

Gruß
Chris

Torrentula
03.01.2012, 15:34
Zuerst musst du die util/delay.h includen und dann kannst du per _delay_ms(x); für x millisekunden pausieren.




#include "asuro.h"
#include <util/delay.h> int main(void) { Init(); int i; i=1; while(i<300) { MotorDir(FWD,FWD); MotorSpeed(200,200); i++;
_delay_ms(500); // eine halbe sekunde pausieren bevor weitergemacht wird } MotorDir(BREAK,BREAK); MotorSpeed(0,0);
}


EDIT: sorry der online editor hat mir das layout zerissen.. :/

radbruch
03.01.2012, 16:04
Hallo

In der Library des asuro befindet sich die Funktion Sleep() zur Verzögerung. Ein Sleep(1) dauert 1/72000 Sekunden, eine Verzögerung um eine Sekunde könnte dann etwa so aussehen:

while(1=0; i<1000; i++) Sleep(72); // 72 ist eine Millisekunde mit der 72kHz-Library.

Programme für AVR-Microkontroller sollten nie beendet werden, da niemand weiß, wohin der Rücksprung aus main() führt und welche Folgen ein Rücksprung haben kann! Deshalb sollten die Progamme als Endlosschleife laufen oder in einer solchen Enden:


#include "asuro.h"

int main(void)
{
Init();
while(1)
{
//eigenes Programm
}
return(0);
}(Programmgrundgerüst für den asuro)


Dein Programm von oben könnte also etwa so aussehen:


#include "asuro.h"

int i;

int main(void)
{
Init();
MotorDir(FWD,FWD);
MotorSpeed(200,200);
for(i=0; i>1000; i++) Sleep(72);
StatusLED(RED);
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
while(1);
return(0);
}

Gruß

mic

brandy_000
03.01.2012, 22:48
Vielen Dank für eure Antworten - ich hab mir schon soetwas gedacht, hab aber nicht recht gewusst wie ich die Sleep-Funktion richtig einsetze - vielen Dank nochmal, auch den Tipp bez. des Codes!


Eines ist mir aber noch unklar - wieso ist da eine Schleife vor dem Sleep? Die bräucht ich in dem Fall ja gar nicht, wenn ich einfach die Sleepzeit mit 1000 multipliziere hab ich ja die Sekunden, oder verstehe ich da was falsch?

Vielen Dank!

radbruch
03.01.2012, 23:24
Die for-Schleife macht 1000 mal Sleep(72), wartet also eine Sekunde. Die Sleepzeit kann nicht größer als 255 sein, weil der Parameter für Sleep() ein char ist.

brandy_000
04.01.2012, 09:41
Ok danke...

Vielen Dank!

brandy_000
04.01.2012, 10:10
So jetzt brauch ich nochmals eure Hilfe!

Hier mein Code:

#include "asuro.h"

int i;

int main(void)
{
Init();
MotorDir(FWD,FWD);
MotorSpeed(200,200);
StatusLED(GREEN);
for(i=0; i>2000; i++) Sleep(72);
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
StatusLED(RED);
while(1);
return(0);
}

Theoretisch sollte er jetzt losfahren - 2 Sekunden lang fahren und dann bremsen. Macht er aber nicht, sondern nach dem Booten leuchtet sofort die rote LED!
Vielen Dank nochmal!

radbruch
04.01.2012, 10:15
i>2000

i ist nie größer als 2000, die Schleife wird deshalb sofort wieder verlassen. Blöd wenn man ungetestete Programme verbreitet. Entschuldigung. Richtig wäre

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

brandy_000
04.01.2012, 10:25
Ok das hätte ich auch selbst sehen können! ;-)
Danke nochmal!

brandy_000
04.01.2012, 15:07
Vielen Dank er fährt jetzt so wie ich das möchte.
Jetzt wollte ich eine kleine Modifikation machen und mal was mit den Kollisionsdinger machen:


#include "asuro.h"

int i;

int main(void)
{

Init();

MotorDir(FWD,FWD);
MotorSpeed(200,200);
StatusLED(GREEN);
if ((PollSwitch()!=0) || (PollSwitch()!=0) || (PollSwitch()!=0))
{
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
StatusLED(RED);
for(i=0; i<1000; i++) Sleep(72);
MotorDir(FWD,BREAK);
MotorSpeed(100,0);
StatusLED(GREEN);
}
while(1);
return(0);


Jedoch fährt er mir jetzt durch, was nicht sein sollte - aber laut einem anderem Forum, soll man die Abfrage mehrmals, oder so wie oben machen, da verschiedene Werte zurückkommen und man das so umgehen könnte (suchs euch nochmals raus, wenn ihr wollt).

Weiters hab ich eine generelle Frage - arbeitet ihr noch immer in der test.c? Welche Dateien von der Original-Cd sind essentiell? Hab diese hier rüberkopiert:

file:///home/davidb/Asuro/AsuroFl.ini
file:///home/davidb/Asuro/Test-all.bat
file:///home/davidb/Asuro/Test-clean.bat
file:///home/davidb/Asuro/asuro.c
file:///home/davidb/Asuro/asuro.d
file:///home/davidb/Asuro/asuro.h
file:///home/davidb/Asuro/asuro.lst
file:///home/davidb/Asuro/asuro.o
file:///home/davidb/Asuro/makefile
file:///home/davidb/Asuro/test.c
file:///home/davidb/Asuro/test.c~
file:///home/davidb/Asuro/test.d
file:///home/davidb/Asuro/test.eep
file:///home/davidb/Asuro/test.elf
file:///home/davidb/Asuro/test.hex
file:///home/davidb/Asuro/test.lss
file:///home/davidb/Asuro/test.lst
file:///home/davidb/Asuro/test.map
file:///home/davidb/Asuro/test.o
file:///home/davidb/Asuro/test_original.c

Brauch ich da wirklich alles? test.c ist ja meine und asuro.h brauch ich ja auch...

Macht ihr euch eigentlich eigene Programme? Was müsste ich dazu beachten. Ist es überhaupt ratsam, weil normal reicht es ja aus, wenn man immer in der test.c arbeitet, man kann sie anders abspeichern wenn man verschiedene Programme abspielen will...

brandy_000
04.01.2012, 18:11
So jetzt hab ich noch eine Modifikation gemacht, doch das If wird bei Kollision trotzdem nicht ausgeführt. Fahren tut er brav!


#include "asuro.h"

int i;

int main(void)
{

Init();

if (PollSwitch()==0 && PollSwitch()==0 && PollSwitch()==0 && PollSwitch()==0)
{
MotorDir(FWD,FWD);
MotorSpeed(200,200);
BackLED(ON,ON);
}

if (PollSwitch()!=0 && PollSwitch()!=0 && PollSwitch()!=0 && PollSwitch()!=0)
{
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
StatusLED(RED);
MotorDir(FWD,BREAK);
MotorSpeed(100,0);
StatusLED(GREEN);
}

while(1);
return(0);
}

oernie97
04.01.2012, 18:51
Hallo,

du musst die If-Abfrage in die while-Schleife tun, sonst fragt er nur beim Starten die Taster ab und bleibt danach in der Endlosschleife.

Grüße,
oernie97

brandy_000
04.01.2012, 19:16
Ja das hab ich jetzt schon gemacht - jedoch auch ohne Ergebnis - er fährt einfach nicht los:



#include "asuro.h"

int i;

int main(void)
{

Init();
while(1);
if (PollSwitch()==0 && PollSwitch()==0 && PollSwitch()==0 && PollSwitch()==0)
{
MotorDir(FWD,FWD);
MotorSpeed(200,200);
BackLED(ON,ON);
StatusLED (GREEN);
}
else
{
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
BackLED(OFF,OFF);
StatusLED(RED);
MotorDir(FWD,BREAK);
MotorSpeed(100,0);
}
return(0);
}

oernie97
04.01.2012, 19:24
Ich meine _in_ die while-Schleife (bedeutet, das Semikolon hinter while (1) wird zu einer geöffneten geschweiften Klammer und vor return(0); wird eine geschlossene geschweifte Klammer eingefügt).

brandy_000
04.01.2012, 19:30
Ups mein Fehler!

brandy_000
04.01.2012, 20:37
Dieser Code hier funktioniert. Zuerst fährt er brav vorwärts, bei Kollision (also Drücken eines Kollisionsschalter) dreht sich auch ein Rad nach hinten. Jedoch bleibt er mir hin- und wieder in einer Schleife stecken, in der sich beide Räder nach vorne drehen oder zB auch nur eines nach hinten. Dann bleibt er mal komplett stehen und das Status-LED beginnt zu blinken. Einmal hat sich sogar das untere LED eingeschaltet, als er stehengeblieben ist.
Was passiert da?



#include "asuro.h"

int i;

int main(void)
{

Init();
while(1){
if (PollSwitch()==0 && PollSwitch()==0)
{
MotorDir(FWD,FWD);
MotorSpeed(200,200);
BackLED(ON,ON);
StatusLED (GREEN);
}
else
{
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
BackLED(OFF,OFF);
StatusLED(RED);
MotorDir(RWD,BREAK);
MotorSpeed(150,0);
}
}
return(0);
}
/*for(i=0; i<2000; i++) Sleep(72);*/

radbruch
04.01.2012, 21:25
"Dann bleibt er mal komplett stehen und das Status-LED beginnt zu blinken."

Halt dann mal den Transceiver über den asuro und schaue ins Terminalfenster. Vermutlich erscheint dann endlos "VLVLVLVLVL..". Das würde für Unterspannung (Voltage Low) stehen und sich aus der Belastung der Akkus beim Fahren und auch beim schnellen Richtungswechsel der Antriebe erklären. Spannungseinbrüche könnten auch die anderen seltsamen Erscheinungen erklären. (Anleitung Seite 29 Kapitel 6.3.3.)

brandy_000
04.01.2012, 21:35
Ok bekomm schöne VLs ausgegeben - Was kann man dagegen tun?
Hab nachdem ich ihn fertiggebaut habe neue Batterien reingegeben - vielleicht sind die auch schon zu schwach...

brandy_000
04.01.2012, 22:58
Muss an den Batterien liegen - hab gerade ein Programm geschrieben, wo er 5 Sekunden geradeausfährt, kurz stehenbleibt und sich dreht und bei jedem Stück und jeder Drehung sehe ich wie er an den Batterien zehrt...

oderlachs
05.01.2012, 10:28
Hallo Brandy_000 !
Vileicht findest Du HIER (http://www.traenendersonne.de/website/asuro.html) auch noch etwas Anleitung zu Asuro in "C"

Gruss Gerhard

radbruch
05.01.2012, 11:08
Hallo

Was für eine dubiose Quelle ist das denn? 63MB "Programmierumgebung" und 28MB "Quelltexte" als EXE-Dateien? Woher stammt die AsuroFS3.0-Library?

Gruß

mic

Auch nicht schlecht:
http://glossar.hs-augsburg.de/Programmbibliothek_des_Asuro
http://www.cs.hs-rm.de/~linn/vpdv0809/semk/asurolib-2.8/main.html

Valen
05.01.2012, 19:38
Hallo

Was für eine dubiose Quelle ist das denn? 63MB "Programmierumgebung" und 28MB "Quelltexte" als EXE-Dateien? Woher stammt die AsuroFS3.0-Library?

Gruß

mic

Auch nicht schlecht:
http://glossar.hs-augsburg.de/Programmbibliothek_des_Asuro
http://www.cs.hs-rm.de/~linn/vpdv0809/semk/asurolib-2.8/main.html

De exe Datein sind Auto-extrahier Zip Dateien. Den enthalte Dateien kannst du einfach öffnen mit WinRAR und solcher Programmen. Die Programmier Umgebung Datei Enthalt Dev-cpp. Das ist ein bisschen mehr als nötig nach meiner Meinung.

brandy_000
08.01.2012, 14:48
Hallo!

War jetzt schon in einigen Foren unterwegs, doch hab bis jetzt noch keine zufriedenstellende Antwort erhalten, deshalb melde ich wiedermal bei euch.

Bekomm bei meinem Cutecom folgende Ausgabe:



Ausgabe des Linken:
\0x00Ausgabe d\0x00\0x00\0x00\0x00\0x00
Ausgabe des Rechten:
\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0xdd\0x00 \0x00\0x00\0x00\0x00
Ausgabe des Linken:
\0x00Ausgabe d\0x1f\0x00\0x00\0xf8\0xfe
Ausgabe des Rechten:
\0x00\0x00\0x00\0x00\0x1e\0x00\0x1f\0x00\0xd8\0x00 \0x00\0xf8\0xfe\0xff


Der entsprechende Code dazu wäre dieser hier:



#include "asuro.h"
unsigned int data[2];
int i;

int main(void)
{
Init();
while(1){
LineData(data);
FrontLED(ON);
SerWrite("Ausgabe des Linken:\n",30);
SerWrite(data[0],5);
SerWrite("Ausgabe des Rechten:\n",30);
SerWrite(data[1],5);
}
return(0);
}


Wie bekomm ich hier schöne Zahl ausgegeben, mit denen ich auch arbeiten kann?
Hab jetzt schon sprintf und itoa, welche mir am logischten vorgekommen sind, jedoch hat sich keine Lösung eingestellt...
Vielen Dank

Valen
08.01.2012, 14:51
Lösung: function itoa

http://www.cplusplus.com/reference/clibrary/cstdlib/itoa/

brandy_000
08.01.2012, 15:04
Habs jetzt so umgebaut:



#include "asuro.h"
unsigned int data[2];
char string;
char string_l;
char string_r;

int main(void)
{
Init();
while(1){
LineData(data);
FrontLED(ON);
itoa ( data[0], string_l, 10);
SerWrite("Ausgabe des Linken:\n",30);
SerWrite(string_l,5);
itoa ( data[1], string_r, 10);
SerWrite("Ausgabe des Rechten:\n",30);
SerWrite(string_r,5);
}
return(0);
}


Gibt mir aber jetzt sowas aus:



Ausgabe des Linken:
\0x00Ausgabe d\0x00\0x00\0x00\0x82\0x00
Ausgabe des Rechten:
\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00\0x00 \0x00\0x00\0x82\0x00
Ausgabe des Linken:
\0x00Ausgabe d\0x8222\0x00\0x00

Valen
08.01.2012, 15:09
Itoa braucht aber auch einbindung der Datei stdlib.h


#include <stdlib.h>

Valen
08.01.2012, 15:15
Ausserdem brauchen unsigned integer Werten ein Zeichenketten von 5 Zeichen Länge.

Also:


char string_l[6]; // Ein weiteres Zeichen für Null-Terminator
char string_r[6]; // Ein weiteres Zeichen für Null-Terminator

brandy_000
08.01.2012, 15:48
Wo muss die stdlib.h liegen? Ich schätze im gleichen Verzeichnis wie die asuro.h?
Hab sie mir aus folgender Quelle erstellt: http://www2.hs-fulda.de/~klingebiel/c-stdlib/stdlib.h.htm

Vielen Dank!

Valen
08.01.2012, 15:53
Irgendwo in das WinAVR Verzeichnis. Wo genau macht nichts, den WinAVR Compiler wird das automatisch finden und einbinden wenn das #include am anfang des Programms steht.

brandy_000
08.01.2012, 16:14
Ok die ist eh schon vorinstalliert hab ich gerade gesehen.
Bei erneuten make bekomm ich aber jetzt die folgende Ausgabe:



make: *** Keine Regel vorhanden, um das Target »stdlib.h«,
benötigt von »test.o«, zu erstellen. Schluss.
[root@localhost Asuro]#

Valen
08.01.2012, 16:24
Leider kenne ich diese Fehlermeldung nicht so genau. Und auch Linux/Unix nicht. :(

brandy_000
08.01.2012, 17:04
Hab die Meldung jetzt mal ignoriert und die Ausgabe hat sich auch verändert:



Ausgabe des Linken:
\0x00Ausgabe d\0x8233\0x00\0x00
Ausgabe des Rechten:
\0x00\0x00\0x00\0x00\0x00$\0x00%\0x0033\0x00\0x00\ 0x00
Ausgabe des Linken:
\0x00Ausgabe d91309
Ausgabe des Rechten:
\0x00\0x00\0x00\0x00\0x00#3$391309

brandy_000
08.01.2012, 20:06
Mit itoa schaut die Ausgabe jetzt gar nicht mehr so schlecht aus:



Ausgabe des Rechten:
\0x0029
Ausgabe des Linken:
\0x0024
Ausgabe des Rechten:
\0x0031
Ausgabe des Linken:
\0x0027


Aber die Abfrage mit zB 29, 24, 31, funktioniert hier nicht - was muss ich noch machen, damit die Zeichen davor verschwinden bzw. dass das ganze zu einer Zahl wird?
Vielen Dank!

brandy_000
09.01.2012, 14:24
Hat keiner eine Idee wie ich diese Zeichen umwandeln kann? Bzw. wie kann ich diese anschaulicher bekommen?

Zum Verständnis hier mein Quelltext:


#include "asuro.h"
#include <stdlib.h>
unsigned int data[2];
unsigned char string_l[6];
unsigned char string_r[6];

int main(void)
{
Init();
SerWrite("Asuro gestartet!\n",18);
while(1){
FrontLED(ON);
LineData(data);
itoa (data[0], string_l, 10);
itoa (data[1], string_r, 10);
SerWrite("Ausgabe des Linken:\n",21);
SerWrite(string_l,2);
SerWrite(" \n",2);
SerWrite("Ausgabe des Rechten:\n",22);
SerWrite(string_r,2);
SerWrite(" \n",2);
}
return(0);
}


Vielen Dank!

brandy_000
12.01.2012, 20:55
Keiner eine Idee dazu?

Vielen Dank!

Valen
13.01.2012, 12:45
Ist das

unsigned char

wirklich notwendig? Reicht es nicht mit nur ein char? Laut die folgende erklärung ist das möglich die Lösung.

http://stackoverflow.com/questions/75191/what-is-an-unsigned-char

brandy_000
15.01.2012, 10:20
Hallo!

Habs jetzt mit Char probiert und bekomm folgende Ausgabe:



Ausgabe des Rechten:
\0x0034
Ausgabe des Linken:
\0x0035
Ausgabe des Rechten:
\0x0034
Ausgabe des Linken:
\0x0035


Naja ich probier jetzt einfach mal mit diesen Werten zu Arbeiten - werds auf weißen und schwarzen Untergrund stellen um die Extremwerte herauszufinden.
Wo ich aber ein Problem sehe, ist, das ich nicht abfragen kann ob der Wert größer oder kleiner ist... Naja ich probier mal herum...

Vielen Dank!

brandy_000
15.01.2012, 11:52
So hab jetzt den genannten Test gemacht:

Auf weißen Untergrund bekomm ich Werte um \0x0045 ausgegeben, bei Schwarz unter \0x007\0x00 . Dies erfreut mich ja schon mal, aber da sollte ja mehr Unterschied sein zwischen den Ausgaben.