3

I am trying to make a small keyboard class to handle two buttons(in the future>2) that are connected to my arduino UNO. The buttons being pressed are detected using interrupts. Here is the code:

Timer

class Timer{
 private:
 uint32_t start_time;
 public:
 Timer(){
 start_time=millis();
 }
 void mark(){
 start_time=millis();
 }
 uint32_t lapsed(){
 return millis()-start_time;
 }
};

Keyboard

class KeyboardBtn{
 private:
 const static byte clicksDelay=255; //255 ms max
 struct btn{
 byte state=0; //0->nothing;1-click;2-dblClick
 Timer clickDelay;
 };
 volatile static btn buttons[2]; //only two buttons for now
 public:
 KeyboardBtn(){
 attachInterrupt(digitalPinToInterrupt(2),this->int_handler_btn0,FALLING); //Initially the pins are set to HIGH(pullup behaviour)
 attachInterrupt(digitalPinToInterrupt(3),this->int_handler_btn1,FALLING);
 }
 static void int_handler_btn0(){
 btns_handler(0);
 }
 static void int_handler_btn1(){
 btns_handler(1);
 }
 static void btns_handler(byte key){
 if(buttons[key].state==1 && buttons[key].clickDelay.lapsed()<=clicksDelay){
 buttons[key].state=2;
 }else{
 buttons[key].state=1;
 buttons[key].clickDelay.mark(); //Pressed one time? mark this and wait for second press
 }
 }
 byte stateChanged(byte key){
 //Function called to get key status
 byte temp_state=buttons[key].state;
 if(temp_state==1 && buttons[key].clickDelay.lapsed()<clicksDelay){
 return 0; //We still wait:don't know if it's a dblClick or single
 }else{
 buttons[key].state=0;
 return temp_state;
 }
 }
};
volatile KeyboardBtn::btn KeyboardBtn::buttons[2];

But the compiler gives me headaches(of course my code is wrong somewhere but he could just have kept quite about it):

C:\Users....\Humidity.ino: In static member function 'static void KeyboardBtn::btns_handler(byte)':

C:\Users...\Humidity\Humidity.ino:74:68: warning: passing 'volatile Timer' as 'this' argument of 'uint32_t Timer::lapsed()' discards qualifiers [-fpermissive]

 if(buttons[key].state==1 && buttons[key].clickDelay.lapsed()<=clicksDelay){
 ^

C:\Users...\Humidity\Humidity.ino:78:40: warning: passing 'volatile Timer' as 'this' argument of 'void Timer::mark()' discards qualifiers [-fpermissive]

 buttons[key].clickDelay.mark();
 ^

C:\Users....\Humidity\Humidity.ino: In member function 'byte KeyboardBtn::stateChanged(byte)':

C:\Users....\Humidity\Humidity.ino:83:58: warning: passing 'volatile Timer' as 'this' argument of 'uint32_t Timer::lapsed()' discards qualifiers [-fpermissive]

 if(temp_state==1 && buttons[key].clickDelay.lapsed()<clicksDelay){
 ^

What is the problem? Note:It does allow me to upload the code but I am almost certain it will generate some errors while running...

asked Apr 13, 2017 at 20:12

1 Answer 1

4

If you want to use an instantiated object as volatile then the functions within it also have to be marked as volatile. That tells the compiler that the instance pointer you will be passing to the function (the auto-inserted this parameter) is volatile:

class Timer{
 private:
 uint32_t start_time;
 public:
 Timer(){
 start_time=millis();
 }
 void mark() volatile {
 start_time=millis();
 }
 uint32_t lapsed() volatile { 
 return millis()-start_time;
 }
};
answered Apr 13, 2017 at 21:52

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.