PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Telementriedaten des ASURO -> kleines Problem



NomiS
20.11.2007, 07:37
Hallo alle zusammen,

ich habe mal versucht ein kleines Programm zu schreiben, welches den ASURO von 80 auf 255 in 10er Schritten ein mal vorwärts und ein mal rückwärts beschleunigt.
Dabei sollen:
der Weg,
die Geschwindigkeit
und die Beschleunigung
gemessen werden (Drehzahl fehlt noch).
Leider ist mein Programm etwas zu groß geraten und der ASURO-Flasher meckert. Außerdem geht es nur manchmal. Mal kommen im Hyperterminal die richtigen Werte, mal nur die Überschriften, mal Chinesisch .... mal macht der ASURO gar nix mehr ... liegt evtl an den vielen Prints oder an der Größe des Progs.
Zur Zeit ist der untere Teil des Progs auskommentiert aus Platzgründen des Controllers (steht aber fast das selbe wie oben nur die Richtung und langsamer oder schneller ändern sich -- vlt bekommts ja jemand fertig mit einer "Kopfzeile" das ganze laufen zu lassen da bin ich grade dran)



#include <asuro.h>
#include <string.h> // für strlen

/*Left min/max, right min/max values da minimiert auf acht bit *4

+00150 *4 = 600 //data[1] left
+00222 *4 = 888

+00190 *4 = 760 //data[0] right
+00236 *4 = 944

*/


//Variablenverageb

int speed; //PWM des Rades
float msleft; //Metre pro Sekunde (Radgeschwindigkeit links
float msright; //Metre pro Sekunde (Radgeschwindigkeit rechts

float msleft1; // Vorherige Geschwindigkeit (für a)
float msright1; // Vorherige Geschwindigkeit (für a)

float mleft; //Gefahrene Strecke links
float mright; //Gefahrene Strecke rechts

float aleft; //Beschleunigung linkes Rad
float aright; //Beschleunigung rechtes Rad

unsigned int data [2]; //Array erstellen mit 2 Speicherzellen für Odometriedaten
//data [0] links T11
//data [1] rechts T12

int Zeit = 1000; //Zeit in der die Impulse gezählt werden 1s
int Zeit1 = 0; //letzte Zeit zur bestimmung der Zeit dif (für a)

int triggerleft = (((222-150)/2)+150)*4; //Helldunkelwechsel linkes Rad
int leftimpuls = 0; //gezählte Impulse pro Zeit links

int triggerright = (((236-190)/2)+190)*4; //Helldunkelwechsel rechtes Rad
int rightimpuls = 0; //gezählte Impulse pro Zeit rechts

unsigned int long stopzeit;

float pie = 3.14; //15927; //pie
float Umfang = 12; //.0165920775; //(38.25*pie); //Umfang in cm
int Muster = 12; //anzahl der Hell Dunkel übergänge
//-----------------------------------------------------------------------------
int main(void)
{
BackLED(OFF,OFF); //alle LED werden im Programm zur Veranschaulichung genutzt
StatusLED(RED); //d.h. wo bin ich im Prog. die Backeled´s sind aus da Odometrie an


Init();
while(1){
//-----------------------------------------------------------------------------
//Intro für Hyperterminal
//-----------------------------------------------------------------------------
SerPrint("\t Telemetriedaten\n\r\n\r");

//Überschrift im Hyperterminal für Vorwärts

SerPrint("\tVorwärts\n\r\n\r");
//-----------------------------------------------------------------------------
//Los gehts beschleunigen
//-----------------------------------------------------------------------------
StatusLED(GREEN);
MotorDir(FWD,FWD); //Richtung festlegen

Zeit1 = 0 ; //muss vor der Schleife genullt werden fals nioch restwert aus letzter Schleife
msright1 = 0;
msleft1 = 0;

for (speed=80;speed<=255;speed +=10){ //Geschwindigkeit von 80 auf 255 in 10er schritten
MotorSpeed(speed,speed); //Geschwindigkeit einlesen

leftimpuls = 0; //Impullse vor Zählvorgang auf null
rightimpuls = 0; //Impullse vor Zählvorgang auf null

//Detektierung der Impulse
stopzeit=Gettime()+Zeit; //1 sekunde Hell Dunkel Wechsel detektieren
do {
OdometrieData(data); //Odo daten bereitstellen
if(data[0]==triggerright) //wenn data = trigerlevel
rightimpuls++; //impulse erhöhen
if(data[1]==triggerleft) //siehe zwei drüber
leftimpuls++; //siehe zwei drüber

} while (stopzeit>Gettime()); //das ganze bis Zeit um (1s)

//Auswertung der Impulse

//Geschwindigkeit
msright = (rightimpuls * ((Umfang*pie)/Muster))/(Zeit*1000); //da ms
msleft = (leftimpuls * ((Umfang*pie)/Muster))/(Zeit*1000); //da ms

//Zurückgelegter Weg
mright = msright * Zeit;
mleft = msleft * Zeit;

//Beschleunigung
aright = (msright-msright1) / (Zeit-Zeit1);
aleft = (msleft-msleft1) / (Zeit-Zeit1);

Zeit1 = Zeit; //jetzige Zeit Zwischenspeichern für a beim nächsen turn
msright1 = msright; //jetzige Geschwindigkeit Zwischenspeichern für a beim nächsen turn
msleft1 = msleft; //jetzige Geschwindigkeit Zwischenspeichern für a beim nächsen turn

//Ausgabe





//rechtes
SerPrint("Rechtes Rad ");
PrintFloat(mright,2,2);
SerPrint (" m ");
PrintFloat(msright,2,2);
SerPrint(" cm/s" );
PrintFloat(aright,2,2);
SerPrint(" cm/s²");

//Lehrstellen zwischen rechts und links
SerPrint(" ");

//links
SerPrint("Linkes Rad ");
PrintFloat(mleft,2,2);
SerPrint (" m ");
PrintFloat(msleft,2,2);
SerPrint(" cm/s ");
PrintFloat(aleft,2,2);
SerPrint(" cm/s²");

//2*absatz

SerPrint("\n\r\n\r");
}
//-----------------------------------------------------------------------------
//Langsamer werden
//-----------------------------------------------------------------------------
Zeit1 = 0 ;
msright1 =0;
msleft1 =0;

for (speed=255;speed>=80;speed -=10){
MotorSpeed(speed,speed);

leftimpuls = 0;
rightimpuls = 0;

//Detektierung der Impulse
stopzeit=Gettime()+Zeit; //1 sekunde Hell Dunkel Wechsel detektieren
do {
OdometrieData(data);
if(data[0]==triggerright)
rightimpuls--;
if(data[1]==triggerleft)
leftimpuls--;

} while (stopzeit>Gettime());

//Auswertung der Impulse

//Geschwindigkeit
msright = (rightimpuls * ((Umfang*pie)/Muster))/(Zeit*1000); //da ms
msleft = (leftimpuls * ((Umfang*pie)/Muster))/(Zeit*1000); //da ms

//Zurückgelegter Weg
mright = msright * Zeit;
mleft = msleft * Zeit;

//Beschleunigung
aright = (msright-msright1) / (Zeit-Zeit1);
aleft = (msleft-msleft1) / (Zeit-Zeit1);

Zeit1 = Zeit;
msright1 = msright;
msleft1 = msleft;

//Ausgabe





//rechtes
SerPrint("Rechtes Rad ");
PrintFloat(mright,2,2);
SerPrint (" m ");
PrintFloat(msright,2,2);
SerPrint(" cm/s" );
PrintFloat(aright,2,2);
SerPrint(" cm/s²");

//Lehrstellen zwischen rechts und links
SerPrint(" ");

//links
SerPrint("Linkes Rad ");
PrintFloat(mleft,2,2);
SerPrint (" m ");
PrintFloat(msleft,2,2);
SerPrint(" cm/s ");
PrintFloat(aleft,2,2);
SerPrint(" cm/s²");

//2*absatz

SerPrint("\n\r\n\r");
}
//-----------------------------------------------------------------------------
//Rückwärts
//-----------------------------------------------------------------------------


//Überschrieft im Hyperterminal

SerPrint("\t Rückwärts\n\r\n\r");
//-----------------------------------------------------------------------------
//Los gehts beschleunigen
//-----------------------------------------------------------------------------
StatusLED(YELLOW);
MotorDir(RWD,RWD);

Zeit1 = 0 ;
msright1 =0;
msleft1 =0;

for (speed=80;speed<=255;speed +=10){
MotorSpeed(speed,speed);

leftimpuls = 0;
rightimpuls = 0;

//Detektierung der Impulse
stopzeit=Gettime()+Zeit; //1 sekunde Hell Dunkel Wechsel detektieren
do {
OdometrieData(data);
if(data[0]==triggerright)
rightimpuls++;
if(data[1]==triggerleft)
leftimpuls++;

} while (stopzeit>Gettime());

//Auswertung der Impulse

//Geschwindigkeit
msright = (rightimpuls * ((Umfang*pie)/Muster))/(Zeit*1000); //da ms
msleft = (leftimpuls * ((Umfang*pie)/Muster))/(Zeit*1000); //da ms

//Zurückgelegter Weg
mright = msright * Zeit;
mleft = msleft * Zeit;

//Beschleunigung
aright = (msright-msright1) / (Zeit-Zeit1);
aleft = (msleft-msleft1) / (Zeit-Zeit1);

Zeit1 = Zeit;
msright1 = msright;
msleft1 = msleft;

//Ausgabe





//rechtes
SerPrint("Rechtes Rad ");
PrintFloat(mright,2,2);
SerPrint (" m ");
PrintFloat(msright,2,2);
SerPrint(" cm/s" );
PrintFloat(aright,2,2);
SerPrint(" cm/s²");

//Lehrstellen zwischen rechts und links
SerPrint(" ");

//links
SerPrint("Linkes Rad ");
PrintFloat(mleft,2,2);
SerPrint (" m ");
PrintFloat(msleft,2,2);
SerPrint(" cm/s ");
PrintFloat(aleft,2,2);
SerPrint(" cm/s²");

//2*absatz

SerPrint("\n\r\n\r");
}


//-----------------------------------------------------------------------------
//Langsamer werden
//-----------------------------------------------------------------------------

Zeit1 = 0 ;
msright1 =0;
msleft1 =0;

for (speed=255;speed>=80;speed -=10){
MotorSpeed(speed,speed);

leftimpuls = 0;
rightimpuls = 0;

//Detektierung der Impulse
stopzeit=Gettime()+Zeit; //1 sekunde Hell Dunkel Wechsel detektieren
do {
OdometrieData(data);
if(data[0]==triggerright)
rightimpuls--;
if(data[1]==triggerleft)
leftimpuls--;

} while (stopzeit>Gettime());

//Auswertung der Impulse

//Geschwindigkeit
msright = (rightimpuls * ((Umfang*pie)/Muster))/(Zeit*1000); //da ms
msleft = (leftimpuls * ((Umfang*pie)/Muster))/(Zeit*1000); //da ms

//Zurückgelegter Weg
mright = msright * Zeit;
mleft = msleft * Zeit;

//Beschleunigung
aright = (msright-msright1) / (Zeit-Zeit1);
aleft = (msleft-msleft1) / (Zeit-Zeit1);

Zeit1 = Zeit;
msright1 = msright;
msleft1 = msleft;

//Ausgabe





//rechtes
SerPrint("Rechtes Rad ");
PrintFloat(mright,2,2);
SerPrint (" m ");
PrintFloat(msright,2,2);
SerPrint(" cm/s" );
PrintFloat(aright,2,2);
SerPrint(" cm/s²");

//Lehrstellen zwischen rechts und links
SerPrint(" ");

//links
SerPrint("Linkes Rad ");
PrintFloat(mleft,2,2);
SerPrint (" m ");
PrintFloat(msleft,2,2);
SerPrint(" cm/s ");
PrintFloat(aleft,2,2);
SerPrint(" cm/s²");

//2*absatz

SerPrint("\n\r\n\r");
}


}

return 0;}

Viel spaß und schon mal danke

NomiS

NomiS
20.11.2007, 07:41
ou Nachtrag das ganze geht nur mit der ganz neuen Lib

Sternthaler
20.11.2007, 14:19
Hallo NomiS,
um Platz zu sparen würde ich erst mal folgende Teile zusammenfassen:

SerPrint(" Vorwärts");
SerPrint("\n\r");
SerPrint("\n\r");zu
SerPrint("\tVorwärts\n\r\n\r");

Und dies hier:
SerPrint("Linkes Rad");
SerPrint(" "); zu
SerPrint("Linkes Rad ");

Das spart erst einmal die Funktionsaufrufe und die Zuweisungen der Parameter für die Funktion. Kleinkram, aber in deinem Programm läppert es sich doch erheblich.

Gruß Sternthaler

NomiS
20.11.2007, 14:42
Hi Sternthaler,

hab ich gemacht.
Code ist oben im ersten Eintrag geändert.
Jedoch beträgt das HEX file weiterhin 20kb. Wieviel passt denn eigentlich auf den Speicher?
Und geht das Programm bei jemandem? Mein ASURO hat grade irgendwas. Wenn ich ein und das selbe Programm auf ihn schreibe macht er unterschiedliche Sachen. Vlt. Batterie leer. Muss ich nachher daheim schauen.

radbruch
20.11.2007, 15:34
Hallo NomiS

Soweit ich's überblicke, sollte dein Code erstmal etwas optimiert werden :

--- Bei den vielen gleichen Ausgaben würde sich wohl eine Funktion ala

schreibeWert(text_parameter, wert_links, wert_rechts, text_einheit)

lohnen.

--- keine floats! Auch mit integern kann man prima rechnen, bzw. speichert man nicht so: float pie = 3.14; sondern int pie =314; und teilt nach der Rechnung das Ergebniss durch 100 (oder verzichtet ganz auf pi und schreibt direkt 314 in die Rechnung):

msright = (rightimpuls * ((Umfang*pie)/Muster))/(Zeit*1000);
wird dann zu
msright = (rightimpuls * ((Umfang*pie/100)/Muster))/(Zeit*1000);

oder, noch besser, man rechnet konstante Werte schon vorher aus:

int pie = 314; //15927; //pie
int Umfang = 12; //.0165920775; //
(38.25*pie); //Umfang in cm
int Muster = 12; //anzahl der Hell Dunkel übergänge

int pie_umfang_muster=pie*umfang/(Muster*100);

