Trying to create a PID heat controller, but I'm getting errors with declarations

As stated in the subject line, I’ve taken files uploaded by GlennD in the past and started to modify them to work with an updated maxim thermocouple IC. I’m currently using a mega board and I have double checked the installation my libraries. I’ve worked my way through 20 other errors and I can’t figure out this Advance Button issue.

I’m including my errors, my code, and the two libraries that are giving me issues. Thanks in advance for any help!

These are the errors that I’m getting:

Arduino: 1.5.5-r2 (Windows 7), Board: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"

KilnSetup:78: error: 'OnKeyDownBStart' was not declared in this scope
KilnSetup:79: error: 'OnKeyDownButton1' was not declared in this scope
KilnSetup:80: error: 'OnKeyDownButton2' was not declared in this scope
KilnSetup:81: error: 'OnKeyDownButton3' was not declared in this scope
KilnSetup:82: error: 'OnKeyDownButton4' was not declared in this scope
KilnSetup.ino: In function 'void setup()':
KilnSetup:94: error: 'LCDCLearScreen' was not declared in this scope
KilnSetup:97: error: 'class PID' has no member named 'SetInputLimits'
KilnSetup.ino: In function 'void loop()':
KilnSetup:129: error: 'LCDCLearScreen' was not declared in this scope
KilnSetup:131: error: 'LCDFirstLine' was not declared in this scope
KilnSetup:133: error: 'LCDSecondLine' was not declared in this scope
KilnSetup:198: error: 'temp0' was not declared in this scope
KilnSetup:200: error: 'TCErrorPrint' was not declared in this scope
KilnSetup:204: error: 'LCDCLearScreen' was not declared in this scope
KilnSetup:205: error: 'LCDFirstLine' was not declared in this scope
KilnSetup:210: error: 'LCDSecondLine' was not declared in this scope
Firing.ino: In function 'void FUSE()':
Firing:7: error: 'AUTO' was not declared in this scope
Firing:103: error: 'LCDFirstLine' was not declared in this scope
Firing:112: error: 'Max_PID_Compute' was not declared in this scope
Firing:128: error: 'MinutesPrint' was not declared in this scope
Firing:145: error: 'LCDCLearScreen' was not declared in this scope
Firing:150: error: 'LCDSecondLine' was not declared in this scope
Firing:183: error: 'MinutesPrint' was not declared in this scope
Firing:204: error: 'LCDCLearScreen' was not declared in this scope
Firing:209: error: 'LCDSecondLine' was not declared in this scope
Firing:225: error: 'LCDCLearScreen' was not declared in this scope
Firing:226: error: 'formattimeseconds' was not declared in this scope
Firing:253: error: 'LCDCLearScreen' was not declared in this scope
Firing:258: error: 'LCDSecondLine' was not declared in this scope
Firing:267: error: 'temp0' was not declared in this scope
Firing:269: error: 'TCErrorPrint' was not declared in this scope
Firing:274: error: 'LCDSecondLine' was not declared in this scope

Here’s my code:

#include <stdlib.h>
#include <PID_v1.h>
#include <Adafruit_MAX31855.h>
#include <TimerOne.h>
#include <AdvButton.h> //I started with buttons but moved to this not sure if better or not 
#include <ButtonManager.h>
#include <SoftwareSerial.h>
#include <serLCD.h>


#define txPin 2// Convert the txPin to pin number 2


long previousMillis = 0;
int Heater = 9;             // To SSR for heater Coil mine is 12v
int thermoCS = 11;              // CS pin for Max31855
int thermoDO = 12;              // DO pin for Max31855
int thermoCLK = 13;             // CLK pin for Max31855
int units = 0;            // Units to readout temp (0 = degF, 1 = degC)
float error = -8.0;        // Temperature compensation error
int temperature = 0;  // Temperature output variable
// initialize the library with the numbers of the interface pins
SoftwareSerial LCD = SoftwareSerial(0, txPin);
// Initialize the MAX6675 Library for our chip
// MAX6675 Library already sets pin modes for MAX6675 chip!
Adafruit_MAX31855 thermocouple(thermoCLK, thermoCS, thermoDO);
// Initialize PID items
unsigned long RampStartTime;
double Input, Output, Setpoint,AmntTime,InitInput;
PID pid (&Input, &Output, &Setpoint, 4,3.75,1.5,0);
unsigned long InitStartTime= 0;
unsigned long MyDelay; //this will help us know when to talk with processing
int SelTemp,SelHold, SelButton,StartCycle;
int ButtonPressed=0;
unsigned long cumulativeSeconds = 0;
unsigned int totalseconds = 0;
unsigned int totalminutes = 0;
unsigned int totalhours = 0;
char totaltime[6] = "  :  ";
//char lasttotaltime[9] = "  :  :  ";
//char stepelapsedtime[9] = "  :  :  ";
unsigned long cyclecount=0;
//char steptotaltime[9] = "  :  :  ";
char temptime[9] = "  :  :  ";

#define PinBStart 49
#define PinButton1 50
#define PinButton2 51
#define PinButton3 52
#define PinButton4 53

AdvButton BStart = AdvButton(PinBStart,NULL,NULL,OnKeyDownBStart,btn_Digital);
AdvButton Button1 = AdvButton(PinButton1,NULL,NULL,OnKeyDownButton1,btn_Digital);
AdvButton Button2 = AdvButton(PinButton2,NULL,NULL,OnKeyDownButton2,btn_Digital);
AdvButton Button3 = AdvButton(PinButton3,NULL,NULL,OnKeyDownButton3,btn_Digital);
AdvButton Button4 = AdvButton(PinButton4,NULL,NULL,OnKeyDownButton4,btn_Digital);

void setup() {
  Serial.begin(9600);
  pinMode(Heater, OUTPUT);
  pinMode(txPin, OUTPUT);
 
  //Make sure heater is off SSR is 12v so using arduino as a sink

  Timer1.initialize();			//turn on the Timer, default 1 second frequency
  //Setup Serial for LCD
  LCD.begin(9600);
  LCDCLearScreen();
  LCD.print ("Beta v2");
  pid.SetOutputLimits(0,255); 
  pid.SetInputLimits(0,2000);//with out this the inputs stop at 1023 and the kiln temp goes on up.
  pid.SetTunings(3,4,1); //Is not easy to tune a system that takes 3hrs to get to temp this seems to hold at +- 2 degrees
  Output=2;
  MyDelay=0;
  Timer1.pwm(Heater, Output);//start PWM on pin 9 with a 0% duty cycle
  //BStart.assign(49);
  //Button1.assign(50);
  // Button2.assign(51);
  // Button3.assign(52);
  // Button4.assign(53);
  // BStart.setMode(OneShotTimer);
  // Button1.setMode(OneShotTimer);
  // Button2.setMode(OneShotTimer);
  // Button3.setMode(OneShotTimer);
  // Button4.setMode(OneShotTimer);
  delay(1000);//give a chance for the lcd to boot
  SelButton=0;
  digitalWrite(Heater, LOW);//get the SSR in a know state!
}

void loop() {

  int MessageLoop=0;//the loop function only gets used on start up and when the kiln is down.
  ButtonManager::instance()->checkButtons();
  switch (ButtonPressed)
  {
  case 1:
    MyDelay=millis()+(5000);
    ButtonPressed=0;
    SelTemp=1479;
    SelHold=15;
    SelButton=1;
    LCDCLearScreen();
    Serial.print("Button1");
    LCDFirstLine();
    LCD.print("Fuse            ");
    LCDSecondLine();
    LCD.print("Select Start    ");
    delay(50);
    break;
  case 2:
    MyDelay=millis()+(5000);
    ButtonPressed=0;
    SelTemp=1450;
    SelHold=15;
    SelButton=2;  
    LCDSecondLine();
    Serial.print("Button2");
    LCDFirstLine();
    LCD.print("Tack Fuse       ");
    LCDSecondLine();
    LCD.print("Select Start    ");
    break;
  case 3:
    MyDelay=millis()+(5000);
    ButtonPressed=0;
    SelTemp=1370;
    SelHold=15;
    SelButton=3;
    LCDSecondLine();
    Serial.print("Button3");
    LCDFirstLine();
    LCD.print("Fire Polish     ");
    LCDSecondLine();
    LCD.print("Select Start    ");
    break;
  case 4:
    MyDelay=millis()+(5000);
    ButtonPressed=0;
    SelTemp=1250;
    SelHold=15;
    SelButton=4;
    LCDSecondLine();
    Serial.print("Button4");
    LCDFirstLine();
    LCD.print("Slump           ");
    LCDSecondLine();
    LCD.print("Select Start    ");
    break;
  case 5:
    MyDelay=millis()+(5000);
    ButtonPressed=0;
    StartCycle=1;
    //Serial.print("Button Start");
    switch (SelButton){
    case 0:
      LCDCLearScreen();
      LCD.print("Select a Cycle");
      LCDSecondLine();
      LCD.print("                ");
      LCDSecondLine();
      LCD.print("Button First");
      break;
    default :
      Serial.print("In Default");
      InitStartTime= millis();
      LCDCLearScreen();
      FUSE();
    }
  }
  if (millis()>MyDelay){
    InitInput = temp0.read_temp(5);        
    delay(40);
    if(InitInput == -1) TCErrorPrint();                 // If there is an error with the TC, temperature will be -1
    else 
    {
      if (MessageLoop<19){ //did this as a reset for a accidental button press.
        LCDCLearScreen();  // resets the LCD text and the cycle button count.
        LCDFirstLine();
        LCD.print ("Beta v2");
        MessageLoop=0;
        SelButton=0;
      }
      LCDSecondLine();
      LCD.print("                ");//Was just doing the temp but when you lose a digit 
      LCDSecondLine();              // it leaves the original behind. Could probably figure out right
      // justify save for later.
      LCD.print("Curr.Temp: "); //Really should be writting in just the temp but this
      LCD.print((int)InitInput);// works for now. 
      MyDelay=millis()+(1000);
      MessageLoop++;

    }
  }
}

The Firing.ino is here:

void FUSE(){
  //I need break this up into smaller subs or functions this one is huge but it works.
  pid.SetMode(AUTO); //turn on the PID
  unsigned long  m_StartedHold=0;//millis()*1000000;
  unsigned long m_ReadDelay=0; //instead of doing a delay function so we can check for a button
  //unsigned long  m_ElapsedTime=0 ;//used to hold the cound down for the hold time
  int m_SetOneTime=0;
  int m_rate,MyTemp,m_HoldTime;
  int m_CurStep=1;
  int m_oneShot=0;
  int m_Step=0;
  int varLength=0;
  // press
  delay(40);
  while (StartCycle==1)//Allows us to escape by hitting start button
  {  
    while (m_CurStep<=6)//This is to keep us in the Fuse portion until it is done
    {
      //Serial.print("Current m_Step");
      // Serial.print(m_Curm_Step);
      // Serial.println("");
      if(m_CurStep!=m_Step)//did this so it did not go through the switch loop everytime
      {
        RampStartTime=millis();
        switch(m_CurStep)//This is based off of the System 96 website google is your friend
        {
        case 1://Intial ramp m_rate is 300/hr temp 1150 hold for 30 minutes
          // the above is the format for below.
          if (SelButton==4){
            m_rate=150;
            MyTemp=300;
            m_HoldTime=15;
          }
          else{
            m_rate=300;
            MyTemp=1150;
            m_HoldTime=30;
          }
          AmntTime= (MyTemp-InitInput)/m_rate;//calcalate the amount of time in hours it will take
          m_Step=1;                           // for the cycle to get to temp
          break;     
        case 2:
          if (SelButton==4 || SelButton==3){
            m_rate=300;
            MyTemp= 1100;
            m_HoldTime=20;
          }
          else{
            m_rate=200;
            MyTemp=1370;
            m_HoldTime=20;
          }
          m_ReadDelay=0;
          AmntTime= (MyTemp-InitInput)/m_rate;
          m_Step=2;
          break;
        case 3:
          if (SelButton==4){
            m_rate=150;
            MyTemp=SelTemp;
            m_HoldTime=SelHold;
          }
          else{
            m_rate=400;
            MyTemp=SelTemp;
            m_HoldTime=SelHold;
          }
          m_ReadDelay=0;
          AmntTime= (MyTemp-InitInput)/m_rate;
          m_Step=3;
          break;
        case 4:
            m_rate=9999;
            MyTemp=950;
           m_HoldTime=60;
          m_ReadDelay=0;
          AmntTime= (MyTemp-InitInput)/m_rate;
          m_Step=4;
          break;
        case 5:
            m_rate=150;
            MyTemp=800;
            m_HoldTime=10;
          AmntTime= (MyTemp-InitInput)/m_rate;
          m_ReadDelay=0;
          m_Step=5;
          break;
        case 6: //final m_Step they had at 100 but I like it hotter
          m_rate=300;
          MyTemp=200;
          m_HoldTime=0;
          m_ReadDelay=0;
          AmntTime= (MyTemp-InitInput)/m_rate;
          m_Step=6;
          break;
        }
        if (AmntTime<0)AmntTime*=-1.0;
      }
      LCDFirstLine();
      LCD.print("                ");
      LCDFirstLine();
      LCD.print("Seg:");
      LCD.print(m_CurStep);
      LCD.print(" Ttemp:");
      LCD.print(MyTemp);
      if (millis()>m_ReadDelay) 
      {
        Max_PID_Compute(AmntTime , MyTemp, InitInput);
        if (m_CurStep<=3){
          if ((int)Input>=MyTemp)m_oneShot=1;
          while(m_oneShot==1){
            if (m_SetOneTime!=1){
              m_SetOneTime=1;
              InitInput = Input;
              m_StartedHold =millis()+(m_HoldTime*60000);
              //***************************************
              delay(50);
            }
            while (millis()<m_StartedHold)
            {
              if (millis()>m_ReadDelay){
                m_ReadDelay=millis()+500;
                Max_PID_Compute(AmntTime , MyTemp, InitInput);
                MinutesPrint(m_CurStep,m_StartedHold);
              }
              ButtonManager::instance()->checkButtons();
              switch(ButtonPressed){
              case 1:
                InitInput=Input;
                ButtonPressed=0;
                m_StartedHold=millis()+1;
                break;
              case 2:
                m_CurStep--;
                ButtonPressed=0;
                m_StartedHold=millis()+1;
                break;
              case 5:
                SelButton=0;
                ButtonPressed=0;
                LCDCLearScreen();
                StartCycle=0;
                m_ReadDelay=0;
                LCDFirstLine();
                LCD.print("Cycle Stopped");
                LCDSecondLine();
                LCD.print("Curr.Temp: ");
                LCD.print(temperature);
                m_CurStep=7;
                m_StartedHold=millis()+1;
                break;
              } 
              //m_ReadDelay++ ;
            }
            if (m_SetOneTime==1){
              m_ReadDelay=millis()-1;
              m_SetOneTime=0;
              m_StartedHold=0;
              ++m_CurStep;
              m_oneShot=0;
            }
          }
        }
        else{
          if ((int)Input<=MyTemp)m_oneShot=1;
          while (m_oneShot==1)
          {
            if (m_SetOneTime!=1){
              m_SetOneTime=1;
              InitInput = Input;
              m_StartedHold=millis()+(m_HoldTime*60000);
              delay(50);
            }
            while (millis()<m_StartedHold)
            {
              if (millis()>m_ReadDelay){
                m_ReadDelay=millis()+500;
                Max_PID_Compute(AmntTime, MyTemp, InitInput);
                MinutesPrint(m_CurStep,m_StartedHold);
              }
              //m_ReadDelay++ ;
              delay(50);
              ButtonManager::instance()->checkButtons();
              switch(ButtonPressed){
              case 1:
                m_oneShot=0;
                InitInput=Input;
                m_SetOneTime=1;
                ButtonPressed=0;
                m_StartedHold=millis()+1;
                break;
              case 2:
                m_oneShot=0;
                m_CurStep--;
                ButtonPressed=0;
                m_StartedHold=millis()+1;
                break;
              case 5:
                 ButtonPressed=0;
                LCDCLearScreen();
                StartCycle=0;
                m_ReadDelay=0;
                LCDFirstLine();
                LCD.print("Cycle Stopped");
                LCDSecondLine();
                LCD.print("Curr.Temp: ");
                LCD.print(temperature);
                m_CurStep=7;
                m_StartedHold=millis()+1;
                SelButton=0;
                break;
              } 
            }
            if (m_SetOneTime==1){
              m_ReadDelay+500;
              m_SetOneTime=0;
              m_StartedHold=0;
              ++m_CurStep;
              if (m_CurStep==7){
                digitalWrite(Heater, LOW); 
                LCDCLearScreen();
                formattimeseconds(((millis()-InitStartTime)/1000),totaltime);//I removed seconds from output 
                //dont care if it took 12:14 and 45 seconds//hours and minutes are important though.
                LCDFirstLine();
                LCD.print("Tot.Time: ");
                LCD.print(totaltime);
              }
              m_oneShot=0;
            }
          }
        }
        m_ReadDelay=millis()+500 ; 
      }
      //m_ReadDelay++ ;
      delay(50);
      ButtonManager::instance()->checkButtons();
      switch(ButtonPressed){
      case 1:
        m_CurStep ++;
        ButtonPressed=0;
        break;
      case 2:
        m_CurStep--;
        ButtonPressed=0;
        break;
      case 5:
        SelButton=0;
        ButtonPressed=0;
        LCDCLearScreen();
        StartCycle=0;
        m_ReadDelay=0;
        LCDFirstLine();
        LCD.print("Cycle Stopped");
        LCDSecondLine();
        LCD.print("Curr.Temp: ");
        LCD.print(temperature);
        m_CurStep=7;
      }
      // **********************
    } //End of Step while
    // ************************
    if (millis()>m_ReadDelay){
      Input = temp0.read_temp(5); 
      delay(40);
      if(Input == -1)TCErrorPrint();                   // If there is an error with the TC, temperature will be -1
      else 
      {
        Serial.print("Temperature:");
        Serial.println((int)Input);
        LCDSecondLine();
        LCD.print("                ");
        LCDSecondLine();
        LCD.print("Curr.Temp: ");
        LCD.print((int)Input);
      }
      m_ReadDelay=millis()+1000;
    }
    ButtonManager::instance()->checkButtons();
    switch( ButtonPressed){
    case 5:
      ButtonPressed=0;
      StartCycle=0;
      InitStartTime=millis();
      break; //even though this is the only case trying to create a habit
    }
    // **********************
  } //End of StartCycle while
  // ************************
}

