Header Not Passing Variables To CCP

Hey all,

I’ve been playing with a Button Class from two sources such as the “Ditch Delay” tutorial and the Arduino “LibraryTutorial”. I am obviously missing a key piece of information in regards to the way I’m declaring variables in the header that are to be set in the .ccp file. If someone could shed some light that would be much appreciated! At the very bottom of this message I have posted the error logs in a “code box”.

This is the working code as a whole before I decided to make the class into a library and it works as intended:

class Button
{
  //Private Variables
  private:
  int pinNumber;
  int debounceTime = 20;
  int buttonState;  
  int lastButtonState = 1;
  long unsigned int lastPress;
  
  //Public Variables
  public:
  int toggleState;
  bool buttonPressed = false;

  public:
  //Constructor
  Button(int pin)
  {
    pinMode(pin,INPUT_PULLUP);
    pinNumber = pin;
  }

  void checkButton()
  {
    buttonState = digitalRead(pinNumber);

    if((millis() - lastPress) > debounceTime)
    {
      lastPress = millis();
  
      if(buttonState == 0 && lastButtonState == 1)
      {
        toggleState =! toggleState;
        buttonPressed = true;
        lastButtonState = 0;
      }
      else if(buttonState == 1 && lastButtonState == 0)
      {
        lastButtonState = 1;
      }
    }
  }
};

#include <LiquidCrystal.h>

//LCD Pins
LiquidCrystal LCD(0,1,6,5,4,3);

//Motor Pins
int ENABLE = 9;
int DIRA = 8;
int DIRB = 7;

//Button Pins
Button powerButton(13);
Button increaseButton(12);
Button decreaseButton(11);
Button modeButton(10);

//Global Variables
String modeText = "forward";
float motorSpeed = 127.5;
 
void setup() 
{ 
  //initialize LCD
  LCD.begin(16,2);
  LCD.print("Remote Control");
  LCD.setCursor(0,1);
  LCD.print("By Me");
  delay(2000); //give time to read message/brand
  LCD.clear(); //clear LCD for display values
  
  //set outputs
  pinMode(ENABLE,OUTPUT);
  pinMode(DIRA,OUTPUT);
  pinMode(DIRB,OUTPUT);
}

void loop() 
{
  handleLCD();      
  handleMotor();
  handleModes();
  handleSpeed();  
  
  powerButton.checkButton();
  modeButton.checkButton();
  increaseButton.checkButton();
  decreaseButton.checkButton();
}

void handleLCD()
{
  LCD.setCursor(0,0);
  LCD.print("Mode: ");
  LCD.print(modeText);

  LCD.setCursor(0,1);
  LCD.print("Power: ");
  LCD.print((int)((motorSpeed/255) * 100)); //display motorSpeed as a percentage
  LCD.print("% ");
}

void handleMotor()
{
  if(powerButton.toggleState == 0) 
  {
    digitalWrite(ENABLE,LOW); 
    digitalWrite(DIRA,LOW); 
    digitalWrite(DIRB,LOW);
  }
  else analogWrite(ENABLE,motorSpeed);
}

void handleModes()
{
  if(modeButton.toggleState == 0)
  {
    modeText = "forward";
    digitalWrite(DIRA,HIGH); 
    digitalWrite(DIRB,LOW);    
  }
  else
  {
    modeText = "reverse";
    digitalWrite(DIRA,LOW); 
    digitalWrite(DIRB,HIGH); 
  }
}

void handleSpeed()
{
  if(increaseButton.buttonPressed == true)
  {
    if(motorSpeed <= 191.25)
    {
      motorSpeed += 63.75;
    }
    else motorSpeed = 255; //max value

    increaseButton.buttonPressed = false;
  }
  
  if(decreaseButton.buttonPressed == true)
  {
    if(motorSpeed >= 127.5)
    {
      motorSpeed -= 63.75;
    }
    else motorSpeed = 63.75; //min value

    decreaseButton.buttonPressed = false;
  }
}

Now here is the code broken up into a library and sketch…

.h:

/*
Button.h - Library for creating a toggle or push button.
Created by U.N. Owen, February 25, 2019.
Private Library.
*/
#ifndef Button_h
#define Button_h

#include "Arduino.h"

class Button
{
	public:
	Button(int pin);
	int toggleState;
	bool buttonPressed;
	void checkButton();

	private:
	int pinNumber;
	int debounceTime;
	int buttonState;
	int lastButtonState;
	long unsigned int lastPress;
};

#endif

.ccp:

#include "Arduino.h"
#include "Button.h"

//Contructor
Button::Button(int pin)
{
	pinMode(pin, INPUT_PULLUP);
	pinNumber = pin;

	toggleState = 0;
	buttonPressed = false;

	debounceTime = 20;
	buttonState;
	lastButtonState = 1;
	lastPress;
}

