Forum: Mikrocontroller und Digitale Elektronik Arduino STM 32 PWM Frequenz


von Kay L. (kgbrus)


Lesenswert?

Hallo und guten Tag,

ich habe eine Frage zur Frequenz vom PWM Ausgang beim STM32 Blue Pill.
Die Frequenz beträgt bei allen 4 Timern im default 1kHz.

Ich habe gelesen das, zumindest bei den Atmega boards man einen anderen 
prescaler auswählen kann und somot sich eine andere Frequenz ergibt.

Kann man dem STM 32 mittels einem Befehl einen anderen Prescaler 
zuweisen? So etwas "prescale(TIM2, 3)"

Ich steuere damit eine Modelleisenbahn und da ist 1kHz suboptimal da 
hörbar. Ich würde gerne eine niedrigere Frequenz nehmen.

Gruß

Kay

von Ingo L. (corrtexx)


Lesenswert?

Kay L. schrieb:
> Ich steuere damit eine Modelleisenbahn und da ist 1kHz suboptimal da
> hörbar. Ich würde gerne eine niedrigere Frequenz nehmen.
Dann musst du höher gehen, nicht tiefer...

von Axel S. (a-za-z0-9)


Lesenswert?

Kay L. schrieb:

> Ich habe gelesen das, zumindest bei den Atmega boards man einen anderen
> prescaler auswählen kann und somot sich eine andere Frequenz ergibt.

Wo hast du das gelesen? Und welche Relevanz soll eine Aussage, die für 
einen ATMega Arduino getroffen wurde, für einen STM32 Arduino haben?

> Kann man dem STM 32 mittels einem Befehl einen anderen Prescaler
> zuweisen? So etwas "prescale(TIM2, 3)"

Das nicht. Aber die Idee an sich ist schon richtig. Such im Arduino 
Framework nach einer Lösung. Nur dann ist sichergestellt, daß die 
Arduino-Lib den Timer nicht auch anderweitig verwendet.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Kay L. schrieb:
> Kann man dem STM 32 mittels einem Befehl einen anderen Prescaler
> zuweisen? So etwas "prescale(TIM2, 3)"

Bei den STM32 kann man flexibel beliebige Prescaler einstellen (jede 
16/32bit Zahl je nach Modell; der STM32F103 auf den Bluepills kann "nur" 
16bit). Das geht z.B. mit "TIM2->PSC = 1234;". Der STM32 hat so viele 
Timer, da wird es sicherlich einen geben, der vom Arduino-Framework in 
Ruhe gelassen wird und den du nach deinen Wünschen nutzen kannst.

von Kay L. (kgbrus)


Lesenswert?

Niklas G. schrieb:
> Kay L. schrieb:
>> Kann man dem STM 32 mittels einem Befehl einen anderen Prescaler
>> zuweisen? So etwas "prescale(TIM2, 3)"
>
> Bei den STM32 kann man flexibel beliebige Prescaler einstellen (jede
> 16/32bit Zahl je nach Modell; der STM32F103 auf den Bluepills kann "nur"
> 16bit). Das geht z.B. mit "TIM2->PSC = 1234;". Der STM32 hat so viele
> Timer, da wird es sicherlich einen geben, der vom Arduino-Framework in
> Ruhe gelassen wird und den du nach deinen Wünschen nutzen kannst.

Hallo Niklas,

vielen Dank, damit komme ich weiter, zumindest ich kann die Frequenz 
ändern, zwar nicht kontrolliert sondern zufällig aber die Frequenz 
ändert sich (bei 0x16 zB auf 77Hz)

Dazu noch ne blöde Frage (ich bin blutiger Anfänger) wie finde ich über 
das Framework heraus ob der Timer frei ist? Mir ist der Begriff 
Framework dabei nicht geläufig

Gruß

Kay

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Kay L. schrieb:
> zwar nicht kontrolliert sondern zufällig aber die Frequenz ändert sich
> (bei 0x16 zB auf 77Hz)

Naja eigentlich kann man den nötigen Prescaler ausrechnen für die 
gewünschte Frequenz...

Kay L. schrieb:
> Dazu noch ne blöde Frage (ich bin blutiger Anfänger) wie finde ich über
> das Framework heraus ob der Timer frei ist?

Im Quelltext von Arduino für STM32 nach "TIM2" o.ä. suchen...

von Steve van de Grens (roehrmond)


Lesenswert?

Ich würde allerdings empfehlen, hier nicht am Arduino Framework vorbei 
zu programmieren. Wenn du analogWrite() zum Erzeugen der PWM verwendest, 
dann verwende die dazu gehörende Funktion analogWriteFrequency().

Siehe 
https://github.com/stm32duino/Arduino_Core_STM32/blob/61a1680ef96871a38672b5d9ea57d7a9df9b3141/cores/arduino/wiring_analog.h#L74

