[Solved] How disable sleep timer ?
-
Hello,
I am working on a keyboard project allowing to enter a code on 4 keys and as the keyboard as 16 touch, I will use key 10 to 16 as a scene controller.
Everything is working correctly except a small thing. I use this sleep function:
interuptionType = node.sleep(SDA_PIN - 2, FALLING, WAITING_TIME);
The idea is to sleep between two keys of the code:
- wait for the second key or
- awake after 2 seconds if no key was pressed to cancelled the code.
If the second key is greater than 9 I cancelled the code but the sleep of 2 seconds is still actif !
How I can disable the sleep timer ? Is there a specific function ?
Thanks for your help.
David.
-
Look at the return value of the sleep function. It will show whether the wakeup reason. If the reason was timer, cancel just like you do after 9 presses.
-
Hello. It's what I done, no problem.
I will try to clarify what happens:- User push key 0-9
- Start sleep with interruption and 2 seconds timer
- User push key 10 (before timer reach 2 seconds)
- The software detects it and return (beginning of the loop)
- At the beginning of the loop there is an interruption to wait a key and it seems that as the 2 seconds timer is finish the sleep is interrupted ...
David.
-
Post your sketch?
Once awake you shouldn't need to do anything.
-
Hello,
This is the code:
/** * The MySensors Arduino library handles the wireless radio link and protocol * between your home built sensors/actuators and HA controller of choice. * The sensors forms a self healing radio network with optional repeaters. Each * repeater and gateway builds a routing tables in EEPROM which keeps track of the * network topology allowing messages to be routed to nodes. * * Created by Henrik Ekblad <henrik.ekblad@mysensors.org> * Copyright (C) 2013-2015 Sensnology AB * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors * * Documentation: http://www.mysensors.org * Support Forum: http://forum.mysensors.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation. * * * Code modified from AWI * (http://forum.mysensors.org/topic/3128/slim-node-scene-controller-keypad) * * Buzzer code from Sparkfun * (SparkFun Inventor's Kit / Example sketch 11) * */ /**************************************************************************************/ /* Keyboard sensor. */ /* */ /* Version : 1.4.10 */ /* Date : 15/04/2016 */ /* Modified by : David Carlier */ /**************************************************************************************/ /* --------------- */ /* RST | | A5 */ /* RX | | A4 */ /* TX | ARDUINO | A3 */ /* RFM69 (DIO0) --------- D2 | UNO | A2 */ /* Keyboard SDA --------- D3 | | A1 */ /* Keyboard SCL --------- D4 | ATMEGA 328p | A0 */ /* +3v --------- VCC | | GND --------- GND */ /* GND --------- GND | 8MHz int. | REF */ /* OSC | | VCC --------- +3v */ /* OSC | | D13 --------- RFM69 (SCK) */ /* D5 | | D12 --------- RFM69 (MISO) */ /* D6 | | D11 --------- RFM69 (MOSI) */ /* D7 | | D10 --------- RFM69 (NSS) */ /* LED --------- D8 | | D9 --------- Buzzer */ /* --------------- */ /* */ /* +3v = 2*AA */ /* */ /**************************************************************************************/ #include <SPI.h> #include <MySensor.h> #include <MyTransportRFM69.h> #include <MySigningAtsha204Soft.h> //Constants for MySensors #define SKETCH_NAME "Keyboard Sensor" #define SKETCH_VERSION "1.4.10" #define CHILD_ID_DIGICODE 0 #define KEYPAD_ID_SCENE 1 #define CHILD_ID_VOLTAGE 2 #define SDA_PIN 3 #define SCL_PIN 4 #define LED_PIN 8 #define BUZZER_PIN 9 #define BUZZ_FREQ_KEY 350 #define BUZZ_TIME_KEY 100 #define BUZZ_FREQ_ERROR 75 #define KEYBOARD_SIZE 16 #define MAX_SCENE 7 #define BATTERY_FULL 3143 // 2xAA usually gives 3.143V when full #define BATTERY_ZERO 2340 // 2.34V limit for 328p at 8MHz //Length must equal the total number of notes and spaces const byte songLength = 18; //Notes is an array of text characters corresponding to the notes //in your song. A space represents a rest (no tone) char notes[] = "cdfda ag cdfdg gf "; // a space represents a rest //Beats is an array of values for each note and rest. //A "1" represents a quarter-note, 2 a half-note, etc. //Don't forget that the rests (spaces) need a length as well. int beats[] = {1,1,1,1,1,1,4,4,2,1,1,1,1,1,1,4,4,2}; //The tempo is how fast to play the song. //To make the song play faster, decrease this value. int tempo = 113; //Misc. variables unsigned long WAITING_TIME = 2000; //Waiting time for key pressing boolean keyState[KEYBOARD_SIZE] ; //Construct MySensors library MySigningAtsha204Soft signer; MyHwATMega328 hw; MyTransportRFM69 transport; MySensor node(transport, hw, signer); MyMessage msgCode(CHILD_ID_DIGICODE, V_VAR1); MyMessage msgSceneOn(KEYPAD_ID_SCENE, V_SCENE_ON); MyMessage msgSceneOff(KEYPAD_ID_SCENE, V_SCENE_OFF); MyMessage msgVolt(CHILD_ID_VOLTAGE, V_VOLTAGE); /**************************************************************************************/ /* Initialization */ /**************************************************************************************/ void setup() { //Get time (for setup duration) #ifdef DEBUG unsigned long startTime = millis(); #endif //Setup buzzer and LED pins pinMode(BUZZER_PIN, OUTPUT); pinMode(LED_PIN, OUTPUT); blinkLedFastly(3); //Set keyboard pin pinMode(SDA_PIN,INPUT); pinMode(SCL_PIN, OUTPUT); digitalWrite(SCL_PIN, HIGH); //Start MySensors and send the Sketch Version Information to the Gateway node.begin(); node.sendSketchInfo(SKETCH_NAME, SKETCH_VERSION); //Register all sensors node.present(CHILD_ID_DIGICODE, S_CUSTOM); node.present(KEYPAD_ID_SCENE, S_SCENE_CONTROLLER); node.present(CHILD_ID_VOLTAGE, S_MULTIMETER); //Load last Scenestates from EEPROM (7 scenestates available) for (int i = 0 ; i < MAX_SCENE; i++) { keyState[i] = node.loadState(i); #ifdef DEBUG Serial.print(" "); Serial.print(keyState[i]); #endif } //Setup done ! blinkLedFastly(3); //Print setup debug #ifdef DEBUG int duration = millis() - startTime; Serial.println(""); Serial.print("[Setup duration: "); Serial.print(duration, DEC); Serial.println(" ms]"); #endif } /**************************************************************************************/ /* Main loop */ /**************************************************************************************/ void loop() { //Sleep, node wakes up on key interrupt byte interuptionType = node.sleep(SDA_PIN - 2, FALLING); //Verify if a key was pressed if (interuptionType == 0) { return; } //Get time (for a complete loop) #ifdef DEBUG unsigned long startTime = millis(); #endif //Get first digit byte key = getKeyPressed(); tone(BUZZER_PIN, BUZZ_FREQ_KEY, BUZZ_TIME_KEY); //Check validity if (key == 0) { blinkLedFastlyAndBuzz(3); return; } //Inform user that key is valid blinkLedFastly(1); int digicode = key * 1000; //Check if key corresponds to a scene touch or a code if (key > 9) { //Update scene state node.saveState(key - 10, (boolean)node.loadState(key - 10)?false:true); //Report data to the gateway long voltage = getVoltage(); node.send(node.loadState(key - 10)?msgSceneOn.set(key - 10):msgSceneOff.set(key - 10)); node.send(msgVolt.set(voltage / 1000.0, 3)); int batteryPcnt = round((voltage - BATTERY_ZERO) * 100.0 / (BATTERY_FULL - BATTERY_ZERO)); if (batteryPcnt > 100) {batteryPcnt = 100;} node.sendBatteryLevel(batteryPcnt); //Print debug #ifdef DEBUG Serial.print("Scene "); Serial.print(key - 10); Serial.print(": "); Serial.print((boolean)node.loadState(key - 10)?" 1 ":" 0 "); Serial.print(" "); Serial.print(voltage / 1000.0); Serial.print(" v"); int duration = millis() - startTime; Serial.print(" "); Serial.print("["); Serial.print(duration, DEC); Serial.println(" ms]"); Serial.flush(); #endif } else { //Wait for next key pressed or WAITING_TIME without action interuptionType = node.sleep(SDA_PIN - 2, FALLING, WAITING_TIME); //Verify if a key was pressed if (interuptionType == 0) { blinkLedFastlyAndBuzz(3); return; } //Get second digit key = getKeyPressed(); tone(BUZZER_PIN, BUZZ_FREQ_KEY, BUZZ_TIME_KEY); //Check validity if (key == 0 || key > 9) { blinkLedFastlyAndBuzz(3); return; } //Inform user that key is valid blinkLedFastly(1); digicode = digicode + key * 100; //Wait for next key pressed or WAITING_TIME without action interuptionType = node.sleep(SDA_PIN - 2, FALLING, WAITING_TIME); //Verify if a key was pressed if (interuptionType == 0) { blinkLedFastlyAndBuzz(3); return; } //Get third digit key = getKeyPressed(); tone(BUZZER_PIN, BUZZ_FREQ_KEY, BUZZ_TIME_KEY); //Check validity if (key == 0 || key > 9) { blinkLedFastlyAndBuzz(3); return; } //Inform user that key is valid blinkLedFastly(1); digicode = digicode + key * 10; //Wait for next key pressed or WAITING_TIME without action interuptionType = node.sleep(SDA_PIN - 2, FALLING, WAITING_TIME); //Verify if a key was pressed if (interuptionType == 0) { blinkLedFastlyAndBuzz(3); return; } //Get fourth digit key = getKeyPressed(); tone(BUZZER_PIN, BUZZ_FREQ_KEY, BUZZ_TIME_KEY); //Check validity if (key == 0 || key > 9) { blinkLedFastlyAndBuzz(3); return; } //Inform user that key is valid blinkLedFastly(1); digicode = digicode + key; //Report data to the gateway long voltage = getVoltage(); node.send(msgCode.set(digicode)); node.send(msgVolt.set(voltage / 1000.0, 3)); int batteryPcnt = round((voltage - BATTERY_ZERO) * 100.0 / (BATTERY_FULL - BATTERY_ZERO)); if (batteryPcnt > 100) {batteryPcnt = 100;} node.sendBatteryLevel(batteryPcnt); //Print debug #ifdef DEBUG Serial.print("Complete code: "); Serial.print(digicode); Serial.print(" "); Serial.print(voltage / 1000.0); Serial.print(" v"); int duration = millis() - startTime; Serial.print(" "); Serial.print("["); Serial.print(duration, DEC); Serial.println(" ms]"); Serial.flush(); #endif //Play final song instead of sleeping playFinalSong(); } //node.sleep(1000); } /**************************************************************************************/ /* Allows to play the final song. */ /**************************************************************************************/ void playFinalSong() { //Declare local variables int i, duration; // step through the song arrays for (i = 0; i < songLength; i++) { // length of note/rest in ms duration = beats[i] * tempo; // is this a rest? if (notes[i] == ' ') { delay(duration); // then pause for a moment } else // otherwise, play the note { tone(BUZZER_PIN, frequency(notes[i]), duration); delay(duration); // wait for tone to finish } delay(tempo/10); // brief pause between notes } } /**************************************************************************************/ /* takes a note character (a-g), and returns the corresponding frequency in Hz */ /* for the tone() function. */ /**************************************************************************************/ int frequency(char note) { //Declare local variables int i; const int numNotes = 8; // number of notes we're storing // The following arrays hold the note characters and their // corresponding frequencies. The last "C" note is uppercase // to separate it from the first lowercase "c". If you want to // add more notes, you'll need to use unique characters. // For the "char" (character) type, we put single characters // in single quotes. char names[] = { 'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C' }; int frequencies[] = {262, 294, 330, 349, 392, 440, 494, 523}; // Now we'll search through the letters in the array, and if // we find it, we'll return the frequency for that note. for (i = 0; i < numNotes; i++) // Step through the notes { if (names[i] == note) // Is this the one? { return(frequencies[i]); // Yes! Return the frequency } } return(0); // We looked through everything and didn't find it, // but we still need to return a value, so return 0. } /**************************************************************************************/ /* Allows to get the pressed key. */ /**************************************************************************************/ byte getKeyPressed() { //Get first bit digitalWrite(SCL_PIN, LOW); delayMicroseconds(100); digitalWrite(SCL_PIN, HIGH); //Read all keys for(int i = 0; i < KEYBOARD_SIZE; i++) { keyState[i] = (digitalRead(SDA_PIN) == LOW); digitalWrite(SCL_PIN, LOW); delayMicroseconds(100); digitalWrite(SCL_PIN, HIGH); delayMicroseconds(100); } //Read keyboard table to find the pressed key byte keyPressed = -1; for(int i = 0 ; i < KEYBOARD_SIZE; i++) { if (keyState[i]) { keyPressed = i; } } //Return the result return (keyPressed + 1); } /**************************************************************************************/ /* Allows to fastly blink the LED. */ /**************************************************************************************/ void blinkLedFastly(byte loop) { byte delayOn = 150; byte delayOff = 150; for (int i = 0; i < loop; i++) { blinkLed(LED_PIN, delayOn); delay(delayOff); } } /**************************************************************************************/ /* Allows to fastly blink the LED and to play a sound on the buzzer. */ /**************************************************************************************/ void blinkLedFastlyAndBuzz(byte loop) { byte delayOn = 150; byte delayOff = 150; for (int i = 0; i < loop; i++) { blinkLed(LED_PIN, delayOn); tone(BUZZER_PIN, BUZZ_FREQ_ERROR, delayOff); delay(delayOff); } } /**************************************************************************************/ /* Allows to blink a LED. */ /**************************************************************************************/ void blinkLed(byte pinToBlink, int delayInMs) { digitalWrite(pinToBlink,HIGH); delay(delayInMs); digitalWrite(pinToBlink,LOW); } /**************************************************************************************/ /* Allows to get the real Vcc (return value in mV). */ /* http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/ */ /**************************************************************************************/ long getVoltage() { ADMUX = (0<<REFS1) | (1<<REFS0) | (0<<ADLAR) | (1<<MUX3) | (1<<MUX2) | (1<<MUX1) | (0<<MUX0); delay(50); // Let mux settle a little to get a more stable A/D conversion //Start a conversion ADCSRA |= _BV( ADSC ); //Wait for it to complete while (bit_is_set(ADCSRA, ADSC)); //Compute and return the value uint8_t low = ADCL; // must read ADCL first - it then locks ADCH uint8_t high = ADCH; // unlocks both long result = (high << 8) | low; result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000 return result; // Vcc in millivolts }
Not very easy to explain the problem !
David.
-
@carlierd I can't see any delay (sleep) until you sleep with interrupt again after another. How's that working? When or how does the key reset and settle?
-
Hello @m26872 , I set some serial.print in the code and found that i need to add some node.sleep when an incorrect key is pushed. The problem was due to the fact that the interruption pin is still valid when i restart the loop function !
David.