Synchronisation of digital i/o state

I am struggling to modify existing LoRaWAN example code to my needs. I want to synchronize the state of a magnetic reed-switch with my home automation using a CubeCell board.
Normally the CubeCell does deepsleep with a battery-life message every 24h.
Only when the switch changes, an interrupt occurs and a Lora message is sent. All of this already works by slightly modifying the examle scetch “LoRaWAN_Interrupt.ino”. So what is my issue:
When the switch changes state back in just a second, another interrupt is generated. But this seems to be “forgotten”. What I think is happening: The prepareTxFrame() is called again, the LoRaWAN.send() is called again, but because this is too early after the last message, it is just omitted.
I can (and do) remember the last state sent and the current state in variables, but my issue is the control flow. When one message is omitted, the device sleeps and is not retriggered (only after 24h…).
And the LoRaWAN.send() method does not indicate, if the message was simply dropped.

Is there some example code which is nearer to my use case, or do you have another proposal where I should be looking?

Frankly speaking: I do not fully understand the interrrupt-propagation in combination with the state machine in the example code. What I imagine would work: Once an interupt occurs, the duty-cycle is shortened to like 10s, and only after the I/O state is identical to the last message sent, it falls back to 24h sleep.

Please explain what are you trying to achieve exactly and maybe i can help…

  1. if it’s a reed switch, usually it is always open and when a magnet is near by then the switch closes and the interrupt should fire (depending how to attached your Pin Rising or Falling) if BOTH then it will will fire on Open and close.

which situation are you trying to detect?



The switch is connected to a physical mailbox door and typically only changes state twice a day (one on/off cycle with 1-3 sec in between), but I need to record, whether the door has been closed again, so I need a subsequent message even if the second interrupt occurs shortly after the first one. It does not matter, whether the second message gets delayed for some seconds, but it should not be forgotten.

I have a switch connectec to GPIO0. This works fine.
I have configured GPIO0 to generate interrupts on CHANGE. This works fine.
I have used the LoraWan_interrupt scetch as a basis. This works, but only on the first interrupt.

When the interrupt fires while in deep sleep, I write the switch value to the message buffer, and the uplink message is sent. So the first state change of the GPIO is sent successfully.

Now when the switch changes state again BEFORE the CubeCell has gone back to deep sleep, the interrupt fires and the LoRaWAN.send() method is called, but it does not send anything. (supposed reason: there is a “if nextTx == true” guard condition inside the LoRaWAN.send() method, but no return value to know whether this happened).

I currently have a crude workarround with a busy-waiting while-loop, which calls delay(6000) three times and checks the state by polling in between. This guarantees that the second call to LoRaWAN.send() happens at least 6s after the first one, and so it somehow does not fail. After that the CubeCell goes back to deep sleep and the interrupt works again. But this workaround is highly undesirable, because it burns too much time and energy. A fully interrupt-driven option would be desirable.

What my topic of “Synchronization of digital i/o state” means, is that the messages sent should allow the receiver to know the latest state ot the GPIO0. For fast on/off/on/off cycles intermediate states may be discarded (“debounced”), but at least after the GPIO is stable again, the last message sent must reflect the state of the GPIO.

(BTW: I have a fine solution to keep the sleep current low in either state of the reed contact switch: I use a “toggle” reed contact with three connectors (NO/NC and middle contact). The middle contact goes to the GPIO and the NO and NC contacts go to Gnd and Vcc (over 10kOhm resistors). This is preferable, because otherwise a pullup or pulldown solution with a “simple” NO-reed contact would burn 600 Microamperes in at least one of the states, whereas the solution with a toggle-switch is using 9 Microamperes in deep sleep, no matter whether the reed contact is on or off.)