Go Down

Topic: Problem using attachInterrupt() inside a library(class). (Read 137 times) previous topic - next topic

Microzod

Hello.

I have spent some time working on a class for a RGB LED rotary encoder with a integrated switch bought from sparkfun: https://www.sparkfun.com/products/10982

The encoder part(react to turning the knob/press the switch) is no problem, that is not the issue.

First I made a sketch that performed all the functionality I want and when that worked I tried to reduce the 5 separate sketch pages into one class and use that class as a library.

To do things in the right order I have removed the code that causes the problem raised in the title of this thread, I don't mean to mislead anyone and as soon as I have solved the problem below I will get to the main problem.
It feel as this can't be any serious problem, I have been writing a couple of these sort of classes, one to control a DAC and another for a ADC and they worked fine but why is this object once instantiated not recognized?

This is how the sketch looks like:

Code: [Select]
#include <timeWaste.h>
#include <encoderClass.h>


int UP();      // Function prototype for clock-wise rotation.
int DOWN();    // Function prototype for anti clock-wise rotation.
int SINGLE();  // Function prototype for single click with the switch.
int DOUBLE();  // Function prototype for double click with the switch.

int (*pUP)() = UP;         // Function pointer for UP()
int (*pDOWN)() = DOWN;     // Function pointer for DOWN()
int (*pSINGLE)() = SINGLE; // Function pointer for SINGLE()
int (*pDOUBLE)() = DOUBLE; // Function pointer for DOUBLE()

const int encoderPinA = 14;  // Encoder pin A
const int encoderPinB = 15;  // Encoder pin B

const int switchPin = 6;    // the number of the pushbutton pin
const int redPin = 8;       // the number of the RED LED pin
const int greenPin = 7;     // the number of the GREEN LED pin
const int bluePin = 5;      // the number of the BLUE LED pin
const int LED = 12;         // the number of the pin used for confirmation of correct rotation detection, with red LED.

EncoderClass enc(encoderPinA, encoderPinB, switchPin, redPin, greenPin, bluePin); // Constructor
enc.setRange(0, 100);                                    // Set the range of values that the encoder rotation will control
enc.RGB(100, 0, 100);                                    // Used to set the RGB LED color, PWM steps is converted into steps of 0-100
enc.encCallbacks(int (*pUP)(), int (*pDOWN)());          // Function to pass the function pointers for the UP & DOWN functions to the class
enc.clickCallbacks(int (*pSINGLE)(), int (*pDOUBLE)());  // Function to pass the function pointers for single/double click to the class

void setup()
{
  pinMode(LED, OUTPUT);    // Initilize the confirmation LED
  digitalWrite(LED, LOW);  // ---

}

void loop()
{
  // A program to control a adjustable 0-50V @ 5A shall be added.

}

int UP()
{
  enc.encoderValue++;
}

int DOWN()
{
  enc.encoderValue--;
}

int SINGLE()
{
  
}

int DOUBLE()
{
  
}


But I get this compile error:

encoderClassTest.ino:25:1: error: 'enc' does not name a type
encoderClassTest.ino:26:1: error: 'enc' does not name a type
encoderClassTest.ino:27:1: error: 'enc' does not name a type
encoderClassTest.ino:28:1: error: 'enc' does not name a type
Error compiling.

This is the second time I try to solve these problems and I have spent many hours without any success.
Any help would be very much appreciated.

Regards

Microzod

This does concern the Due specifically though it does not show jet.

Microzod

Sorry, forgot the class:

.h:
Code: [Select]
#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:
Code: [Select]
#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);

};

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy