PIR interrupt and send

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
Post Reply
lghi
Posts: 2
Joined: Thu Jul 22, 2021 3:09 am

PIR interrupt and send

Post by lghi » Thu Jul 22, 2021 3:40 am

Hello, I am novice to micropython as well as to programming. I have to write a program with esp32 where it connects to dht sensor and a pir sensor, then sends data to asksensor. The dht data is updated every 10 minutes while PIR should send data as soon as motion is detected(interrupt) and set to zero after a while. I came up with this code but somehow I feel it's not optimized as asksensor first shows on/off correctly then just stays off. All required libraries imported correctly and connection to asksensor also avialable.

Code: Select all

def handle_interrupt(pin):
  global motion
  motion = True
  global interrupt_pin
  interrupt_pin = pin  
pir.irq(trigger=Pin.IRQ_RISING, handler=handle_interrupt)  
UPDATE_TIME_INTERVAL = 600000  # in ms 
last_update = time.ticks_ms()
motion = 0
while True: 
  if time.ticks_ms() - last_update >= UPDATE_TIME_INTERVAL: 
    dht1.measure()
    temp=dht1.temperature
    hum=dht1.humidity
    request = urequests.get( 'https://api.asksensors.com/write/'+'APIkey'+'module1='+str(dht_temp)+'&module2='++str(hum))
    request.close() 
    last_update = time.ticks_ms()
 
  elif motion:
    print('motion detected')
    motion_start= time.ticks_ms()
    motion_time = 1000
    motion = 1
    request = urequests.get( 'https://api.asksensors.com/write/'+'APIkey'+'module3='+str(motion))
    request.close()
    if time.ticks_ms() - motion_start >= motion_time:
      motion = 0
      request = urequests.get( 'https://api.asksensors.com/write/'+'APIkey'+'module3='+str(motion))
      request.close()

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

Re: PIR interrupt and send

Post by jimmo » Thu Jul 22, 2021 4:22 am

lghi wrote:
Thu Jul 22, 2021 3:40 am
then just stays off.
I think the problem is that the main loop is constantly checking the "motion" flag, but if the flag is set then it re-sets "motion_start" to the current time. So once motion is set to True in the interrupt, then it will never "time out" because "motion_start" is always being updated.

The easiest thing to do is to distinguish between "there was motion, i need to notify the server" and "i previously detected motion, and now i'm waiting for the timeout".

Something like:

Code: Select all

motion = False
motion_start = None

while True:
  if time.ticks_diff(time.ticks_ms(), last_update) >= UPDATE_TIME_INTERVAL:
    ... DHT as before
  elif motion:
    motion = False
    motion_start = time.ticks_ms()
    # send start request
  elif motion_start and time.ticks_diff(time.ticks_ms(), motion_start) >= MOTION_TIME:
    motion_start = None
    # send stop request
I'm also using time.ticks_diff rather than just subtracting the times (this correctly handles wraparound).

lghi
Posts: 2
Joined: Thu Jul 22, 2021 3:09 am

Re: PIR interrupt and send

Post by lghi » Thu Jul 22, 2021 10:13 am

Thank yo for reply. That code you suggested also somehow didn't work. Maybe I implemented wrong. But thank you for the time.ticks_diff() ...
However if I use sleep everything work fine sth like this

Code: Select all

elif motion:
    print('motion detected')  
    motion= 1
    request = urequests.get('https://api.asksensors.com/write/'+'ka7BDz5SgFs24ljZUALCXjzTuG7lUgW2?'+'module3='+str(motion))
    request.close()
    sleep(5)
    motion=0
    request = urequests.get('https://api.asksensors.com/write/'+'ka7BDz5SgFs24ljZUALCXjzTuG7lUgW2?'+'module3='+str(motion))
    request.close()

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

Re: PIR interrupt and send

Post by jimmo » Fri Jul 23, 2021 3:05 am

lghi wrote:
Thu Jul 22, 2021 10:13 am
That code you suggested also somehow didn't work.
Sorry I haven't tested it, but if you add some print statements it should be possible to figure out what's going on. (Add a print in the interrupt handler to confim that it's setting `motion`, and then print in the different if/else cases to see when they're being activated).

The sleep() works because it prevents the loop from re-setting motion_start, but this will prevent your code doing anything else in this time (which might be fine!).

Post Reply