msright = (rightimpuls * pie_umfang_Muster / (Zeit*1000);

Was das allerdings soll, verstehe ich nicht ganz. Umfang ist doch schon pi*2r?

--- Warum nimmst du alle Odowerte mal 4? Du füllst nur mit zusätzlichen Nullen auf und vergleichst mit einem Wert, der auch zusätzliche Nullen hat. Lass die Multiplikationen weg, dann kannst du platzsparend und viel schneller mit 8Bit-Werten rechnen.(Der AVR ist ein 8Biter!):

unsigned char triggerleft = (((222-150)/2)+150); //Helldunkelwechsel linkes Rad


--- if(data[0]==triggerright)

Ähm, das verstehe ich auch nicht. Auf == sollte man bei Odowerten nicht prüfen, denn es könnte sein, das genau dieser Wert übersprungen wird. Was passiert eigentlich, wenn mehrmals hintereinander triggerlevel beim selben Segment der Codescheibe erkannt wird? Woran erkennst du das nächste Segment auf der Codescheibe? (data[0] war doch links, oder?)

---Vielleicht sollte man erst den Weg ausrechnen:
weg=impulse/anzahldercodescheibensegmente*umfang

Und dann die Geschwindigkeit:
geschw=weg/zeit

Die Beschleunigung ist dann die Geschwindigkeitsänderung und nicht ganz so einfach zu messen/zu berechnen und hier wohl nicht so sinnvoll.

--- Warum nennst du das "telemetrie"?

Das sind mal die gröbsten Punkte die mir auffallen. Wie ist denn dieses Programm entstanden? Hast du das am Stück eingegeben oder hast du die einzelnen Teile erstmal getestet und dann zusammengefügt?

Gruß

Mic

[Edit]
Oje:

for (speed=80;speed<=255;speed +=10) wenn speed schon >245 ist, muss die Schleife beendet werden.

rightimpuls--; negative Beschleunigung beim Abbremsen?

...
MotorSpeed(0,0);
return 0;}

