Sorry, forgot the class:
.h:
#ifndef encoderClass_H
#define encoderClass_H
#include "Arduino.h"
#include "C:\Users\David\OneDrive\Arduino\libraries\timeWaste/timeWaste.h"
class EncoderClass
{
private:
const int _encoderPinA; // Holder for the pin connected to the encoder A signal.
const int _encoderPinB; // Holder for the pin connected to the encoder B signal.
const int _encoderPinSW; // Holder for the pin connected to the encoder switch/button signal.
const int _encoderPinRED; // Holder for the pin connected to the
const int _encoderPinGREEN; // Holder for the pin connected to the
const int _encoderPinBLUE; // Holder for the pin connected to the
int _LEDpin; // Holder for the pin connected to a LED.
int _highRange; // Holder for the maximum value '_encoderValue' can assume.
int _lowRange; // Holder for the minimum value '_encoderValue' can assume.
volatile int _lastEncoded; // The previous encoder position.
volatile int _RGBledState; // The current setting for the RGB LED(1-7 handled with a switch expression)
volatile bool _doubleClicking; // Boolean variable to indicate the detection of a double click action.
volatile bool _singleClicking; // Boolean variable to indicate the detection of a single click action.
int (*_UPptr)(); // Function pointer/callback for the function responding to clockwise encoder rotation.
int (*_DOWNptr)(); // Function pointer/callback for the function responding to anti-clockwise encoder rotation.
int (*_SINGLEptr)(); // Function pointer/callback for the function responding to the event of single clicks.
int (*_DOUBLEptr)(); // Function pointer/callback for the function responding to the event of double clicks.
int _encUP(); // Function for calling a callback function for turning the encoder clockwise.
int _encDOWN(); // Function for calling a callback function for turning the encoder anti-clockwise.
int _singleClickFcn(); // Function for calling a callback function for single clicks with the encoder switch.
int _doubleClickFcn(); // Function for calling a callback function for double clicks with the encoder switch.
void _updateEncoder(void); // ISR to determine direction of the encoders rotation which calls _encUP()/_encDOWN() accordingly.
void _encSwitch(void); // ISR for the encoders switch/button.
//void (*_pSW)(void); // Pointer for the '_encSwitch()' interrupt to be passed to 'attachInterrupt()'.
//void (*_pENC)(void); // Pointer for the '_updateEncoder()' interrupt to be passed to 'attachInterrupt()'.
public:
volatile long encoderValue; // Value to display the encoder value.
EncoderClass(int pinA, int pinB, int pinSW, int pinRED, int pinGREEN, int pinBLUE) : _encoderPinA(pinA),
_encoderPinB(pinB),
_encoderPinSW(pinSW),
_encoderPinRED(pinRED),
_encoderPinGREEN(pinGREEN),
_encoderPinBLUE(pinBLUE)
{
/* _pENC = _updateEncoder;
_pSW = _encSwitch;
pinMode(_encoderPinA, INPUT); // Encoder pin A with external Pull-Up.
pinMode(_encoderPinB, INPUT); // Encoder pin B with external Pull-Up.
// Call updateEncoder() when any rising edge is seen on ether encoder pin A or B.
attachInterrupt(_encoderPinA, _pENC, RISING);
attachInterrupt(_encoderPinB, _pENC, RISING);
// Set the mode and interrupt for the encoder switch.
pinMode(_encoderPinSW, INPUT);
attachInterrupt(_encoderPinSW, _pSW, RISING); */
// Initialize the RED LED pin & set it to low output state.
pinMode(_encoderPinRED, OUTPUT);
digitalWrite(_encoderPinRED, LOW);
// Initialize the GREEN LED pin & set it to low output state.
pinMode(_encoderPinGREEN, OUTPUT);
digitalWrite(_encoderPinGREEN, LOW);
// Initialize the BLUE LED pin & set it to low output state.
pinMode(_encoderPinBLUE, OUTPUT);
digitalWrite(_encoderPinBLUE, LOW);
_RGBledState = 0; // the current state of the output pin
_doubleClicking = false;
_singleClicking = false;
}
void encCallbacks(int (*pUP)(), int (*pDOWN)());
void clickCallbacks(int (*pSINGLE)(), int (*pDOUBLE)());
void setRange(int low = 0, int high = 255);
void RGB(int red, int green, int blue);
};
#endif
.cpp:
#include "encoderClass.h"
EncoderClass::EncoderClass(int pinA, int pinB, int pinSW, int pinRED, int pinGREEN, int pinBLUE)
{
};
int EncoderClass::_encUP()
{
_UPptr();
};
int EncoderClass::_encDOWN()
{
_DOWNptr();
};
void EncoderClass::_updateEncoder()
{
//unsigned long int input_data = REG_PIOD_PDSR;
int MSB = !!(PIOD->PIO_PDSR & (1<<4)); //MSB = most significant bit - X Digital pin 14 = PIO D 4.
int LSB = !!(PIOD->PIO_PDSR & (1<<5)); //LSB = least significant bit - Y Digital pin 15 = PIO D 5.
int encoded = (MSB << 1) | LSB; //converting the 2 pin value to single number = XY
int sum = (lastEncoded << 2) | encoded; //adding it to the previous encoded value - LL XY
int oldValue = encoderValue;
if(sum == 0b1011)
{
EncUP();
}
if(sum == 0b0111)
{
EncDOWN();
}
if(encoderValue < _lowRange) encoderValue = _lowRange;
if(encoderValue > _highRange) encoderValue = _highRange;
lastEncoded = encoded; //store this value for next time
};
int EncoderClass::_singleClickFcn()
{
_SINGLEptr();
};
int EncoderClass::_doubleClickFcn()
{
_DOUBLEptr();
};
void EncoderClass::_encSwitch()
{
static int switchState; // the current reading from the input pin
static int lastSwitchState = LOW; // the previous reading from the input pin
static long timeOfFirstClick;
static long timeOfSecondClick;
static long lastDebounceTime = 0; // the last time the output pin was toggled
static long debounceDelay = 10000; // the debounce time; increase if the output flickers
static long _doubleClickTime = 400000; // The time within a second click must be to count as a _doubleClick
static bool isDouble;
isDouble = false;
static int clickCount1 = 0;
static int clickCount2 = 1;
int reading = !!(PIOC->PIO_PDSR & (1<<24)); // Digital pin 6 = PIO C 24.
// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH), and you've waited
// long enough since the last press to ignore any noise:
// If the switch changed, due to noise or pressing:
if (reading != lastSwitchState)
{
// reset the debouncing timer
lastDebounceTime = micros();
}
if ((micros() - lastDebounceTime) > debounceDelay)
{
// whatever the reading is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:
// if the button state has changed:
if (reading != switchState)
{
switchState = reading;
// only toggle the LED if the new button state is HIGH
if (switchState == HIGH)
{
clickCount1++;
// if clickCount1 is higher than clickCount2 that means that
// its is the second click thus possibly a double click.
if(clickCount1 > clickCount2)
{
isDouble = true;
}
timeOfSecondClick = micros();
if(timeOfSecondClick - timeOfFirstClick < _doubleClickTime | isDouble)
{
_doubleClicking = true;
clickCount1 = 0;
clickCount2 = 0;
}
timeOfFirstClick = micros();
clickCount2++;
_singleClicking = true;
_RGBledState += 1;
if(_RGBledState > 7)
{
_RGBledState = 1;
}
}
}
}
// save the reading. Next time through the loop,
// it'll be the lastButtonState:
lastSwitchState = reading;
};
void EncoderClass::encCallbacks(int (*pUP)(), int (*pDOWN)())
{
_UPptr = pUP;
_DOWNptr = pDOWN;
};
void EncoderClass::clickCallbacks(int (*pSINGLE)(), int (*pDOUBLE)())
{
_SINGLEptr = pSINGLE;
_DOUBLEptr = pDOUBLE;
};
void EncoderClass::setRange(int low = 0, int high = 255)
{
_lowRange = low;
_highRange = high;
};
void EncoderClass::RGB(int red, int green, int blue)
{
// int RED = map(red, 0, 100, 0, 255);
// int GREEN = map(green, 0, 100, 0, 255);
// int BLUE = map(blue, 0, 100, 0, 255);
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
};