[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.


  • Mod

    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.


  • Hardware Contributor

    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.


  • Hardware Contributor

    @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.


Log in to reply
 

Suggested Topics

23
Online

11.2k
Users

11.1k
Topics

112.5k
Posts