multiple interrupt calls when sending with LoRa
Hi! I'm creating a tipping bucket rain gauge that should save every tip to the local flash memory and in the end send it as a payload through LoRaWAN. So far (without LoRa), everything worked fine. I'm using software debouncing and have no duplicates over long periods (hours) with 20 s tipping interval on our test device.
However, now I added the LoRa code and on average get about 6 duplicates per 15 minutes. Each with approx. 3 s delay whatever time I use for debouncing - the sensor calls for 460 ms, so I tested a couple of different setups. Can anybody tell me where this might be coming from?
# OTAA authentication parameters app_eui = ubinascii.unhexlify('app_eui') app_key = ubinascii.unhexlify('app_key') # join network using OTAA (Over the Air Activation) lora.join(activation=LoRa.OTAA, auth=(app_eui, app_key), timeout=0) # create a LoRa socket s = socket.socket(socket.AF_LORA, socket.SOCK_RAW)
Side note on main: I save the lora state after the first succesfull join and reload it on deepsleep wakeup
# init pins self.gage = Pin(pin_in, mode=Pin.IN, pull=Pin.PULL_DOWN) self.wifi_pressed = Pin(pin_wifi, mode=Pin.IN, pull=Pin.PULL_DOWN) # init wake up interrupt machine.pin_deepsleep_wakeup(pins=[self.gage, self.wifi_pressed], mode=machine.WAKEUP_ANY_HIGH, enable_pull=True) # init interrupt action for rain gage self.gage.callback(trigger=Pin.IRQ_RISING, handler=self.drip) # handler for drip interrupt def drip(self, arg): # debouncing # drip interval for 300 year rainstorm if utime.ticks_diff(self.debounce_timer, utime.ticks_ms()) > 2500: # get time of drip drip_time = utime.time() # init debounce_timer self.debounce_timer = utime.ticks_ms() # raise drip count self.count += 1 # get byte value for variables (1 short 2 integers = 8 bytes) byte_data = ustruct.pack('<HIH', self.event_count, drip_time, self.count) # write byte value to file self.rainfile.write("%s,%s,%s\n" % (self.event_count, drip_time, self.count)) # send byte value to LoRaWAN gateway if self.networking: self.send_byte_data(byte_data) print('Johnny counted', self.count, 'tipped bucket(s) during event', self.event_count, 'after', drip_time, 's since the beginning of this epoch') # testing # reset sleeper's timer to indicate ongoing rain event self.reset_alarm() machine.idle() def send_byte_data(self, byte_data): # I tried with and without blocking ... same result self.lorasocket.setblocking(True) self.lorasocket.send(byte_data) self.lorasocket.setblocking(False)
Side note on raingage: gauge wakes up after the first bucket tipped and stays awake for 15 minutes to wait for further buckets. After 15 minutes without buckets it goes back to deepsleep to save battery time.
Nevermind, I solved it.
I'm new to real time programming and apparently had to find out the hard way not to put code that's too time consuming into an ISR. I changed it so that the ISR just changes a flag and that the actual work is being done in the main loop.