//Functions
void checkButton()
{
	buttonState = digitalRead(pinNumber);

	if ((millis() - lastPress) > debounceTime)
	{
		lastPress = millis();

		if (buttonState == 0 && lastButtonState == 1)
		{
			toggleState = !toggleState;
			buttonPressed = true;
			lastButtonState = 0;
		}
		else if (buttonState == 1 && lastButtonState == 0)
		{
			lastButtonState = 1;
		}
	}
}

and the sketch:

#include <Button.h>
#include <LiquidCrystal.h>

//LCD Pins
LiquidCrystal LCD(0,1,6,5,4,3);

//Motor Pins
int ENABLE = 9;
int DIRA = 8;
int DIRB = 7;

//Button Pins
Button powerButton(13);
Button increaseButton(12);
Button decreaseButton(11);
Button modeButton(10);

//Global Variables
String modeText = "forward";
float motorSpeed = 127.5;
 
void setup() 
{ 
  //initialize LCD
  LCD.begin(16,2);
  LCD.print("Remote Control");
  LCD.setCursor(0,1);
  LCD.print("By Me");
  delay(2000); //give time to read message/brand
  LCD.clear(); //clear LCD for display values
  
  //set outputs
  pinMode(ENABLE,OUTPUT);
  pinMode(DIRA,OUTPUT);
  pinMode(DIRB,OUTPUT);
}

void loop() 
{
  handleLCD();      
  handleMotor();
  handleModes();
  handleSpeed();  
  
  powerButton.checkButton();
  modeButton.checkButton();
  increaseButton.checkButton();
  decreaseButton.checkButton();
}

void handleLCD()
{
  LCD.setCursor(0,0);
  LCD.print("Mode: ");
  LCD.print(modeText);

  LCD.setCursor(0,1);
  LCD.print("Power: ");
  LCD.print((int)((motorSpeed/255) * 100)); //display motorSpeed as a percentage
  LCD.print("% ");
}

void handleMotor()
{
  if(powerButton.toggleState == 0) 
  {
    digitalWrite(ENABLE,LOW); 
    digitalWrite(DIRA,LOW); 
    digitalWrite(DIRB,LOW);
  }
  else analogWrite(ENABLE,motorSpeed);
}

void handleModes()
{
  if(modeButton.toggleState == 0)
  {
    modeText = "forward";
    digitalWrite(DIRA,HIGH); 
    digitalWrite(DIRB,LOW);    
  }
  else
  {
    modeText = "reverse";
    digitalWrite(DIRA,LOW); 
    digitalWrite(DIRB,HIGH); 
  }
}

void handleSpeed()
{
  if(increaseButton.buttonPressed == true)
  {
    if(motorSpeed <= 191.25)
    {
      motorSpeed += 63.75;
    }
    else motorSpeed = 255; //max value

    increaseButton.buttonPressed = false;
  }
  
  if(decreaseButton.buttonPressed == true)
  {
    if(motorSpeed >= 127.5)
    {
      motorSpeed -= 63.75;
    }
    else motorSpeed = 63.75; //min value

    decreaseButton.buttonPressed = false;
  }
}

Below are the log errors which are indicating issues with the function and variables (I know I’m not passing the variables correctly I just don’t see the solution).

C:\Users\Dave's PC\Documents\Arduino\libraries\Button\Button.cpp: In function 'void checkButton()':

C:\Users\Dave's PC\Documents\Arduino\libraries\Button\Button.cpp:14:2: error: 'toggleState' was not declared in this scope

  toggleState = 0;

  ^

C:\Users\Dave's PC\Documents\Arduino\libraries\Button\Button.cpp:15:2: error: 'buttonPressed' was not declared in this scope

  buttonPressed = false;

  ^

C:\Users\Dave's PC\Documents\Arduino\libraries\Button\Button.cpp:17:2: error: 'debounceTime' was not declared in this scope

  debounceTime = 20;

  ^

C:\Users\Dave's PC\Documents\Arduino\libraries\Button\Button.cpp:18:2: error: 'buttonState' was not declared in this scope

  buttonState;

  ^

C:\Users\Dave's PC\Documents\Arduino\libraries\Button\Button.cpp:19:2: error: 'lastButtonState' was not declared in this scope

  lastButtonState = 1;

  ^

C:\Users\Dave's PC\Documents\Arduino\libraries\Button\Button.cpp:20:2: error: 'lastPress' was not declared in this scope

  lastPress;

  ^

C:\Users\Dave's PC\Documents\Arduino\libraries\Button\Button.cpp:22:28: error: 'pinNumber' was not declared in this scope

  buttonState = digitalRead(pinNumber);

                           ^

exit status 1
Error compiling for board Arduino/Genuino Mega or Mega 2560.

Should be:

void Button::checkButton() {

Also, it’s a ‘cpp’ file, not a ‘ccp’ file.

Lol omg... it was right in front of me. Thanks so much. Yeah it's saved as cpp. and now that I have fixed void Button::checkButton() { it compiles and works. Sorry about that!