du hast doch bereits eine funktion erstellt, nämlich die funktion Odometrie(void) =)
Druckbare Version
du hast doch bereits eine funktion erstellt, nämlich die funktion Odometrie(void) =)
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
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:
es werden zwei zahlen festgelegt, mithilfe der eben definierten funtion addiert, und dann wird hallo im terminal ausgegeben.Code:#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;
}
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?
OK ich habe das mal versucht. Ich wollte die Odometrie und die Ausgabe als Funktion machen. Jetzt kommen aber fehler.
Code: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
Wo müssen die Funktionen hin?Code:#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;}
ÜBER die main funktion!
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/in...ial#Funktionen
Unter "Prototypen" steht auch, wie man Funktionen hinter main() unterbringen kann.
Gruß
mic
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
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
Danke schon mal im VorausCode:#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;}
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?