Encoder works as a sketch but not as a library

So I am trying to understand how to program encoders and I wrote this: (oh yeah and it works as a sketch)

#include <PinChangeInt.h>
#define pinA 6
#define pinB 5
byte previousSituation;
long degreesMoved = 0;
//Both Pins are low
void situation1(){
  switch (previousSituation){
    case 2:
      degreesMoved ++;
      break;
    case 3:
      degreesMoved --;
      break;
  }
  previousSituation = 1;
  PCintPort::detachInterrupt(pinA);
  PCintPort::detachInterrupt(pinB);
  PCintPort::attachInterrupt(pinA, situation3, RISING);
  PCintPort::attachInterrupt(pinB, situation2, RISING);

}

//Pin A is low and Pin B is high
void situation2(){
  switch (previousSituation){
    case 4:
      degreesMoved ++;
      break;
    case 1:
      degreesMoved --;
      break;
  }
  previousSituation = 2;
  PCintPort::detachInterrupt(pinA);
  PCintPort::detachInterrupt(pinB);
  PCintPort::attachInterrupt(pinA, situation4, RISING);
  PCintPort::attachInterrupt(pinB, situation1, FALLING);
  
}

//Pin A is high and Pin B is low
void situation3(){
  switch (previousSituation){
    case 1:
      degreesMoved ++;
      break;
    case 4:
      degreesMoved --;
      break;
  }
  previousSituation = 3;
  PCintPort::detachInterrupt(pinA);
  PCintPort::detachInterrupt(pinB);
  PCintPort::attachInterrupt(pinA, situation1, FALLING);
  PCintPort::attachInterrupt(pinB, situation4, RISING);
  
}

//Both Pins are high
void situation4(){
  switch (previousSituation){
    case 3:
      degreesMoved ++;
      break;
    case 2:
      degreesMoved --;
      break;
  }
  previousSituation = 4;
  PCintPort::detachInterrupt(pinA);
  PCintPort::detachInterrupt(pinB);
  PCintPort::attachInterrupt(pinA, situation2, FALLING);
  PCintPort::attachInterrupt(pinB, situation3, FALLING);
}



void setup(){
  pinMode(pinA, INPUT);
  pinMode(pinB, INPUT);
  digitalWrite(pinA,LOW);
  digitalWrite(pinB,LOW);
  Serial.begin(9600);
  int startingSituation = digitalRead(pinA) << 1;
  startingSituation += digitalRead(pinB) +1;
  Serial.println(startingSituation);
  switch (startingSituation) {
  case 1:
    previousSituation = 1;
    situation1();
    break;
  case 2:
    previousSituation = 2;
    situation2();
    break;  
  case 3:
    previousSituation = 3;
    situation3();
    break;
  case 4:
    previousSituation = 4;
    situation4();
    break;
  }
  
  
}

void loop(){
    Serial.println(degreesMoved);
}

but when i went to make it into a library that im putting together that does pid. I have the pid library working for a potentiometer but i can’t get it working for the encoder. My library as it stands now is this: (the plan was to make it not all on the header once it works)

#ifndef PIDEncoder_H
#define PIDEncoder_H

#if (ARDUINO >= 100)
  #include <Arduino.h>
#else
  #include <WProgram.h>
#endif
#include <inttypes.h>
#include "Print.h"
#include "PIDBase.h"
#include <PinChangeInt.h>

class PIDEncoder: public PIDBase{


//Both Pins are low	
	void m_situation1(){
	  switch (m_previousSituation){
		case 2:
		  m_currentPosition ++;
		  break;
		case 3:
		  m_currentPosition --;
		  break;
	  }
	  m_previousSituation = 1;
	  PCintPort::detachInterrupt(PIDEncoder::m_pinA);
	  PCintPort::detachInterrupt(PIDEncoder::m_pinB);
	  PCintPort::attachInterrupt(PIDEncoder::m_pinA, PIDEncoder::m_situation3, RISING);
	  PCintPort::attachInterrupt(PIDEncoder::m_pinB, PIDEncoder::m_situation2, RISING);

	}

//Pin A is low and Pin B is high
	void m_situation2(){
	  switch (m_previousSituation){
		case 4:
		  m_currentPosition ++;
		  break;
		case 1:
		  m_currentPosition --;
		  break;
	  }
	  previousSituation = 2;
	  PCintPort::detachInterrupt(m_pinA);
	  PCintPort::detachInterrupt(m_pinB);
	  PCintPort::attachInterrupt(m_pinA, PIDEncoder::m_situation4, RISING);
	  PCintPort::attachInterrupt(m_pinB, PIDEncoder::m_situation1, FALLING);
	  
	}