Der ATMega8 hat 8kB Flashspeicher(Datenblatt (http://atmel.com/dyn/resources/prod_documents/doc2486.pdf))


Und geht das Programm bei jemandem?
Wohl kaum...

NomiS
20.11.2007, 15:57
Boa danke radbruch,

coole Ideen. Hab ich morgen mal was zu tun im geschäft!!! ;-)
Ich fang mal von unten an:
telemetrie = na ja ich habe nen namen gebraucht und der hat mir gefallen.
wie mache ich das mit der segmenterkennung? hab im Moment keine so rechte Idee.
Und meine größte frage. Wie schreibt man selbst so ne kleine Funktion wie in den Bibliotheken. Hab das im Geschäft versucht - es wollte aber nicht. Versuche es noch mal. Wie komme ich aus so einer Funktion wieder raus?
Aber erst mal vielen, vielen dank.

Gruß NomiS

NomiS
20.11.2007, 16:25
Noch mal ein paar fragen!
Wenn ich das triggerlevel nicht mal 4 nehme funktioniert es nicht!
Kann man Variablen auch so definieren int xx 10/20;?
Warum bekomme ich eine 15Kb hex-datei auf einen 8kb prozessor?
das programm entstand so:
Ich wollte die Geschwindigkeit der Räder erhöhen und wieder verringern
Dann kam der Vor und Rücklauf dazu
Dann die Auswertung der Geschwindigkeit
-> bis dahin hat das Prog gestern was ausgegeben (obst stimmt weiß ich nicht ob die Formeln stimmen hab ich noch nicht geprüft aber 9 - 36cm/s dacht ich ist doch ganz gut
Ja dann dachte ich heute ich könnte ja aus der Geschwindigkeit den Rest ermiteln
Was bedeutet:
for (speed=80;speed<=255;speed +=10) wenn speed schon >245 ist, muss die Schleife beendet werden.
und das -- ist ein fehler das Programm war ursprünglich anderst ausgelegt hab ich übersehen deshalb wird im Hyperterminal immer - xx ausgegeben danke

Sternthaler
20.11.2007, 23:04
Hallo NomiS,
ja, da hast du noch ein bisschen zu tum.

Zu deinen Fragen:

Wenn ich das triggerlevel nicht mal 4 nehme funktioniert es nicht!
Die Multiplikation mit 4 lass mal drin.
- int triggerleft = (((222-150)/2)+150)*4;
Hier nutzt du ja die 8-Bit-Werte (222; 150) aus dem Testprogramm von Arexx-Henk. Ein Vergleich nachher mit den 16-Bit-Werten aus OdometrieData() macht hier das *4 also nötig.
Aber ganz wichtig ist der Einwand von radbruch, den Triggerlevel nicht mit == zu vergleichen.


Kann man Variablen auch so definieren int xx 10/20;
Nein, einer Variablen muss man mit = etwas 'zuweisen'.
Eine Definition wäre mit "#define xx 10/20" gemacht.
Hier würde ich aber von abraten, da dann an allen Stellen, an denen du xx benutzt, der Computer zur Laufzeit die 10/20 rechnen muss.
Bei "int xx = 10/20;" wird diese Rechnung vom Compiler gemacht.
Aber auch das ist nicht gut, da dann ja 0,5 rauskommt, den du im int-Wert nicht speichern kannst.
Hier also unbedingt genau überlegen was du benötigst.


Warum bekomme ich eine 15Kb hex-datei auf einen 8kb prozessor?
Da schaust du am besten hier: http://www.schulz-koengen.de/biblio/intelhex.htm


9 - 36cm/s dacht ich ist doch ganz gut
Das sieht bestens aus. 9 cm/s ist gegenüber meinem Asuro sogar ein Top-Wert. Ich bleibe schon bei ca. 15 cm/s stehen. Allerdings bin ich mit ca. 40 dafür ein bisschen schneller.


Wie schreibt man selbst so ne kleine Funktion wie in den Bibliotheken.
Da haben einige Leute, die schon viel Erfahrung haben, viel Arbeit und Ergeiz reingesteckt. Erfahrung ist hier das Zauberwort. Mit 20 werden das noch längst nicht alle schaffen. Also nicht verzweifeln.


wie mache ich das mit der segmenterkennung?
Um diese Frage zu beantworten, solltest du mal die Forums-Suche eine zeitlang quälen.
Das wird dir nicht nur eine perfekte Antwort liefern, sondern auch einige andere Fragen sicherlich gut beantworten. Lesen unterstützt die Erfahrung ungemein ;-)

Gruß Sternthaler

damaltor
21.11.2007, 13:02
die größe der .hex-datei ist gar nicht sooo entscheidend. in dieser datei sind neben dem programm auch noch sämtliche zeilennummern sowie alle möglichen prüfsummen enthalten. diese werden im prozessor nicht mitgespeichert, also wird sie schon deutlich kleiner. meine größte .hex datei ist etwa 14kb groß und hat gerade noch so gepasst.

NomiS
21.11.2007, 13:36
Ja das dachte ich mir nach Sternthalers link schon. Ich habe zur Zeit leider irgend ein Problem mit dem Compiler. Wenn ich ein und die selbe datei UNVERÄNDERT mehrmals compilieren und dann flashe ist die Packetanzahl und die Größe ab und an mal anderst. Komisch !!!
Na ja
Ich hab mal bisschen was am code geändert. Geht zwar jetzt gar nicht mehr aber ich Poste ihn trotzdem mal. Das ist lediglich der geänderte Teil. Wie man eine Funktion erstellt habe ich aber Leider immer noch nicht heraus. Und verkürzt sich durch Funktionen der code?
Ersetzt der Compiler nicht den Funktionsaufruf mit der Funktion oder gibt es den Teil dann nur einmal als Unterprogramm?



#include <asuro.h>
#include <string.h> // für strlen

/*Left min/max, right min/max values da minimiert auf acht bit *4

+00150 *4 = 600 744 //data[0] left
+00222 *4 = 888
798
+00190 *4 = 760 852 //data[1] right
+00236 *4 = 944

*/
//Statische Vergabe

#define Triggerlevel 798
#define Hysteresis 25
#define LOW 0
#define HIGH 1

//Variablenverageb

int speed; //PWM des Rades
float cmsleft; //Metre pro Sekunde (Radgeschwindigkeit links
float cmsright; //Metre pro Sekunde (Radgeschwindigkeit rechts

float cmsleft1; // Vorherige Geschwindigkeit (für a)
float cmsright1; // Vorherige Geschwindigkeit (für a)

float cmleft; //Gefahrene Strecke links
float cmright; //Gefahrene Strecke rechts

float aleft; //Beschleunigung linkes Rad
float aright; //Beschleunigung rechtes Rad

unsigned int data [2]; //Array erstellen mit 2 Speicherzellen für Odometriedaten
//data [0] links T11
//data [1] rechts T12

signed int status[2]={0,0};

int Zeit = 1000; //Zeit in der die Impulse gezählt werden 1s
int Zeit1 = 0; //letzte Zeit zur bestimmung der Zeit dif (für a)

int leftimpuls = 0; //gezählte Impulse pro Zeit links
int rightimpuls = 0; //gezählte Impulse pro Zeit rechts

unsigned int long stopzeit;

int anzahldercodescheibensegmente_umfang = 1; //Breite eines Segmentes

//-----------------------------------------------------------------------------
int main(void)
{
BackLED(OFF,OFF); //alle LED werden im Programm zur Veranschaulichung genutzt
StatusLED(RED); //d.h. wo bin ich im Prog. die Backeled´s sind aus da Odometrie an


Init();
while(1){
//-----------------------------------------------------------------------------
//Intro für Hyperterminal
//-----------------------------------------------------------------------------
SerPrint("\t Telemetriedaten\n\r\n\r");

//Überschrift im Hyperterminal für Vorwärts

SerPrint("\tVorwärts\n\r\n\r");
//-----------------------------------------------------------------------------
//Los gehts beschleunigen
//-----------------------------------------------------------------------------
StatusLED(GREEN);
MotorDir(FWD,FWD); //Richtung festlegen

Zeit1 = 0 ; //muss vor der Schleife genullt werden fals nioch restwert aus letzter Schleife
cmsright1 = 0;
cmsleft1 = 0;

for (speed=80;speed>245;speed +=10){ //Geschwindigkeit von 80 auf 255 in 10er schritten
MotorSpeed(speed,speed); //Geschwindigkeit einlesen

leftimpuls = 0; //Impullse vor Zählvorgang auf null
rightimpuls = 0; //Impullse vor Zählvorgang auf null

//Detektierung der Impulse
stopzeit=Gettime()+Zeit; //1 sekunde Hell Dunkel Wechsel detektieren

do {
OdometrieData(data); //Odo daten bereitstellen

//Wechselt linker Sensor von niedrig auf hoch?
if((status[0]==LOW)&&(data[0]>Triggerlevel+Hysteresis)){
status[0] = HIGH;
leftimpuls++;}

//Wechselt linker Sensor von hoch auf niedrig?
if((status[0]==HIGH)&&(data[0]<Triggerlevel-Hysteresis)){
status[0] = LOW ;
leftimpuls++;}

//Wechselt rechter Sensor von niedrig auf hoch?
if((status[1]==LOW)&&(data[1]>Triggerlevel+Hysteresis)){
status[1] = HIGH;
StatusLED(RED);
rightimpuls++; }

//Wechselt rechter Sensor von hoch auf niedrig?
if((status[1]==HIGH)&&(data[1]<Triggerlevel-Hysteresis)){
status[1] = LOW;
rightimpuls++; }

} while (stopzeit>Gettime()); //das ganze bis Zeit um (1s)



//Auswertung der Impulse


//Zurückgelegter Weg
cmright = ((rightimpuls / anzahldercodescheibensegmente_umfang)/5); // /5 da Übersetzungsverhältniss 1/5
cmleft = ((leftimpuls / anzahldercodescheibensegmente_umfang)/ 5 );

//Geschwindigkeit
cmsright = cmright * (Zeit/1000);
cmsleft = cmleft * (Zeit/1000); //da ms

//Beschleunigung
aright = (cmsright-cmsright1) / (Zeit-Zeit1);
aleft = (cmsleft-cmsleft1) / (Zeit-Zeit1);

Zeit1 = Zeit; //jetzige Zeit Zwischenspeichern für a beim nächsen turn
cmsright1 = cmsright; //jetzige Geschwindigkeit Zwischenspeichern für a beim nächsen turn
cmsleft1 = cmsleft; //jetzige Geschwindigkeit Zwischenspeichern für a beim nächsen turn

//Ausgabe





//rechtes
SerPrint("Rechtes Rad ");
PrintFloat(cmright,2,2);
SerPrint (" cm ");
PrintFloat(cmsright,2,2);
SerPrint(" cm/s" );
PrintFloat(aright,2,2);
SerPrint(" cm/s²");

//Lehrstellen zwischen rechts und links
SerPrint(" - ");

//links
SerPrint("Linkes Rad ");
PrintFloat(cmleft,2,2);
SerPrint (" cm ");
PrintFloat(cmsleft,2,2);
SerPrint(" cm/s ");
PrintFloat(aleft,2,2);
SerPrint(" cm/s²");

//2*absatz

SerPrint("\n\r\n\r");
}

}

MotorSpeed(0,0);
return 0;}


/*
void Odometrie (){
do {
OdometrieData(data); //Odo daten bereitstellen
if(data[0]<=760 + 50 || data[0]>=888 -50) //wenn data = trigerlevel
rightimpuls++; //impulse erhöhen
if(data[1]<=600 +50 || data[1]>8888 - 50) //siehe zwei drüber
leftimpuls++; //siehe zwei drüber

} while (stopzeit>Gettime());}*/


Wie geht den, dass mit Daten direkt in Excel importiert werden? Währe ganz net wenn das Programm das machen würde, dann müsste man nicht immer mit diesem Hyperterminal arbeiten und hätte eine saubere Liste.

damaltor
21.11.2007, 13:40
du hast doch bereits eine funktion erstellt, nämlich die funktion Odometrie(void) =)

NomiS
21.11.2007, 13:42
Aber diese geht nicht. Wie komme ich aus einer Funktion wieder heraus. Wie ist die Strucktur einer Funktion, was gibt es zu beachten.

Gruß NomiS

damaltor
21.11.2007, 14:16
ok. eine grundstruktur einer funktion sieht so aus:

[RÜCKGABETYP] [NAME]([EINGABETYP1] [EINGABENAME1], [EINGABETYP2] [EINGABENAME2], ...){
Programmcode;
return [RÜCKGABENAME];
}

Rückgabetyp: wenn ein wert zurückgegeben werden soll, zB so wie bei pollswitch, musst du hier hinschreiben von welchem typ die rückgabe ist. also zB char, int oder so. wenn kein wert zurückgegeben werden soll, zB wie bei OdometrieData, dann steht hier "void".

Name: hier steht, wie die funktion heissen soll. mit diesem namen kannst du die funktion dann im hauptprogramm aufrufen. zB: Odometrie (wird dann später durch Odometrei(...) aufgerufen)

EingabetypX: wenn du der funktion werte übergeben willst, dann musst du hier hinschreiben was das für werte sind. zB char, int...
EingabenameX: hier schreibst du hin, wie die werte innerhalb der funktion heissen sollen.
wenn du keine werte übergeben willst, dann kommt zwischen die klammern nur das wort "void". beispiel: PollSwitch(void) wird aufgerufen mit PollSwitch();
MotorSpeed(unsigned char speedleft, unsigned char speedright) wird zB aufgerufen mit MotorSpeed(255,255).

Dann kommt zwischen zwei geschweifte klammern {} der programmcode, hier wird gesagt was die funktion tun soll.

Rückgabename: mit return wird ein wert zurückgegeben, dessen name steht hier. wenn nichts zurückgegeben wird, kannst du bei einigen compilern die zeile weglassen. besser ist es jedoch, hier nur "return;" hinzuschreiben.

ein beispiel:



#include "asuro.h"

int addieren(int erstezahl, int zweitezahl){
int summe;
summe = erstezahl + zweitezahl;
return summe;
}

void saghallo(void){
SerWrite("Hallo",5);
return;
}

///////////////hier beginnt das hauptprogramm:
int main(void){

int meinezahl1;
int meinezahl2;
int meinesumme;

Init();

meinezahl1 = 123;
meinezahl2 = 456;
meinesumme = addieren(meinezahl1, meinezahl2);

saghallo();

while(1);
return 0;
}

es werden zwei zahlen festgelegt, mithilfe der eben definierten funtion addiert, und dann wird hallo im terminal ausgegeben.

NomiS
21.11.2007, 14:25
Danke damaltor dehr gut beschrieben kann man so was nicht mal ins wiki stellen? nur noch zwei Fragen!
1.) was bedeutet der Rückgabename nach return. In den Bsp´s im Buch ist das immer 0. Was bewirt diese

2.)du schreibst in deiner Funktion
int meinezahl1;
meinezahl1 = 123;

geht auch int meinezahl1 = 123;
oder ist die Variable dann statisch?

NomiS
21.11.2007, 14:42
OK ich habe das mal versucht. Ich wollte die Odometrie und die Ausgabe als Funktion machen. Jetzt kommen aber fehler.


test.c:88: warning: implicit declaration of function 'Odometrie'
test.c:112: warning: implicit declaration of function 'Ausgabe'
test.c: At top level:
test.c:361: warning: conflicting types for 'Odometrie'
test.c:88: warning: previous implicit declaration of 'Odometrie' was here
test.c:392: warning: conflicting types for 'Ausgabe'
test.c:112: warning: previous implicit declaration of 'Ausgabe' was here





#include <asuro.h>
#include <string.h> // für strlen


/*Left min/max, right min/max values da minimiert auf acht bit *4

+00150 *4 = 600 744 //data[0] left
+00222 *4 = 888
798
+00190 *4 = 760 852 //data[1] right
+00236 *4 = 944

*/
//Statische Vergabe

#define Triggerlevel 798
#define Hysteresis 25
#define LOW 0
#define HIGH 1

//Variablenverageb

int speed; //PWM des Rades
float cmsleft; //Metre pro Sekunde (Radgeschwindigkeit links
float cmsright; //Metre pro Sekunde (Radgeschwindigkeit rechts

float cmsleft1; // Vorherige Geschwindigkeit (für a)
float cmsright1; // Vorherige Geschwindigkeit (für a)

float cmleft; //Gefahrene Strecke links
float cmright; //Gefahrene Strecke rechts

float aleft; //Beschleunigung linkes Rad
float aright; //Beschleunigung rechtes Rad

unsigned int data [2]; //Array erstellen mit 2 Speicherzellen für Odometriedaten
//data [0] links T11
//data [1] rechts T12

signed int status[2]={0,0};

int Zeit = 1000; //Zeit in der die Impulse gezählt werden 1s
int Zeit1 = 0; //letzte Zeit zur bestimmung der Zeit dif (für a)

int leftimpuls = 0; //gezählte Impulse pro Zeit links
int rightimpuls = 0; //gezählte Impulse pro Zeit rechts

unsigned int long stopzeit;

int anzahldercodescheibensegmente_umfang = 1; //Breite eines Segmentes

//-----------------------------------------------------------------------------
int main(void)
{
BackLED(OFF,OFF); //alle LED werden im Programm zur Veranschaulichung genutzt
StatusLED(RED); //d.h. wo bin ich im Prog. die Backeled´s sind aus da Odometrie an


Init();
while(1){
//-----------------------------------------------------------------------------
//Intro für Hyperterminal
//-----------------------------------------------------------------------------
SerPrint("\t Telemetriedaten\n\r\n\r");

//Überschrift im Hyperterminal für Vorwärts

SerPrint("\tVorwärts\n\r\n\r");
//-----------------------------------------------------------------------------
//Los gehts beschleunigen
//-----------------------------------------------------------------------------

MotorDir(FWD,FWD); //Richtung festlegen

Zeit1 = 0 ; //muss vor der Schleife genullt werden fals nioch restwert aus letzter Schleife
cmsright1 = 0;
cmsleft1 = 0;
FrontLED(ON);
for (speed=80;speed>245;speed +=10){ //Geschwindigkeit von 80 auf 255 in 10er schritten
MotorSpeed(speed,speed); //Geschwindigkeit einlesen
StatusLED(RED);
leftimpuls = 0; //Impullse vor Zählvorgang auf null
rightimpuls = 0; //Impullse vor Zählvorgang auf null

//Detektierung der Impulse
stopzeit=Gettime()+Zeit; //1 sekunde Hell Dunkel Wechsel detektieren

Odometrie();



//Auswertung der Impulse


//Zurückgelegter Weg
cmright = ((rightimpuls / anzahldercodescheibensegmente_umfang)/5); // /5 da Übersetzungsverhältniss 1/5
cmleft = ((leftimpuls / anzahldercodescheibensegmente_umfang)/ 5 );

//Geschwindigkeit
cmsright = cmright * (Zeit/1000);
cmsleft = cmleft * (Zeit/1000); //da ms

//Beschleunigung
aright = (cmsright-cmsright1) / (Zeit-Zeit1);
aleft = (cmsleft-cmsleft1) / (Zeit-Zeit1);

Zeit1 = Zeit; //jetzige Zeit Zwischenspeichern für a beim nächsen turn
cmsright1 = cmsright; //jetzige Geschwindigkeit Zwischenspeichern für a beim nächsen turn
cmsleft1 = cmsleft; //jetzige Geschwindigkeit Zwischenspeichern für a beim nächsen turn

//Ausgabe
Ausgabe();


}

}

MotorSpeed(0,0);
return 0;}



void Odometrie (void){
do {
OdometrieData(data); //Odo daten bereitstellen

//Wechselt linker Sensor von niedrig auf hoch?
if((status[0]==LOW)&&(data[0]>Triggerlevel+Hysteresis)){
status[0] = HIGH;
leftimpuls++;}

//Wechselt linker Sensor von hoch auf niedrig?
if((status[0]==HIGH)&&(data[0]<Triggerlevel-Hysteresis)){
status[0] = LOW ;
leftimpuls++;}

//Wechselt rechter Sensor von niedrig auf hoch?
if((status[1]==LOW)&&(data[1]>Triggerlevel+Hysteresis)){
status[1] = HIGH;
StatusLED(RED);
rightimpuls++; }

//Wechselt rechter Sensor von hoch auf niedrig?
if((status[1]==HIGH)&&(data[1]<Triggerlevel-Hysteresis)){
status[1] = LOW;
rightimpuls++; }

} while (stopzeit>Gettime());
return;} //das ganze bis Zeit um (1s)




