Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Development
  3. [Solved] How disable sleep timer ?

[Solved] How disable sleep timer ?

Scheduled Pinned Locked Moved Development
7 Posts 3 Posters 2.0k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    carlierd
    wrote on last edited by carlierd
    #1

    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.

    1 Reply Last reply
    0
    • mfalkviddM Offline
      mfalkviddM Offline
      mfalkvidd
      Mod
      wrote on last edited by
      #2

      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.

      1 Reply Last reply
      1
      • C Offline
        C Offline
        carlierd
        wrote on last edited by
        #3

        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.

        1 Reply Last reply
        0
        • M Offline
          M Offline
          m26872
          Hardware Contributor
          wrote on last edited by
          #4

          Post your sketch?
          Once awake you shouldn't need to do anything.

          1 Reply Last reply
          0
          • C Offline
            C Offline
            carlierd
            wrote on last edited by
            #5

            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.

            M 1 Reply Last reply
            0
            • C carlierd

              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.

              M Offline
              M Offline
              m26872
              Hardware Contributor
              wrote on last edited by m26872
              #6

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

              1 Reply Last reply
              0
              • C Offline
                C Offline
                carlierd
                wrote on last edited by
                #7

                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.

                1 Reply Last reply
                0

                Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                With your input, this post could be even better 💗

                Register Login
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                12

                Online

                12.0k

                Users

                11.2k

                Topics

                113.4k

                Posts


                Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • MySensors
                • OpenHardware.io
                • Categories
                • Recent
                • Tags
                • Popular