How to make PWM rising edge trigger an interrupt?
Posted: Fri Jul 15, 2022 11:41 am
Is it possible to have a pin output PWM meanwhile let the output's rising or falling edge trigger an interrupt?
Please see the new forum at
https://forum.micropython.org/
In fact, I thought the latter approach as the fallback solution, but it seems to be redundant. That's also why I raised this question.Roberthh wrote: ↑Sat Jul 16, 2022 11:24 amAlmost all internal counters can be programmed to trigger an interrupt if the count range is reached, which is at every period of PWM. With pyb.Timer you could check, if the callback options of timer.channel is doing that. Alternatively, you can connect the PWM output to an input Pin object and use pin.irq(). Be aware of the callback latency, which is fast for PyBoard (~5 µs), but slow for other boards like ESP32.
That's hardware dependent and configurable ni the hardware. If that should be implemented, a common semantics would have to be defined for all ports supporting it. So for the moment, pin IRQ is the way to go.As for the period triggered interrupt, I doubt it triggers the interrupt at the very end of the period.
Code: Select all
from pyb import Pin, Timer
from time import ticks_us, ticks_diff, sleep_ms
from array import array
import micropython
micropython.alloc_emergency_exception_buf(160)
pb3 = Pin('B3') # ------- B3 has TIM2, CH2 on Stm32F411 Blackpill board ----
tim = Timer(2, freq=1000)
ch = tim.channel(2, Timer.PWM, pin=pb3)
ch.pulse_width_percent(70)
n_td_told = array("i", (0, ticks_us(),
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0))
@micropython.viper
def _callb(pin):
p = ptr32(n_td_told)
n = p[0] + 1
if n <= 50:
p[2*n] = n
p[2*n+1] = int(ticks_us())
p[0] = n
try:
pb3.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=_callb, hard=True) # Pin.IRQ_RISING | Pin.IRQ_FALLING
print('hard interrupt')
except TypeError:
pb3.irq(trigger=Pin.IRQ_RISING, handler=_callb)
print('soft interrupt')
print('total', n_td_told[0], 't0:', n_td_told[1])
for i in range(1, 51):
print('n', n_td_told[2*i], 't:', n_td_told[2*i+1], 't-diff', n_td_told[2*i+1]-n_td_told[2*i-1])
Code: Select all
hard interrupt
total 1 t0: 1020892502
n 1 t: 1020894079 t-diff 1577
n 2 t: 1020894376 t-diff 297
n 3 t: 1020895083 t-diff 707
n 4 t: 1020895376 t-diff 293
n 5 t: 1020896076 t-diff 700
n 6 t: 1020896376 t-diff 300
n 7 t: 1020897076 t-diff 700
n 8 t: 1020897376 t-diff 300
n 9 t: 1020898076 t-diff 700
n 10 t: 1020898382 t-diff 306
n 11 t: 1020899083 t-diff 701
n 12 t: 1020899376 t-diff 293
n 13 t: 1020900076 t-diff 700
n 14 t: 1020900376 t-diff 300
n 15 t: 1020901076 t-diff 700
n 16 t: 1020901376 t-diff 300
n 17 t: 1020902076 t-diff 700
n 18 t: 1020902376 t-diff 300
n 19 t: 1020903076 t-diff 700
n 20 t: 1020903376 t-diff 300
n 21 t: 1020904076 t-diff 700
n 22 t: 1020904376 t-diff 300
n 23 t: 1020905078 t-diff 702
n 24 t: 1020905376 t-diff 298
n 25 t: 1020906076 t-diff 700
n 26 t: 1020906376 t-diff 300
n 27 t: 1020907076 t-diff 700
n 28 t: 1020907376 t-diff 300
n 29 t: 1020908083 t-diff 707
n 30 t: 1020908376 t-diff 293
n 31 t: 1020909076 t-diff 700
n 32 t: 1020909376 t-diff 300
n 33 t: 1020910076 t-diff 700
n 34 t: 1020910376 t-diff 300
n 35 t: 1020911083 t-diff 707
n 36 t: 1020911376 t-diff 293
n 37 t: 1020912083 t-diff 707
n 38 t: 1020912376 t-diff 293
n 39 t: 1020913076 t-diff 700
n 40 t: 1020913376 t-diff 300
n 41 t: 1020914076 t-diff 700
n 42 t: 1020914376 t-diff 300
n 43 t: 1020915076 t-diff 700
n 44 t: 1020915376 t-diff 300
n 45 t: 1020916076 t-diff 700
n 46 t: 1020916381 t-diff 305
n 47 t: 1020917076 t-diff 695
n 48 t: 1020917376 t-diff 300
n 49 t: 1020918076 t-diff 700
n 50 t: 1020918376 t-diff 300
Code: Select all
ch.callback(_callb)
Thank you rkompass. This example is very enlightening.rkompass wrote: ↑Sun Jul 17, 2022 3:49 pmgives as output on my Blackpill with uPy 1.19 (should be the same with pyboard):Code: Select all
from pyb import Pin, Timer from time import ticks_us, ticks_diff, sleep_ms from array import array import micropython micropython.alloc_emergency_exception_buf(160) pb3 = Pin('B3') # ------- B3 has TIM2, CH2 on Stm32F411 Blackpill board ---- tim = Timer(2, freq=1000) ch = tim.channel(2, Timer.PWM, pin=pb3) ch.pulse_width_percent(70) n_td_told = array("i", (0, ticks_us(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) @micropython.viper def _callb(pin): p = ptr32(n_td_told) n = p[0] + 1 if n <= 50: p[2*n] = n p[2*n+1] = int(ticks_us()) p[0] = n try: pb3.irq(trigger=Pin.IRQ_RISING | Pin.IRQ_FALLING, handler=_callb, hard=True) # Pin.IRQ_RISING | Pin.IRQ_FALLING print('hard interrupt') except TypeError: pb3.irq(trigger=Pin.IRQ_RISING, handler=_callb) print('soft interrupt') print('total', n_td_told[0], 't0:', n_td_told[1]) for i in range(1, 51): print('n', n_td_told[2*i], 't:', n_td_told[2*i+1], 't-diff', n_td_told[2*i+1]-n_td_told[2*i-1])
so it proves, it is possible to have a pin as pwm out and then afterwards put an external interrupt on it.Code: Select all
hard interrupt total 1 t0: 1020892502 n 1 t: 1020894079 t-diff 1577 n 2 t: 1020894376 t-diff 297 n 3 t: 1020895083 t-diff 707 n 4 t: 1020895376 t-diff 293 n 5 t: 1020896076 t-diff 700 n 6 t: 1020896376 t-diff 300 n 7 t: 1020897076 t-diff 700 n 8 t: 1020897376 t-diff 300 n 9 t: 1020898076 t-diff 700 n 10 t: 1020898382 t-diff 306 n 11 t: 1020899083 t-diff 701 n 12 t: 1020899376 t-diff 293 n 13 t: 1020900076 t-diff 700 n 14 t: 1020900376 t-diff 300 n 15 t: 1020901076 t-diff 700 n 16 t: 1020901376 t-diff 300 n 17 t: 1020902076 t-diff 700 n 18 t: 1020902376 t-diff 300 n 19 t: 1020903076 t-diff 700 n 20 t: 1020903376 t-diff 300 n 21 t: 1020904076 t-diff 700 n 22 t: 1020904376 t-diff 300 n 23 t: 1020905078 t-diff 702 n 24 t: 1020905376 t-diff 298 n 25 t: 1020906076 t-diff 700 n 26 t: 1020906376 t-diff 300 n 27 t: 1020907076 t-diff 700 n 28 t: 1020907376 t-diff 300 n 29 t: 1020908083 t-diff 707 n 30 t: 1020908376 t-diff 293 n 31 t: 1020909076 t-diff 700 n 32 t: 1020909376 t-diff 300 n 33 t: 1020910076 t-diff 700 n 34 t: 1020910376 t-diff 300 n 35 t: 1020911083 t-diff 707 n 36 t: 1020911376 t-diff 293 n 37 t: 1020912083 t-diff 707 n 38 t: 1020912376 t-diff 293 n 39 t: 1020913076 t-diff 700 n 40 t: 1020913376 t-diff 300 n 41 t: 1020914076 t-diff 700 n 42 t: 1020914376 t-diff 300 n 43 t: 1020915076 t-diff 700 n 44 t: 1020915376 t-diff 300 n 45 t: 1020916076 t-diff 700 n 46 t: 1020916381 t-diff 305 n 47 t: 1020917076 t-diff 695 n 48 t: 1020917376 t-diff 300 n 49 t: 1020918076 t-diff 700 n 50 t: 1020918376 t-diff 300
Riddle: why is total = 1 in the printout?