how run IRQ() IN IRQ()

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
mehdi_ziyaei
Posts: 16
Joined: Tue May 21, 2019 5:58 pm

how run IRQ() IN IRQ()

Post by mehdi_ziyaei » Sun Jun 02, 2019 9:46 pm

I want to run the next function by knock sensor

i have a knock sensor when in the main function , toch it run next function and in next function i have use irq().but not work irq in secend function. how fix it ???




from machine import Pin
num_knock = 0


def main():
while True:
P5 = Pin(5, Pin.IN)
P5.irq(trigger=Pin.IRQ_RISING , handler=enter_password ) //ONE IRQ :!:



def enter_password(P):
print("enter password starting")
p5 = Pin(5, Pin.IN)
door_password=""
for i in range(5):
global num_knock
num_knock = 0
chk_time = utime.time() + 12
while utime.time() <= chk_time:
p5.irq(trigger=Pin.IRQ_RISING , handler=callback ) //TWO IRQ - BUT NOT WORK :?:
door_password += str(num_knock )
return


def callback(p):
global num_knock
if num_knock < 9 :
num_knock += 1
led_num_knock = Pin(4, Pin.OUT)
led_num_knock.on()
utime.sleep_ms(200)
led_num_knock.off()
return
Last edited by mehdi_ziyaei on Mon Jun 03, 2019 3:34 pm, edited 1 time in total.

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: IRQ() IN IRQ()

Post by jimmo » Sun Jun 02, 2019 11:12 pm

irq handlers need to be very short - you want them to do the minimal processing possible.

Can you try instead making the irq handler only record the time that the event happened, and then have your main program detect when these flags have been set and do the actual user input etc.

The other option is to take a look at micropython.schedule

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: IRQ() IN IRQ()

Post by jimmo » Sun Jun 02, 2019 11:17 pm

Also, once you set an IRQ on a pin, it stays on - you code will be continually adding the same callback to the pin.

Can you explain what your code needs to do (i.e. what is the sequence of knocks it needs to detect) and I can help you modify it.

mehdi_ziyaei
Posts: 16
Joined: Tue May 21, 2019 5:58 pm

Re: IRQ() IN IRQ()

Post by mehdi_ziyaei » Sun Jun 02, 2019 11:48 pm

Hi. I can not speak English well.
I want the device to be in standby mode and run enter_password() function by knock.
by one knock ,enter_password() starting .after finish go to standby mode and wait for new knock to run again enter_password() .

mehdi_ziyaei
Posts: 16
Joined: Tue May 21, 2019 5:58 pm

Re: IRQ() IN IRQ()

Post by mehdi_ziyaei » Sun Jun 02, 2019 11:56 pm

Code: Select all

num_knock = 0


def main():
   while True:
       P5 = Pin(5, Pin.IN)
       P5.irq(trigger=Pin.IRQ_RISING , handler=enter_password() ) //ONE IRQ  :!: 



def enter_password(P): 
    print("enter password starting")
    p5 = Pin(5, Pin.IN)
    door_password=""
    for i in range(5):
       global num_knock 
       num_knock = 0
       chk_time = utime.time() + 12
       while utime.time() <= chk_time:
           p5.irq(trigger=Pin.IRQ_RISING , handler=callback ) //TWO IRQ - BUT NOT WORK  :?: 
   door_password += str(num_knock )
   return


def callback(p):
   global num_knock 
   if num_knock < 9 :
        num_knock += 1
  led_num_knock = Pin(4, Pin.OUT)
  led_num_knock.on()
  utime.sleep_ms(200) 
  led_num_knock.off() 
  return

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: IRQ() IN IRQ()

Post by jimmo » Mon Jun 03, 2019 12:05 am

No problem, your English is fine :)

What sequence of knocks does your program need to detect? Is it just 5 quick knocks, or does there need to be a pattern?

Another way to think about the problem -- if you had somehow a list that recorded the times when the last N knocks were detected, could you write a function that returned True if it was the correct "password"?

mehdi_ziyaei
Posts: 16
Joined: Tue May 21, 2019 5:58 pm

Re: IRQ() IN IRQ()

Post by mehdi_ziyaei » Mon Jun 03, 2019 12:18 am

by one knock must run enter_password() And get the password from the user by 5 loop .every one loop give 1 or 2 or ...or 9 knock .

for ex:
1knock >> run app >> run enter_password()

for i range 4 >> 5 loop
loop 1 >>1knock >>my pass >> 1
loop 2 >> 7knock >>my pass >> 17
loop3 >> 4knock >>my pass >> 174
loop 4 >> 0knock >>my pass >> 1740
loop 5 >> 2knock >>my pass >> 17402

my pass >> 17402

if ok >> open door #serach by another function in my db and return ok or not ok
else >> nothing

and go to standby and wait for 1 knock to run app and again and again .

tnx google translate :D

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: IRQ() IN IRQ()

Post by jimmo » Mon Jun 03, 2019 1:13 am

OK, makes sense. FYI, this is actually quite a difficult problem.

The way to think about problems like this is with a thing called a "state machine". The idea is that your program can be in some state, and inputs cause it to move to the next state. An input is something like "a knock", or "some time elapsed". There's lots of good information online about this.

Your program will have states like "waiting", "counting knocks", etc. If a certain amount of time passes, then it should move from one state to the next (e.g. onto the next set of knocks for the next digit of the password). Or if a knock happens then it should do the right thing for the given state.

But all the IRQ handler has to do is set a flag to say that the knock was detected. Then it's up to the state machine in the main loop to figure out what to do with that.

I would start with a simple program that can just count the number of knocks it's seen. Then make it stop counting and reset if there's a delay of more than 2 seconds. Then make it remember the sequence of counts.

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: IRQ() IN IRQ()

Post by jimmo » Mon Jun 03, 2019 1:15 am

Just another note from your code:

Code: Select all

P5.irq(trigger=Pin.IRQ_RISING , handler=enter_password() )
This should be

Code: Select all

P5.irq(trigger=Pin.IRQ_RISING , handler=enter_password )
(You're want to set the handler to the function "enter_password". If you include the "()", then you're setting it to whatever enter_password returns.)

mehdi_ziyaei
Posts: 16
Joined: Tue May 21, 2019 5:58 pm

Re: how run IRQ() IN IRQ()

Post by mehdi_ziyaei » Tue Jun 04, 2019 1:04 am

I worked on it for 24 hours. I tried different ways. I think this is the best way. How do I fix it?
I started micropython in about a month and I do not have enough information.
how use flag for my app??


when one irq run by knock , secend irq not work.


i use

pin_starter= Pin(5 ,Pin.IN ,handler = enter_password() ,trigger = Pin.IRQ_RISING)

instead of

P5.irq(trigger=Pin.IRQ_RISING , handler=enter_password )

but not work.only run enter_password function and after the end of the function, it does not run again and send error for me about arg...


next i use while

def main():
knock_pin = Pin(5, Pin.IN)
while True:
if knock_pin .value()==1:
enter_password()
print(" oh my god plssssssss work goood ")
return



But sometimes it works well and sometimes works badly
And one more point
when use only second irq ,
The second irq is always active and calls the callback function with a knock detection
Last edited by mehdi_ziyaei on Tue Jun 04, 2019 1:32 pm, edited 1 time in total.

Post Reply