Forum: Mikrocontroller und Digitale Elektronik Soft-PWM mit Atmega16


von Chris (Gast)


Lesenswert?

Hallo,

ich habe eine Frage zu dem Artikel Soft-PWM hier auf der Seite. Ich habe 
einen atmega16 mit 16 Mhz und habe dies als einziges im Code geändert, 
sowie dass PORTD statt PORTB verwendet wird. Ich verstehe nun aber 
nicht, wieso schon bei einem Wert von 50 die vollen 2ms high sind bzw 
wie ich bei diesem Code die 256 auf 2 ms mappen kann.

Vielen Dank schonmal

von Chris (Gast)


Lesenswert?

Vielleicht habe ich mich ungenau ausgedrückt.

Ich habe vor, eine Servosteuerung für 16 Servos zu programmieren. Diese 
müssen in einem Intervall von 18 ms immer ein Signal zwischen 1 und 2 ms 
bekommen. ich habe es jetzt geschafft 2 ms auf 256 zu mappen indem ich 
die PWM Frequenz erhöht habe und am Ende vom Timer nochma 18ms ins OCR1A 
Register geschrieben habe. jedoch sobald ich versuche 256 auf 1 ms zu 
mappen, da das ja reicht für meine Servos, funktioniert das alles 
nichtmehr mit der Taktanzahl in der ISR usw. :(

Es muss doch eine Möglichkeit geben. Ich weiß nicht, ob es mit weniger 
als einem Grad Genauigkeit funktioniert. Wäre schön wenn ich mind. einen 
Wert pro Grad des Servos habe.

von Falk B. (falk)


Lesenswert?

@Chris (Gast)

>bekommen. ich habe es jetzt geschafft 2 ms auf 256 zu mappen indem ich
>die PWM Frequenz erhöht habe und am Ende vom Timer nochma 18ms ins OCR1A
>Register geschrieben habe.

Ob das so einfah funktioniert?

>mappen, da das ja reicht für meine Servos, funktioniert das alles
>nichtmehr mit der Taktanzahl in der ISR usw. :(

Das ist wohl das Problem.

>Es muss doch eine Möglichkeit geben. Ich weiß nicht, ob es mit weniger
>als einem Grad Genauigkeit funktioniert. Wäre schön wenn ich mind. einen
>Wert pro Grad des Servos habe.

Schon mal gerechnet, wie hoch man da zeitlich auflösen muss?

1-2ms = 0-270 Grad

-> 3,7µs/Grad

Macht selbst bei 16 MHz gerade mal 60 Takte.

Such mal im Forum, da gibt es einen 20 Kanal Servogeber, der kann das, 
funktioniert aber anders.

MFG
Falk

von Christian (Gast)


Lesenswert?

Danke schonmal für die Antwort.

Dann suche ich mal ein neues Verfahren, wenn es hiermit an der 
Genauigkeit scheitert.

von MaWin (Gast)


Lesenswert?

> Ich habe vor, eine Servosteuerung für 16 Servos zu programmieren.

Dann sei schlau und lass nicht alle Servos zur gleichen Zeit anlaufen, 
sondern verteile die Impulse zeitlich nacheinander, du hast offiziell 
25msec Zeit, die kann man auch auf 32msec dehnen.

Also ein Timer, ein Servo, 1-2msec seinen Ausgang high, dann der nächste 
Servo auf anderem Ausgang mit demselben Timer nur neuem Timerwert.

Denn wenn du bei allen 16 Servos gleichzeitig eine Positionsänderung 
auslöst und alle gleichzeitg anfangen Strom zu ziehen, dann bricht deine 
Betriebsspannung zusammen.

von Christian (Gast)


Lesenswert?

hmm

also wenn die alle synchron laufen wäre schon recht wichtig und ich hab 
mal geschaut wenn sich alle bewegen ohne großartig Gewicht dran sind es 
ungefähr 700 mAh. Dafür ist meine Platine ausgelegt. Unter gewisser Last 
komme ich grad so an die 2 Ah. das ist zwar kritisch aber noch 
schaffbar.

Und selbst wenn ich sie versetzt laufen lasse, habe ich noch nicht das 
Problem mit den max 100 unterschiedlichen Servopositionen gelöst.

von Falk B. (falk)


Lesenswert?

@  Christian (Gast)

>also wenn die alle synchron laufen wäre schon recht wichtig

Das tun sie auch bei der beschriebenen methode, aber nicht gleichphasig.

>und ich hab
>mal geschaut wenn sich alle bewegen ohne großartig Gewicht dran sind es
>ungefähr 700 mAh.

Ohne h.

> Dafür ist meine Platine ausgelegt. Unter gewisser Last
>komme ich grad so an die 2 Ah.

dito.

>Und selbst wenn ich sie versetzt laufen lasse, habe ich noch nicht das
>Problem mit den max 100 unterschiedlichen Servopositionen gelöst.

Doch. Eben weil man bei versetzter Ansteuerung deutlich kleinere 
Zeitauflösungen schafft. Praktisch nahezu bis auf den Controllertakt 
runter, ggf. etwas mehr. Stichwort Output Compare Funktion und Interupt.

MFG
Falk

von Christian (Gast)


Lesenswert?

Ich weiß nicht, wie du das vorhast?
Soll ich beide OC1A und OC1B nutzen für die Versetzung oder wie?
Mir reicht ansich Pseudocode oder eine Idee. Und wie soll ich die Servos 
auf nahezu 16 MHz laufen lassen? wenn die Interruptroutine zu häufig 
aufgerufen wird, klappt die Uart nichtmehr, da die ja auch eine Weile 
braucht.

von Falk B. (falk)


Lesenswert?

@  Christian (Gast)

>Soll ich beide OC1A und OC1B nutzen für die Versetzung oder wie?

Nein, einer reicht. In einem OCR1A Interrupt muss man zwei Sachen 
machen.
Pin Nr. X einschalten. Dann nach der gewünschten Anzahl Takte den 
Interrupt wieder aktiv werden lassen, im Prinzp so wie bei Soft-PWM.
1
ISR(TIMER1_COMPA_vect) {
2
    static uint8_t channel=0;
3
4
    // aktuellen Pin löschen
5
    PORTD & = ~portvalue[channel];
6
7
    // neuen Kanal
8
    channel++;
9
    if (channel == 15) channel=0;
10
11
    //neuen Pin setzen    
12
    PORTD | = portvalue[channel];
13
14
    // Pulszeit einstellen
15
16
    OCR1A += (uint16_t)pulsewidth[channel];
17
}

>Mir reicht ansich Pseudocode oder eine Idee. Und wie soll ich die Servos
>auf nahezu 16 MHz laufen lassen?

Die Servos kaum, dein AVR schon. Siehe oben.

>wenn die Interruptroutine zu häufig
>aufgerufen wird, klappt die Uart nichtmehr, da die ja auch eine Weile
>braucht.

Das passt schon, keine Bange. Die Servo-Pulse sind mindesten 1ms breit, 
eine kleine Ewigkeit für deinen uC.

MFG
Falk

von Christian (Gast)


Lesenswert?

ah die Idee ist super danke ich probier mal mein Glück.
Werde ja sehen, ob das alles mit der UART klappt.

von Christian (Gast)


Lesenswert?

Eh sry, dass ich dafür einen zweiten Beitrag mache, aber nach der Idee 
würde doch dann erst ein Pin angesteuert, nach seiner Zeit also max 2 ms 
würde der Nächste usw. Das hieße ich hätte nach max 32 ms alle 16 servos 
angesteuert oder? wäre das net bissl viel versetzt wenn der erste 30 ms 
vor dem zweiten Servo seine Position anfährt?

von Falk B. (falk)


Lesenswert?

@  Christian (Gast)

>würde doch dann erst ein Pin angesteuert, nach seiner Zeit also max 2 ms
>würde der Nächste usw. Das hieße ich hätte nach max 32 ms alle 16 servos
>angesteuert oder?

Ja.

> wäre das net bissl viel versetzt wenn der erste 30 ms
> vor dem zweiten Servo seine Position anfährt?

Jain. Die Servos halten doch ihre Position. Wenn du nicht gerade 
superschnelle, hochkomplexe Servobewegungen machen willst, sollte die 
versetzte Ansteuerung kein Problem sein.

MfG
Falk

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.