Forum: Mikrocontroller und Digitale Elektronik Zähler für PWM-Signal


von Alexander R. (alex12)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

ich hätte mal eine Frage zum PWM-Signal an meinem Teensy 3.5
Und zwar habe ich einen PID-Regler programmiert, der soweit auch 
funktioniert und einen Stellwert (y_value1) liefert, den ich wie im Code 
zu erkennen auf max.100 gedeckelt ist.
Nun bin ich noch relativer Anfänger, und habe mir gedacht ich mache aus 
meinem Stellwert ein PWM-Signal. Ich wollte eine Periodendauer von 2s 
haben, also wenn der Stellwert 100 ist will ich 100% HIGH-TIME und bei 
Stellwert 50 z.B 50% HIGH-TIME und 50% LOW-TIME. Das soll dann über 
einen digitalen PIN geschalten werden.
Nur leide fehlt mir die Programmiererfahrung das Ganze zu realiesieren.

Ansatz wäre eine if-Funktion gewesen:
if (Zählerwert > Stellwert) {PIN auf LOW}
if (Zählerwert == 0) {dann wieder auf HIGH}

Habt ihr eine Idee wie man das realisieren könnte? Also wie bekomme ich 
einen Zähler hin, der alle 2s (Periodendauer) ein neues PWM erzeugt?

Danke im Vorraus

Anbei noch der bisherige Code

von Stefan F. (Gast)


Lesenswert?

PWM realisiert man normalerweise nicht durch solche Softwareschleifen, 
sondern durch Hardware-Timer.

Den dein Programm muss ja noch mehr machen, als nur das PWM Signal zu 
erzeugen. Ohne Hardware-Timer geht das nur sehr eingeschränkt und 
unpräzise.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Alexander R. schrieb:
> Also wie bekomme ich einen Zähler hin, der alle 2s (Periodendauer) ein
> neues PWM erzeugt?
Indem du zuallererst mal einen Zähler hast, der die Zeit mitzählt. Denn 
prinzipiell kennt ein Programm keine Zeit, sondern läuft so schnell wie 
möglich.
Und weil du jetzt ja eine gewisse und zudem ziemlich lange Zeit low und 
dann eine bestimmte Zeit high haben willst, brauchst du eine Uhr, die im 
einfachsten Fall die Millisekunden zählt.
Und wenn du dann 50% PWM willst, dann machst du jeweils 1s high und low.

Beim Arduino heißt diese Uhr millis()

: Bearbeitet durch Moderator
von Alexander Raab (Gast)


Lesenswert?

Lothar M. schrieb:
> Alexander R. schrieb:
> Also wie bekomme ich einen Zähler hin, der alle 2s (Periodendauer) ein
> neues PWM erzeugt?
>
> Indem du zuallererst mal einen Zähler hast, der die Zeit mitzählt. Denn
> prinzipiell kennt ein Programm keine Zeit, sondern läuft so schnell wie
> möglich.
> Und weil du jetzt ja eine gewisse und zudem ziemlich lange Zeit low und
> dann eine bestimmte Zeit high haben willst, brauchst du eine Uhr, die im
> einfachsten Fall die Millisekunden zählt.
> Und wenn du dann 50% PWM willst, dann machst du jeweils 1s high und low.
>
> Beim Arduino heißt diese Uhr millis()

Danke für die schnelle Antwort.
Hast du vielleicht ein Beispiel wie man so einen Zähler realisieren 
kann? Find im Netz nur unnötig komplizierte Sachen.

von Stefan F. (Gast)


Lesenswert?

Alexander Raab schrieb:
> Hast du vielleicht ein Beispiel wie man so einen Zähler realisieren
> kann? Find im Netz nur unnötig komplizierte Sachen.

Wie gefällt Dir das: 
http://stefanfrings.de/multithreading_arduino/index.html

Ein Thread erzeugt das PWM Signal, der andere liest den Stellwert ein.

von Wolfgang (Gast)


Lesenswert?

Alexander Raab schrieb:
> Hast du vielleicht ein Beispiel wie man so einen Zähler realisieren
> kann?

Der Zähler (Timer) läuft mit Sicherheit schon. Die millis()-Funktion 
basiert darauf - allerdings nicht mit 2s ;-)

von Joe F. (easylife)


Lesenswert?

Ich nutze für so langsame PWM gerne einen Timer-Interrupt.
Wenn dir eine Auflösung von 1% bei 2 Hz ausreicht, wird dieser ja nur 
alle 20ms aufgerufen.

Die PWM wird "gesteuert", indem du irgendwo in loop() pwm_set auf einen 
Wert zwischen 0 und 100 setzt.
Die in timer_isr() implementierte Routine kann mit den Extremfällen PWM 
0% (dauerhaft AUS) und 100% (dauerhaft EIN) umgehen.
1
#include "TimerOne.h"
2
#include <stdint.h>
3
4
uint8_t pwm_cnt = 0;
5
uint8_t pwm_set = 0;
6
uint8_t pwm_state = 0;
7
8
void timer_isr()
9
{
10
  digitalWrite(PWM_PIN, pwm_state);
11
12
  pwm_cnt++;
13
  if (pwm_cnt >= 100)
14
  {
15
    pwm_cnt = 0;
16
    pwm_state = 1;
17
  }
18
  
19
  if (pwm_cnt >= pwm_set)
20
    pwm_state = 0;
21
}
22
23
void setup() 
24
{
25
  Timer1.initialize(20000); // every 20ms
26
  Timer1.attachInterrupt(timer_isr);
27
}
28
29
void loop() 
30
{
31
  // do other stuff
32
33
  pwm_set = 10; // set PWM to 10%
34
  while(1);
35
}

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Alexander Raab schrieb:

> Find im Netz nur unnötig komplizierte Sachen.

Wie willst du mit deinem Wissensstand von quasi NULL einschätzen können, 
was nötig und was unnötig ist?

Tsss...

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.