	//Pin A is high and Pin B is low
	void m_situation3(){
	  switch (m_previousSituation){
		case 1:
		  m_currentPosition ++;
		  break;
		case 4:
		  m_currentPosition --;
		  break;
	  }
	  previousSituation = 3;
	  PCintPort::detachInterrupt(m_pinA);
	  PCintPort::detachInterrupt(m_pinB);
	  PCintPort::attachInterrupt(m_pinA, PIDEncoder::m_situation1, FALLING);
	  PCintPort::attachInterrupt(m_pinB, PIDEncoder::m_situation4, RISING);
	  
	}

	//Both Pins are high
	void m_situation4(){
	  switch (m_previousSituation){
		case 3:
		  m_currentPosition ++;
		  break;
		case 2:
		  m_currentPosition --;
		  break;
	  }
	  previousSituation = 4;
	  PCintPort::detachInterrupt(m_pinA);
	  PCintPort::detachInterrupt(m_pinB);
	  PCintPort::attachInterrupt(m_pinA, PIDEncoder::m_situation2, FALLING);
	  PCintPort::attachInterrupt(m_pinB, PIDEncoder::m_situation3, FALLING);
	}
		
	public:
	void setup(int pinA, int pinB){
		m_pinA = pinA;
		m_pinB = pinB;	
	};
	
	void begin(){
		clear();
		pinMode(m_pinA, INPUT);
		pinMode(m_pinB, INPUT);
		digitalWrite(m_pinA,LOW);
		digitalWrite(m_pinB,LOW);
		int startingSituation = digitalRead(m_pinA) << 1;
		startingSituation += digitalRead(m_pinB) +1;
		switch (startingSituation) {
			case 1:
				m_previousSituation = 1;
				m_situation1();
				break;
			case 2:
				m_previousSituation = 2;
				m_situation2();
				break;  
			case 3:
				m_previousSituation = 3;
				m_situation3();
				break;
			case 4:
				m_previousSituation = 4;
				m_situation4();
				break;
		}
	};
	
	void clear(){
		m_currentPosition = 0;
	};
	
	double PIDGet(){
		return m_currentPosition;
	};
	
	
	uint8_t m_pinA, m_pinB;
	byte m_previousSituation;
	float m_currentPosition;
};

#endif

everything worked until I added the void situations. now when I put in this code to see if it compiles i get errors. I know its not in the PIDBase library because I’ve tested it and it works for the potentiometer version.

#include <PIDBase.h>
#include <PIDEncoder.h>
#include <PinChangeInt.h>

PIDEncoder test;

void setup(){
  
}

void loop(){
  
}