von Kay L. (kgbrus)


Lesenswert?

Steve van de Grens schrieb:
> Ich würde allerdings empfehlen, hier nicht am Arduino Framework vorbei
> zu programmieren. Wenn du analogWrite() zum Erzeugen der PWM verwendest,
> dann verwende die dazu gehörende Funktion analogWriteFrequency().
>
> Siehe
> 
https://github.com/stm32duino/Arduino_Core_STM32/blob/61a1680ef96871a38672b5d9ea57d7a9df9b3141/cores/arduino/wiring_analog.h#L74

Hallo Steve,

auch dir vielen Dank für den Tip. Dies funktioniert einwandfrei. Damit 
ich das besser verstehe, der Befehl bezieht sich nur auf analogWrite? 
die Prescaler der einzelnen Timer bleiben unangetastet und somit kann 
sich kein Zeitablauf im Arduino (wie delay oder millis) ändern?

Gruß

kay

von Kay L. (kgbrus)


Lesenswert?

Ingo L. schrieb:
> Kay L. schrieb:
>> Ich steuere damit eine Modelleisenbahn und da ist 1kHz suboptimal da
>> hörbar. Ich würde gerne eine niedrigere Frequenz nehmen.
> Dann musst du höher gehen, nicht tiefer...

Hallo Ingo,
von der Tonhöhe betrachtet hat Du Recht. Die Motoren der Loks verhalten 
sich aber so, das je höher die Frequenz, desto kleiner ist der 
Regelbereich.
ZB. bei 100 Hz dreht der Motor bis zum Wert 40 also ein Regelbereich von 
40-254
bei 1kHz geht der Bereich nur bis zum Wert 90 danach dreht der Motor 
nicht mehr.

Gruß

Kay

von Jasson J. (jasson)


Lesenswert?

>ZB. bei 100 Hz dreht der Motor bis zum Wert 40 also ein Regelbereich von
>40-254
>bei 1kHz geht der Bereich nur bis zum Wert 90 danach dreht der Motor
>nicht mehr.

Du meinst, der minimale PWM-Wert damit die Motoren noch drehen?
Ich hatte mal beruflich ein bisschen mit Modelleisenbahn zu tun und was 
ich bisher generell an E-Motoren unterschiedlicher Güte gesehen habe,
-
würde ich sagen, dass das nicht unmittelbar ein Verhalten von 
Lok-Motoren ist, sondern davon abhängt, ob es es angeharzter 
Bürstenmotor ist, ein gut gewarteter Glockenankermotor und dem Gewicht, 
dass an der Lok hängt.
-
zumindest die konkreten Werte, "wo Motoren noch anlaufen" - in der 
Tendenz stimmt es, dass eine höhere PWM-Frequenz zu einem verringerten 
nutzbaren PWM-Bereich führt (someone correct me please)

: Bearbeitet durch User
von Kay L. (kgbrus)


Lesenswert?

Jasson J. schrieb:
> Du meinst, der minimale PWM-Wert damit die Motoren noch drehen?

Ja exakt.

Jasson J. schrieb:
> würde ich sagen, dass das nicht unmittelbar ein Verhalten von
> Lok-Motoren ist, sondern davon abhängt, ob es es angeharzter
> Bürstenmotor ist, ein gut gewarteter Glockenankermotor und dem Gewicht,
> dass an der Lok hängt.

Ja bei meinen Märklin ist es sogar noch komplizierter... Gleicher 
Loktyp, gleiche Art Motor, beide komplett zerlegt und gereinigt. 
Trotzdem unterschiedlich schnell bei gleicher Fahrspannung. Und anderer 
Spannungswert zum anfahren von Nöten.


Jasson J. schrieb:
> in der
> Tendenz stimmt es, dass eine höhere PWM-Frequenz zu einem verringerten
> nutzbaren PWM-Bereich führt

das ist für Langsamfahrt eine niedrigere Frequenz hilfreich

: Bearbeitet durch User
von Jasson J. (jasson)


Lesenswert?

Ich nehme an, es geht um die Standardgröße H0?
Die sind natürlich für Hobbybaster schon recht klein - wobei ich deinen 
Skill und Equipment natürlich nicht kenne.

Auch unter dem Aspekt ist das was ich jetzt schreibe entweder hilfreich 
/ inspirierend oder bossing :>

Man könnte mehrere Dinge überlegen
-
* die Frequenz dynamisch zum PWM Wert machen
* zum anfahren könnte man in den Stellwert einen D-Anteil 
(Differentiellen Wert) addieren, der für einen kurzen Puls sorgt, um den 
Motor zuverlässiger anfahren zu können. Da wird man auch schon fiddeln 
müssen mit Dingen wie ob der D-Anteil nur bei hochsetzen der PWM greift 
oder in beide Richtungen und dann ggf. mit unterschiedlichen 
Zeitkonstanten
* Vielleicht kann man mit ner Drehzahlerfassung und Drehzahlregelung was 
reißen. Dann hat man aber das Fiddeln mit nem Regler am Hals.

