Forum: Mikrocontroller und Digitale Elektronik 4x Servo-PWM mit ATTiny2313


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Alex B. (alde_oma)


Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich versuche mit dem Attiny2313 4 Servos anzusteuern.
habe mit Timern leider nicht besonders viel Erfahrung.
Jetzt hab ich hier im FOrum den Beitrag 
http://www.mikrocontroller.net/articles/Modellbauservo_Ansteuerung#Signalerzeugung_f.C3.BCr_1_Servo_mittels_Timer_.28C.29 
gefunden und habe ihn versucht auf die 4 Servos anzupassen. Mit halbem 
Erfolg...
Hier mal mein Code:
1
#define F_CPU 1000000UL
2
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <util/delay.h>
6
7
ISR( TIMER0_COMPA_vect )                // Interruptbehandlungsroutine
8
{
9
  OCR0A = 2500-OCR0A;      
10
}
11
12
ISR( TIMER0_COMPB_vect )                // Interruptbehandlungsroutine
13
{
14
  OCR0B = 2500-OCR0B;      
15
}
16
17
ISR( TIMER1_COMPA_vect )                // Interruptbehandlungsroutine
18
{
19
  OCR1A = 2500-OCR1A;      
20
}
21
22
ISR( TIMER1_COMPB_vect )                // Interruptbehandlungsroutine
23
{
24
  OCR1B = 2500-OCR1B;      
25
}
26
27
void init_pwm (void)
28
{
29
  
30
  // Timer 0 PWM Init
31
32
    TCCR0A = (0 << WGM00) | (1 << WGM01) | (1 << COM0A0) | (1 << COM0B0);
33
    TCCR0B = (0 << WGM02) | (1 << CS00) | (1 << CS01) | (0 << CS02);
34
35
36
  // OC0A PWM Port
37
38
  DDRB   |= (1 << PB2);
39
40
  OCR0A = 139;
41
42
43
  // OC0B PWM Port
44
  
45
  DDRD   |= (1 << PD5);
46
47
  OCR0B = 139;
48
  
49
50
  // Timer 1 PWM Init
51
52
  TCCR1A = (1 << COM1A0) |(1 << COM1B0);
53
  TCCR1B = (1 << WGM12) | (1 << CS11);
54
  TIMSK  = (1 << OCIE1A) | (1 << OCIE1B) |(1 << OCIE0A) | (1 << OCIE0B);                 // Timer-Compare Interrupt an
55
56
  // OC1A PWM Port
57
58
  DDRB   |= (1 << PB3);
59
  
60
  OCR1A = 2250;  //2250-2,0 ms
61
          //2312-1,5 ms
62
          //2374-1,0 ms
63
64
  // OC1B PWM Port
65
66
  DDRB   |= (1 << PB4);
67
  
68
  OCR1B = 1125;  //1185-1,0 ms
69
          //1156-1,5 ms
70
          //1125-2,0 ms
71
          
72
}
73
74
int main (void) {
75
  
76
  init_pwm();
77
  sei();
78
  
79
  while(1){
80
    
81
  }
82
  
83
84
}

Timer1A funktioniert wie er soll. Timer1B eigenlich auch. Jedoch die 
Frage, warum der OCR1B auf einen anderen Wert gesetzt werden muss, damit 
ich das gleiche Ergebnis erhalte? Genauso beim Timer0. Den bekomme ich 
nicht auf 20ms.
Ich könnte auch mit _delay_ms arbeiten, da der Tiny sonst nichts anderes 
macht, aber wenn ich jetzt dabei bin, möchte ich natürlich eine richtige 
PWM erzeugen.
Habe auch schon beispiele gesehen, bei denen ICR1 als angabe dient, die 
Periodendauer anzugeben.. Bin im Moment etwas verwirrt.

von Simon R. (simon_r44)


Bewertung
0 lesenswert
nicht lesenswert
Also die RS-2 Servos sind komisch, deshalb haben die mit 
Rechenbeispielen auch nie in die Stellung gekommen die man wollte also 
sind die Werte für OCR1A experimentell ermittelt worden...

von Alex B. (alde_oma)


Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe die Servos im Moment noch nicht angeschlossen. Beobachte die 
Signale mit einem Oszi.

von Simon R. (simon_r44)


Bewertung
0 lesenswert
nicht lesenswert
Alex B. schrieb:
> Hi,
>
> ich habe die Servos im Moment noch nicht angeschlossen. Beobachte die
> Signale mit einem Oszi.

Was willst du mit den 4 Servos genau anstellen? Hab da auch mal ne Weile 
an so einem Programm rumgebastelt (auch für den 2313) das aber nie 
sonderlich gut lief...

von Alex B. (alde_oma)


Bewertung
0 lesenswert
nicht lesenswert
Hi,
ich will Brushlessmotoren betrieben. Und der Brushless-Controller 
benötigt das PWM-Signal eines Servos.

von Jasson (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Du könntest auch einen anderen Ansatz wählen und die PWM von nur einem 
OCR Output erzeugen lassen und multiplexen. Löte 4 Widerstände (z.B. 
4k7) an den Pin. Die vom Controller abgewandten Seite verbindest du 
jeweils mit einem Prozessor Pin, den du aber nur zwischen LOW und 
Floating schaltest. Bis auf einen MultiplexPin sind alle LOW und du 
lädst das OCR Register mit dem zugehörigen Wert. Sind alles Kanäle 
abgearbeitet, wartest du noch die Totzeit ab. Dann beginnt das Spiel von 
vorne.

von Alex B. (alde_oma)


Bewertung
0 lesenswert
nicht lesenswert
Wäre auch noch eine Idee. Ich möchte aber wie beschrieben die PWM 
"richtig" erzeugen, damit ichs jetzt kapiere und für spätere Projekte 
nutzen kann.
Mein Hauptproblem ist im Moment kurzgefasst: Wie stelle ich die 
Periodendauer und die Pulsdauer der einzelnen Timer ein?

von Karl H. (kbuchegg) (Moderator)


Bewertung
0 lesenswert
nicht lesenswert
generelle Timerberechnung
FAQ: Timer

Im übrigen gebe ich Jasson recht. Es ist nicht wirklich klug, seine 
kostbaren Timer für das Erzeugen von 4 PWM Signalen zu verschwenden, 
wenn das 1 Timer alleine genausogut kann, und man damit dann noch nicht 
mal auf die Pins festgenagelt ist. Am 'Timer lernen' und wie man damit 
Zeiten berechnet ändert das ja nichts.

: Bearbeitet durch Moderator
von Alex B. (alde_oma)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

die Timerberechnung habe ich mittlerweile hinbekommen. Was mich aber 
immernoch verwirrt, ist die Sache, dass bei mir Timer1A und 1B andere 
Werte haben, damit ich 20ms zusammenbekomme.

Beschaltung siehe Anhang...
Kannst du das mit dem Schalten nochmal etwas genauer erklären? Komm da 
grad nicht mit.

von Stefan us (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Schau von meinem Programm ab: 
http://stefanfrings.de/servocontroller/ServoController.zip

Ich nutze einen Timer und ein Compare-Register, um 5 PWM Signale zu 
erzeugen. Das Multiplexing erledigt die Interrupt-Routine.

Das zweite Compare Register nutze ich, um weitere 5 Kanäle zu 
implementieren.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.