Arduino (Nano): ISR synchron zu PWM?

Begonnen von habichthugo, 27 Juni 2020, 12:43:00

Vorheriges Thema - Nächstes Thema

habichthugo

Ich versuche mit dem Arduino über PWM verschiedene Wellenformen (Sinus, Dreieck u.ä.) zu erzeugen. Dazu benutze ich bisher die normalen PWM-Pins und analogwrite. Wenn ich das nun im Main-loop (mit delay) mache oder auch per selbst programmiertem Timer und ISR (Timer 2) ist das immer asynchron zum PWM. Wie kann man eine ISR synchron zu den PWM-Intervallen rufen lassen (also für z.B. Pin3 ~ 490/s) ? Eventuell die Standard ISR der Arduino-Bibliothek (wie) hooken?
CUL (CC1101-USB-Lite module-V3) + 5*fht80b + 6*Mumbi-Funksteckdosen (=Elro AB440); HM-LAN + 11*HM-LC-Bl1PBU-FM Rollladenaktor + 1*HM-LC-Sw1PBU-FM Funklichtschalter + 2*HM-RC-12-W; Raspbian (Raspberry Pi Model B Rev 1 ECN0001 256MB)

loetmeister

Hi,

ich bin mir nicht ganz Sicher ob ich die Problemstellung erfasst habe... was Genau willst synchron zum PWM haben? Eine Funktion...? Wie hast du die Asynchronizität festgestellt? Mit einem Pin (set/clear im wechsel)?

Wenn du eine Funktion in Timer 2 einbindest und auch den PWM Ausgang nutzt der von Timer 2 gesteuert ist, sollte das doch gehen?

PWM Pins am Nano (328p):
5  - PWM out (controlled by timer0)
6  - PWM out (controlled by timer0)
9  - PWM out (controlled by timer1)
10 - PWM out (controlled by timer1)
11 - PWM out (controlled by timer2)
3  - PWM out (controlled by timer2)

Gruß,
Thomas

habichthugo

Na ich möchte in jedem PWM-Intervall den Aussteuergrad (duty cycle bzw. analogwrite) anpassen, also für z.B. Pin3 rund 490 Mal pro Sekunde. Dazu brauche ich einen Interrupt, der synchron zu den PWM-Intervallen kommt.
Ich habe mich jetzt damit beschäftigt, die Timer selbst zu programmieren. Dabei habe ich aber bisher nur Beispiele gefunden, die die entweder als PWM oder für ISR konfigurieren. Ich bin mir also immer noch nicht einig, ob beides gleichzeitig geht.
Und dann wäre noch zu klären, wie genau sich die Timer bei Überschreiben des Compare-Registers verhalten: Also wenn z.B. der Interrupt zum Start des Intervalls käme un ich den Duty cicle von z.B. 50% auf 0 reduziere, der Counter aber schon ein Stück hochgezählt hat, was passiert dann? Läuft das Intervall mit Pin High zu Ende oder schaltet der Timer dann sofort (dennoch zu spät) wieder auf Low? Eigentlich müsste das gepuffert sein bzw. der Registerwert dann immer erst zum Start des Intervalls übernommen werden. Aber ist das so? Ich habe dazu bisher nichts finden können.
Wenn ich, wie ich das in mehreren Beispielen gefunden habe, das einfach asynchron aus dem Main-loop mache, dann bekomme ich Schwebungen und offenbar genau solche 'Stöße', wie zuvor beschrieben. Ich habe zwar kein Oszi, aber das kann ich über Lautsprecher hören.
CUL (CC1101-USB-Lite module-V3) + 5*fht80b + 6*Mumbi-Funksteckdosen (=Elro AB440); HM-LAN + 11*HM-LC-Bl1PBU-FM Rollladenaktor + 1*HM-LC-Sw1PBU-FM Funklichtschalter + 2*HM-RC-12-W; Raspbian (Raspberry Pi Model B Rev 1 ECN0001 256MB)

loetmeister

Hi,

Danke für die zusätzlichen Info.
So was hab ich bisher noch nicht versucht, aber man kann ja ohne Probleme die PWM Ausgänge nutzen, die an timer 0 hängen und weiterhin millis() verwenden, welcher brav weiter zählt.

Den duty cycle in der interrupt routine änderst du dann direkt über die register? AnalogWrite ist ja relativ langsam?

Gruß,
Thomas

habichthugo

Wenn man die Timer eh von Hand konfigurieren muss kann man alles auch gleich direkt über Register machen. Aber ein exaktes Timing, wie ich es wollte, kriegt man zusammen mit PWM offenbar nicht hin, es sei denn, man mamaged alle Interrupts selbst (und killt damit millis, I2C etc.).
Ich werde wohl einen fertigen DDS (Basis AD9833) nehmen...
CUL (CC1101-USB-Lite module-V3) + 5*fht80b + 6*Mumbi-Funksteckdosen (=Elro AB440); HM-LAN + 11*HM-LC-Bl1PBU-FM Rollladenaktor + 1*HM-LC-Sw1PBU-FM Funklichtschalter + 2*HM-RC-12-W; Raspbian (Raspberry Pi Model B Rev 1 ECN0001 256MB)