Confused about Classes

Hello there. First post here in the forum. I have been looking for quite long for a solution to my problem but I didn't find anything close to my case so I decided to register.

I'm new to C++ language so I'm not quite sure about what can be done inside classes.

I wanted to pack all my hardware interface functions (potensiometers, buttons and leds) from a project I'm working on inside a class in order to get things less complicated. In the original project I'm using the bounce library for debouncing the buttons and I wanted to hide the bounce object inside my class. So the basic concept was that in the constructor I declare the pin I want to use and then if it is potentiometer, button or led. If it is a button I wanted to automatically create a bounce object one time and use it inside the functions referred to the button. The problem is that I cannot declare the bounce object inside the header because I get the error that I haven't declare in the function scope. The same goes if I declare it inside the constructor. The only way I could use it without compiling errors was to declare it in every function separately but in this case I had to put a delay in order to make it work in the real world.

So the question here is if there is a way to declare the bounce object inside the constructor one time and use it's functions inside my class'es functions.

Here is the code so far.

The header file

#include <Bounce.h>
#ifndef hardinter_h
#define hardinter_h


#include "WProgram.h"

class hardinter : public Bounce
{
  public:
          hardinter(int pin,char type);      //constructor      

          
          boolean potactivity();             //potentiometer move detection  
          int potvalue();                    //current value of potentiometer
          
          boolean butstate();                //state of button  
          unsigned long buttime();           //time the button has been pressed  
          
          void ledstate();                   //led's state
          
   private:
            int _pin;                        //pin of current object
            char _type;                      //type of current pin (potentiometer, button, led)

            
            int _smooth();                   //smoothing potentiometer values
            int _lastvalue;                  //last value of potentiometer
            int _crnvalue;                   //current value of potentiometer
            
            boolean _butstate;               //state of button
            unsigned long _buttime;          //time the button has  been pressed
    
           
            
            boolean _ledstate;               //led's state
            
            int i;                           //counter for smoothing function
};

#endif

The ccp file

#include "hardinter.h"
#include "WProgram.h"



hardinter::hardinter(int pin, char type) : Bounce (pin, 10){    //constructor and bounce library inherited
  _pin=pin;                                                     //set pin
  _type=type;                                                   //set type

    if (type=='p'){                                             //type potensiometer
      pinMode (_pin,INPUT);                                     //set as input
      _lastvalue=0;                                             //initialise variables
      _smooth();                                                //call smooth function for initialisation
    }
    if (type=='b'){                                             //type button
        pinMode (_pin,INPUT);                                   //set as input    
        Bounce _button(_pin,10);                                //create Bounce object for the button
      
    }   
    if (type=='l'){                                             //type led
          pinMode (_pin,OUTPUT);                                //set as output
    }     
}



int hardinter::_smooth(){                                       //smooth function for potentiometer readings
  for (i=0; i<10; i++){                                         //count 10 times
    _crnvalue+=analogRead(_pin);                                //add 10 readings to the current value
    }
    _crnvalue/=10;                                              //after adding divide with 10 to get the average value
}    
  
boolean hardinter::potactivity(){                              //function returning true if potensiometer has made any move
  if (_type=='p'){                                             //check if it is a potensiometer
  _smooth();
      if (_lastvalue!=_crnvalue){                              //check if the potensiometer has the same value as the last time   
        _lastvalue=_crnvalue;                                  //store the new value of the potensiometer
        return true;
      }
      else {
        return false;
      }
  }
}

int hardinter::potvalue(){                                    //function for returning the potentiometer's current value
  if (_type=='p'){                                            //check if it is a potensiometer
    _smooth();                                                //call smooth function
    return _crnvalue;                                         //return current value
  }
}

boolean hardinter::butstate()         {                       //function for returning button state
  if (_type=='b'){

     if (_button.update()){                                   //check if the bounce object was updated
       if (_button.risingEdge()){                             //if there was a low to high change 
        _buttime=millis();                                    //store the current time for buttime function
        return true;                                          //return true
        }

     else {
       return false;
     }
  }
        
} 
}

unsigned long hardinter::buttime(){

if (_button.update()){                                        //check if the bounce object was updated
       if (_button.fallingEdge()){                            //if there was a high to low change 
        _buttime=millis()-_buttime;                           //calculate the time the button was in high state
        return _buttime;                                      //return the time
        }  
     }
     }

To make it more clear in the ccp file. Inside the constructor I declare the bounce object and then try to call it's functions inside butstate and buttime functions.

The problem is that I cannot declare the bounce object inside the header because I get the error that I haven't declare in the function scope.

But you aren't doing that. You are deriving your class from Bounce.

To save me looking for it, where did you get the Bounce library from?

You're right I have tried many methods and had this in my mind. Actually I want to declare the bounce object one time so I thought that I should do either inside the header or the constructor(like I do in the code I posted before).

Anyway here is where I found the bounce library http://www.arduino.cc/playground/Code/Bounce

        Bounce _button(_pin,10);                                //create Bounce object for the button

This code, in your constructor, creates a local variable called _button. That variables goes out of scope when the constructor ends.

Actually I want to declare the bounce object one time so I thought that I should do either inside the header or the constructor(like I do in the code I posted before).

What you want to do may not be possible. You need to define an instance of the class in the header. Doing so invokes the default constructor for the class, with no arguments. Then, in the source file, in the constructor, you use the set methods of the class to set all required values.

If the class has not provided a no-argument constructor, you can not do this.

You must, instead, define a pointer to the instance, in the header file, and create an instance in the constructor that the pointer points to, using the new operator.

The Arduino makes this difficult by not providing a new operator.

There have been some posts on the forum that have defined the new and delete operators that you could add to your header file. Happy hunting.

Oh, you want the one Bounce object shared amongst many objects? Or one Bounce object shared amongst many functions?

As PaulS said, this could be tricky. A static class variable might do the trick, but as he said, if it takes a non-default constructor (that is, if the constructor needs arguments) this will be difficult. I see from the Bounce library this is indeed the case.

Making it a pointer and initializing it once could be a work around.

Or, do you want one Bounce per hardinter?

If you want one Bounce per hardinter, this compiles (apart from no setup nor loop):

Header:

...


class hardinter
{
  Bounce _bounce;
  public:

...

That makes _bounce a class variable, not an inherited class.

Implementation:

...

hardinter::hardinter(int pin, char type) : _bounce (_pin, 10) {   

...

That initializes the constructor for _bounce in the constructor for hardinter.

Fix a couple of compile problems further down:

boolean hardinter::butstate()         {                       //function for returning button state
  if (_type=='b'){

    if (_bounce.update()){                                   //check if the bounce object was updated
      if (_bounce.risingEdge()){                             //if there was a low to high change 
        _buttime=millis();                                    //store the current time for buttime function
        return true;                                          //return true
      }

      else {
        return false;
      }
    }

  } 
}

unsigned long hardinter::buttime(){

  if (_bounce.update()){                                        //check if the bounce object was updated
    if (_bounce.fallingEdge()){                            //if there was a high to low change 
      _buttime=millis()-_buttime;                           //calculate the time the button was in high state
      return _buttime;                                      //return the time
    }  
  }
}

I changed _button to _bounce.

Thank you both Nick and PaulS you have been the most helpfull. I'll follow your advice and return to you(after the hang over goes away, you know it was saturday yesterday :P) if I have any more problems but I think I get it.