counter library

hello

i have created a counter library that increments or decrement a counter when you press a push button, it also checks for the pressed time, if it exceeds a sec for example, it will start counting fast.

this is the .cpp code:

#include "Arduino.h"
#include "Counter.h"

   Counter :: Counter( int presetValue, int resetValue, int upInput, int downInput,
                       unsigned long incTimem, int  incSpeed)  {
           
           _presetValue = presetValue;
           _resetValue = resetValue;
           pinMode( upInput, INPUT);
           _upInput = upInput;
           pinMode( downInput, INPUT);
           _downInput = downInput;          
           _count = _resetValue;
		   _incSpeed = incSpeed;
           }
   
   Counter :: Counter( int presetValue, int resetValue, int upInput, int downInput,
                       unsigned long incTime, int  incSpeed, int presetInput, int resetInput)  {
                    
           _presetValue = presetValue;
           _resetValue = resetValue;
           pinMode( upInput, INPUT);
           _upInput = upInput;
           pinMode( downInput, INPUT);
           _downInput = downInput;
           _count = _resetValue;
		   _incSpeed = incSpeed;
           pinMode( presetInput, INPUT);
           _presetInput = presetInput;
           pinMode( resetInput, INPUT);
           _resetInput = resetInput; 
           _count = _resetValue;
            _incTime = incTime;
                               
           }          

           
    void Counter :: up() {
               
    int buttonActive = 0;
    int longPressActive = 0;
	
        
    if (digitalRead(_upInput) == 1) {

      if (buttonActive == 0 && _count <_presetValue) {

         buttonActive = 1;
         _buttonTimerUp = millis();
      }

      if ((millis() - _buttonTimerUp > _incTime) && (longPressActive == 0)) {

         longPressActive = 1; 

         while (longPressActive == 1 && digitalRead(_upInput) == 1  && _count < _presetValue)   {    
                         
           delay(_incSpeed);
           _count++;
		   
          } 
      }
      

    }// end of if (digitalRead(button) == HIGH)  
    
   else {

       if (buttonActive == 1) {

         if (longPressActive == 1) {
            longPressActive = 0;
          }
      
         else {
            _count++;
            }

         buttonActive = 0;
       }

    }  // end of else   
} // end of function up

    void Counter :: down() {

	int buttonActive = 0;
    int longPressActive = 0;
    
	
	if (digitalRead(_downInput) == 1) {

      if (buttonActive == 0 && _count > _resetValue) {

         buttonActive = 1;
         _buttonTimerDown = millis();
      }

      if ((millis() - _buttonTimerDown > _incTime) && (longPressActive == 0)) {

         longPressActive = 1; 
		 delete p_buttonTimerDown;
         while (longPressActive == 1 && digitalRead(_downInput) == 1 && _count > _resetValue)  {    
           
           delay(_incSpeed);
           _count--;
		   
          } 
      }

    }// end of if (digitalRead(button) == HIGH)  
    
    else {

       if (buttonActive == 1) {

         if (longPressActive == 1) {
            longPressActive = 0;
          }
      
         else {
            _count--;
            }

         buttonActive = 0;
       }

    }  // end of else
} // end of function down  

   void Counter :: preset() {
           
           int buttonState = 0;
           int lastButtonState = 0;
           
           buttonState = digitalRead(_presetInput);
           if (buttonState != lastButtonState && buttonState == 1 ) {
           _count = _presetValue;
           }

   }  // end of function preset
   
   void Counter :: reset() {
           
           int buttonState = 0;
           int lastButtonState = 0;
           
           buttonState = digitalRead(_resetInput);
           if (buttonState != lastButtonState && buttonState == 1 ) {
           _count = _resetValue;
		   }

   }  // end of function reset
   
   
    int Counter:: count() {
                 
              return(_count);   
    }  // end of function count

this is the .h code:

#include "Arduino.h"

#ifndef Counter_h
#define Counter_h

 class Counter   {
       
       public:
       
       Counter( int presetValue, int resetValue, int upInput, int downInput,
       unsigned long _incTime, int  _incSpeed); 
       Counter( int presetValue, int resetValue, int upInput, int downInput,
                unsigned long _incTime,int  _incSpeed, int presetInput, int resetInput);
       
       
	   
	   void up();
       void down();
       void preset();
       void reset(); 
       int count();

	   
              
       private:
       
       int  _presetValue;
       int  _resetValue;
       int  _upInput;
       int  _downInput;
       int  _presetInput;
       int  _resetInput;
       int  _count; 
	   int  _incSpeed;
       unsigned long   _incTime;
	   unsigned int  _buttonTimerUp;
	   unsigned int  _buttonTimerDown;
	   
       
       }; // end of class Counter
 
 #endif

the problem is that i cant store millis() value in the variable _buttonTimerUp

_buttonTimerUp = millis();

because it is an instance variable, one the function is executed the variable will lose its memory, so i need something that will act as a global variable, i think new is used to specify when the memory of the variable is deleted, but i need help with this.

thanks you