void Ausgabe (void){
//Ausgabe





//rechtes
SerPrint("Rechtes Rad ");
PrintFloat(cmright,2,2);
SerPrint (" cm ");
PrintFloat(cmsright,2,2);
SerPrint(" cm/s" );
PrintFloat(aright,2,2);
SerPrint(" cm/s²");

//Lehrstellen zwischen rechts und links
SerPrint(" - ");

//links
SerPrint("Linkes Rad ");
PrintFloat(cmleft,2,2);
SerPrint (" cm ");
PrintFloat(cmsleft,2,2);
SerPrint(" cm/s ");
PrintFloat(aleft,2,2);
SerPrint(" cm/s²");

//2*absatz

SerPrint("\n\r\n\r");
return;}



Wo müssen die Funktionen hin?

damaltor
21.11.2007, 14:56
ÜBER die main funktion!

radbruch
21.11.2007, 17:18
Hallo NomiS

Sehr gut wie das Programm jetzt schon aussieht, ganz großes Lob von mir dafür.

Du solltest getrennte Triggerlevel für beide Seiten definieren. Für rechts niedrig steht in deiner Tabelle 760. Dein aktueller Triggerlevel minus Hysterese (768-25) ist dann recht knapp; möglicherweise werden dadurch einige Impluse übersehen.

Aus der Wegrechnung werde ich immer noch nicht schlau, aber das wird sicher auch noch. Wie groß ist denn die Hex-Datei inzwischen(beide Werte, denn es sollte nun auch durch weniger Codezeilen die Datei kleiner sein)

Hast das hier schon gelesen?
https://www.roboternetz.de/wissen/index.php/C-Tutorial#Funktionen
Unter "Prototypen" steht auch, wie man Funktionen hinter main() unterbringen kann.

Gruß

mic

Sternthaler
22.11.2007, 01:21
Ja, Klasse, es wird.

Mit der Länge der Variablen:
-- int anzahldercodescheibensegmente_umfang = 1; //Breite eines Segmentes
solltes du vorsichtig sein.
Einige Compiler vertragen nur maximale Längen bei Namen. Dann kann es passieren, dass 2 Variablen mit so langen Namen nicht mehr unterschieden werden wenn sie sich nur hinten unterscheiden.
Wir hatten diese Problem mal bei einem Kunden, natürlich hektische Inbetriebname, und haben ein paar Stunden benötigt um den Fehler zu finden. Und der Compiler spuckte nur warnings aus, die man nicht beachtete. Selber Schuld also.

Zu deinem Programm:
Ich bekommen nach dem Übersetzten konstant 11 KByte (11.014) Hex-Datei mit immer 62 Blöcken zum Asuro.

Allerdings werden nur die Zeilen
- SerPrint("\t Telemetriedaten\n\r\n\r");
- SerPrint("\tVorwärts\n\r\n\r");
status-LED red
back-LED off
front-LED on
ausgeführt. Kein Motor läuft, und keine Daten werden gesendet.

Bei der Zeile
--- for (speed=80;speed>245;speed +=10)
steckt der Fehlerteufel
Nicht >, sondern < soll es heissen.

Nun ist das Programm mit 13 KByte (12.462 Byte) und 70 Blöcken zum Asuro ja noch gut handelbar.
Es werden nun Daten zum PC gesendet:
-- Rechtes Rad 0.00 cm 0.00 cm/s2.00 cm/s² - Linkes Rad 0.00 cm 0.00 cm/s 2.00 cm/s

Der Inhalt sieht mir noch nicht OK aus. Aber eins nach dem anderen. Da bist du ja der Rechenchef.

Gruß Sternthaler

NomiS
23.11.2007, 10:46
Hi vlt. kann ja mal jemand kurz das Programm anschauen. Nach dem ich die einzellnen Programmteile in Unterfunktionen eingeteilt habe geht gar nichts mehr.
Vorher kam wenigstens noch was im Hyperterminal an und die Räder haben sich gedreht (auch wenn im Hyperterminal immer 0.00 xx stand/vlt weiß da ja auch jemand woran das lag)
Die inaktiven LED-Funktionen sind zum Kontrollieren des Programmablaufs


#include <asuro.h>
#include <string.h> // für strlen


/*Left min/max, right min/max values da minimiert auf acht bit *4

+00150 *4 = 600 744 //data[0] left
+00222 *4 = 888
798
+00190 *4 = 760 852 //data[1] right
+00236 *4 = 944

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//---------------------------------------------------------------------------*/

//Statische Vergabe

#define Triggerlevel 798
#define Hysteresis 15
#define LOW 0
#define HIGH 1
#define einticklaenge 2 // /10 da 0,2mm //Gefahrene Strecke bei einem Tick

//Variablenverageb

int speed; //PWM des Rades
float cmsleft; //Metre pro Sekunde (Radgeschwindigkeit links
float cmsright; //Metre pro Sekunde (Radgeschwindigkeit rechts

float cmsleft1; // Vorherige Geschwindigkeit (für a)
float cmsright1; // Vorherige Geschwindigkeit (für a)

float cmleft; //Gefahrene Strecke links
float cmright; //Gefahrene Strecke rechts

float aleft; //Beschleunigung linkes Rad
float aright; //Beschleunigung rechtes Rad

unsigned int data [2]; //Array erstellen mit 2 Speicherzellen für Odometriedaten
//data [0] links T11
//data [1] rechts T12

signed int status[2]={0,0};

int Zeit = 1000; //Zeit in der die Impulse gezählt werden 1s
int Zeit1; //letzte Zeit zur bestimmung der Zeit dif (für a)

int leftimpuls; //gezählte Impulse pro Zeit links
int rightimpuls; //gezählte Impulse pro Zeit rechts

