Hello,
is there a way how to pause "While loop" by IRQ signal and then continue back in while?
Reason:
I have an external signal connected to one of the pins (counting number of signals), this part of code is supposed to work while the time the "While loop" operates another part of code. and if Counter reaches a specific amount then break "While Loop".
Thank you
Jan Vaško
Pause While loop by IRQ
Re: Pause While loop by IRQ
hi,
Not completely sure I understand what you're asking, but can you set a global flag in your IRQ that enables/disables the while loop's contents.
i.e.
On some ports, you could experiment with lightsleep/wfi to "sleep" the loop (instead of the "continue") but best get it working first.
Not completely sure I understand what you're asking, but can you set a global flag in your IRQ that enables/disables the while loop's contents.
i.e.
Code: Select all
enabled = True
def irq_handler():
global enabled
enabled = not enabled
def main():
while True:
if not enabled:
continue
# do the main program thing
counter += 1
if counter == N:
break
main()
Re: Pause While loop by IRQ
Hi,
thank you for the reply. think is that during while cycle inside "Move_MR.py" the designed IRQ "Stepp_Count" is not triggered:
- first IRQ is done on display by xpt2046 (works well)
- second IRQ should be done by Stepp_Count
- PIN25 and PIN26 are physically connected by wire
Program:
boot.py:
main.py:
Move_MR.py
Motor_Move.py
Result:
REPL:
1) printed text "Touched" (by IRQ in main.py)
2) Continuous printing of text "Counter: 0"
>>>Touched
Counter: 0
Counter: 0
Counter: 0
Counter: 0
Counter: 0
Counter: 0
Counter: 0
Counter: 0
Counter: 0
Counter: 0
...
--> there is no interruption by IRQ which would increase Counter + print text "Counting each PWM: " and then continue with While cycle to finish the main program on Move_MR.py
thank you for the reply. think is that during while cycle inside "Move_MR.py" the designed IRQ "Stepp_Count" is not triggered:
- first IRQ is done on display by xpt2046 (works well)
- second IRQ should be done by Stepp_Count
- PIN25 and PIN26 are physically connected by wire
Program:
boot.py:
Code: Select all
Empty
Code: Select all
def touch_ON(pin):
#Touch
stisk = ts_touch.raw_touch()
#Search
if stisk!=None:
print("Touched")
import Move_MR
Move_MR.Start()
import machine
import xpt2046
spi = machine.SPI(1, baudrate=2000000, polarity=0, phase=0, miso=machine.Pin(19), mosi=machine.Pin(23), sck=machine.Pin(18))
ts_touch = xpt2046.XPT2046(spi = spi, confidence=5, margin=50, delay=10)
#Display
ts_bussy = machine.Pin(0, machine.Pin.IN)
ts_bussy.irq(handler=touch_ON)
print("Main Finished")
Code: Select all
def Start():
def Count(pin):
nonlocal Counter
Counter = Counter + 1
print("Counting each PWM: "+str(Counter))
if Counter == 100:
Step.deinit()
import machine
import time
Stepp_Count = machine.Pin(26, machine.Pin.IN)
Stepp_Count.irq(handler=Count, trigger=machine.Pin.IRQ_FALLING)
Step = machine.PWM(machine.Pin(25, machine.Pin.OUT))
Counter = 0
speed = 200
while True:
import Motor_Move
Motor_Move.Start_Movement(speed)
print("Counter: "+str(Counter))
time.sleep(1)
speed = speed - 1
if speed == 0:
break
Code: Select all
def Start_Movement(speed):
import machine
Step = machine.PWM(machine.Pin(25, machine.Pin.OUT))
Step.deinit()
Step.init()
Step.freq(speed)
Step.duty(512)
REPL:
1) printed text "Touched" (by IRQ in main.py)
2) Continuous printing of text "Counter: 0"
>>>Touched
Counter: 0
Counter: 0
Counter: 0
Counter: 0
Counter: 0
Counter: 0
Counter: 0
Counter: 0
Counter: 0
Counter: 0
...
--> there is no interruption by IRQ which would increase Counter + print text "Counting each PWM: " and then continue with While cycle to finish the main program on Move_MR.py
Re: Pause While loop by IRQ
Hi,
I think the core issue here is that you're doing all the program logic inside IRQ context. It looks like this must be ESP32 (i.e. soft interrupts) which is why this works at all, but in general the rule is: do the absolute minimum in interrupt handlers.
See http://docs.micropython.org/en/latest/r ... rules.html
That doc is mostly written with "hard" interrupt handlers in mind, but on ESP32 they're soft which means they're implicitly scheduled by micropython.schedule. What this means is that while you're currently in an interrupt handler, another one cannot be scheduled. There's a scheduler queue, but scheduled tasks can only interrupt the "main" thread, not other scheduled tasks.
So the while loop in Start prevents Count from being able to run.
What you need to do instead is think of this like a state machine. The interrupt handlers should only set flags or increment counters (no loops or delays), while your main loop looks at these flags and counters and does the appropriate actions.
Even better would be to use asyncio, which might be worth looking into. https://github.com/peterhinch/micropyth ... UTORIAL.md
I think the core issue here is that you're doing all the program logic inside IRQ context. It looks like this must be ESP32 (i.e. soft interrupts) which is why this works at all, but in general the rule is: do the absolute minimum in interrupt handlers.
See http://docs.micropython.org/en/latest/r ... rules.html
That doc is mostly written with "hard" interrupt handlers in mind, but on ESP32 they're soft which means they're implicitly scheduled by micropython.schedule. What this means is that while you're currently in an interrupt handler, another one cannot be scheduled. There's a scheduler queue, but scheduled tasks can only interrupt the "main" thread, not other scheduled tasks.
So the while loop in Start prevents Count from being able to run.
What you need to do instead is think of this like a state machine. The interrupt handlers should only set flags or increment counters (no loops or delays), while your main loop looks at these flags and counters and does the appropriate actions.
Even better would be to use asyncio, which might be worth looking into. https://github.com/peterhinch/micropyth ... UTORIAL.md