Servo mit PWM ansteuern

OP #2273076
Lesenswert?

Hallo zusammen,

Ich habe folgendes Problem. Ich will einen Servo Motor mittels PWM
ansteuern. Die Aufgabestellung :
8 bit Timer0
Minimalzeit  1ms
Maximalzeit  zirka = 2 ms
Wiederholungsfrequenz = 50 HZ (20ms)
16* 64 µs = 1024 µs
Power Reset = 1ms
2 Tasten :
Taste1 Zeit erhöhen  Servo  nach rechts
Taste2 Zeit reduzieren Servo nach links
Programmiersprache c :

Meine Frage ist jetzt, hat jemand von euch schonmal den internen PWM
Modus vom Atmega16 benutzt und kann mir vllt sogar ein kleines
Beispielprogramm dazu schicken? (Ich weiß es ist unschön nach einem
fertigen Beispielprogramm zu fragen, aber daran versteh ich es immer am
besten)

Ich danke euch schon jetzt für die Mühe.
#2273099
Lesenswert?

Du hast im falschen Forum gepostet.

LISA SCHMIDT schrieb:
> 16* 64 µs = 1024 µs
> Power Reset = 1ms
???
Was soll uns das sagen?

Zu deinem Anliegen: es finden sich hier auf der Seite viele fertige 
Projekte oder Codeauszüge dazu, wie man einen Servo ansteuert.
AVR-Tutorial: Servo
Modellbauservo Ansteuerung
http://www.mikrocontroller.net/forum/codesammlung?filter=*servo
http://www.mikrocontroller.net/forum/codesammlung?filter=servo*
Welcher davon den Timer0 oder einen kompatiblen Timer benutzt, überlasse 
ich dir, rauszusuchen.

Hast du eine Vorgabe nach der Auflösung oder wie groß ein Schritt sein 
soll?

Hast du fertige Hardware zum Ausprobieren?
Gast #2273214
Lesenswert?

holger schrieb:
>>wurde mir gesagt ich muss das mit Timer0 8 bit programmieren .
>>fertige Hardware hab ich stk500 und ein servo .
>
> Servo und PWM haben aber auch gar nichts gemeinsam.

Nun das typische Ansteuersignal für ein Servo ist schon ein
PWM-Signal; allerdings wird nur der Bereich zwischen 5 und 10%
ausgenutzt.
Gruss
Harald
#2273242
Lesenswert?

Es sieht nur ähnlich aus, solange die Frequenz eingehalten wird.
Wenn nicht, dann stellt sich heraus, daß die Pulslänge maßgeblich ist, 
und nicht der Duty-Anteil wie bei PWM.

Also lieber nicht das als PWM verkaufen; es wird schon zu oft hier so 
erzählt, ohne daß es wahrer wird.
#2273341
Lesenswert?

Man kann es schon auf die Schnelle mit PWM machen - aber nicht in der 
Auflösung! 1ms Aussteuerbereich in 16 oder 32 schritten bei 20ms periode 
gibt 9 (8,3) oder 10 (9,3) bit.

Den internen PWM-Generator kannst du zur direkten Ansteuerung also 
vergessen.

> 16* 64 µs = 1024 µs
Das soll dir eher etwas über den Timer und den richtigen Modus verraten.
#2273357
Lesenswert?

Michael H. schrieb:
> Man kann es schon auf die Schnelle mit PWM machen - aber nicht in der
> Auflösung! 1ms Aussteuerbereich in 16 oder 32 schritten bei 20ms periode
> gibt 9 (8,3) oder 10 (9,3) bit.


Der springende Punkt ist, dass das Servo die 20ms überhaupt nicht 
interessieren. Stell die 'PWM' auf eine Zykluszeit von 6 oder 7ms ein 
und schon hast du wieder einen vernünftigen Einstellbereich.
(Firma: KHTronik) #2273460
Lesenswert?

Hallo Karl Heinz,

Karl Heinz Buchegger schrieb:
> Der springende Punkt ist, dass das Servo die 20ms überhaupt nicht
> interessieren. Stell die 'PWM' auf eine Zykluszeit von 6 oder 7ms ein
> und schon hast du wieder einen vernünftigen Einstellbereich.

Da irrt der Meister :-). Es gibt viele Servos, die unter 15ms nicht mehr 
reagieren. Ich mache seit 2001 Servoansteuuerung für 
Modellbahnweichenantriebe, und habe bestimmt >50 Servotypen 
durchgeprüft. Die meisten preiswerten Servos, und auch ältere Edelservos 
machen bei <10-15ms Schluss.

Zur Benennung: man verwendet den PWM-Baustein des Prozessors, um ein 
Puls-Pausen-Modulationssignal (PPM) zu erzeugen.

Grüße, Kurt
Gast #2273481
Lesenswert?

Warum postest du eigentlich zwei mal? Und dann auch noch mit dem 
gleichen Titel? "Ein Schelm, wer dabei Böses denkt." ;)
Auch Doppelposts schüren nicht unbedingt die Lust fertige Lösungen zu 
präsentieren... Eigentlich müßtest du jetzt auch alles haben, was du für 
die Ansteuerung brauchst...

Gruß
OP #2280916
Lesenswert?

#define F_CPU 1000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

ISR( TIMER1_COMPA_vect )  // Interruptbehandlungsroutine
{
  OCR1A = 2500-OCR1A;  // Das Servosignal wird aus der Differenz von
                        // Periodenlänge (2500*0,008ms=20ms) und letztem
                                        // Vergleichswert (OCR1A) 
gebildet
}


int main (void)
{
  DDRB = 0b11111100;
  PORTB = (1<<PB1) | (1<<PB0);          // Pullup für PB0 und PB1

  TCCR1A = (1<<COM1A0);                 // Togglen bei Compare Match
  TCCR1B = (1<<WGM12) | (1<<CS11);      // CTC-Mode; Prescaler 8
  TIMSK  = (1<<OCIE1A);                 // Timer-Compare Interrupt an

  OCR1A = 2312;                         // Neutralposition 
((2500-2312)*0.008ms)=1,5ms)

  sei();                                // Interrupts global an

  while( 1 ) {

    if ( !(PINB & (1<<PINB0)) ) {       // Impuls-Zeit verlängern
      cli();
      OCR1A = OCR1A + 3;
      sei();
      _delay_ms(50);
    }

    if ( !(PINB & (1<<PINB1)) ) {       // Impuls-Zeit verkürzen
      cli();
      OCR1A = OCR1A - 3;
      sei();
      _delay_ms(50);
    }
  }

  return 0;
}
Das Prog hat funktioniert nun  will ich das mir timer0 programmieren 
kannst du mir dabei helfen ?
kannst du mir vielleicht sagen wie kann ich das Programm ändern mit 
ISR(TIMER0_OVF_vect) //Interrupt durch Timer0 (Uberlauf alle 20ms)?
und kannst du bitt mir sagen wofür OCR1A = 2312;und OCR1A = OCR1A + 3; 
also +3 und -3 und OCR1A = 2500-OCR1A; also woher kommt die 2500 ?

DANNKE
#2281095
Lesenswert?

Kurt Harders schrieb:
> Hallo Karl Heinz,
>
> Karl Heinz Buchegger schrieb:
>> Der springende Punkt ist, dass das Servo die 20ms überhaupt nicht
>> interessieren. Stell die 'PWM' auf eine Zykluszeit von 6 oder 7ms ein
>> und schon hast du wieder einen vernünftigen Einstellbereich.
>
> Da irrt der Meister :-). Es gibt viele Servos, die unter 15ms nicht mehr
> reagieren.

Dann muss ich Glück gehabt haben. Von meinen Servos machen da alle mit. 
Danke für die Info.
#2281103
Lesenswert?

LISA SCHMIDT schrieb:

> kannst du mir vielleicht sagen wie kann ich das Programm ändern mit
> ISR(TIMER0_OVF_vect) //Interrupt durch Timer0 (Uberlauf alle 20ms)?
> und kannst du bitt mir sagen wofür OCR1A = 2312;und OCR1A = OCR1A + 3;
> also +3 und -3 und OCR1A = 2500-OCR1A; also woher kommt die 2500 ?
>
> DANNKE

Tja. Dann wirst du das lernen müssen.
Es ist ja schliesslich dein Projekt.

AVR-Tutorial
AVR-GCC-Tutorial

bzw. das Datenblatt zum jeweiligen Prozessor.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren