I noticed that the microcontroller inside transmitter sends wrong values from I2C device when it’s disconnected and reconnected during operation. The microcontroller tries to read the sensor without initalizing it (because it was already initialized once during system startup). I added some code to detect when the device is disconnected and reconnected, so that it’s reinitialized. I also added software interface to the Compass and Accelerometer classes as they are kind of the same (“Disconnectable”), but the reading process is different for each device.
Digging a little deeper showed that the microcontroller also hangs sometimes when I connect and disconnect one of the I2C devices during operation. The hanging happens when the device is disconnected during I2C transaction – I suspect that Wire library is not implementing timeouts and it’s waiting for some kind of signal on I2C bus from the device.
I had two options: modify Wire library or add watchdog to reset the device. I assume that this hanging behaviour would never occur during normal operation (the connectors are pretty solid), but nevertheless it has to be eliminated somehow.
I chose to try the watchdog path. Found some article online, setup the watchdog, test it and… it hangs! It turns out that standard Arduino bootloader (not the optiboot one) does not reset some register regarding watchdog, so during execution of bootloader code after restart it restarts again. And again. And again.
I switched to optiboot bootloader. Uploaded the sample code and woohoo! it works. But after I upload my code (transmitter) and play with the I2C connector – it hangs again, resets and locks in bootloader section (just like before). And then something else broke, because the code hanged during NRF module initialization…
At that moment I’d had enough of this project and decided to call it a day. I’ll try to fix it tomorrow.