-         

Seite 1 von 3 123 LetzteLetzte
Ergebnis 1 bis 10 von 22

Thema: Zeiten ohne Delay

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    32
    Beiträge
    199

    Zeiten ohne Delay

    Anzeige

    Moin!
    Da ich mein letztes Problem schon nicht hinbekommen habe (Servo-Steuerung) will ich mich gleich mal dem nächsten Problem zuwenden. Ich hab jetzt die werte für den Servo eingegeben und lass den servo über eine Variable hin und dann wieder zurück fahren. (Auf dem Servo ist ein GP2D12). Nun hab ich das aber mit delays gemacht und mein restliches Programm läuft in der bearbeitungszeit nicht weiter. Das heißt alles andere Wird auch verzögert (bis jetzt zwar nur eine Lichtmessung, aber das ist schon nervig genug.)

    Hier mal mein Code. Hab mal alles was nicht direkt mit dem Servo zu tun hat, sondern nur Delay-mäßig gestört wird, gelöscht. Die Struktur is auch ganz schön hässlich, bekomme das aber irgendwie nich besser hin

    Code:
    #include <avr/io.h>
    #include <stdint.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    
    #ifndef F_CPU
    #define F_CPU 16000000
    #endif
    
    #define Scheinwerfer 0
    #define Rueckleuchten 1
    #define PWM_ServoPort 5
    
    //-------------------------------------IR_Servosteuerung---------------------------------------
    void IR_Servosteuerung(void)
    {
    uint8_t a, b, i;
    uint16_t x;
    a=1;
    b=0;
    x=450;
    
    while (a)
      {
      OCR1A=x;
      for (i=0; i<=3; i++)
        {
        _delay_ms(10);
    	}
      x++;
      if (x>=480)
        {
    	a=0;
    	b=1;
        }
      }
    
    while (b)
      {
      OCR1A=x;
      for (i=0; i<=3; i++)
        {
        _delay_ms(10);
        }
      x--;
        if (x<=450)
        {
    	a=1;
    	b=0;
    	}
      }
    }
    
    //-------------------------------------initialisierungen---------------------------------------
    
    
    void Initial_IR_Servo(void)
    {
    TCCR1A = ((1<<WGM11)|(1<<COM1A1)|(1<<COM1A0)); //9-Bit PWM, Inverted Mode
    TCCR1B = (1<<CS12); 	//Prescaler 256
    DDRD |= (1<<PWM_ServoPort); 
    PORTD |= (1<<PWM_ServoPort);
    }
    
    //---------------------------------------Hauptprogramm---------------------------------
    int main(void)
    {
    Initial_IR_Servo();
    
    while(1)
      {
      IR_Servosteuerung();
      }
    }
    Hoffe es kann wieder jemand helfen.

    MfG Jan
    Habe Mut, dich deines eigenen Verstandes zu bedienen.

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von Dirk
    Registriert seit
    30.04.2004
    Ort
    NRW
    Beiträge
    3.791

    Sevoansteuerung

    Hallo Spongebob85,

    dein Servo wird ja den IR-Distanzsensor in bestimmte Richtungen stellen, danach wird gemessen und eine neue Position angefahren.
    Ich würde deshalb in der Servoansteuerung keine Delays einbauen. Die wirst du ja in deiner Hauptschleife zwischen den Messungen brauchen.

    Um in der Hauptschleife keine blockierenden Delays einzubauen, könntest du auch die PWM nutzen: Wenn der Counter bei TOP angekommen ist, wird ein Interrupt ausgelöst, in der ISR eine Zählvariable inkrementiert. Erreicht die einen bestimmten Wert, erfolgt die nächste Messung (natürlich nach dem Anfahren der neuen Position durch das Servo).

    Oder habe ich da bei deinem Projekt etwas falsch verstanden?

    Gruß Dirk

  3. #3
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.190
    Das Problem ist das wärend eines Delay der µC nichts (sinnvolles ausser warten) macht. Du kannst das nur über die Timer lösen.
    Siehe hier unter: http://www.mikrocontroller.net/artic...R-GCC-Tutorial
    Die Timer/Counter des AVR

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    32
    Beiträge
    199
    @Dirk
    Oder habe ich da bei deinem Projekt etwas falsch verstanden?
    Ne, hast du genau richtig verstanden. Glaub langsam verstehe ich diese ganze Zählergeschichte immer besser... Naja, komme wohl auch nicht drum herum.
    Ich werde mich dann sicher noch mal melden, wenn ich wieder nicht weiter komme.

    MfG Jan
    Habe Mut, dich deines eigenen Verstandes zu bedienen.

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    32
    Beiträge
    199
    So, ich hab jetzt was Programmiert. Es kamen natürlich erstmal extrem viele Fehlermeldungen

    Das sieht so aus:

    Code:
    int main(void)
    {
    Initial_ADC0();
    Initial_IR_Servo();
    uint8_t a;  //Global?
    a=0;        //Global?
    uint8_t i;  //Global?
    i=0;         //Global?
    
    while(1)
      {
      helligkeitsmessung();
      IR_Servosteuerung();
      }
    }
    unter Initial... (wo ich ADC und PWM krams initialisiere)
    hab ich a und i deklariert. Is das nicht Global?

    Dann hab ich das hier geschrieben, damit bei jedem Overflow von Timer1 eine Variable endweder hoch- oder runtergezählt wird:
    Code:
    ISR(TIMER1_OVF) //Diese Routine soll bei Overflow von Timer1 ausgeführt werden
    {
    if(a=0)
      {
      IR_Servosteuerung(i);
      i++;
      if (i>=50)
        {
    	a=1;
    	}
      }
    if (a=1)
      {
      IR_Servosteuerung(i);
      i--;
      if (i<=0)
        {
    	a=0;
    	}
      }
    }
    und diese Variable will ich auch gleich verwenden um den OCR1A zu beeinflussen. Das hab ich mir so vorgestellt:
    Code:
    extern void IR_Servosteuerung(uint8_t count)
    { 
    OCR1A=(count+440); //440=min, 490=max
    }
    Der meckert aber irgendwie wegen den Variablen a und i rum und die Funktion IR_Servosteuerung in main in der Whileschleife gefällt ihm nicht.
    Hoffe mir kann jemand helfen. Ach ja. Wo müsste ich dann sei() und cli() hinsetzen? Meine C-Kenntnisse sind wohl nicht so die dollsten... Aber was nicht is kann ja noch kommen
    Habe Mut, dich deines eigenen Verstandes zu bedienen.

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    13.04.2007
    Ort
    NRW
    Beiträge
    37
    Hallo,

    globale Variablen wertden vor der main-Funktion deklariert. also nicht wie die es gemacht hast in der main.

    #asm("sei")

    kommt in die main Funktion vor deine while-schleife.

    Pierce
    Lasst mich Arzt, ich bin durch...

    http://www.pennergame.de/change_please/9251940/

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    32
    Beiträge
    199
    Hab die Variablen jetzt unter die #define x y sachen geschrieben und IR_Servosteuerung aus der main-Function komplett rausgenommen.

    Mein kompletter Code
    Code:
    #include <avr/io.h>
    #include <stdint.h>
    #include <avr/interrupt.h>
    //#include <util/delay.h>
    
    #ifndef F_CPU
    #define F_CPU 16000000
    #endif
    
    #define Scheinwerfer 0
    #define Rueckleuchten 1
    #define PWM_ServoPort 5
    
    
    //Globale Variablen
    uint8_t a;
    uint8_t i;
    
    //---------------------------------Interrupt-routinen---------------------------------
    ISR(TIMER1_OVF) //(c:20)Diese Routine soll bei Overflow von Timer1 ausgeführt werden
    {
    if(a=0) //(c:22)
      {
      IR_Servosteuerung(i); //(c:24)
      i++;
      if (i>=50)
        {
    	a=1;
    	}
      }
    if (a=1)  //(c:31)
      {
      IR_Servosteuerung(i);
      i--;
      if (i<=0)
        {
    	a=0;
    	}
      }
    }
    
    //---------------------------------Helligkeitsmessung---------------------------------
    void helligkeitsmessung(void)
    {
    uint16_t LDR;
    
    ADCSRA |= (1<<ADSC);
      while (ADCSRA & (1<<ADSC))
        {
    	;
    	}
      LDR = ADCL;
      LDR += (ADCH<<8);
      
      if (LDR<150)
        {
        PORTD |= (1<<Scheinwerfer);
        PORTD |= (1<<Rueckleuchten);
        }
      if (LDR>160)
        {
    	PORTD &= ~(1<<Scheinwerfer);
    	PORTD &= ~(1<<Rueckleuchten);
    	}
    }
    
    //-------------------------------------IR_Servosteuerung---------------------------------------
    void IR_Servosteuerung(uint8_t count)
    {  //(c:69)
    OCR1A=(count+440); //440=min, 490=max
    }
    
    //-------------------------------------initialisierungen---------------------------------------
    void Initial_ADC0(void)
    {
    ADMUX = 0x00;	//AREF, resultat rechtsbündig, ADC-Eingang ADC0
    ADCSRA = ((1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0));  //ADC eingeschaltet, Teilungsfaktor..
    DDRD |= ((1<<Scheinwerfer) | (1<<Rueckleuchten));
    }
    
    void Initial_IR_Servo(void)
    {
    TCCR1A = ((1<<WGM11)|(1<<COM1A1)|(1<<COM1A0)); //9-Bit PWM, Inverted Mode
    TCCR1B = (1<<CS12); 	//Prescaler 256
    DDRD |= (1<<PWM_ServoPort); 
    PORTD |= (1<<PWM_ServoPort);
    }
    
    //---------------------------------------Hauptprogramm---------------------------------
    int main(void)
    {
    Initial_ADC0();
    Initial_IR_Servo();
    a=0;
    i=0;
    
    sei();
    while(1)
      {
      helligkeitsmessung();
    //  IR_Servosteuerung();
      }
    cli();
    }  //(c:104:2)
    und das sind die ganzen Fehlermeldungen:

    Code:
    main.c:20: warning: `TIMER1_OVF' appears to be a misspelled signal handler
    main.c: In function `TIMER1_OVF':
    main.c:22: warning: suggest parentheses around assignment used as truth value
    main.c:24: warning: implicit declaration of function `IR_Servosteuerung'
    main.c:31: warning: suggest parentheses around assignment used as truth value
    main.c: At top level:
    main.c:69: error: conflicting types for 'IR_Servosteuerung'
    main.c:24: error: previous implicit declaration of 'IR_Servosteuerung' was here
    main.c:104:2: warning: no newline at end of file
    Hab mal die Zeilenzahlen kommmentiert drangeschrieben.
    Freu mich über jeden Tipp!

    MfG Jan
    Habe Mut, dich deines eigenen Verstandes zu bedienen.

  8. #8
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.190
    Ich glaube du solltest mal das GCC-Tutorial durcharbeiten. Die Fehler die da angezeigt werden sind relativ banal.
    Code:
    #include <avr/io.h>
    #include <stdint.h>
    #include <avr/interrupt.h>
    //#include <util/delay.h>
    
    #ifndef F_CPU
    #define F_CPU 16000000
    #endif
    
    #define Scheinwerfer 0
    #define Rueckleuchten 1
    #define PWM_ServoPort 5
    
    
    //Globale Variablen
    uint8_t a;
    uint16_t i;
    uint16_t count;
    void IR_Servosteuerung(uint16_t i);
    //---------------------------------Interrupt-routinen---------------------------------
    ISR(TIMER1_OVF_vect) //(c:20)Diese Routine soll bei Overflow von Timer1 ausgeführt werden
    {
    if(a==0) //(c:22)
      {
      IR_Servosteuerung(i); //(c:24)
      i++;
      if (i>=50)
        {
       a=1;
       }
      }
    if (a==1)  //(c:31)
      {
      IR_Servosteuerung(i);
      i--;
      if (i<=0)
        {
       a=0;
       }
      }
    }
    
    //---------------------------------Helligkeitsmessung---------------------------------
    void helligkeitsmessung(void)
    {
    uint16_t LDR;
    
    ADCSRA |= (1<<ADSC);
      while (ADCSRA & (1<<ADSC))
        {
       ;
       }
      LDR = ADCL;
      LDR += (ADCH<<8);
     
      if (LDR<150)
        {
        PORTD |= (1<<Scheinwerfer);
        PORTD |= (1<<Rueckleuchten);
        }
      if (LDR>160)
        {
       PORTD &= ~(1<<Scheinwerfer);
       PORTD &= ~(1<<Rueckleuchten);
       }
    }
    
    //-------------------------------------IR_Servosteuerung---------------------------------------
    void IR_Servosteuerung(uint16_t count)
    {  //(c:69)
    OCR1A=(count+440); //440=min, 490=max
    }
    
    //-------------------------------------initialisierungen---------------------------------------
    void Initial_ADC0(void)
    {
    ADMUX = 0x00;   //AREF, resultat rechtsbündig, ADC-Eingang ADC0
    Ich habe die Fehler behoben, bei den globalen Variablen sind zwei Zeilen eingfügt, sonst hat sich in der Struktur nichts geändert, so kannst du deine Fehler selbst kontrollieren. Ob das Programm auch richtig läuft habe ich nicht getestet.

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    32
    Beiträge
    199
    Danke erstmal!!!
    Jetzt kommen auf jeden Fall keine Fehlermeldungen mehr.
    Mein Servo sagt aber irgendwie auch nichts mehr. Hab also auch noch einen Logik-fehler eingebaut. Dann hab ich ja jetzt erstmal wieder was zu tun.

    MfG Jan
    Habe Mut, dich deines eigenen Verstandes zu bedienen.

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    32
    Beiträge
    199
    Ich könnte echt durchdrehen.
    kann das sein das man den Interrupt wieder löschen muss?
    Der Servo bleibt in einer Stellung stehen. Und zwar immer in der wo (Count+440) steht zB. bei 440. wenn man Count+490 eingibt fährt er auf 490.
    Das heißt Count wird nicht hochgezählt.
    Ich weiß nicht warum.
    Hab das Programm nochmal leicht umgeschrieben.
    Hier der Code:
    Code:
    #include <avr/io.h>
    #include <stdint.h>
    #include <avr/interrupt.h>
    //#include <util/delay.h>
    
    #ifndef F_CPU
    #define F_CPU 16000000
    #endif
    
    #define Scheinwerfer 0
    #define Rueckleuchten 1
    #define PWM_ServoPort 5
    
    
    //Globale Variablen
    uint8_t a;
    uint16_t i;
    //uint16_t count;  //hier geändert (wegkommentiert)
    //void IR_Servosteuerung(uint16_t i);  //hier geändert (wegkommentiert)
    
    //---------------------------------Interrupt-routinen---------------------------------
    ISR(TIMER1_OVF_vect) //Diese Routine soll bei Overflow von Timer1 ausgeführt werden
    {
    while (a==0) 
      {
      //IR_Servosteuerung(i);  //hier geändert (wegkommentiert)
      i=i+1;
      if (i==50)
        {
    	a=1;
    	}
      }
    while (a==1)
      {
      //IR_Servosteuerung(i);  //hier geändert (wegkommentiert)
      i=i-1;
      if (i==0)
        {
    	a=0;
    	}
      }
    }
    
    //---------------------------------Helligkeitsmessung---------------------------------
    void helligkeitsmessung(void)
    {
    uint16_t LDR;
    
    ADCSRA |= (1<<ADSC);
      while (ADCSRA & (1<<ADSC))
        {
    	;
    	}
      LDR = ADCL;
      LDR += (ADCH<<8);
      
      if (LDR<150)
        {
        PORTD |= (1<<Scheinwerfer);
        PORTD |= (1<<Rueckleuchten);
        }
      if (LDR>160)
        {
    	PORTD &= ~(1<<Scheinwerfer);
    	PORTD &= ~(1<<Rueckleuchten);
    	}
    }
    
    //-------------------------------------IR_Servosteuerung---------------------------------------
    void IR_Servosteuerung(uint16_t count)  //hierher wird der Wert von i  
                                                                //übergeben
    {
    OCR1A=(count+440); //440=min, 490=max
    }
    
    //-------------------------------------initialisierungen---------------------------------------
    void Initial_ADC0(void)
    {
    ADMUX = 0x00;	//AREF, resultat rechtsbündig, ADC-Eingang ADC0
    ADCSRA = ((1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0));  //ADC eingeschaltet, Teilungsfaktor..
    DDRD |= ((1<<Scheinwerfer) | (1<<Rueckleuchten));
    }
    
    void Initial_IR_Servo(void)
    {
    TCCR1A = ((1<<WGM11)|(1<<COM1A1)|(1<<COM1A0)); //9-Bit PWM, Inverted Mode
    TCCR1B = (1<<CS12); 	//Prescaler 256
    DDRD |= (1<<PWM_ServoPort); 
    PORTD |= (1<<PWM_ServoPort);
    }
    
    //---------------------------------------Hauptprogramm---------------------------------
    int main(void)
    {
    Initial_ADC0();
    Initial_IR_Servo();
    a=0;
    i=0;
    
    while(1)
      {
      cli();    //hier geändert
      helligkeitsmessung();
      IR_Servosteuerung(i);  //hier geändert
      sei();  //hier geändert
      }
    }
    Aus dem AVR-GCC-Tutorial werde ich irgendwie auch nicht schlau.

    MfG Jan
    Habe Mut, dich deines eigenen Verstandes zu bedienen.

Seite 1 von 3 123 LetzteLetzte

Berechtigungen

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