Archiv verlassen und diese Seite im Standarddesign anzeigen : Asuroprojekt mit Odometrie und LCD-Display
Hermann Wessel
29.03.2011, 16:07
Hallo liebe Community,
ich habe zurzeit ein Projekt mit dem Asuro in der Schule. Ich sollte es mit dem LCD-Display ausrüsten, dann mit der Odometrie die Geschwindigkeit auslesen und diese dann mit dem gesamten Weg und die durchschnittsgeschwindigkeit ausgeben.
Doch dabei bin ich auf einige Probleme gestoßen.
Ich habe ein Programm geschrieben das mir die Odometriedaten im hyperterminal ausgibt.
Doch leider weiß ich nicht, wie ich aus diese Odometriedaten die Geschwindigkeit bzw die Strecke ausfindig machen kann.
Desweiteren fällt mir keine Idee ein, wie ich die Zeit stoppen kann, da ich die ja für die Durchschnittsgeschwinigkeit brauche.
Ich habe mich mitlerweise damit 8 Stunden am Stück beschäftigt, diese Probleme zu lösen. Habe auch schon unzählige Seiten und Beiträge dazu durchgelesen aber bin nicht schlau geworden.
Kann mir irgendeiner helfen?
Mfg Hermann
PS: In der Schule haben wir das Odometrieren nicht durchgenommen, also bin ich in dem Gebit ein Anfänger. Und mein Lehrer hat davon selber keine ahnung, da ich der erste Schüler bin der sowas macht..
homer3345
30.03.2011, 19:53
Ich kann dir leider nur bedingt weiterhelfen! :(
Wie man die Zeit zählt weiß ich leider auch überhaupt nicht!
Hier erstmal ein Programmcode zum Gerradeausfahren mit Odometrie (Aus dem Asuro Buch :D)!
#include "asuro.h"
#define TRIGGERLEVEL 600
#define HYSTERESIS 10
#define LOW 0
#define HIGH 1
int main(void)
{
unsigned int data[2];
signed int status[2]={0,0};
signed int difference=0;
unsigned long int distance=0;
signed int speed;
int i;
Init();
MotorDir(FWD,FWD);
while(1) {
// Odometrie auslesen
OdometrieData(data);
// Links von niedrig auf hoch?
if ((status[0]==LOW) && (data[0]>TRIGGERLEVEL+HYSTERESIS)) {
status[0]=HIGH;
difference++;
distance++;
}
// Links von hoch auf niedrig?
if ((status[0]==HIGH) && (data[0]<TRIGGERLEVEL-HYSTERESIS)) {
status[0]=LOW;
difference++;
distance++;
}
// Rechts von niedrig auf hoch?
if ((status[1]==LOW) && (data[1]>TRIGGERLEVEL+HYSTERESIS)) {
status[1]=HIGH;
difference--;
}
// Rechts von hoch auf niedrig?
if ((status[1]==HIGH) && (data[1]<TRIGGERLEVEL-HYSTERESIS)) {
status[1]=LOW;
difference--;
}
// Wenn difference über dem erlaubten Wert ist
if (difference<-speed) difference=-speed;
if (difference>speed) difference=speed;
// Status LED nach der Odometrie leuchten lassen
StatusLED(status[0]+status[1]*2);
// difference auf Motoren verteilen
if (difference>0) MotorSpeed(speed-difference,speed);
else MotorSpeed(speed,speed+difference);
}
return 0;
}
Jetzt würde die Variable distance nach jedem Odometrietick den Wert um 1 erhöhen (Bei mir wären das 40 Ticks pro Umdrehung! Der Radumfang beträgt ca. 116mm) jetzt muss man nur noch gucken, dass man zählt wie viele Ticks es jede Sekunde gibt!
radbruch
30.03.2011, 20:46
Hallo
Mit der orginalen CD-Library des asuro und ohne gute C-Kenntnisse ist die Zeitmessung wohl nicht lösbar. Deshalb würde ich dir raten die Library zu tauschen. Obwohl es inzwischen die sehr umfangreiche Version v2.8 (http://sourceforge.net/projects/asuro/) und auch die TinyLib (http://sourceforge.net/projects/libtinyasuro/) gibt, rate ich Einsteigern eher zu Version v2.3:
asuroLib v2.3 (http://sourceforge.net/projects/asuro/files/AsuroLib/asuro%20lib%20V2.3/)
Zum Installieren werden alle vorhandenen asuro.c und asuro.h durch die neuen Versionen aus dem Zip ersetzt.
Wesentliche Neuerungen gegenüber der CD-Version ist der 36kHz-Takt zur Zeitmessung mit Sleep(), die Ansteuerung der IR-Led und die Funktionen PrintInt() ubd Msleep().
Ebenfalls neu und für deine Zeitmessung gut geeignet ist die Funktion Gettime(). Sie liefert als 32-Bit-Wert die Anzahl der Millisekunden zurück, die seit dem Programmstart vergangen sind.
Zur Odometrieauswertung enthält sie zusätzlich die Funktionen Encoder_Init(), Encoder_Start(), Encoder_Stop() und Encoder_Set(int,int) zum Initialisieren, Starten, Stoppen und Setzen der Startwerte für die Odometriefunktion. Eine Anpassung an die Helligkeitswerte des asuro kann man in der Funktion SIGNAL (SIG_ADC) in asuro.c vornehmen. Die Zählung erfolgt interruptgesteuert im Hintergrund, die Zählwerte stehen dann jeweils in encoder[0] und encoder[1]. (Theoretisch, weil ich das selbst noch nie ausprobiert habe. :)
Wenn du nicht klarkommst, melde dich einfach nochmals. Ich kann's halt (wie immer) leider nicht selbst testen...
Gruß
mic
Edit:
Mit v2.3 würde ich es etwa so versuchen:
#include "asuro.h"
int left=0, right=0;
unsigned long time;
unsigned long time_left=0, time_right=0;
unsigned long temp_time_left=0, temp_time_right=0;
int main(void)
{
Init();
Encoder_Init();
Msleep(500);
while(1)
{
StatusLED(RED);
while((encoder[LEFT]==left) && (encoder[RIGHT]==right));
cli();
time=Gettime();
sei();
if(encoder[LEFT] != left)
{
cli();
left=encoder[0];
temp_time_left=time-time_left;
time_left=time;
sei();
StatusLED(GREEN);
SerWrite("/n/rLinks: ", 10);
PrintInt(left);
SerWrite(" ", 1);
PrintInt(temp_time_left & 0x7fff);
}
if(encoder[RIGHT] != right)
{
cli();
right=encoder[1];
temp_time_right=time-time_right;
time_right=time;
sei();
StatusLED(YELLOW);
SerWrite("/n/rRechts: ", 10);
PrintInt(right);
SerWrite(" ", 1);
PrintInt(temp_time_right & 0x7fff);
}
SerWrite("/n/r", 2);
}
return(0);
}(ungetestet)
Hermann Wessel
31.03.2011, 15:02
ich bedanke mich schonma sehr bei euch :)
@homer hab ich schon ausprobiert geht nich xD
@radbruch was soll das programm denn bewirken? bzw was wird mir da ausgegeben?
mein lehrer meinte aber das ich das mit der aktuellen version tun soll..
und das programm funktioniert nicht, die statusled bleibt die ganze zeit rot
radbruch
31.03.2011, 16:35
Hallo
Es war ja zu befürchten, dass das Programm nicht funktioniert. Es sollte eigentlich die Autoencoder-Funktion aktivieren und dann auf die Flankenwechsel der Odoscheiben warten. Wenn der Wechsel erkannt wird (das jeweilige Rad muss man dazu natürlich von Hand drehen), sollte der aktuelle Zählerstand und die vergangene Zeit seit dem letzten Flankenwechsel ausgegeben werden. Wenn die StatusLED immer rot bleibt (und nichts zu Terminal gesendet wird) sind die Pegel möglicherweise ungünstig gewählt (orginal: 140 für fallend, 160 für steigend).
Auf den ersten Blick scheint hier ein kleiner Bug versteckt zu sein:
SIGNAL (SIG_ADC)
{
static unsigned char tmp[2],flag[2],toggle;
if (autoencode){
tmp[toggle]= ADCH;
if (toggle) ADMUX = (1 <<ADLAR) | (1 <<REFS0) | WHEEL_RIGHT;
else ADMUX = (1 <<ADLAR) | (1 <<REFS0) | WHEEL_LEFT;
if ( (tmp[toggle] < 140) && (flag[toggle] == TRUE)) {
encoder[toggle] ++;
flag[toggle] = FALSE;
}
if ( (tmp[toggle] > 160) && (flag[toggle] == FALSE)) {
encoder[toggle] ++;
flag[toggle] = TRUE;
}
toggle ^= 1;
}(Aus der Datei asuro.c der 2.3er Lib)
tmp[toggle] wird mit dem letzten Messwert des ADC geladen. Allerdings wird nur das Highbyte geladen. Da aber ADLAR in ADMUX ebenfalls gesetzt ist und das Ergebniss deshalb vom ADC linksbündig ausgegeben wird, passt das schon. Weil du aber eh nicht mit dieser Version der Lib arbeiten sollst/willst, kannst du das alles vergessen ;)
Versuchen wir also einen anderen Ansatz:
Ich habe ein Programm geschrieben das mir die Odometriedaten im hyperterminal ausgibt.Kann dieses Programm schon die Segmente der Codescheiben zählen oder gibt es nur die gemessenen Helligkeitswerte am Terminal aus? Wenn es Segmente zählt, kannst du den nächsten Absatz überspringen.
Die Odo-Sensoren messen die Helligkeit des Codescheibenbereichs, der sich direkt vor den Sensoren befindet. Diese Helligkeit schwankt zwischen einem maximalen (dunkles Segment) und einem minimalen Wert (helles Segment), der Werteverlauf bei drehender Codescheibe ist in etwa sinusförmig. Um in diesen Werten die Flanken der Codesegmente zu erkennen kann man entweder prüfen, ob der aktuell gemessene Wert, im Vergleich zu zuletzt gemessenen Wert,von der unteren Wertebereichshälfte in die obere Wertebereichshälfte gewechselt ist (, oder entsprechend von der oberen in die untere Hälfte). Diese Methode wird am häufigsten angewand, z.B. auch im Codeschnippsel der ADC-ISR oben. Alternativ kann man den Flankenwechsel auch daran erkennen, dass mehrere aufeinander folgende Messungen immer steigende oder fallende Werte ergeben. Wichtig bei allen Anwendung ist die axiale Fixierung des Codescheibenzahnrads, weil eine Abstandsänderung der Scheibe zu den Sensoren die Messwerte beinflussen. Günstig ist zusätzlich eine Abschirmung der Sensoren gegen Fremdlicht.
Um mit den erkannten Flanken die Geschwindigleit zu messen, könnte man blockierend auf aufeinander folgende steigende (oder fallende) Flankenwechsel warten und gleichzeitig eine Zählvariable hochzählen. Der Zählwert steht dann im umgekehrten Verhältniss zur (relativen) Geschwindigkeit. Zur Messung der absoluten Geschwindigkeit ist eine Funktion auf Timerbasis nötig. Bei diesem Ansatz wird die Zählvariable in der ISR des Timers erhöht und beim Flankenwechsel vom Hauptprogramm ausgelesen.
Viel Spaß und Erfolg beim Umsetzen...
Gruß
mic
PS zum homer-Programm:
Der TRIGGERLEVEL sollte etwa der Mittelwert der gemessenen Werte sein. Welchen Wert hat "speed"?
Hermann Wessel
31.03.2011, 17:09
ja ok im großen und ganzen habe ich das jetz verstanden
auf der einen seite lag der bei knapp 600 also passt das undgefähr.
emm ebend ma kurz ne andere frage
#include "stdlib.h"
#include "asuro.h"
#include "lcd.h"
#include "i2c.h"
int o = 1;
void start(int speed)
{
int keys;
int i = 1;
int zaehler = 0 ;
while(i >0)
{
keys = PollSwitchLCD();
if (keys & LCD_KEY_YELLOW) //schwarzer Taster
{
while ( zaehler == 0)
{
if(speed < 355) //Geschwindigkeit erhöhen
{
speed = speed +10;
ClearLCD();
PrintSetLCD(0,0,"Geschwindigkeit");
SetCursorLCD(0, 1);
zaehler = zaehler +1;
PrintIntLCD(speed);
}
zaehler = zaehler +1;
}
}
else if (keys & LCD_KEY_RED ) //roter Taster
{ //wechseln von der Geschwindigkeiseinstellung
i = 0; //in den Messbetrieb
}
else if (keys & LCD_KEY_BLUE ) //Blauer Taster
{
while ( zaehler == 0)
{
if(speed >0)
{
speed = speed -10; //Geschwindigkeit vermindern
ClearLCD();
PrintSetLCD(0,0,"Geschwindigkeit");
SetCursorLCD(0, 1);
PrintIntLCD(speed);
zaehler = zaehler +1;
}
zaehler = zaehler +1;
}
}
if(!keys) // für das einmalige hochzählen beim drücken eines knopfes
{
Msleep(100);
zaehler = 0;
}
}
o--;
}
//Hauptprogramm
int main(void)
{
//Geschwindigkeit
//void int speed = 100;
int speed = 100;
Init();
InitI2C();
InitLCD();
GREEN_LED_ON;
while(o > 0)
{
PrintSetLCD(0,0,"Geschwindigkeit");
SetCursorLCD(0, 1);
PrintIntLCD(speed);
start(speed);
}
MotorDir(FWD,FWD);
MotorSpeed(speed,speed);
return 0;
}
weshalb hat speed unten immernoch hundert obwohl ich den wert oben verändert habe?
radbruch
31.03.2011, 17:16
while(o > 0)
{
...
}
MotorDir(FWD,FWD);
MotorSpeed(speed,speed);
return 0;
}
Achtung! Wenn das return erreicht wird, springt das Programm irgendwohin! Das kann bleibende Schäden am asuro verursachen!
Hermann Wessel
31.03.2011, 17:21
ja ok hab ich sofort entfernt^^
doch weswegen hat er unten denn immernoch speed = 100 obwohl ich den wert oben durch tastereingabe verändert habe?
Und welcher Tastereingaben meinst du? Mein Glasskügel fehlt mir wieder. :(
Hermann Wessel
31.03.2011, 20:15
emm wie gesagt ich hab das ja mit dem lcd-display programmiert und dieser besitzt 3 taster
und dann hab ich halt ne funktion geschrieben, die von der main aufgerufen wird, die dann bei tasterdrücken die vaiable speed 10 höher oder niedriger setzt
aber der wert bleibt in der funktion und geht nich mit rüber ins hauptporgramm
glasskügel?
emm wie gesagt ich hab das ja mit dem lcd-display programmiert und dieser besitzt 3 taster
und dann hab ich halt ne funktion geschrieben, die von der main aufgerufen wird, die dann bei tasterdrücken die vaiable speed 10 höher oder niedriger setzt
aber der wert bleibt in der funktion und geht nich mit rüber ins hauptporgramm
glasskügel?
Einer Magische Glasskügel:
http://www.joepaduda.com/scrambled-toast-crystal-ball.JPG
Na ja, dass das LCD-display Taster hat ist mir schon bekannt. Aber in welcher Folge sind sie an geprellt.
radbruch
31.03.2011, 20:46
Hallo
Hier zuerst mal dein etwas umformatierter Code:
#include "stdlib.h"
#include "asuro.h"
#include "lcd.h"
#include "i2c.h"
int o = 1;
void start(int speed)
{
int keys;
int i = 1;
int zaehler = 0 ;
while(i >0)
{
keys = PollSwitchLCD();
if (keys & LCD_KEY_YELLOW) //schwarzer Taster
{
while ( zaehler == 0)
{
if(speed < 355) //Geschwindigkeit erhöhen
{
speed = speed +10;
ClearLCD();
PrintSetLCD(0,0,"Geschwindigkeit");
SetCursorLCD(0, 1);
zaehler = zaehler +1;
PrintIntLCD(speed);
}
zaehler = zaehler +1;
}
}
else if (keys & LCD_KEY_RED ) //roter Taster
{ //wechseln von der Geschwindigkeiseinstellung
i = 0; //in den Messbetrieb
}
else if (keys & LCD_KEY_BLUE ) //Blauer Taster
{
while ( zaehler == 0)
{
if(speed >0)
{
speed = speed -10; //Geschwindigkeit vermindern
ClearLCD();
PrintSetLCD(0,0,"Geschwindigkeit");
SetCursorLCD(0, 1);
PrintIntLCD(speed);
zaehler = zaehler +1;
}
zaehler = zaehler +1;
}
}
if(!keys) // für das einmalige hochzählen beim drücken eines knopfes
{
Msleep(100);
zaehler = 0;
}
}
o--;
}
//Hauptprogramm
int main(void)
{
//Geschwindigkeit
//void int speed = 100;
int speed = 100;
Init();
InitI2C();
InitLCD();
GREEN_LED_ON;
while(o > 0)
{
PrintSetLCD(0,0,"Geschwindigkeit");
SetCursorLCD(0, 1);
PrintIntLCD(speed);
start(speed);
}
MotorDir(FWD,FWD);
MotorSpeed(speed,speed);
return 0;
}Was mir als Wichtigstes erscheint: Eigentlich dürftest du nur einmal eine Ausgabe von speed erhalten, denn nach dem ersten Aufruf von start() wird o (sehr schlechter Variablenname!) zu 0 und das Programm verläßt nach MotorSpeed(); den asuro (und verschwindet im Nirwana!):
while(o > 0)
{
...
PrintIntLCD(speed);
start(speed);
}
MotorDir(FWD,FWD);
MotorSpeed(speed,speed);
return 0;
}
Zur besseren Übersichtlichkeit würde ich die if/else-Verschachtelungen in Start() durch switch/case ersetzen. Dann würde ich das Hauptprogramm in eine Endlosschleife packen und dann einen neuen Versuch starten.
"Würde", denn ohne LCD mit seiner Lib und der I2C-Lib kann ich nun überhaupt nichts mehr selbst testen, ich kann's nun nicht mal mehr übersetzen. :(
Aber egal, mach mal weiter.
Gruß
mic
Edit: Anstelle von while(o > 0) ein while(1) wäre ein schneller Test für die start()-Funktion ohne Motorbewegung. ;)
Hermann Wessel
31.03.2011, 21:15
hm ich glaube wir reden an einander vorbei :D:D
in dem programm gebe ich ja die variable speed zur funktion start und dort kann ich das ja mithilfe der taster rauf oder runter setzen
das problem ist lediglich das er den wert speed nicht wieder zur main gibt, sondern nur mit dem definierten wert 100 nimmt.
im internet habe ich gelesen das (int &speed) helfen sollte funktioniert aber nicht.
das ist garnicht das fertige programm doch das problem ist mir beim schreiben des programmes aufgefallen das das nich funktioniert.
bei bedarf kann ich hier das fertige programm poste
mfg
Hermann
radbruch
31.03.2011, 21:21
Upps, du hast recht, wir reden aneinander vorbei. Versuche es mal so:
void start()
{
....
start() sollte dann die Variable speed von main() übenehmen. Wenn's dann immer noch nicht funzt:
//Hauptprogramm
int speed = 100;
int main(void)
{
Init();
...
So ist speed auf jeden Fall global
Oder start() als Funktion mit Rückgabewert:
int start(int speed)
{
...
}
o--;
return(speed);
}
und Aufruf mit Zuweisung:
...
PrintIntLCD(speed);
speed = start(speed);
}
Hermann Wessel
01.04.2011, 09:21
hmm hab alles ausprobiert.. der arbeitet aber trotzdem mit 100
Sind deine änderungen in das .c datei gespeichert und dannach neu ubersetzt? Das speichern wird oft vergessen.
radbruch
01.04.2011, 15:36
Oje, langsam wird's zäh. Versuche mal das:
#include "stdlib.h"
#include "asuro.h"
#include "lcd.h"
#include "i2c.h"
int o = 1;
//Geschwindigkeit
int speed = 100;
void start(void)
{
int keys;
int i = 1;
while(i)
{
keys = PollSwitchLCD();
if(!keys)
{
Msleep(100);
}
else
{
switch(keys)
{
case LCD_KEY_YELLOW:
if(speed < 246) speed = speed +10;
break;
case LCD_KEY_BLUE:
if(speed > 9) speed = speed -10;
break;
case LCD_KEY_RED:
i = 0;
break;
}
ClearLCD();
PrintSetLCD(0,0,"Geschwindigkeit");
SetCursorLCD(0, 1);
PrintIntLCD(speed);
}
}
o--;
}
//Hauptprogramm
int main(void)
{
Init();
InitI2C();
InitLCD();
GREEN_LED_ON;
while(o > 0)
{
PrintSetLCD(0,0,"Geschwindigkeit");
SetCursorLCD(0, 1);
PrintIntLCD(speed);
start();
}
MotorDir(FWD,FWD);
MotorSpeed(speed,speed);
while(1); // Das Programm darf nie beendet werden!
return 0;
}Nicht getestet, aber mit diesen Dummy-Files fehlerfrei übersetzt:
lcd.h:
#define LCD_KEY_YELLOW 1
#define LCD_KEY_BLUE 2
#define LCD_KEY_RED 4
void InitLCD(void);
int PollSwitchLCD(void);
void ClearLCD(void);
void SetCursorLCD(unsigned char colum, unsigned char line);
void PrintIntLCD(int i);
void PrintSetLCD(unsigned char colum, unsigned char line, char *data);
void InitI2C(void);lcd.c
#define LCD_KEY_YELLOW 1
#define LCD_KEY_BLUE 2
#define LCD_KEY_RED 4
void InitLCD(void){}
int PollSwitchLCD(void){return(0);}
void ClearLCD(void){}
void SetCursorLCD(unsigned char colum, unsigned char line){}
void PrintIntLCD(int i){}
void PrintSetLCD(unsigned char colum, unsigned char line, char *data){}
void InitI2C(void){}
Aber dan wird es immer noch das selbe Zeichen auf dem LCD. (Geschwindigkeit 100) Weil am ende der erste Durchlauf von start wird die globale Variable o auf 0 gesetzt. (ist am Anfang 1) Das verhindert den zweite Durchlauf von den while-schleife in das main Programm. Und geht dann (nach der Motor Kommandos) in dem Endlos--schleife von Radbruch. Was genau bedeutet diese Variable "o". Was ist ihre Funktion in dein (Hermann Wessel) Logik? Wieso wird sie am ende von den start Funktion decrementiert?
radbruch
01.04.2011, 16:03
Das Display wird auch in start() nach jedem Tastendruck aktualisiert. Sein Programm ist wohl ein Ausschnitt eines größeren Programms, vielleicht dient o dort zur Steuerung des Ablaufs? In meiner Version wird speed einmalig editiert und dann schwirrt der asuro davon ;)
Radbruch stimmt. Ohne Roten Taster wird es in dem Funktion start stecken bleiben und dem LCD aktualisieren.
(Notiz an selb: NICHT 2 Quellcodes durcheinander liesen!!!!!!)
Hermann Wessel
03.04.2011, 01:58
so
tut mir echt leid für die verspätete antwort hatte letzen tage bissl stress^^
das hier ist mein volles programm
ich gehe mal von aus das ihr das dann versteht was o auf sich hat
#include "stdlib.h"
#include "asuro.h"
#include "lcd.h"
#include "i2c.h"
int speed = 100;
int o = 1;
void start(int speed)
{
int keys;
int i = 1;
int zaehler = 0 ;
while(i >0)
{
keys = PollSwitchLCD();
if (keys & LCD_KEY_YELLOW) //schwarzer Taster
{
while ( zaehler == 0)
{
if(speed < 350) //Geschwindigkeit erhöhen
{
speed = speed +10;
ClearLCD();
PrintSetLCD(0,0,"Geschwindigkeit");
SetCursorLCD(0, 1);
zaehler = zaehler +1;
PrintIntLCD(speed);
}
zaehler = zaehler +1;
}
}
else if (keys & LCD_KEY_RED ) //roter Taster
{ //wechseln von der Geschwindigkeiseinstellung
i = 0; //in den Messbetrieb
}
else if (keys & LCD_KEY_BLUE ) //Blauer Taster
{
while ( zaehler == 0)
{
if(speed >0)
{
speed = speed -10; //Geschwindigkeit vermindern
ClearLCD();
PrintSetLCD(0,0,"Geschwindigkeit");
SetCursorLCD(0, 1);
PrintIntLCD(speed);
zaehler = zaehler +1;
}
zaehler = zaehler +1;
}
}
if(!keys) // für das einmalige hochzählen beim drücken eines knopfes
{
Msleep(100);
zaehler = 0;
}
}
o--;
}
void berechnung(int zeit)
{
int keys;
int reifen = 120; //Reifenumfang in mm
int wegaenderung = 0;
int inszeit = 0;
int geschwindigkeit = 0;
int durchschnitt = 0;
int zaehler = 1 ;
while(1)
{
int odometrie = encoder[0];
wegaenderung = odometrie + reifen / 8 / 10;
inszeit = Gettime() /1000;
geschwindigkeit = wegaenderung / inszeit;
durchschnitt = wegaenderung / inszeit;
keys = PollSwitchLCD();
if(keys) // für das ständige aktuallisieren der Daten
{
zaehler = 0;
}
if ((keys & LCD_KEY_YELLOW) || (zaehler == 1) ) // Geschwindigkeit
{
ClearLCD();
PrintSetLCD(0,0,"CM pro S");
SetCursorLCD(0, 1);
PrintIntLCD(geschwindigkeit);
zaehler = 1;
}
else if ((keys & LCD_KEY_RED) || (zaehler == 2)) //Zurückgelegter Weg
{
ClearLCD();
PrintSetLCD(0,0,"Weg in CM");
SetCursorLCD(0, 1);
PrintIntLCD(wegaenderung);
zaehler = 2;
}
else if ((keys & LCD_KEY_BLUE) || (zaehler == 3)) // Durchschnittsgeschwindigkeit
{
ClearLCD();
PrintSetLCD(0,0,"CM pro S");
SetCursorLCD(0, 1);
PrintIntLCD(durchschnitt);
zaehler = 3;
}
Msleep(100);
}
}
//Hauptprogramm
int main(void)
{
//Geschwindigkeit
//void int speed = 100;
Init();
InitI2C();
InitLCD();
EncoderInit();
EncoderSet(780,790);
EncoderStart();
GREEN_LED_ON;
while(o > 0)
{
PrintSetLCD(0,0,"Geschwindigkeit");
SetCursorLCD(0, 1);
PrintIntLCD(speed);
start(speed);
}
MotorDir(FWD,FWD);
MotorSpeed(speed,speed);
int zeit = Gettime() / 1000; //zeit in Sekunden
ClearLCD();
PrintIntLCD(zeit);
berechnung(zeit);
}
das einzigste problem ist einfach das speed mit start zwar verändert werden kann aber nicht weiter übernommen wird
radbruch
03.04.2011, 02:13
Wenn du die Funktion mit "void start(int speed)" definierst, wird beim Aufruf eine für diese Funktion lokale Variable "speed" erzeugt. Diese ist nicht identisch mit der beim Programmstart global definierten gleichnamigen Variablen. Wenn du aber mit "void start(void)" keine Parameterübergabe festlegst, verwendet start() die selbe Variable wie main(). Dann wird die Änderung an der globalen Variablen durchgeführt.
Oder mit Zeiger und Referenzen. Im Bericht 13 war er schon ganz in die nähe mit (int &speed) :
http://www.rn-wissen.de/index.php/C-Tutorial#Parameter.C3.BCbergabe
Hermann Wessel
03.04.2011, 10:49
alles kla valen und radbruch mein programm funktioniert jetzt außer einigen macken die zwischendurch mal wieder auftreten, die aber nach dem neutstart wieder weg sind ^^
ok ich kann dieses forum nur weiterempfehlen
vielen dank
mfg Hermann (:
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.