- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 10 von 24

Thema: Asuroprojekt mit Odometrie und LCD-Display

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    62
    Beiträge
    5.799
    Blog-Einträge
    8
    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 und auch die TinyLib gibt, rate ich Einsteigern eher zu Version v2.3:

    asuroLib v2.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:
    PHP-Code:
    #include "asuro.h"

    int left=0right=0;
    unsigned long time;
    unsigned long time_left=0time_right=0;
    unsigned long temp_time_left=0temp_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)
    Geändert von radbruch (30.03.2011 um 21:13 Uhr) Grund: Testcode angefügt
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  2. #2
    Neuer Benutzer Öfters hier
    Registriert seit
    29.03.2011
    Beiträge
    9
    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

  3. #3
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    62
    Beiträge
    5.799
    Blog-Einträge
    8
    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:

    Code:
    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"?
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    29.03.2011
    Beiträge
    9
    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
    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;
    }
    weshalb hat speed unten immernoch hundert obwohl ich den wert oben verändert habe?

  5. #5
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    62
    Beiträge
    5.799
    Blog-Einträge
    8
    Code:
    	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!
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    29.03.2011
    Beiträge
    9
    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?
    Geändert von Hermann Wessel (31.03.2011 um 16:22 Uhr) Grund: rechtschreibung^^

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    01.03.2008
    Ort
    Niederlanden
    Beiträge
    1.170
    Und welcher Tastereingaben meinst du? Mein Glasskügel fehlt mir wieder.

Ähnliche Themen

  1. Odometrie
    Von HAWK-Matze im Forum Asuro
    Antworten: 33
    Letzter Beitrag: 05.03.2008, 09:40
  2. Odometrie die 10.000
    Von NebuK im Forum Asuro
    Antworten: 5
    Letzter Beitrag: 10.11.2006, 13:02
  3. odometrie
    Von Toschtosch im Forum Asuro
    Antworten: 9
    Letzter Beitrag: 03.11.2006, 19:52
  4. Navigation mit Odometrie
    Von Rosowitsch im Forum Asuro
    Antworten: 1
    Letzter Beitrag: 07.06.2006, 16:36
  5. Odometrie LED
    Von Rosowitsch im Forum Asuro
    Antworten: 2
    Letzter Beitrag: 30.05.2006, 20:29

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

fchao-Sinus-Wechselrichter AliExpress