Forum: Mikrocontroller und Digitale Elektronik ATMega32: 18 PWM Kanäle benötigt


von Marv (Gast)


Lesenswert?

Hey Leute,

im Rahmen eines Schulprojekts übertragen wir das Bewegungskonzept von 
Sechsfüßer auf ein technisches Modell. Wahrscheinlich sind andere 
ähnliche Projekte als "Hexapod" unter euch bekannt ;)

Die Entwicklungsumgebung: WinAVR, PonyProg.
Die Hardware: Pollin Evaluationsboard, ATMega32.

Benutzt werden 18 Servos, die einzeln ansteuerbar sind. D.H es werden 18 
PWM's benötigt. Die Ansteuerung der Servos und die erstellung der Soft 
PWM's klappt soweit.

PROBLEM: Da außer den PWM's auch noch die bewegungsmodis über den µC 
gesteuert werden soll, suchen wir nun verzweifelt nach einer 
Möglichkeit, die PWM's praktisch "parallel" neben dem Hauptprogramm 
ablaufen zu lassen. Mir ist durchaus bewusst, dass der µC natürlich 
keine befehle wirklich parallel ausführen kann, Ich hoffe unser problem 
ist trotzdem deutlich geworden und ihr wisst, worauf ich hinaus will.

Es gab erste ansätze mit der DWORD WINAPI Thread Funktion. Jedoch 
funktionierte diese nur unter windows und ließ sich unter WinAVR (auch 
nach dem kopieren der entsprechenden libraries) nicht compillieren. Ist 
es möglich diese Funktion auf einem µC auszuführen??

Auch andere Lösungsvorschläge sind herzlich wilkommen !

Danke schonmal im Vorraus!

von ado (Gast)


Lesenswert?

Wenn aus dem PWM-Signal eh eine Gleichspannung erzeut wird könnte man 
vielleicht auch Digital/Analogwandler mit SPI oder anderen 
Schnittstellen verwenden.
Also Bausteine bis 16 Kanälen habe ich schon gesehen. Vielleicht gibt es 
noch größere oder man nimmt 2.

von    (Gast)


Lesenswert?


von Floh (Gast)


Lesenswert?


von Marv (Gast)


Lesenswert?

Danke für die schnellen Antworten ! Der Multitasking Thread hört sich 
schonmal verdammt gut an ;9

von Klaus (Gast)


Lesenswert?

ado schrieb:
> Wenn aus dem PWM-Signal eh eine Gleichspannung erzeut wird könnte man
> vielleicht auch Digital/Analogwandler mit SPI oder anderen
> Schnittstellen verwenden.

Es geht nicht um wirkliches PWM, Marv will Servos ansteuern, er nennt 
das nur PWM.

MfG Klaus

von Dirk (Gast)


Lesenswert?

Hi Marv,

ich habe gerade ein Projekt mit AVR und Servo fertiggestellt.

In welcher Auflösung (Stufen) willst Du denn die Servobewegung steuern ?

Dirk

von N. Müller (Gast)


Lesenswert?

Gibt es nicht auch Portexpander (glaub für LEDs) die jeden Kanal einzeln 
mit einer PWM ansteuern können?
Soweit ich weis ist bei denen die Frequenz (hier dann 50Hz) und das 
Tastverhältnis für jeden Kanal einzeln einstellbar.
Bei 10 Bit wär dass immerhin eine Auflösung von 20ms/1024= 19,5us.
Müssten dann so um die 50-60 Positionen sein die man einstellen kann.

Vorteil: Einfach über SPI/I2C anzusteuern und der uC hatt außer die 
neuen Werte über SPI zu senden nichts zu tun.

Grüße
N.Müller

von m.n. (Gast)


Lesenswert?

Vielleicht hift Dir dieses Programmbeispiel, viele PWM-Kanäle zu 
realisieren. Falls nicht alle 64 Kanäle gebraucht werden, bleibt mehr 
Zeit für die Verarbeitung anderer Programmteile.
http://www.mino-elektronik.de/AVR_PWM_64/AVR_PWM_64.htm

von Floh (Gast)


Lesenswert?

Marv schrieb:
> Danke für die schnellen Antworten ! Der Multitasking Thread hört sich
> schonmal verdammt gut an ;9

Multitasking halt ich für übertrieben, schau dir mal den Link zur 
Ansteuerung an. Mit einem Timer lassen sich bequem 8 Servos ansteuern.
Mit z.B. 3 Timern lassen sich dann alle 18 (eigentlich schon 24) Servos 
ansteuern.

Der Trick dabei ist, dass die 8 benötigten Pulse über die Periodendauer 
verteilt sind, um die Prozessorzeit zu minimieren.

von Dirk (Gast)


Lesenswert?

Floh schrieb:
> Multitasking halt ich für übertrieben, schau dir mal den Link zur
> Ansteuerung an. Mit einem Timer lassen sich bequem 8 Servos ansteuern.
> Mit z.B. 3 Timern lassen sich dann alle 18 (eigentlich schon 24) Servos
> ansteuern.

Es reicht ein einzigster Timer und eine intelligente Programmierung um 
die benötigten 18 Pulsweiten zu erzeugen, welche auch stabil sein 
sollten.