Advance Button Lib:

 Usage: 
* - Include AdvButton.h and ButtonManager.h in your sketch
* - Add a call to ButtonManager::instance()->checkButtons(); in your main loop
* - Declare each button and define the events using a overload of AdvButton ( AdvButton button = AdvButton(<pin>) )
* - Declare the required event functions ( void OnKeyXXX(AdvButton* but) )
* - See the comments below for more help
*/



#if defined(ARDUINO) && ARDUINO >= 100
      #include "Arduino.h"
#else
      #include "WProgram.h"
#endif

#ifndef ADVBUTTON_H
#define ADVBUTTON_H

class AdvButton;

typedef void (*functiontype)(AdvButton*);

enum buttonMode {btn_Digital, btn_Analog}; 


class AdvButton
{

public:
	/*
	This is the first constructor call, use it for keypress buttons 
	pin        : pin number of the button
        OnKeyPress : Function to call when the event occurs
     	repeat     : time between the event is raised while pressing the button (optional)
	startDelay : amount of time between the initial keypress event and when to start repeating (optional)
	mode       : type of button, analog or digital
	*/
	AdvButton(uint8_t pin,void (*OnKeyPress)(AdvButton*) , unsigned long repeat = 300, unsigned long startDelay = 500, buttonMode mode = btn_Digital);

	/*
	This is the second constructor call, use it for other types of buttons
	pin        : pin number of the button
        OnKeyPress : Function to call when the keypress event occurs (optional)
     	OnKeyDown  : Function to call when the keydown event occurs (optional) 
	OnKeyUp    : Function to call when the keyup event occurs (optional) 
	mode       : type of button, analog or digital
	*/
	AdvButton(uint8_t pin,void (*OnKeyPress)(AdvButton*) =NULL, void (*OnKeyDown)(AdvButton*)=NULL,void (*OnKeyUp)(AdvButton*)=NULL, buttonMode mode = btn_Digital);

	/* 
	Checks the state of the button and triggers events accordingly
	Will be called from the ButtonManager	
	*/
	void check();

	/* 
	This function will set the function to call when the keypress event occurs
	*/
	void setOnKeyPress(void (*f)(AdvButton*));

	/* 
	This function will set the function to call when the keydown event occurs
	*/
	void setOnKeyDown(void (*f)(AdvButton*));