Alle Ideen haben unterschiedliche Level an Komplexität.
Grundsätzlich sollte man auf Dauer Parameter nicht hard coden. Zum 
Ansatz / Konzept ausarbeiten und experimentieren auf einer Versuchslok 
kann man das machen.
Später sollte es aber auf irgendeine Art parametrierbar sein, um die 
Funktonskomponenten die man hat, dynamisch auf verschiedene Loks 
anpassen zu können - oder man müsste eben für jede Lok eine eigene 
Code-Kopie haben. Das ist einfacher im ersten Schritt, jedoch wird man 
früher oder später plötzlich verschiedene Stände auf verschiedenen Loks 
haben und nicht mehr durchblicken.

von Steve van de Grens (roehrmond)


Lesenswert?

Kay L. schrieb:
> Damit
> ich das besser verstehe, der Befehl bezieht sich nur auf analogWrite?
> die Prescaler der einzelnen Timer bleiben unangetastet und somit kann
> sich kein Zeitablauf im Arduino (wie delay oder millis) ändern?

Arduino scheint deswegen einfach, weil die Dokumentation knapp gehalten 
wird. Ich weiß die Antwort nicht und kann sie auch nicht mal eben 
schnell an den wenigen Worten Doku ablesen. Ich würde dir empfehlen, den 
Quelltext auf GitHub zu lesen.

von Jasson J. (jasson)


Lesenswert?

Das ist (leider) der Punkt - so lange man sich in dehnbaren Boundarys 
bewegt und nur sehr begrenzt Libs mischt oder bestimmte Funktonen 
tweaken möchte, ist es einfach.
-
Direkt darüber hinaus muss man dann doch Source Code durchstöbern, 
verstehen und sich mit dem µC auf dem es läuft aus einander setzten.

Daher werden für wirklich reine Hobbybastler geschickte und höher 
inetegrierte Lösungen dann doch recht bald auch mit Arduino schwierig.

von Kay L. (kgbrus)


Lesenswert?

Jasson J. schrieb:
> Ich nehme an, es geht um die Standardgröße H0?

Ja darum handelt es sich, aber um einen anderen Ansatz.
ich benutze nur alte analoge Loks die Arduinos steuern nur die Abläufe 
der Streckenabschnitte und ersetzten die analogen AC Trafos.

Wer sich ein wenig mit dem alten Zeugs befasst kennt die "Zugsteuerung 
durch Signalbeeinflussung" oder den Universalfernschalter von Märklin 
dies ersetzte ich durch arduinos somit sind komplexe Abläufe möglich. 
Dies baue ich mittels Arduinos nach.

An den Gleisen sind Lichtschranken die die durchfahrt einer Lok melden 
daraufhin werden Weichen gestellt, Fahrstrecken ab oder angeschaltet 
usw.
Ein Beispiel ist der Schattenbahnhof:
- Zug fährt ein, bekommt ein freies Gleis zugewiesen und fährt darauf 
bis zum Haltepunkt
Der Arduino wertet die Lichtschranke in der Einfahrt aus, die 
Lichtschranken in den Abstellgleisen ebenfalls, stellt danach die 
Weichen so das die Lok auf das freie Abstellgleis geleitet wird und 
schaltet den Fahrstrom ab, wenn die Endposition erreicht ist.
In den Loks selber werden (Stand heute ) keine Arduinos oä verbaut.
Der Fahrstrom wird für jeden Abschnitt (oder Gleis) je nachdem separat 
geregelt (als würde man an einem Trafo drehen) Entweder automatisch oder 
manuell.
Das zu den Randbedingungen.

Jasson J. schrieb:
> * zum anfahren könnte man in den Stellwert einen D-Anteil
> (Differentiellen Wert) addieren, der für einen kurzen Puls sorgt, um den
> Motor zuverlässiger anfahren zu können

Ja auf dieses Problem bin ich auch schon gestoßen. Bei einem Wert von 
analogWrite von zB 50 fährt die Lok zwar noch wenn sie aus der Bewegung 
abgebremst wird, aber anfahren tut sie nicht. Im Moment habe ich das 
(wahrscheinlich sehr unelegant) so gelöst das ich zuerst den Wert 120 
nehme (damit fährt jede Lok an) und dann erst auf denn langsameren (zb 
50) gehe.
Da ich viel mit State Maschine (mit next_State) arbeite ist das auch 
relativ einfach zu realisiern.

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.