unsigned int long stopzeit;


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Subfunktionen
void Odometrie (void){


// StatusLED(GREEN);
leftimpuls = 0; //Impullse vor Zählvorgang auf null
rightimpuls = 0; //Impullse vor Zählvorgang auf null

//Detektierung der Impulse
stopzeit=Gettime()+Zeit; //1 sekunde Hell Dunkel Wechsel detektieren


do {
OdometrieData(data); //Odo daten bereitstellen

//Wechselt linker Sensor von niedrig auf hoch?
if((status[0]==LOW)&&(data[0]>Triggerlevel+Hysteresis)){ //Wenn vorher Low und jetz HI dann
status[0] = HIGH;
// FrontLED(ON); //
// FrontLED(OFF); //
leftimpuls++; //1 impuls ausgeben
}

//Wechselt linker Sensor von hoch auf niedrig?
if((status[0]==HIGH)&&(data[0]<Triggerlevel-Hysteresis)){
status[0] = LOW;
// FrontLED(ON);
// FrontLED(OFF);
leftimpuls++;
}

//Wechselt rechter Sensor von niedrig auf hoch?
if((status[1]==LOW)&&(data[1]>Triggerlevel+Hysteresis)){
status[1] = HIGH;
// StatusLED(GREEN);
// StatusLED(OFF);
rightimpuls++;
}

//Wechselt rechter Sensor von hoch auf niedrig?
if((status[1]==HIGH)&&(data[1]<Triggerlevel-Hysteresis)){
status[1] = LOW;
// StatusLED(GREEN);
// StatusLED(OFF);
rightimpuls++;
}

} while (stopzeit>Gettime());
return;} //das ganze bis Zeit um (1s)
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void Auswertung (void){

// BackLED(ON,OFF);

//Auswertung der Impulse


//Zurückgelegter Weg
cmright = (rightimpuls *(einticklaenge /10)); // /5 da Übersetzungsverhältniss 1/5
cmleft = (leftimpuls *(einticklaenge /10));

//Geschwindigkeit
cmsright = cmright * (Zeit/1000);
cmsleft = cmleft * (Zeit/1000); //da ms

//Beschleunigung
aright = (cmsright-cmsright1) / (Zeit-Zeit1);
aleft = (cmsleft-cmsleft1) / (Zeit-Zeit1);

Zeit1 = Zeit; //jetzige Zeit Zwischenspeichern für a beim nächsen turn
cmsright1 = cmsright; //jetzige Geschwindigkeit Zwischenspeichern für a beim nächsen turn
cmsleft1 = cmsleft; //jetzige Geschwindigkeit Zwischenspeichern für a beim nächsen turn


// BackLED(OFF,OFF);

return;}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void Ausgabe (void){
//Ausgabe
// BackLED(OFF,ON);

//rechts
SerPrint("Rechtes Rad ");
PrintFloat(cmright,2,2);
SerPrint (" cm ");
PrintFloat(cmsright,2,2);
SerPrint(" cm/s" );
PrintFloat(aright,2,2);
SerPrint(" cm/s²");

//Zeilenwechsel zwischen rechts und links
SerPrint("\n\r\n\r");

//links
SerPrint("Linkes Rad ");
PrintFloat(cmleft,2,2);
SerPrint (" cm ");
PrintFloat(cmsleft,2,2);
SerPrint(" cm/s ");
PrintFloat(aleft,2,2);
SerPrint(" cm/s²");

//2*absatz

SerPrint("\n\r\n\r\n\r\n\r");
// BackLED(OFF,OFF);

return;}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void Nullen_Sekunderwerte_a (void){

// StatusLED(RED);

Zeit1 = 0 ;
cmsright1 =0;
cmsleft1 =0;

// StatusLED(OFF);

return;}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int main(void)
{
BackLED(OFF,OFF); //alle LED werden im Programm zur Veranschaulichung genutzt
StatusLED(OFF); //d.h. wo bin ich im Prog. die Backeled´s sind aus da Odometrie an


Init();
while(1){
// StatusLED(OFF);
//-----------------------------------------------------------------------------
//Intro für Hyperterminal
//-----------------------------------------------------------------------------
SerPrint("\t\t\tTelemetriedaten\n\r\n\r");

//Überschrift im Hyperterminal für Vorwärts

SerPrint("\t\tVorwärts\n\r\n\r");
//-----------------------------------------------------------------------------
//Los gehts beschleunigen
//-----------------------------------------------------------------------------
MotorDir(FWD,FWD); //Richtung festlegen

Nullen_Sekunderwerte_a();

StatusLED(GREEN);

//FrontLED(ON);

for (speed=80;speed<245;speed +=10){ //Geschwindigkeit von 80 auf 255 in 10er schritten speed kleiner 245
MotorSpeed(speed,speed); //Geschwindigkeit einlesen

Odometrie();

Ausgabe();

Ausgabe();
}
//-----------------------------------------------------------------------------
//Langsamer werden
//-----------------------------------------------------------------------------
Nullen_Sekunderwerte_a();

for (speed=255;speed>85;speed -=10){
MotorSpeed(speed,speed);

Odometrie();

Ausgabe();

Ausgabe();
}
//-----------------------------------------------------------------------------
//Rückwärts
//-----------------------------------------------------------------------------


//Überschrieft im Hyperterminal

SerPrint("\t\t\t\tRückwärts\n\r\n\r");
//-----------------------------------------------------------------------------
//Los gehts beschleunigen
//-----------------------------------------------------------------------------
MotorDir(RWD,RWD);

Nullen_Sekunderwerte_a();

for (speed=80;speed<245;speed +=10){
MotorSpeed(speed,speed);

Odometrie();

Ausgabe();

Ausgabe();
}
//-----------------------------------------------------------------------------
//Langsamer werden
//-----------------------------------------------------------------------------
Nullen_Sekunderwerte_a();

for (speed=255;speed>85;speed -=10){
MotorSpeed(speed,speed);

Odometrie();

Ausgabe();

Ausgabe();
}
}
MotorSpeed(0,0);
return 0;}

Danke schon mal im Voraus

NomiS
23.11.2007, 11:23
OK, das mit es kommt nix hat sich erledigt.
Hab vor lauter Bäumen den Wald nicht gesehen.
Hyperterminal war nicht angewählt.....
Jetzt kommen aber immer noch 0.00xx raus und es erscheinen irgendwie immer 2 Messreihen dann gibt er eine Pause und dann kommen wieder zwei Messreihen. Woran liegt das?

Sternthaler
23.11.2007, 16:42
@NomiS
Ich hatte dein Programm schon angeschaut und dir einen Tip zur Korrektur gegeben. Siehe Beitrag von 02:21. Extra für dich!
Den Hinweis von mir, dass da ein Fehler in der for()-Schleife ist, hast du ja auch in der letzten Version behoben. Dieser Fehler kann ja nun nicht am Hyperterminal gelegen haben.

Das ich dir auch schon geschrieben habe, dass FAST immer 0.00 rauskommt, kannst du auch nachlesen. Geschrieben hatte ich dir hierzu, dass du mal selber danach siehst.
Warum also nimmst du nicht mal eine Version, repariert den Inhalt, und strukturiert erst danach wieder alles um? Es ist dann für 'Helferlein' etwas einfacher, und es muss nicht jedesmal neu nach Syntax-Fehlern gesucht werden.

Sternthaler

NomiS
28.11.2007, 06:53
So ich hab jetzt hoffentlich mal alles nach euren Tips geändert.
Leider gehts immer noch nicht so ganz.
Das Eigenartige ist: Ohne die SerPrintbefehle, die den Programmstatus (wo ist der ASURO gerade im Programm) angeben funktioniert das Programm eine zwei durchläufe. Dann hängt es sich auf. Mit den SerPrints geht gar nix. Mal geht die StatusLED auf ROT, mal auf GRÜN, mal AUS. Dann geben die Motoren Vollgas ... . Keine Ahnung was da los ist.



#include <asuro.h>
#include <string.h> // für strlen


/*Left min/max, right min/max values da minimiert auf acht bit *4

+00150 *4 = 600 744 //data[0] left
+00222 *4 = 888
798
+00190 *4 = 760 852 //data[1] right
+00236 *4 = 944

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//---------------------------------------------------------------------------*/

//Statische Vergabe

#define Triggerlevel 798
#define Hysteresis 15
#define LOW 0
#define HIGH 1


//Variablenverageb

int einticklaenge = 2; // /10 da 2mm 0.02cm //Gefahrene Strecke bei einem Tick

int speed;
//PWM des Rades
float cmsleft; //Metre pro Sekunde (Radgeschwindigkeit links
float cmsright; //Metre pro Sekunde (Radgeschwindigkeit rechts

float cmsleft1; // Vorherige Geschwindigkeit (für a)
float cmsright1; // Vorherige Geschwindigkeit (für a)

float cmleft; //Gefahrene Strecke links
float cmright; //Gefahrene Strecke rechts

float aleft; //Beschleunigung linkes Rad
float aright; //Beschleunigung rechtes Rad

unsigned int data [2]; //Array erstellen mit 2 Speicherzellen für Odometriedaten
//data [0] links T11
//data [1] rechts T12

signed int status[2]={0,0};

int Zeit = 1000; //Zeit in der die Impulse gezählt werden 1s
int Zeit1; //letzte Zeit zur bestimmung der Zeit dif (für a)