	/* 
	This function will set the function to call when the keyup event occurs
	*/
	void setOnKeyUp(void (*f)(AdvButton*));

	/* 
	Sets the time (milliseconds) between each repeated keypress event
	*/
	void setRepeat(unsigned long repeat);

	/* 
	Sets the delay (milliseconds) before the keypress event is repeated
	*/
	void setStartDelay(unsigned long startDelay);

	/* 
	Changes the pin number 
	*/
	void setPin(uint8_t pin);
	
	/* 
	Retrieve the amount of milliseconds the button was pressed,  only valid in keyevents
	*/
	unsigned long getPressTime(); 
private: 
	/* private variables */
	functiontype func_keyUp;
	functiontype func_keyDown;
	functiontype func_keyPress;
    	uint8_t pin;
	buttonMode mode;
	int debounceTime;
    	unsigned long repeat;
	unsigned long startDelay;
	unsigned long startPress;
	unsigned long lastChange;
        int lastState;
        unsigned long prevPres;
};





#endif

And here’s serLCD, the last piece :slight_smile:

#ifndef serLCD_h
#define serLCD_h

#if ARDUINO >= 100
#include "Arduino.h"       // for delayMicroseconds,digitalPinToBitMask, etc
#else
#include "WProgram.h"      // for delayMicroseconds
#include "pins_arduino.h"  // for digitalPinToBitMask, etc
#endif
#include "SoftwareSerial.h"

// Commands
#define LCD_BACKLIGHT		0x80
#define LCD_CLEARDISPLAY	0x01
#define LCD_CURSORSHIFT		0x10
#define LCD_DISPLAYCONTROL	0x08
#define LCD_ENTRYMODESET	0x04
#define LCD_FUNCTIONSET		0x20
#define LCD_SETCGRAMADDR	0x40
#define LCD_SETDDRAMADDR	0x80
#define LCD_SETSPLASHSCREEN	0x0A
#define LCD_SPLASHTOGGLE	0x09
#define LCD_RETURNHOME		0x02

// Flags for display entry mode
#define LCD_ENTRYRIGHT		0x00
#define LCD_ENTRYLEFT		0x02

// Flags for display on/off control
#define LCD_BLINKON		0x01
#define LCD_CURSORON		0x02
#define LCD_DISPLAYON		0x04

// Flags for display size
#define LCD_2LINE		0x02
#define LCD_4LINE		0x04
#define LCD_16CHAR		0x10
#define LCD_20CHAR		0x14

//  Flags for setting display size
#define LCD_SET2LINE		0x06
#define LCD_SET4LINE		0x05
#define LCD_SET16CHAR		0x04
#define LCD_SET20CHAR		0x03

class serLCD : public SoftwareSerial {
public:
	serLCD (int pin);

	void clear();
	void clearLine(int);
	void home();
	void setBrightness(int);

	void setSplash();
	void toggleSplash();

	void blink();
	void noBlink();
	void cursor();
	void noCursor();
	void display();
	void noDisplay();

	void setCursor(int, int);
	void selectLine(int);

	void leftToRight();
	void rightToLeft();
	void autoscroll();
	void noAutoscroll();

	void createChar(int, uint8_t[]);
	void printCustomChar(int);

private:
	void command(uint8_t);
	void specialCommand(uint8_t);

	uint8_t _displayfunction;
	uint8_t _displaycontrol;
	uint8_t _displaymode;
	uint8_t _numlines;
	uint8_t _numchars;
	uint8_t _rowoffset;
};

#endif

KilnSetup:78: error: 'OnKeyDownBStart' was not declared in this scope

Where is this function defined? You are trying to tell the AdvButton instance to call that function, but you haven't defined that function.

Most of the rest of those errors relate to you calling functions that you haven't defined.

Do you care to elaborate? Should it be something like:

void setOnKeyPress(void (f)(AdvButton));

Do you care to elaborate?

Not really. You are telling the instance that it can call a function that you will provide, but then you don't provide the function. It is difficult to be clearer than that.

Should it be something like:

void setOnKeyPress(void (f)(AdvButton));

It? What is it? If you mean "should the function declaration be like...", no. You need to read your own code:

* - Declare the required event functions ( void OnKeyXXX(AdvButton* but) )