neuoy / OneWireArduinoSlave

An arduino library to communicate using the Dallas one-wire protocol, where the Arduino takes the role of a slave. Entirely implemented using interrupts, you can perform other tasks while communication is handled in background.
58 stars 19 forks source link

Question: Is there a way to check if an interrupt has occured? #16

Closed chris-iot closed 6 years ago

chris-iot commented 6 years ago

Hi all, i use the lib in my code to emulate a 1-wire device. As my hardware runs on batteries i'm using https://github.com/rocketscream/Low-Power.git to set the device into low power mode as often as possible.

The uC - a Attiny85 - wakes up either if the watchdog timer expires or if there was another interrupt like e.g. the one from the 1-wire interface. Both is fine and works like a charm.

The only problem is that i need to count something like a timestamp within my code. If the code just continues to execute as the watchdog has timed out, counting seconds is easy. But if the uC wakes up due to a pin change interrupt / 1-wire communication, counting the seconds is messed up. So i thought if there is any possibility to

If you think this can be solved easier by adding some functionality to the Low Power lib, please let me also know and i will ask my question there.

Thanks.

neuoy commented 6 years ago

Hi,

I don't understand what you're trying to achieve. Do you want to measure the total cumulative time the micro-controller has been awake? Or actually measure "real-time" seconds, so that your clock won't drift at all? Or something else?

If you want to be notified when the 1-wire library is processing an interrupt, you have the OneWireSlave::onEnterInterrupt and OneWireSlave::onLeaveInterrupt functions that are called each time. I use those when I want to put debug code there. However, while they shouldn't hurt performances as long as they are empty (the compiler should remove the calls completely), it might have a negative impact to add code to register custom callbacks. A "dirty" workaround would be to put your code directly in OneWireSlave.cpp. There might be cleaner ways to override these functions from outside of OneWireSlave.cpp, but still allow the compiler to optimize at link time (i.e. not dynamic callbacks that would be registered at run-time, but still have the possibility to define them in your own source file).

Not sure if that helps, let me know...

chris-iot commented 6 years ago

Hi, thanks for the reply. Measuring "real-time" seconds is most likely the best fit for what i want to achieve. During normal operation - this means that no 1-wire communication takes place - the uC will wake up every second and counts the seconds. Once 1-wire communication takes place the uC will wake up a lot more often and therefore the seconds would be counted up way too fast. Only in those situations i want to check if it got woken up by the 1-wire ISR or not.

I think i already found a similar as you described above to solve my problem. I just attached a short callback to setReceiveBitCallback (didn't notice this function before...) that just sets a bool (volatile) value. This value gets checked and cleared periodically during the normal operation of the uC. Clearing the bool value is done as last instruction prior to sending the uC to sleep mode. After resuming from the sleep mode i check if the value is true (that means a 1-wire ISR has happened in between) or not.

With this i might miss up to 2 seconds in one run but this is far better then having the seconds incremented by the number of 1-wire transfers that have happened within that 1 second. The 1-wire communication takes place in bursts of ~10-20 transfers, so my seconds counter would have an offset of +20 instead of max. -2.

The only thing left is that i test if this really does the trick for me. I will give you feedback here and close the issue if everything works.

chris-iot commented 6 years ago

FYI: Got it working. Now i set a flag in the function attached to setReceiveCallback. Btw setReceiveBitCallback would also do the trick but setReceiveCallback callback gets called less often and the only thing i wanted to know if there has been any 1-wire communication between now and the last reset of my flag, so setReceiveCallback callback seems the more logical position for me to put this in.

Sorry for bothering you as it completely was an issue on my side...