my error is this:(but of course it repeats for each time i called attachinterrupt

In file included from sketch_jun27a.cpp:2:
D:\Programs\arduino-1.0.1-modified see notes\libraries\PIDEncoderv1_0/PIDEncoder.h: In member function 'void PIDEncoder::m_situation1()':
D:\Programs\arduino-1.0.1-modified see notes\libraries\PIDEncoderv1_0/PIDEncoder.h:30: error: no matching function for call to 'PCintPort::attachInterrupt(uint8_t&, <unresolved overloaded function type>, int)'
D:\Programs\arduino-1.0.1-modified see notes\libraries\PinChangeInt/PinChangeInt.h:421: note: candidates are: static int8_t

Any ideas? Im completely lost. Thanks

attachInterrupt is a global function, not a class function, so you can't qualify it like that.

sorry for another nooby question but can you explain that. Im lost

Example of doing attachInterrupt here:

http://forum.arduino.cc/index.php/topic,160101.0.html

On another note, member declarations go in the header (.h) file. The implementation of the method does NOT. That goes in the source (.cpp) file.

Use some of the existing libraries that come with the Arduino software as a template, saves spending too much time learning a lot about C++.

Basically the library interface goes in the .h file, the implementation in the .cpp file (more or less).

Is putting all the stuff in the header that big of an issue? I was looking at a library for encoders that worked and it was all in the header. I normally write libraries with the header and .cpp but i was trying to get it going a bit faster so i put in all in the header with the hopes of cleaning it up after

It won’t affect the speed. For single usage you could put everything in the .h file, but once you have multiple .cpp files sharing it (as you would with a larger project) then you would get duplicate symbols.

For the sake of a few seconds making another file, may as well do it right.

Hi so i am back again, I got it working, thanks for the help, but now i have another question. How do i go about making it capable of multiple encoders? Thanks

This is my header

#ifndef PIDEncoder_H
#define PIDEncoder_H

#ifndef PinChangeInt_h
#define LIBCALL_PINCHANGEINT
#include "../PinChangeInt/PinChangeInt.h"
#endif

#if (ARDUINO >= 100)
  #include 
#else
  #include 
#endif

#include 
#include 
#include 


class PIDEncoder: public PIDBase{

    const byte m_pinA, m_pinB, m_number;
//Both Pins are low 
    static void m_situation1();
//Pin A is low and Pin B is high
    static void m_situation2();
//Pin A is high and Pin B is low
    static void m_situation3(); 
//Both Pins are high
    static void m_situation4();
    int returnChannel();
    public:
    void handler1();
    void handler2();
    void handler3();
    void handler4();
//  some more bytes
    volatile byte m_previousSituation;

public:
//Constructor
    PIDEncoder(const byte pinA, const byte pinB,const byte number);
//Start
    void begin();
//  reset count    
    void clear();
//  for use with pidbase
    double PIDGet();
//  for glueing routine 
    static PIDEncoder *numberOne;
    volatile float m_currentPosition;
};

#endif

and this is my cpp

#include "PIDEncoder.h"
#include 
#include "PIDBase.h"



PIDEncoder * PIDEncoder::numberOne;


PIDEncoder::PIDEncoder(const byte pinA, const byte pinB,const byte number): m_pinA (pinA), m_pinB(pinB), m_number(number){
};

void PIDEncoder::m_situation1(){


    numberOne -> handler1();

}

void PIDEncoder::m_situation2(){

    numberOne -> handler2();

}

void PIDEncoder::m_situation3(){

    numberOne -> handler3();

}

void PIDEncoder::m_situation4(){

    numberOne -> handler4();

}

void PIDEncoder::handler1(){
    switch (m_previousSituation){
    case 2:
        m_currentPosition ++;
        break;
    case 3:
        m_currentPosition --;
        break;
    }
    m_previousSituation = 1;
    PCintPort::detachInterrupt(PIDEncoder::m_pinA);
    PCintPort::detachInterrupt(PIDEncoder::m_pinB);
    PCintPort::attachInterrupt(PIDEncoder::m_pinA, m_situation3, RISING);
    PCintPort::attachInterrupt(PIDEncoder::m_pinB, m_situation2, RISING);
};

void PIDEncoder::handler2(){
    switch (m_previousSituation){
    case 4:
        m_currentPosition ++;
        break;
    case 1:
        m_currentPosition --;
        break;
    }
    m_previousSituation = 2;
    PCintPort::detachInterrupt(m_pinA);
    PCintPort::detachInterrupt(m_pinB);
    PCintPort::attachInterrupt(m_pinA, m_situation4, RISING);
    PCintPort::attachInterrupt(m_pinB, m_situation1, FALLING);
};

void PIDEncoder::handler3(){
    switch (m_previousSituation){
    case 1:
        m_currentPosition ++;
        break;
    case 4:
        m_currentPosition --;
        break;
    }
    m_previousSituation = 3;
    PCintPort::detachInterrupt(m_pinA);
    PCintPort::detachInterrupt(m_pinB);
    PCintPort::attachInterrupt(m_pinA, m_situation1, FALLING);
    PCintPort::attachInterrupt(m_pinB, m_situation4, RISING);
};

void PIDEncoder::handler4(){
    switch (m_previousSituation){
    case 3:
        m_currentPosition ++;
        break;
    case 2:
        m_currentPosition --;
        break;
    }
    m_previousSituation = 4;
    PCintPort::detachInterrupt(m_pinA);
    PCintPort::detachInterrupt(m_pinB);
    PCintPort::attachInterrupt(m_pinA, m_situation2, FALLING);
    PCintPort::attachInterrupt(m_pinB, m_situation3, FALLING);
};

void PIDEncoder::begin(){
    numberOne = this;
    numberOne -> clear();

    pinMode(m_pinA, INPUT);
    pinMode(m_pinB, INPUT);
    digitalWrite(m_pinA,LOW);
    digitalWrite(m_pinB,LOW);
    int startingSituation = digitalRead(m_pinA) << 1;
    startingSituation += digitalRead(m_pinB) +1;
    switch (startingSituation) {
        case 1:
            m_previousSituation = 1;
            m_situation1();
            break;
        case 2:
            m_previousSituation = 2;
            m_situation2();
            break;  
        case 3:
            m_previousSituation = 3;
            m_situation3();
            break;
        case 4:
            m_previousSituation = 4;
            m_situation4();
            break;
    }
};

void PIDEncoder::clear(){
    m_currentPosition = 0;
};

double PIDEncoder::PIDGet(){
    return m_currentPosition;
};

int PIDEncoder::returnChannel(){
    return m_number;

};