Eine Servo Ansteuerung lässt sich nicht ohne weiteres mit einer normalen 
PWM Steuerung verleichen.

Man benötigt eine minimale Pulslänge von ca. 1 ms um den Servo in seiner 
0
Referenzposition zu halten.

Die nächste ms (zur Erweiterung der 1.) muss in Stufen geteilt werden um 
den
Servo um ca. 90° zu bewegen.

Dir Wiederholung dieses Vorganges beträgt 20ms.

Mit einer entsprechend intelligenten Ansteuerung (Software) kommt ein 
relativ geringer Softwareaufwand zustande.

von Floh (Gast)


Lesenswert?

Dirk schrieb:
> Es reicht ein einzigster Timer und eine intelligente Programmierung um
> die benötigten 18 Pulsweiten zu erzeugen, welche auch stabil sein
> sollten.

Geile Idee. Also in etwa so (für gedachte 8ms Periodendauer ,da mir hier 
die Breite fehlt :-)
     0   1   2   3   4   5   6   7   8
Zeit |   |   |   |   |   |   |   |   |   |   (je 1 ms)
S1   PPPPPP--------------------------PPPPPPP--
S2   ----PPPPP------------------------------PP
S3   --------PPPPPPP--------------------------
S4   ------------PPPPPPP----------------------

...
Dann skaliert man z.B. einen Timeroverflow auf 1ms.
Zusätzlich hat man nen Output Compare-Interrupt.
Bei Timeroverflow wird immer Serv0(n) angeschaltet und gleichzeitig der 
Output-Compare-Wert von Servo(n-1) genommen.
Bei Output-Compare-Interrupt wird dann Servo(n-1) ausgeschaltet.

Ja so kriegt man elegant 18 Servos in eine 20ms Periode.
:-)

von Matthias (Gast)


Lesenswert?

Floh schrieb:
> Der Trick dabei ist, dass die 8 benötigten Pulse über die Periodendauer
> verteilt sind, um die Prozessorzeit zu minimieren.

Üblicherweise wird das auch als Zeitmultiplex bezeichnet, d.h. innerhalb 
der Periodendauer gibt es für jeden Servo ein 2ms Zeitfenster, in dem 
sein Puls erzeugt wird

Dirk schrieb:
> Dir Wiederholung dieses Vorganges beträgt 20ms.

Als Wiederholung (Periode) werden zwar oft 20ms verwendet, aber den 
Servos ist der genaue Wert ziemlich wurscht. Irgendwas zwischen 10 ms 
und mindestens 100 ms funktioniert eigentilich immer. Einziger Effekt 
einer langen Periodendauer ist, dass die Servos etwas langsamer 
umsteuern.

Es kommt auf einen Versuch drauf an, ob es für den Hexapod ok ist, alle 
18 Servopulse auf eine als Zeitmultiplex erzeugte Serie zu packen. Die 
Chancen sind gut.

von Dirk (Gast)


Lesenswert?

Matthias schrieb:
> Als Wiederholung (Periode) werden zwar oft 20ms verwendet, aber den
> Servos ist der genaue Wert ziemlich wurscht. Irgendwas zwischen 10 ms
> und mindestens 100 ms funktioniert eigentilich immer. Einziger Effekt
> einer langen Periodendauer ist, dass die Servos etwas langsamer
> umsteuern.

Genau in der Reaktionsgeschwindigkeit liegt denke ich hier die 
Anforderung.
100ms wären da wohl eindeutig zu langsam.

Nicht zu vergessen ist, dass preiswerte Servos per PWM offset und 
aktiver Pulslänge evtl. kalibriert werden müssen, um zu verhinder, dass 
der HEXAPOD
in Schräglage durch die Welt läuft.

von Matthias (Gast)


Lesenswert?

Dirk schrieb:
> Genau in der Reaktionsgeschwindigkeit liegt denke ich hier die
> Anforderung.
> 100ms wären da wohl eindeutig zu langsam.

Die 100ms sind ein Wert, bei dem sich bei mir noch kein Servo beschwert 
hat. Mit 18 Servos á 2 ms wäre man bei 36 ms mit der Option, auch noch 
Pausen aus dem Signal rauszukürzen, falls nicht gerade alle in der 2 
ms-Stellung stehen.
Reaktionsgeschindigkeit ist nicht das Problem. Und fast 28 
Positionskommandos pro Sekunde an jeden Servo sollte wohl noch kein 
Engpaß sein.

Dirk schrieb:
> Nicht zu vergessen ist, dass preiswerte Servos per PWM offset und
> aktiver Pulslänge evtl. kalibriert werden müssen, um zu verhinder, dass
> der HEXAPOD in Schräglage durch die Welt läuft.

Ja und? Warum soll man das nicht wie gewohnt machen können? Die Signale 
werden einzig und alleine zeitlich verschachtelt, wie beim Summensignal 
einer Funkfernsteuerung.

von Marv (Gast)


Lesenswert?