int leftimpuls; //gezählte Impulse pro Zeit links
int rightimpuls; //gezählte Impulse pro Zeit rechts

unsigned int long stopzeit;


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void Nullen_Sekunderwerte_a (void){
Zeit1 = 0 ;
cmsright1 =0;
cmsleft1 =0;


return;}


void Funktionsblock (void){

SerPrint("\n\rFunktionsblock begonnen\n\r");
SerPrint("\n\rNullen\n\r");

leftimpuls = 0; //Impullse vor Zählvorgang auf null
rightimpuls = 0; //Impullse vor Zählvorgang auf null
cmright = 0;
cmleft = 0;
cmsright = 0;
cmsleft = 0;
aright = 0;
aleft = 0;

//Detektierung der Impulse
stopzeit=Gettime()+Zeit; //1 sekunde Hell Dunkel Wechsel detektieren

SerPrint("\n\rOdometrie\n\r");

do {
OdometrieData(data); //Odo daten bereitstellen

//Wechselt linker Sensor von niedrig auf hoch?
if((status[0]==LOW)&&(data[0]>Triggerlevel+Hysteresis)){ //Wenn vorher Low und jetz HI dann
status[0] = HIGH;

leftimpuls++; //1 impuls ausgeben
}

//Wechselt linker Sensor von hoch auf niedrig?
if((status[0]==HIGH)&&(data[0]<Triggerlevel-Hysteresis)){
status[0] = LOW;

leftimpuls++;
}

//Wechselt rechter Sensor von niedrig auf hoch?
if((status[1]==LOW)&&(data[1]>Triggerlevel+Hysteresis)){
status[1] = HIGH;

rightimpuls++;
}

//Wechselt rechter Sensor von hoch auf niedrig?
if((status[1]==HIGH)&&(data[1]<Triggerlevel-Hysteresis)){
status[1] = LOW;

rightimpuls++;
}

} while (stopzeit>Gettime());


//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
SerPrint("\n\rAuswertung\n\r");

//Auswertung der Impulse

//Zurückgelegter Weg
cmright = rightimpuls * einticklaenge /100;
cmleft = leftimpuls * einticklaenge /100;

//Geschwindigkeit
cmsright = cmright / (Zeit/1000);
cmsleft = cmleft / (Zeit/1000); //da ms

//Beschleunigung
aright = (cmsright-cmsright1) / (Zeit-Zeit1);
aleft = (cmsleft-cmsleft1) / (Zeit-Zeit1);

Zeit1 = Zeit; //jetzige Zeit Zwischenspeichern für a beim nächsen turn
cmsright1 = cmsright; //jetzige Geschwindigkeit Zwischenspeichern für a beim nächsen turn
cmsleft1 = cmsleft; //jetzige Geschwindigkeit Zwischenspeichern für a beim nächsen turn



//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

SerPrint("\n\rAusgabe\n\r");

//rechts
SerPrint("\n\rRechtes Rad\t");

PrintInt(rightimpuls);
SerPrint(" Impulse-Rechts\t");

PrintFloat(cmright,2,2);
SerPrint (" cm\t");

PrintFloat(cmsright,2,2);
SerPrint(" cm/s\t");

PrintFloat(aright,2,2);
SerPrint(" cm/s²");

//Zeilenwechsel zwischen rechts und links
SerPrint("\n\r\n\r");

//links
SerPrint("\n\rLinkes Rad\t");

PrintInt(leftimpuls);
SerPrint(" Impulse-Links\t");

PrintFloat(cmleft,2,2);
SerPrint (" cm\t");
PrintFloat(cmsleft,2,2);
SerPrint(" cm/s\t");
PrintFloat(aleft,2,2);
SerPrint(" cm/s²");

//2*absatz

SerPrint("\n\r\n\r\n\r\n\r");

SerPrint("\n\rFunktionsblock beendet\n\r");

StatusLED(OFF);
return;}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

int main(void)
{ BackLED(OFF,OFF);
Init();

while(1){
//-----------------------------------------------------------------------------
//Intro für Hyperterminal
//-----------------------------------------------------------------------------
SerPrint("Telemetriedaten\n\r\n\r");

//Überschrift im Hyperterminal für Vorwärts

SerPrint("Vorwärts\n\r\n\r");
//-----------------------------------------------------------------------------
//Los gehts beschleunigen
//-----------------------------------------------------------------------------
MotorDir(FWD,FWD); //Richtung festlegen
Nullen_Sekunderwerte_a();


for (speed=120;speed<245;speed +=10){ //Geschwindigkeit von 80 auf 255 in 10er schritten speed kleiner 245
MotorSpeed(speed,speed); //Geschwindigkeit einlesen

Funktionsblock();

}
//-----------------------------------------------------------------------------
//Langsamer werden
//-----------------------------------------------------------------------------
Nullen_Sekunderwerte_a();

for (speed=255;speed>125;speed -=10){
MotorSpeed(speed,speed);

Funktionsblock();

}
//-----------------------------------------------------------------------------
//Rückwärts
//-----------------------------------------------------------------------------


//Überschrieft im Hyperterminal

SerPrint("Rückwärts\n\r\n\r");
//-----------------------------------------------------------------------------
//Los gehts beschleunigen
//-----------------------------------------------------------------------------
MotorDir(RWD,RWD);

Nullen_Sekunderwerte_a();

for (speed=120;speed<245;speed +=10){
MotorSpeed(speed,speed);

Funktionsblock();

}
//-----------------------------------------------------------------------------
//Langsamer werden
//-----------------------------------------------------------------------------
Nullen_Sekunderwerte_a();

for (speed=255;speed>125;speed -=10){
MotorSpeed(speed,speed);

Funktionsblock();

}
}

MotorSpeed(0,0);
return 0;}


Bitte schaut es euch mal kurz an. Wäre nett wenn es jemand korrigieren könnte, mir erklärt was er gemacht hat und was nicht gegangen ist. Habe nur noch bis morgen Zeit.

Gruß NomiS

m.a.r.v.i.n
28.11.2007, 19:25
Hallo NomiS,

ich habe dein Programm mal ausprobiert. Mit den folgenden Änderungen bekomme ich ganz vernünftige Werte für die Geschwindigkeit.
Die Beschleunigungswerte habe ich erst mal weggelassen, diese ergeben nämlich negativ Werte und bringen dadurch das Programm zum Absturz (vielleicht findest du selbst heraus, wie man das verhindern kann). Die weiteren Änderungen, die ich gemacht habe:
alle zur Berechnung verwendeten Variablen und Konstanten in Float-Werte umwandeln:



//Auswertung der Impulse

//Zurückgelegter Weg
cmright = (float)rightimpuls * (float)einticklaenge /100.0;
cmleft = (float)leftimpuls * (float)einticklaenge /100.0;

//Geschwindigkeit
cmsright = cmright / ((float) Zeit/1000.0);
cmsleft = cmleft / ((float)Zeit/1000.0); //da ms

//Beschleunigung
// aright = (cmsright-cmsright1) / ((float)(Zeit-Zeit1));
// aleft = (cmsleft-cmsleft1) / ((float)(Zeit-Zeit1));

Zeit1 = Zeit; //jetzige Zeit Zwischenspeichern für a beim nächsen turn
cmsright1 = cmsright; //jetzige Geschwindigkeit Zwischenspeichern für a beim nächsen turn
cmsleft1 = cmsleft; //jetzige Geschwindigkeit Zwischenspeichern für a beim nächsen turn