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. My Project
  3. Alarm Clock

Alarm Clock

Scheduled Pinned Locked Moved My Project
13 Posts 4 Posters 4.0k Views 5 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.
  • ben999B Offline
    ben999B Offline
    ben999
    wrote on last edited by ben999
    #4

    Guys

    Funny discovery tonight :
    "alarm time" value in PaperUI can be set by clicking on it !! It is not a read-only value, it can also BE SET !!!

    0_1500492214317_Capture du 2017-07-19 21-23-03.png

    Now the big question is: how can my node retreive that new value ?

    21:17:04.816 [DEBUG] [rsAbstractConnection$MySensorsReader] - 50;255;3;0;21;0
    21:17:20.291 [INFO ] [smarthome.event.ItemCommandEvent    ] - Item 'bedAlarm01' received command 21:12
    21:17:20.296 [DEBUG] [rs.internal.gateway.MySensorsGateway] - Node 50 found in gateway
    21:17:20.298 [DEBUG] [rs.internal.gateway.MySensorsGateway] - Child 0 found in node 50
    21:17:20.299 [DEBUG] [rsAbstractConnection$MySensorsWriter] - Sending to MySensors: 50;0;1;0;47;21:12
    

    Looks like gateway sends a text message (47) towards node... so sketch needs to make a difference between "lock" messages and "alarm time" messages, right ?

    /*** receive alarme state and time from controller ***/
    void receive(const MyMessage & message) {
      if (message.type == V_LOCK_STATUS) {
        setAlarmState(message.getBool(), false);
      }
      if (message.type == V_TEXT) {
        do (
             use strtok_r(message.data, ";", &p) to extract payload
             somehow extract hour and minute from that payload
             store them in int alarmHour int and alarmMin
      }
    }
    

    A clue to get me on the way ?

    Thanks a lot for your input :)

    1 Reply Last reply
    0
    • ben999B Offline
      ben999B Offline
      ben999
      wrote on last edited by
      #5
      This post is deleted!
      1 Reply Last reply
      0
      • ben999B Offline
        ben999B Offline
        ben999
        wrote on last edited by
        #6

        Guys,

        I need some help por favor :)

        I am fighting against payload! The picture (a few posts above) shows that i can modify two values (seen under "Heure de réveil")

        As i validate the new value, the gateway sends a message to the node

        Sending to MySensors: 50;0;1;0;47;21:12
        

        Which is great, that's a new feature to me :)

        Now on the node side : I have included

        void receive(const MyMessage & message) {
          if (message.type == V_TEXT)
            Serial.print(message.data);
           // or Serial.print(message.getString());  // works fine too
        }
        

        Serial monitor of node shows

        21:12
        

        Lovely jobly sounds good

        I am now facing two major problems to me as a noob:

        • what is the format of "message.data" ? string? whenever i try to play with it i get some "invalid conversion" from IDE...
        • how to split that "message.data" into two integers (alarmHour and alarmMin) ?

        Thanks for your help ! That should be the final shout for help as this project is nearly achieved...

        1 Reply Last reply
        0
        • ben999B Offline
          ben999B Offline
          ben999
          wrote on last edited by ben999
          #7

          Can someone please comment on this DIY mess (it's a mix of bits and pieces found here and there)

          void receive(const MyMessage & message) {
            if (message.type == V_LOCK_STATUS)
              setAlarmState(message.getBool(), false);
            if (message.type == V_TEXT) {
              char *alarmTime =  message.data;
              char* token = strtok(alarmTime, ":");
              alarmHour = atoi(token);
              token= strtok(NULL, "");
              alarmMin = atoi(token);
            }
          

          It works the way I need it but i guess it's a dirty way of getting there... your eyes might start bleeding :D i get this from compiler :

          warning: invalid conversion from 'const char*' to 'char*' [-fpermissive]
               char *alarmTime =  message.data;
          

          Any suggestion to make it neater?

          mfalkviddM 1 Reply Last reply
          0
          • ben999B ben999

            Can someone please comment on this DIY mess (it's a mix of bits and pieces found here and there)

            void receive(const MyMessage & message) {
              if (message.type == V_LOCK_STATUS)
                setAlarmState(message.getBool(), false);
              if (message.type == V_TEXT) {
                char *alarmTime =  message.data;
                char* token = strtok(alarmTime, ":");
                alarmHour = atoi(token);
                token= strtok(NULL, "");
                alarmMin = atoi(token);
              }
            

            It works the way I need it but i guess it's a dirty way of getting there... your eyes might start bleeding :D i get this from compiler :

            warning: invalid conversion from 'const char*' to 'char*' [-fpermissive]
                 char *alarmTime =  message.data;
            

            Any suggestion to make it neater?

            mfalkviddM Offline
            mfalkviddM Offline
            mfalkvidd
            Mod
            wrote on last edited by mfalkvidd
            #8

            @ben999 message.data is const char* which means its contents can not (or at least should not) be modified.
            Then you set the alarmTime pointer to point to the same message.data, which means that if you modify the contents of alarmTime you will also modify the contents of message.data (they are not two copies of the same thing, they are the same thing)
            The definition of strtok is

            char *strtok(char *restrict source, const char *restrict delimiters);
            

            which means the first parameter must allow modification (no const), while the second does not need modification.

            The man page of strtok also says this (my emphasis):

            The strtok function returns a pointer to the beginning of each subsequent token in the string, after replacing the separator character itself with a null character. When no more tokens remain, a null pointer is returned.

            which explains why the parameter must allow modification.
            That's why you can't do

            const char *alarmTime =  message.data;
            

            I am not a c expert, but I think you should do this instead:

            void receive(const MyMessage & message) {
              if (message.type == V_LOCK_STATUS) setAlarmState(message.getBool(), false);
              if (message.type == V_TEXT) {
                char alarmTime[MAX_MESSAGE_LENGTH];
                strncpy(alarmTime, message.data, MAX_MESSAGE_LENGTH);
                char* token = strtok(alarmTime, ":");
                alarmHour = atoi(token);
                token = strtok(NULL, "");
                alarmMin = atoi(token);
              }
            }
            

            MAX_MESSAGE_LENGTH is provided by the MySensors library.

            ben999B 1 Reply Last reply
            2
            • mfalkviddM mfalkvidd

              @ben999 message.data is const char* which means its contents can not (or at least should not) be modified.
              Then you set the alarmTime pointer to point to the same message.data, which means that if you modify the contents of alarmTime you will also modify the contents of message.data (they are not two copies of the same thing, they are the same thing)
              The definition of strtok is

              char *strtok(char *restrict source, const char *restrict delimiters);
              

              which means the first parameter must allow modification (no const), while the second does not need modification.

              The man page of strtok also says this (my emphasis):

              The strtok function returns a pointer to the beginning of each subsequent token in the string, after replacing the separator character itself with a null character. When no more tokens remain, a null pointer is returned.

              which explains why the parameter must allow modification.
              That's why you can't do

              const char *alarmTime =  message.data;
              

              I am not a c expert, but I think you should do this instead:

              void receive(const MyMessage & message) {
                if (message.type == V_LOCK_STATUS) setAlarmState(message.getBool(), false);
                if (message.type == V_TEXT) {
                  char alarmTime[MAX_MESSAGE_LENGTH];
                  strncpy(alarmTime, message.data, MAX_MESSAGE_LENGTH);
                  char* token = strtok(alarmTime, ":");
                  alarmHour = atoi(token);
                  token = strtok(NULL, "");
                  alarmMin = atoi(token);
                }
              }
              

              MAX_MESSAGE_LENGTH is provided by the MySensors library.

              ben999B Offline
              ben999B Offline
              ben999
              wrote on last edited by ben999
              #9

              @mfalkvidd thank you very much for your detailed explanation !

              It does make a lot of sense

              And it compiles perfectly

              Thanks again for taking the time to correct and explain :)

              ben999B 1 Reply Last reply
              1
              • ben999B ben999

                @mfalkvidd thank you very much for your detailed explanation !

                It does make a lot of sense

                And it compiles perfectly

                Thanks again for taking the time to correct and explain :)

                ben999B Offline
                ben999B Offline
                ben999
                wrote on last edited by ben999
                #10

                Full sketch
                Some mods to come:

                • stop alarm while ringing
                • snoze
                //#define MY_DEBUG          // Enable debug prints
                #define MY_RADIO_NRF24   // Enable and select radio type attached
                
                #define MY_PARENT_ID 0
                #define MY_NODE_ID 50
                
                #include <SPI.h>
                #include <Adafruit_GFX.h>
                #include <Adafruit_PCD8544.h>
                #include <MySensors.h>
                #include <Time.h>
                #include <Wtv020sd16p.h>
                
                #define ALARM_ID 0                      // Id of TimeOfAlarm value
                #define ACTIV_ID 1                      // Id of ActivateAlarm switch
                
                int resetPin = 5;  // The pin number of the reset pin.
                int clockPin = 6;  // The pin number of the clock pin.
                int dataPin = 7;  // The pin number of the data pin.
                int busyPin = 8;  // The pin number of the busy pin.
                
                static int pinA = 2; // Our first hardware interrupt pin is digital pin 2
                static int pinB = 3; // Our second hardware interrupt pin is digital pin 3
                static int enSW = 4; // Rotary switch push-button
                
                volatile byte aFlag = 0; // let's us know when we're expecting a rising edge on pinA to signal that the encoder has arrived at a detent
                volatile byte bFlag = 0; // let's us know when we're expecting a rising edge on pinB to signal that the encoder has arrived at a detent (opposite direction to when aFlag is set)
                volatile uint16_t encoderPos = 0; //this variable stores our current value of encoder position. Change to int or uin16_t instead of byte if you want to record a larger range than 0-255
                volatile uint16_t oldEncPos = 0; //stores the last encoder position value so we can compare to the current reading and see if it has changed (so we know when to print to the serial monitor)
                volatile byte reading = 0; //somewhere to store the direct values we read from our interrupt pins before checking to see if we have moved a whole detent
                
                // Software SPI (slower updates, more flexible pin options):
                // pin 7 - Serial clock out (SCLK)
                // pin 6 - Serial data out (DIN)
                // pin 5 - Data/Command select (D/C)
                // pin 4 - LCD chip select (CS)
                // pin 8 - LCD reset (RST)
                Adafruit_PCD8544 display = Adafruit_PCD8544(A4, A3, A2, A1, A0);
                
                
                // Create an instance of the Wtv020sd16p class.
                // 1st parameter: Reset pin number.
                // 2nd parameter: Clock pin number.
                // 3rd parameter: Data pin number.
                // 4th parameter: Busy pin number.
                Wtv020sd16p wtv020sd16p(resetPin, clockPin, dataPin, busyPin);
                
                //Declare the Menus you need.
                char menu[][20] = {"ActiverAlarme", "Regler Alarme" , "Contra-ste", "Volume",
                                   "MusiqueAlarme", "EcouterMusique", "Retour"
                                  };
                byte itemCount = 6;
                int itemSelected;
                byte runOnceAWeek = 1;   //allow for time update once a week
                
                char dataBuffer[20];  // for sprintf function
                bool alarmStatus;     // Alarm set/unset status
                int alarmHour = 0;
                int alarmMin = 0;
                int alarmTune = 1;
                unsigned int alarmVolume = 5;
                int contrast = 50;
                int backlightFlag = 0;
                int backlightCountdown = 10000;   // switch off backlight after XX millisec
                int loopTime = 0;
                int prevMillis = 0;
                byte smallFont = 1;
                byte bigFont = 2;
                
                MyMessage  textMsg(ALARM_ID, V_TEXT);      // Initialize clock messages
                MyMessage alarmMsg(ACTIV_ID, V_LOCK_STATUS);    // Initialize switch messages
                
                void presentation()  {
                  sendSketchInfo("Loulou's Clock", "25.07.2017");
                  present(ALARM_ID, S_INFO);
                  present(ACTIV_ID, S_LOCK);
                }
                
                void setup() {
                  wtv020sd16p.reset();     //MP3 player
                  delay(1000);
                  wtv020sd16p.setVolume(alarmVolume);
                  pinMode(A5, OUTPUT);     //5110 screen backlight
                  digitalWrite(A5, LOW);
                  display.begin();
                  pinMode(enSW, INPUT_PULLUP);
                  pinMode(pinA, INPUT_PULLUP);
                  pinMode(pinB, INPUT_PULLUP);
                  attachInterrupt(0, PinA, RISING);
                  attachInterrupt(1, PinB, RISING);
                  Serial.begin(115200);
                  display.setContrast(contrast);
                  display.display();
                  display.clearDisplay();
                  display.setTextColor(BLACK);
                
                  int clockCounter = 0;
                  while (timeStatus() == timeNotSet && clockCounter < 60) {
                    requestTime();
                    clockCounter++;
                    wait(1000);
                    /*
                      Serial.print("état reception:");
                      Serial.println(timeStatus());
                    */
                    if (clockCounter > 16) {
                      /*
                        Serial.print(F("**Failed Clock**"));
                        Serial.print(F("*Syncronization*"));
                      */
                      break;
                    }
                  }
                  alarmStatus = loadState(0);    // Read last lock status from eeprom
                  setAlarmState(alarmStatus, true); // Now set the last known state and send it to controller
                  sendTime();
                }
                
                void loop() {
                  /*** ALARM !!! ***/
                  while (hour() + 2 == alarmHour && minute() == alarmMin) {
                    digitalWrite(A5, LOW);          // switch backlight ON when entering menu
                    display.clearDisplay();
                    display.setTextSize(1);
                    display.setCursor(2, 2);
                    display.print("Debout Axou");
                    display.display();
                    display.setCursor(2, 20);
                    display.print("Faut y aller");
                    display.display();
                    display.setCursor(2, 40);
                    sprintf(dataBuffer, "Il est %02u:%02u ", hour() + 2, minute());
                    display.print(dataBuffer);
                    display.display();
                    wtv020sd16p.playVoice(alarmTune - 1);
                  }
                
                  /*** synchronise clock node with controller from time to time... ***/
                  if (weekday() == 5 && runOnceAWeek == 1) {
                    requestTime();
                    runOnceAWeek = 0;
                  }
                  if (weekday() != 5)
                    runOnceAWeek = 1;
                
                  /*** switch off backlight function ***/
                  loopTime = millis() - prevMillis;
                  prevMillis = millis();
                  backlightFlag = backlightFlag + loopTime;
                  if (backlightFlag > backlightCountdown) {
                    digitalWrite(A5, HIGH);
                    backlightFlag = backlightCountdown + 1;   // to avoid overflow
                  }
                  else
                    digitalWrite(A5, LOW);
                
                  /*** Show time on the default Screen ***/
                  display.clearDisplay();
                  display.setTextSize(2);
                  display.setCursor(14, 2);
                  sprintf(dataBuffer, "%02u:%02u ", hour() + 2, minute());
                  display.print(dataBuffer);
                  //display.display();
                  display.setTextSize(1);
                  display.setCursor(14, 22);
                  sprintf(dataBuffer, "%02u-%02u-%04u ", day(), month(), year());
                  display.print(dataBuffer);
                  display.display();
                
                  if (alarmStatus == 0) {       //Show whether alarm is on or off
                    display.setCursor(14, 35);
                    sprintf(dataBuffer, "Alarme OFF");
                  }
                  else {
                    display.setCursor(7, 35);
                    char alarmText[7] = "Alarme";
                    sprintf(dataBuffer, "%s %02u:%02u", alarmText, alarmHour, alarmMin);
                  }
                  display.print(dataBuffer);
                  display.display();
                
                  /*** Enter the settings menu if select Switch is pressed ***/
                  if (digitalRead(enSW) == 0) {
                    while (digitalRead(enSW) == 0); //wait till switch is released.
                    encoderPos = 0;
                    digitalWrite(A5, LOW);          // switch backlight ON when entering menu
                    switch (encoderPos) {           //Enter main program
                      case 0: display.clearDisplay();
                        display.setTextSize(2);
                        display.setCursor(0, 10);
                        display.println(menu[encoderPos]);
                        display.display();
                        while (digitalRead(enSW)) {
                          encoderPos = constrain(encoderPos, 0, itemCount);
                          display.clearDisplay();
                          display.setCursor(0, 0);
                          display.println(menu[encoderPos]);
                          if (encoderPos < 0)
                            encoderPos = itemCount;
                          if  (encoderPos > itemCount)
                            encoderPos = 0;
                          display.display();
                        }
                        while (digitalRead(enSW) == 0);
                        itemSelected = encoderPos;
                      default: break;
                    }
                    switch (itemSelected) {
                      case 0: display.clearDisplay();      //ACTIVATE ALARME
                        display.setTextSize(bigFont);
                        display.setCursor(0, 10);
                        display.println(menu[itemSelected]);
                        display.display();
                        encoderPos = alarmStatus;
                        while (digitalRead(enSW)) {
                          encoderPos = constrain(encoderPos, 0, 1);
                          display.clearDisplay();
                          display.setCursor(0, 0);
                          display.print(menu[itemSelected]);
                          display.setCursor(16, 34);
                          display.print(encoderPos);
                          if (encoderPos == 0)  {
                            sprintf(dataBuffer, "OFF");
                          }
                          else  {
                            sprintf(dataBuffer, "ON");
                          }
                          display.setCursor(45, 34);
                          display.print(dataBuffer);
                          display.display();
                        }
                        if (encoderPos != alarmStatus)  {
                          alarmStatus = encoderPos;
                          send(alarmMsg.set(alarmStatus));
                        }
                        while (digitalRead(enSW) == 0);
                        break;
                
                      case 1: display.clearDisplay();     //SET ALARME TIME
                        display.setTextSize(bigFont);
                        display.setCursor(0, 10);
                        display.print(menu[itemSelected]);
                        display.display();
                        encoderPos = alarmHour;
                        while (digitalRead(enSW)) {       //SET ALARME HOUR
                          encoderPos = constrain(encoderPos, 00, 23);
                          display.clearDisplay();
                          display.setCursor(0, 0);
                          display.print(menu[itemSelected]);
                          display.setCursor(10, 34);       //HOUR LOCATION
                          display.print(encoderPos);
                          if (encoderPos < 0)
                            encoderPos = 23;
                          if  (encoderPos > 23)
                            encoderPos = 0;
                          display.setCursor(35, 34);       // ":" LOCATION
                          display.print(":");
                          display.setCursor(50, 34);       //MINUTE LOCATION
                          display.print(alarmMin);
                          display.display();
                        }
                        if (encoderPos != alarmHour)  {
                          alarmHour = encoderPos;
                          sendTime();
                        }
                        encoderPos = alarmMin;
                        while (digitalRead(enSW)) {        //SET ALARME MINUTE
                          encoderPos = constrain(encoderPos, 00, 59);
                          display.clearDisplay();
                          display.setCursor(0, 0);
                          display.print(menu[itemSelected]);
                          display.setCursor(10, 34);       //HOUR LOCATION
                          display.print(alarmHour);
                          display.setCursor(35, 34);       //":" LOCATION
                          display.print(":");
                          display.setCursor(50, 34);       //MINUTE LOCATION
                          display.print(encoderPos);
                          if (encoderPos < 0)
                            encoderPos = 59;
                          if  (encoderPos > 59)
                            encoderPos = 0;
                          display.display();
                        }
                        if (encoderPos != alarmMin)  {
                          alarmMin = encoderPos;
                          sendTime();
                        }
                        while (digitalRead(enSW) == 0);
                        break;
                
                      case 2: display.clearDisplay();        //CONTRAST
                        display.setTextSize(bigFont);
                        display.setCursor(0, 10);
                        display.print(menu[itemSelected]);
                        display.display();
                        encoderPos = contrast;
                        while (digitalRead(enSW)) {
                          encoderPos = constrain(encoderPos, 0, 100);
                          display.clearDisplay();
                          display.setCursor(0, 0);
                          display.print(menu[itemSelected]);
                          display.setCursor(16, 16);
                          display.print(encoderPos);
                          if (encoderPos < 0)
                            encoderPos = 100;
                          if  (encoderPos > 100)
                            encoderPos = 0;
                          display.setContrast(encoderPos);
                          display.display();
                        }
                        if (encoderPos != contrast)
                          contrast = encoderPos;
                        while (digitalRead(enSW) == 0);
                        break;
                
                      case 3: display.clearDisplay();        //VOLUME
                        display.setTextSize(smallFont);
                        display.setCursor(0, 10);
                        display.print(menu[itemSelected]);
                        display.display();
                        encoderPos = alarmVolume;
                        while (digitalRead(enSW)) {
                          encoderPos = constrain(encoderPos, 0, 7);
                          display.clearDisplay();
                          display.setCursor(0, 0);
                          display.print(menu[itemSelected]);
                          display.setCursor(16, 34);
                          display.print(encoderPos);
                          if (encoderPos < 0)
                            encoderPos = 7;
                          if  (encoderPos > 7)
                            encoderPos = 0;
                          display.display();
                          wtv020sd16p.setVolume(encoderPos);
                        }
                        alarmVolume = encoderPos;
                        while (digitalRead(enSW) == 0);
                        break;
                
                      case 4: display.clearDisplay();        //ALARM TUNE
                        display.setTextSize(bigFont);
                        display.setCursor(0, 10);
                        display.print(menu[itemSelected]);
                        display.display();
                        encoderPos = alarmTune;
                        while (digitalRead(enSW)) {
                          encoderPos = constrain(encoderPos, 1, 10);
                          display.clearDisplay();
                          display.setCursor(0, 0);
                          display.print(menu[itemSelected]);
                          display.setCursor(16, 34);
                          display.print(encoderPos);
                          if (encoderPos < 1)
                            encoderPos = 10;
                          if  (encoderPos > 10)
                            encoderPos = 0;
                          display.display();
                        }
                        alarmTune = encoderPos;
                        while (digitalRead(enSW) == 0);
                        break;
                
                      case 5: display.clearDisplay();        //PLAYER
                        display.setTextSize(bigFont);
                        display.setCursor(0, 10);
                        display.print(menu[itemSelected]);
                        display.display();
                        encoderPos = 0;
                        while (digitalRead(enSW)) {
                          encoderPos = constrain(encoderPos, 0, 10);
                          display.clearDisplay();
                          display.setCursor(0, 0);
                          display.print(menu[itemSelected]);
                          display.setCursor(16, 34);
                          display.print(encoderPos);
                          if (encoderPos < 0)
                            encoderPos = 10;
                          if  (encoderPos > 10)
                            encoderPos = 0;
                          display.display();
                        }
                        if (encoderPos == 0)
                          wtv020sd16p.stopVoice();
                        else
                          wtv020sd16p.playVoice(encoderPos - 1);
                        while (digitalRead(enSW) == 0);
                        break;
                
                      default: break;
                    }
                  }
                }
                
                /*** receive a new time value ***/
                void receiveTime(unsigned long controllerTime) {
                  setTime(controllerTime);
                }
                
                /*** send alarm time to controller ****/
                void sendTime()  {
                  sprintf(dataBuffer, "%02u:%02u ", alarmHour, alarmMin);
                  send(textMsg.set(dataBuffer));
                  wait(1000);
                }
                
                /*** Activate alarm ***/
                void setAlarmState(bool state, bool doSend) {
                  if (doSend)
                    send(alarmMsg.set(state));
                  saveState(0, state);
                  alarmStatus = state;
                }
                
                /*** receive alarme state from controller ***/
                void receive(const MyMessage & message) {
                  if (message.type == V_LOCK_STATUS)
                    setAlarmState(message.getBool(), false);
                  if (message.type == V_TEXT) {
                    char alarmTime[MAX_MESSAGE_LENGTH];
                    strncpy(alarmTime, message.data, MAX_MESSAGE_LENGTH);
                    char* token = strtok(alarmTime, ":");
                    alarmHour = atoi(token);
                    token = strtok(NULL, "");
                    alarmMin = atoi(token);
                  }
                
                }
                
                /*** rotary encoder interrupt function ***/
                void PinA() {
                  cli(); //stop interrupts happening before we read pin values
                  reading = PIND & 0xC; // read all eight pin values then strip away all but pinA and pinB's values
                  if (reading == B00001100 && aFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
                    encoderPos --; //decrement the encoder's position count
                    bFlag = 0; //reset flags for the next turn
                    aFlag = 0; //reset flags for the next turn
                    backlightFlag = 0;
                  }
                  else if (reading == B00000100) bFlag = 1; //signal that we're expecting pinB to signal the transition to detent from free rotation
                  sei(); //restart interrupts
                }
                
                
                void PinB() {
                  cli(); //stop interrupts happening before we read pin values
                  reading = PIND & 0xC; //read all eight pin values then strip away all but pinA and pinB's values
                  if (reading == B00001100 && bFlag) { //check that we have both pins at detent (HIGH) and that we are expecting detent on this pin's rising edge
                    encoderPos ++; //increment the encoder's position count
                    bFlag = 0; //reset flags for the next turn
                    aFlag = 0; //reset flags for the next turn
                    backlightFlag = 0;
                  }
                  else if (reading == B00001000) aFlag = 1; //signal that we're expecting pinA to signal the transition to detent from free rotation
                  sei(); //restart interrupts
                }```
                1 Reply Last reply
                2
                • N Offline
                  N Offline
                  Newzwaver
                  wrote on last edited by
                  #11

                  Nice project would love to see the finished product as I want to try it as well. Can you post all the details once you get it do Easy?

                  Thanks and good luck

                  1 Reply Last reply
                  0
                  • N Offline
                    N Offline
                    Newzwaver
                    wrote on last edited by
                    #12

                    Hi I need your help, I created this clock and complied the sketch, looked like it worked but when adding it to very I get the error message that D_LcdText1.xml is not available. Where do I find that and how do i add it to the Vera Plus?

                    Excellent project and can't wait to have it up and running.

                    korttomaK 1 Reply Last reply
                    0
                    • N Newzwaver

                      Hi I need your help, I created this clock and complied the sketch, looked like it worked but when adding it to very I get the error message that D_LcdText1.xml is not available. Where do I find that and how do i add it to the Vera Plus?

                      Excellent project and can't wait to have it up and running.

                      korttomaK Offline
                      korttomaK Offline
                      korttoma
                      Hero Member
                      wrote on last edited by
                      #13

                      @Newzwaver you can find the needed files here

                      • Tomas
                      1 Reply Last reply
                      1
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      22

                      Online

                      11.7k

                      Users

                      11.2k

                      Topics

                      113.1k

                      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