Das mit der periodendauer seh ich wie von euch beschrieben nicht so 
eng. test haben ergeben dass die servos noch bei einer pause von 5-50ms 
zwischen den pulsen sauber fahren. Auch unterschiedliche pausen machen 
nichts aus. Zum test haben wir mal alle servos nacheinander angesteuert, 
so ergaben sich pausenzeiten von min.: 17*0,8 = 13,6ms und max.: 17*2,2 
= 37,4ms. Die Servos liefen problemlos. Außer der herangehensweise vom 
multitasking sind mir die funktionsprinzipe der anderen beschriebenen 
herangehensweisen noch unklar. Zum testen wurden bisher nur delays 
eingesetzt. Wir sind aber gerade daran alles mit Timern umzusetzen.

mfG Marv

von MaWin (Gast)


Lesenswert?

> die PWM's praktisch "parallel" neben dem Hauptprogramm
> ablaufen zu lassen.

Ach was.

Das sind Servos.

Deren Ansteuersignal nennt man übrigens PCM pulse code modulation.

Es werden nicht alle Impulse gleichzeitig gesendet,
weil man nicht will, daß alle Servos gleichzeitig Strom ziehen,
sondern nacheinander.
Das geht problemlos, weil ein Servo auch erst in ca. 25msec seinen 
nächsten Impuls sehen will.

Servo1 --XXX-----------------XXX----
Servo2 -----XX------------------XX--
Servo3 -------XXXX----------------XX...
Servo4 -----------XXX---------------

Wenn man das in Form einer Interrupt-Routine machen will, kann diese
einfach jedesmal den "nächsten" Zeitwert setzen. Also pseudocodemässig 
in der Art:

int servoduration[19];

interrupt timer(void)
{
    static int servo=0;

    PORT[servo]=0; // letzten Puls zurücknehmen
    TIMER=servoduration[servo]; // neue Zeit bis zum nächsten Interrupt 
setzen
    servo++;
    if(servo>=19) servo=0;
    PORT[servo]=1; // Puls auslösen
}

Es spielt dabei keine so grosse Rolle, daß die Pausenzeiten von den 
Pulslängen der anderen Servos abhängen.

von Haudrauf ! (Gast)


Lesenswert?

Ist jemandem aufgefallen, dass Servos unter Last Schnattern ? Die 
Schnatterfrequenz ist die Updaterate, bei 20ms also 50Hz.

von Marv (Gast)


Lesenswert?

Danke erstmal für die vielen Antworten!

Es sind allerdings neue Probleme aufgetaucht. Aus uns unerklärlichen 
gründen ist es nicht möglich Timer0 im CTC Modus zu betreiben. Normaler 
Timerbetrieb funktioniert soweit. Nachdem unser programm nicht 
kompillierbar war, haben wir alle fremdfaktoren entfernt, den fehler 
allerding nicht gefunden.
Also: dieser fertige Code versucht zu kompillieren:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
 
4
int main(void)
5
{
6
  // Timer 0 konfigurieren
7
  TCCR0A = (1<<WGM01); // CTC Modus
8
  TCCR0B |= (1<<CS01); // Prescaler 8
9
  // ((1000000/8)/1000) = 125
10
  OCR0A = 125-1;
11
 
12
  // Compare Interrupt erlauben
13
  TIMSK |= (1<<OCIE0A);
14
 
15
  // Global Interrupts aktivieren
16
  sei();
17
 
18
  while(1)
19
  {
20
    /*Hier kann die aktuelle Zeit
21
      ausgeben werden*/
22
  }
23
}
24
 
25
26
27
ISR (TIMER0_COMPA_vect)
28
{
29
 
30
}
ABER: Wir bekommen nur ein Fehlercode. Hat jemand einen Tipp für uns, 
was wir übersehen haben ?
1
Compiling C: main.c
2
avr-gcc -c -mmcu=atmega32 -I. -gdwarf-2 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=./main.lst  -std=gnu99 -MMD -MP -MF .dep/main.o.d main.c -o main.o 
3
main.c: In function 'main':
4
main.c:7: error: 'TCCR0A' undeclared (first use in this function)
5
main.c:7: error: (Each undeclared identifier is reported only once
6
main.c:7: error: for each function it appears in.)
7
main.c:8: error: 'TCCR0B' undeclared (first use in this function)
8
main.c:10: error: 'OCR0A' undeclared (first use in this function)
9
main.c:13: error: 'OCIE0A' undeclared (first use in this function)
10
main.c: At top level:
11
main.c:27: warning: 'TIMER0_COMPA_vect' appears to be a misspelled signal handler
12
make.exe: *** [main.o] Error 1
13
14
> Process Exit Code: 2
15
> Time Taken: 00:01

von Philipp (Gast)


Lesenswert?

>Deren Ansteuersignal nennt man übrigens PCM pulse code modulation.
nein. PPM  PCM ist nur bei moderneren funken zwischen sender und 
empfänger.

Wenn euch irgenwann bei eurem hexapod die Portpins zuneige gehen, könnt 
ihr mit einem 4017 mit 2 portpins 8 servos ansteuern. alles was der 
braucht ist das summensignal und sein sync signal. So in der ausführung 
millionenfach in modellbauempfängern bewährt

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.