Can I have multiple sleep/interrupt events in the one sketch?
-
I have a prototype battery relay node working, where using smart sleep I am able to turn on a relay (currently just a connected LED) and off from the controller, with a lag in actuation equal to the smart sleep duration.
What I would now like to do is to introduce a secondary function where the node is able to turn the relay off after a preset period if no off command is received from the controller. Is this possible by introducing another sleep timer? If so how could I do this (as opposed to having a controller rule send the off command).
Here's my quick and dirty test sketch - hacked from the relay node example.
// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 #define MY_RF24_PA_LEVEL RF24_PA_LOW // Enable repeater functionality for this node // #define MY_REPEATER_FEATURE #include <MySensors.h> #define MY_SMART_SLEEP_WAIT_DURATION_MS 1000 //#define RELAY_1 3 // Arduino Digital I/O pin number for first relay (second on pin+1 etc) #define LEDpin 5 //#define NUMBER_OF_RELAYS 1 // Total number of attached relays //#define RELAY_ON 1 // GPIO value to write to turn on attached relay #define LED_ON 1 //#define RELAY_OFF 0 // GPIO value to write to turn off attached relay #define LED_OFF 0 #define VMIN 1.9 // Battery monitor lower level. Vmin_radio=1.9V #define VMAX 3.0 // " " " high level. Vmin<Vmax<=3.44 int BATTERY_SENSE_PIN = A1; // select the input pin for the battery sense point int oldBatteryPcnt = 0; // Sleep time between sensor updates (in milliseconds) static const uint64_t UPDATE_INTERVAL = 60000; #define child 1 void before() { //for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) { // Then set relay pins in output mode pinMode(LEDpin, OUTPUT); // Set relay to last known state (using eeprom storage) digitalWrite(LEDpin, loadState(LEDpin)?LED_ON:LED_OFF); } //} void setup() { analogReference(INTERNAL); // use the 1.1 V internal reference for battery level measuring } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("Relay", "1.0"); // for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) { // Register all sensors to gw (they will be created as child devices) present(child, S_BINARY); } //} void loop() { // get the battery Voltage int sensorValue = analogRead(BATTERY_SENSE_PIN); #ifdef MY_DEBUG Serial.println(sensorValue); #endif // 1M, 470K divider across battery and using internal ADC ref of 1.1V // Sense point is bypassed with 0.1 uF cap to reduce noise at that point // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts // 3.44/1023 = Volts per bit = 0.003363075 float batteryV = sensorValue * 0.003347095; int batteryPcnt = static_cast<int>(((batteryV-VMIN)/(VMAX-VMIN))*100); #ifdef MY_DEBUG Serial.print("Battery Voltage: "); Serial.print(batteryV); Serial.println(" V"); Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %"); #endif if (oldBatteryPcnt != batteryPcnt) { // Power up radio after sleep sendBatteryLevel(batteryPcnt); oldBatteryPcnt = batteryPcnt; } // Sleep for a while to save energy (using martsleep) smartSleep(UPDATE_INTERVAL); } void receive(const MyMessage &message) { // We only expect one type of message from controller. But we better check anyway. if (message.type==V_STATUS) { // Change relay state digitalWrite(LEDpin, message.getBool()?LED_ON:LED_OFF); // Store state in eeprom saveState(LEDpin, message.getBool()); // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } }
-
you could count how many times you have ran the loop, if your turn off time is a multiple of sleeptime, when you receive a switch on command you just reset the counter.
-
@gohan Lol you're absolutely right! I should have thought of that earlier - thanks!