Forum: Mikrocontroller und Digitale Elektronik Motordrehzahl "flüssig" regeln mit PWM


von Irving (Gast)


Lesenswert?

Hallo,
also ich habe einen Igarashi DC Motor (12V), dessen Drehzahl ich gerne 
mittels PWM meines Atmega32(4PA) regeln möchte. Ich benutze einen L293D 
zum Schalten des Motors und soweit würde auch alles nicht so schlecht 
funktionieren.
Ich weiß ich könnte die Timer Modes für die PWM benutzen (wie es hier in 
einigen Tutorials gezeigt wird) habe mich aber zur Zeit der einfachheit 
halber für folgende naive Lösung entschieden:
1
ISR (TIMER0_OVF_vect)
2
{
3
  TCNT0 = T0RELOAD;
4
  cnt++;
5
  if(mode == 0 && cnt >= highValue)
6
  {
7
    PORTA = 0;
8
    cnt = 0;
9
    mode = 1;
10
  }
11
  if(mode == 1 && cnt >= lowValue)
12
  {
13
    PORTA = 1;
14
    mode = 0;
15
    cnt = 0;
16
  }
17
}
highValue und lowValue werden je nach gewünschter Spannung durch eine 
Funktion bestimmt. Das Timerintervall liegt zur Zeit bei 1ms.
Ich hab mich eigentlich so ziemlich daran 
(http://www.mikrocontroller.net/articles/Pulsweitenmodulation) 
gehalten...

Nun zu meinem eigentlichen Problem...
Die Spannungswerte, welche (im Mittel) am Motor anliegen sind relativ 
umgenau (ca. +/-0.5V), obwohl dies laut Berechnung eigentlich nicht sein 
sollte. Kann mir diesbezüglich jemand einen Tipp geben? Sollte ich 
wirklich die Timer Modes für die Erzeugung der PWM Signale nutzen bzw. 
bringt dies für meine Anwendung wirklich etwas. Hierzu ist zu sagen, 
dass ich nur die Motordrehzahl relativ genau regeln will, der 
Mikrocontroller hat sonst keinerlei Aufgaben und ob das Programm jetzt 
ideal oder nicht ist, ist mir im moment auch ziemlich egal solange es 
funktioniert :).
Gibt es vl. sogar schon fertige Treiber bei denen diese Funktionalität 
schon implementiert ist? vl. kann mir ja jemand helfen.


lg

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Irving schrieb:
> ich könnte die Timer Modes für die PWM benutzen

Naja, 'Timer Modes' sind das ja alle. Du wirst vermutlich die PWM Modes 
meinen und die klare Antwort ist - ja, tue es. Der Grund ist nicht nur 
die einfacherere Programmierung, sondern auch die Erzeugung der PWM 
Pulse durch Hardware, da gibt es kein Zittern durch ein oder 2 Takte 
Unterschied in der Antwort auf den Timer Überlauf , wie es im Moment bei 
dir unvermeidlich ist.

Irving schrieb:
> Hierzu ist zu sagen,
> dass ich nur die Motordrehzahl relativ genau regeln will,

Wenn du regeln willst, ist es ja ausserdem nötig, die Motordrehzahl zu 
erfassen. Je weniger du also den MC mit der Ausgabe der PWM belastest, 
umso mehr Rechenzeit bleibt zur Implementierung der Erfassung und eines 
Regelkreises.
Schau dir für einen einfachen und brauchbaren PID Regler mal die AVR 
Application Note 221 an, das ist ein schöner Regler in C.

von Wolfgang (Gast)


Lesenswert?

Falls du auf höhere PWM-Auflösung Wert legst, ist ein 8-Bit Timer nicht 
die richtige Wahl. Mit einem 16-Bit Timer mit Hardware PWM kannst du 
deutlich feiner steuern.

von Irving (Gast)


Lesenswert?

okay danke erstmals für die doch sehr hilfreichen Antworten. Hab das 
jetzt kurz probiert (mit dem phase and frequency correct mode) und es 
hat eigentlich schon sehr gut funktioniert (ca. 0.1V Fehler, wobei ich 
es auch nur mit nem gewöhnlichen und zum Glück sehr trägen 
Digitalmultimeter messe).
Die Parametrisierung bzw. die Konfiguration einer "beliebigen" 
Ausgangsspannung ist eigentlich auch relativ einfach.
Eigentlich hätt ich nur eine andere kurze Frage am Rand. Gibt es einen 
effizienten Algorithmus um das Verhältnis Um/U0 = te/(te+ta) möglichst 
genau für beliebige Werte zu berechnen. Natürlich könnt ich jetzt einen 
Periode fixieren und dann den anderen ausrechnen und dann beliebige den 
"konstanten" Wert variieren, jedoch scheint mir das ziemlich ineffizient 
(vorallem relativ hohen Rechenaufwand für die langsame CPU...)

lG

von Jörg E. (jackfritt)


Lesenswert?

Der motor wird doch unterschiedlich belastet oder nich? Du musst das 
erfassen sonst is deine rechnung ne schätzung ins blaue.

von Irving (Gast)


Lesenswert?

danke erstmal für die tipps.. funktioniert bis jetzt alles so wie ich 
mir das vorgestellt habe.. hätte nur eine frage am rande. wenn ich jetzt 
den motor bzw. die pwm signale für ein paar sekunden stoppen will, 
könnte ich einfach den verstärker deaktivieren (also ddr register bit = 
0 setzen) oder ist dies in diesem fall eher nicht so gut (so weit ich 
weiß soll man den verstärker nicht andauernd ein und wieder 
abschalten...). oder ist es besser die COMnx bits im TCCRnA Register zu 
löschen?

lg

von Karl H. (kbuchegg)


Lesenswert?

COM Bits löschen ist wahrscheinlich die einfachere Variante.

Wenn es an deinem 'Verstärker' egal ist, ob der ein 0 Bit oder ein 1 Bit 
sieht, dann kannst du alternativ auch einfach den Timer stoppen, in dem 
du ihn auf 'kein Vorteiler' einstellst. SOnst ist COM Bits löschen 
sicher die einfachere Variante, denn du musst ja auch bedenken, dass der 
Ausgabepin nicht von alleine auf 0 zurück geht, nur weil die COM-Bits 
gelöscht werden.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Irving schrieb:
> also ddr register bit =
> 0 setzen) oder ist dies in diesem fall eher nicht so gut. oder ist es
> besser die COMnx bits im TCCRnA Register zu
> löschen?

Beides ist möglich und zulässig. Wenn du per Hardware dafür sorgst, das 
der Ausgangspin auf einen definierten (Aus-)Pegel geht, z.B. per Pullup 
oder Pulldown R, dann ist auch das DDR Bit möglich (wie Karl Heinz schon 
sagte), zumindest machen das auch diverse Application Notes bei Atmel.
> (so weit ich
> weiß soll man den verstärker nicht andauernd ein und wieder
> abschalten...)
Das macht die PWM doch sowieso - ist also perfekt zulässig.

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.