Page 1 of 1

PIR interrupt and send

Posted: Thu Jul 22, 2021 3:40 am
by lghi
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()

Re: PIR interrupt and send

Posted: Thu Jul 22, 2021 4:22 am
by jimmo
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).

Re: PIR interrupt and send

Posted: Thu Jul 22, 2021 10:13 am
by lghi
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()

Re: PIR interrupt and send

Posted: Fri Jul 23, 2021 3:05 am
by jimmo
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!).