The function millis() returns 'unsigned long'. Your _buttonTimerUp is an 'unsigned int'. The value will overflow 65.537 seconds after the Arduino starts. Could that be the problem?

   Counter :: Counter( int presetValue, int resetValue, int upInput, int downInput,
                       unsigned long incTimem, int  incSpeed)  {
           
           _presetValue = presetValue;
           _resetValue = resetValue;
           pinMode( upInput, INPUT);
           _upInput = upInput;
           pinMode( downInput, INPUT);

You can not usefully diddle with the hardware in you constructor. The hardware is not ready yet.

Thanks for sharing

longPressActive would be better as a bool since you use only 0 or 1 for it. (make it true or false)

Are you supposing that bouncing is handled in hardware?

thanks for your replies

johnwasser, i fixed the variables, but it didn't work ' my problem is i cant store millis() value in an instance variable, is there any way i can solve this?

abdmusleh: the problem is that i cant store millis() value in the variable _buttonTimerUp

_buttonTimerUp = millis();

because it is an instance variable, one the function is executed the variable will lose its memory,

That's simply an incorrect statement. Instance variables absolutely maintain their value after any method that changes them exits. They'd be pretty useless otherwise.

Also, your code doesn't compile:

delete p_buttonTimerDown;

First, 'p_buttonTimerDown' is undefined. Second, why are you releasing memory that you haven't dynamically allocated?

Where is the sketch you are using to test the library? What makes you think you can't store the mllis() value?

this is the original program that works as it should

#include <LiquidCrystal.h>

   const int I0 = 8;

   const int I1 = 9;        

   boolean I0buttonActive = 0;

   boolean I0longPressActive = 0;

   long I0buttonTimer = 0;

   long I0longPressTime = 1000;


   boolean I1buttonActive = 0;

   boolean I1longPressActive = 0;

   long I1buttonTimer = 0;

   long I1longPressTime = 1000;

   int counter;      

   LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
 

void setup() {

  // put your setup code here, to run once:

   pinMode(I0, INPUT);

   pinMode(I1, INPUT);

   lcd.begin(16, 2);

   Serial.begin(9600);

}

void printlcd()  {    

     lcd.setCursor(0, 0);

     lcd.print("                ");

     lcd.setCursor(0, 1);

     lcd.print("                ");        

     lcd.setCursor(0, 1);

     lcd.print("counter = ");

     lcd.setCursor(10, 1);

     lcd.print(counter);

}

 

void loop() {

   if (digitalRead(I0) == HIGH) {

      if (I0buttonActive == false && counter <100) { 

      I0buttonActive = true;

      I0buttonTimer = millis();

      } 

      if ((millis() - I0buttonTimer > I0longPressTime) && (I0longPressActive == false)) {

      I0longPressActive = true;   

         while (I0longPressActive == true && digitalRead(I0) == HIGH && counter <10)   {   

           delay(100);

           counter++ ;

           printlcd();

          }

      }

    }// end of if (digitalRead(button) == HIGH)    

    else { 

       if (I0buttonActive == true) {

         if (I0longPressActive == true) {

            I0longPressActive = false;

          }     

         else {

            counter++;

           printlcd();

            }

         I0buttonActive = false;

       }

    }  // end of else

     printlcd();

     if (digitalRead(I1) == HIGH) {

         if (I1buttonActive == false) {

      I1buttonActive = true;

      I1buttonTimer = millis();

      }

      if ((millis() - I1buttonTimer > I1longPressTime) && (I1longPressActive == false)) {

      I1longPressActive = true;   

         while (I1longPressActive == true && digitalRead(I1) == HIGH)   {   

           delay(100);

           counter-- ;

          printlcd();

          }

      }

    }// end of if (digitalRead(button) == HIGH) 

    else {
       if (I1buttonActive == true) {

         if (I1longPressActive == true) {

            I1longPressActive = false;
          }

         else {
          
            counter--;

            printlcd();

            }

         I1buttonActive = false;

       }

    }  // end of else   

    Serial.println(I0buttonTimer);       

} // end of loop

note the I0buttonTimer variable which is a global variable, when you push the button the serial displays the time you pressed the at

since you are storing millis value in it

for example:

9:65
9:65
9:65

an so on,

this is the code that i use to test the library

#include <LiquidCrystal.h>

#include <Counter.h>

Counter counter1(100,5,8,10,1000,100);

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  // put your setup code here, to run once:
   lcd.begin(16, 2);
   Serial.begin(9600);
      
}

void printlcd()  {
    
  lcd.setCursor(0, 0);
  lcd.print("counter = ");
  lcd.setCursor(10, 0);
  lcd.print(counter1.count() );
  lcd.setCursor(0, 1);
}



void loop() {
    if (counter1.count() != counter1.count()  ) {
  lcd.clear();  
  }  

  printlcd();
  counter1.up();
  counter1.down();

  Serial.print("1\n");
  Serial.println(counter1.count());
}

i added a function to the library that returns the value of I0buttonTimer which i called _buttonTimer,
this is instance variable

and i printed the value in serial port

when i pressed the button this is what i get

8:55
8:56
8:57

and so on, the time on which i pressed the button is not saved, and so the counter isn’t counting

i tried to find out why, the only difference between the tow codes is the variable type, which was global and is instance now.

the global variable Scope[Availability] is Through Out Of The Program, and Life-Time[Active in Memory] is Until Total Program is Executed.

but instance variables Scope[Availability] is until that function or block are executed, and Life-Time[Active in Memory] is Until That Function is Executed.

so when i try to store millis() value in an instance variable, it will be deleted as the function is executed.

Your code does not compile. Therefore, by definition, it does not work. Post the COMPLETE CURRENT code you're using:

.info file Counter.h Counter.cpp

But first, fix the formatting, it looks like crap. Type ctrl-t in the IDE to fix the indenting. Then delete all the superfluous blank lines.