-
        

Ergebnis 1 bis 5 von 5

Thema: Frequenz messen - Servo ansteuern

  1. #1

    Frequenz messen - Servo ansteuern

    Anzeige

    Hi,

    wir haben ein Projekt am laufen bei dem wir eine Drehzahl in Form einer Frequenz geliefert bekommen und einen Servo dementsprechend ansteuern.

    Wir haben als Controlerboard das RN Mini mit dem Atmega 168

    Nun habe ich gelesen das man Frequenzen mittels ICP einlesen kann. Wie das genau geht weiß ich zwar noch nicht aber bevor ich mich darin vergrabe habe ich noch eine Frage.

    Das PWM Signal für den Servo braucht ja auch ein ICR Register.

    Hängen ICP und ICR irgendwie zusammen? Ist das Projekt überhaupt so zu realisieren?

    Danke schonmal an alle die sich dem Beitrag annehmen

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.378
    jein, sofern du für in und ausgabe denselben teimer verwendest gehören sie zusamme, aber fnuktionieren dennoch!

    du stellst einen timer auf fast PWM, der zählt dann immer hoch, beim überlauf löst er den PWM Pin, wenn du dann einen Wert im OCR register hast und der counter diesen erreicht, setzt er den pin, dann löscht er ihn wieder beim überlauf und so weiter ...

    der ICP macht nichts weiter, als dass er bei einer detektierten flanke den aktuellen timerwert in das ICR register schreibt, dass du dann in aller ruhe auswerten kannst, anschliessend setzt du das OCR register damit dein servo aussteuert und lässt den timer seine arbeit machen, bis der nächste ICP kommt .. dir werden aber höchstwahrscheinlich die rechenzyklen ausgehen, also wird da noch einiges an gehirnschmalz hinterherfliessen

  3. #3
    So ein Mist...wir waren tierisch happy das der Servo überhaupt geht....es ist nicht so das ich hier einfach nur reinposte weil ich zu faul bin mich drum zu kümmern. Das ist nur nen superkurzfristiges Projekt an der FH...

    Ich poste euch mal grade den Code den wir für die Servoansteuerung nutzen...welche Register ich da genau wo verwende weiß ich im Grunde garnicht, der Code wurde nur mit viel ausprobieren angepasst.

    Ich würde mich gerne tiefer in de Thematik einarbeiten aber ihr wisst ja selber das das nicht in ein paar Tagen möglich ist....

    ################################################## #
    rncontrol.h

    Diese Header-Datei stellt grundlegende Funktionen in C zur Verfügung.
    Dominik Wiechard
    Bearbeitet von
    ################################################## #####
    */
    #include <avr/io.h>
    #include <stdlib.h>
    /*-----------------------------------------------------------------------------------*/
    /*###Portkonfiguration###*/
    /*Pins bzw. Ports als Ein-/Ausgänge konfigurieren*/




    void PORTCONFIG(void)
    {
    //-> alle Pin´s von Port F als Eingänge
    DDRB |= (1<<PB1); //PB5 Servo 1 OC1A
    DDRC |= (1<<PC0);
    }

    /*-------------------------------------------------------------------------------------*/
    /*###PWM Konfiguration###*/

    void PWM_INIT(void)
    {
    // normale 8-bit PWM aktivieren (nicht invertiert), COM1A1=1 und COM1A0=1-->set 1 upcounting set 0 downcounting

    TCCR1A = (1<<COM1A1)|(0<<COM1A0)|(0<<WGM10)|(0<<WGM11);

    // Einstellen der PWM-Frequenz (Prescaler = 8-->CS11)

    TCCR1B = (0<<CS10)|(1<<CS11)|(0<<CS12)|(0<<WGM12)|(1<<WGM13 ); // Mode 8 aktiviert

    TCNT1H=0x00;
    TCNT1L=0x00;

    // Interrupts für Timer1 deaktivieren
    // Achtung: Auch die Interrupts für die anderen Timer stehen in diesem Register
    //TIMSK &= ~0x3c;
    TIMSK1=0x00;

    ICR1 = 20000;
    }

    /*-------------------------------------------------------------------------------------*/
    /*### ADC-Ansteuerung ###*/

    uint16_t adcwert(uint8_t kanal)
    {
    uint16_t wert = 0; //Variable für Ergebnis deklarieren

    ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //Register zur ADC Messung aktivieren

    ADMUX = kanal;
    ADMUX = (0<<REFS1)|(1<<REFS0);

    ADCSRA |= (1<<ADSC); //nach Aktivierung des ADC wird ein Wert eingelesen und verwirft diesen wieder, um den ADC "warmlaufen zu lassen"
    while(ADCSRA & (1<<ADSC)) {} //auf Abschluss der Konvertierung warten
    wert = ADCW; //ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten Wandlung nicht übernommen.

    /* Eigentliche Messung - Mittelwert aus 4 aufeinanderfolgenden Wandlungen */
    wert = 0;
    for(uint8_t i=0; i<4; i++)
    {
    ADCSRA |= (1<<ADSC); //eine Wandlung "single conversion" starten
    while(ADCSRA & (1<<ADSC)) {} //auf Abschluss der Konvertierung warten
    wert = wert + ADCW; //Wandlungsergebnisse aufaddieren
    }

    ADCSRA &= ~(1<<ADEN); //ADC deaktivieren

    wert = wert/4; //Durchschnittswert bilden

    return wert;
    }

  4. #4
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Dadurch das Kommentare und Code teils nicht zusammenpassen ist der Code schwer zu verstehen. Er hilft einem auch kaum weiter. Es wird genau einer der PWM Modes benutzt die das ICR register als obere Grenze für den Timer nutzen, also die ISP Funktion gerade ausschaltet.

    Wenn man nur 1 Senvo hat, könnte man eine den Servo an OC1B hängen und mit MODE15 arbeiten (fast PWM mit OCR1A als TOP wert). Die Frequenzmessung wird dadurch aber schon etwas komplizierter.

    Eine Alternative wäre es das PWM Signal nicht ganz in Hardware zuerzeugen, sondern Teilweise in Software. Timer 1 kann dann durchlaufen und dann jeweils ein Interrupt ausgelöst werden wenn die nächste Änderung ansteht. Der Code sollte sehr ähnlich sein, wie man ihn nutzt um sehr viel Servos (z.B. 10) anzusteuern. Bei einem Servo könnte es sogar noch als Quasi Hardware PWM gehen.
    Wenn die taktfrequenz günstig liegt, könnte es eventuell auch gehen, den timer bis 2^16 laufen zu lassen und dann eine etwas von 20 ms abweichende Periode hinzunehmen.

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    33
    Beiträge
    2.378
    Wenn man nur 1 Senvo hat, könnte man eine den Servo an OC1B hängen und mit MODE15 arbeiten (fast PWM mit OCR1A als TOP wert). Die Frequenzmessung wird dadurch aber schon etwas komplizierter.
    warum das ? ich find die lösung ideal, den timerwert in ne zeit umrechnen muss man so oder so machen!

Berechtigungen

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