I read this topic, specifically reply #8, and thought I had it figured out! Unfortunately even with all that wisdom I'm still having problems. I'm writting a class called FlowRate that reads data from a hall effect sensor that uses an interrupt.
I was trying to use the example shown in the forum that I reference above. Here is the sketch whittled down to the minimum to show what the problem is:
#include <FlowRate.h>
FlowRate flowSens1; //Create a flow rate sensor.
unsigned long restFlRtFreq = 0; //The time the Flow rate was last checked.
int checkFlRtFreq = 2000; //This is how often we want to get the flow rate for an intermediate check
void setup()
{
Serial.begin(9600); //Start Serial
Serial.println("<Arduino Ready...>");
flowSens1.begin();
restFlRtFreq = flowSens1.startInterMeas();
}
void loop()
{
if(millis()-restFlRtFreq > checkFlRtFreq) //if 2 seconds have gone by
{
Serial.print("Intermediate Flow Rate Measurement is:");Serial.print(flowSens1.getInterFlowRate()); //print out the intermediate flow rate.
restFlRtFreq = flowSens1.startInterMeas(); //Reset the intermediate measuremnt start time as well as when we come back into this if statement
}
}
Here is the header file, severely whittled:
#ifndef FlowRate_h
#define FlowRate_h
#include "Arduino.h"
class FlowRate
{
public:
FlowRate(); //Constructor(flowSensPin is assumed 2, calFactor is assumed 1)
void begin(); // This attaches the interupt to the pin and method
unsigned long startInterMeas(); //Called to when one would like to start an intermediated flow rate measurment
float getInterFlowRate(); //Called to get an intermediated flow rate meesurement you have to called
//startInterMeas() before calling this again as it is the start
private:
static void marshall(); //The method that calls the right instance of the ISR (flowCountInc())
void flowCountInc(); //Increments the counter. This is called by the marshall when the interupt
// flowSensPin RISING occurs
int _flowSensPin; //The pin used to flow rate seen by the hall effect sensor (must be interuptable)
float _calFactor; //mulitply this times the number of counts to get the amount of fluid in volume (your choice) per second
volatile unsigned long _flowCount; //This is the counter that hold the number of times the hall effect tranducer has signalled
static FlowRate* _anchor; //this allows marshall() to call the right flowCountInc().
unsigned long _flowCountInter; //This is used to remember the count when an intermeditat flowRate may be requested
unsigned long _startIntMeasTime; //This is the time used to start the intermediate measurment of fluid volume
};
#endif
and of course the all important cpp file, again severely whittled:
#include "Arduino.h"
#include "FlowRate.h"
FlowRate::FlowRate()
{
_anchor = this;
_flowSensPin = 2; //The pin used to flow rate seen by the hall effect sensor (must be interuptable
_calFactor = 1.0; //mulitply this times the number of counts to get the amount of fluid in volume (your choice) per second
_flowCount = 0; //The number of times the hall effect tranducer has sent a pulse
_flowCountInter = 0; //the count start for an intermediate flow rate request
pinMode(_flowSensPin, INPUT); //Sets the pin as an input
}
void FlowRate::begin() //This needs to be called to cause the pin to be linked to the Interupt
{
char irqNum = digitalPinToInterrupt(_flowSensPin); //If 2 is passed and you are compiling for an UNO you irqNum should be 0.
if (irqNum != NOT_AN_INTERRUPT)
{
EIFR = bit(irqNum); // cancel evt. pending interrupt
attachInterrupt(irqNum, FlowRate::marshall, RISING); //Configures interruptpin 0 (pin 2 on the Arduino Uno) to run the function
}
}
static void FlowRate::marshall()
{
_anchor->flowCountInc();
}
unsigned long FlowRate::startInterMeas() //Called to when one would like to start an intermediated
{ //flow rate measurment
_startIntMeasTime = millis();
noInterrupts(); //Disable the interrupts on the Arduino
_flowCountInter = _flowCount;
interrupts(); //inable the interrupts on the Arduino
return _startIntMeasTime;
}
float FlowRate::getInterFlowRate() //Called to get an intermediated flow rate measurment
{
unsigned long now = millis();
float flowRate;
noInterrupts(); //Disable the interrupts on the Arduino
flowRate = ((float(_flowCount)-float(_flowCountInter)) * _calFactor)/(float(now - _startIntMeasTime)/1000.0); //Calcualate the flow rate
interrupts(); //inable the interrupts on the Arduino
_startIntMeasTime = now; //Update the start time for intermediate flowrate inquiziations.
return flowRate;
}
void FlowRate::flowCountInc() //This is used to increment the _flowCount variable
{
_flowCount++;
}
I really have no idea what "classIrq* classIrq::anchor = NULL;" does in the example and I have no clue as to where it should go?
Also, something that struck me as strange was the line "attachInterrupt(irqNum, classIrq::marshall, CHANGE);" because I've never seen :: used in that way.
Here is the output from the compiler:
C:\Users\mhessel\AppData\Local\Temp\ccCvpFwP.ltrans0.ltrans.o: In function `FlowRate::marshall()':
M:\Arduino\Sketches\libraries\FlowRate/FlowRate.cpp:29: undefined reference to `FlowRate::_anchor'
M:\Arduino\Sketches\libraries\FlowRate/FlowRate.cpp:29: undefined reference to `FlowRate::_anchor'
C:\Users\mhessel\AppData\Local\Temp\ccCvpFwP.ltrans0.ltrans.o: In function `__base_ctor ':
M:\Arduino\Sketches\libraries\FlowRate/FlowRate.cpp:6: undefined reference to `FlowRate::_anchor'
M:\Arduino\Sketches\libraries\FlowRate/FlowRate.cpp:6: undefined reference to `FlowRate::_anchor'
collect2.exe: error: ld returned 1 exit status
Using library FlowRate in folder: M:\Arduino\Sketches\libraries\FlowRate (legacy)
exit status 1
Error compiling for board Arduino/Genuino Uno.
I hope I not giving too much or too little data. Thanks!!!!