Home Easy Interrupts everything!
Ok, so all the parts of the arduino code work fine – just not all at the same time! The setup is as follows:
An interrupt procedure gets the home easy (HE) signal, and sends it to a callback function. This converts the sender/recipient/state into strings, and then publishes the data to MQTT. Problem with this is it takes time, and may be interrupted by the next HE signal. This problem is exaggerated by the HE motion detectors, which send about 15 on/off messages one after the other. When this happens, MQTT is interrupted and it leaves the arduino in a very strange state – loop() is paused, and nothing happens until it receives another HE signal, which kicks the arduino back into action – but by that time, any signals like “turn off the central heating” will be lost, so my energy efficient house becomes boiling hot!
So, after lots of hitting my head against a wall, my solution is to add the data to a global “string”, and then in the loop() method, to read this string, split it up into the MQ topic and the data to send to it, and then send it. I have found the WString library crashes the arduino, so it’s all done by manipulating individual characters in the array. Really missing the simplicity of Java!
And there are more problems…
If the arduino receives a message via MQTT at the “same” time as it receives a message via HE, the MQTT message gets lost. Doh. I can’t think of a guaranteed way around this problem as there’s no way of knowing when either will happen. Fortunately the fix should be done server-side, so it’s easier to do more complex things (Java).
What I’ve settled for is to also queue up messages to send to the arduino into a ConcurrentLinkedQueue. I also store the timestamp of the last message received via MQTT notifying me of a HE signal. A thread then sits waiting for a message to be put on the queue. If there is one, and the last received HE signal timestamp is more than 10 seconds ago, it sends the message. It then waits a few seconds and checks that there hasn’t been a more receent HE signal received – if there was, it waits and resends, and loops until there aren’t any HE signals 10s either side of sending.
So, by queueing everything at each end, I think I’ve found a reasonable solution to messages getting lost. I guess I could add some handshaking in, but that’s for another time. Very glad I use Java for my day-job, this C stuff is horrible!!