I am a fairly experienced C++ programmer, but this has me stumped. I am trying to make a generic class for button debouncing, and then derive from that a class specific to an analog touch sensor I made. But when my base class DebouncedButton tries to call a pure virtual method isButtonPressed(), the compiler barks at me like an angry German Shepherd:
o: In function DebouncedButton::update()': undefined reference to
__cxa_pure_virtual'
The line of code it does not like is marked with "//!!!!!" below. Am I doing something wrong, or does this compiler not support pure virtual methods?
/*
touch_sensor.pde - Don Cross - http://cosinekitty.com
Experiment with interfacing darlington-pair touch sensor to analog input on atmega8.
*/
//-------------------------------------------------------------------------------------------------
class DebouncedButton {
public:
DebouncedButton (unsigned _debounceTimeInMilliseconds):
stableButtonState (false), // assume button starts out released
debounceTimeInMilliseconds (_debounceTimeInMilliseconds)
{
}
void update()
{
// Check current sensor reading...
bool sample = isButtonPressed(); //!!!!!
unsigned long now = millis();
// Is the current state different from the last stable state?
if (sample == stableButtonState) {
// might still be bouncing around, so restart debounce timer
lastBounceTime = now;
} else {
unsigned long elapsed = now - lastBounceTime;
if (elapsed > debounceTimeInMilliseconds) {
// the state has changed, and appears stable, so toggle the state now...
stableButtonState = sample;
if (stableButtonState) {
onPress();
} else {
onRelease();
}
}
}
}
virtual bool isButtonPressed() = 0; // derived class defines what it means for noisy button to be pressed
virtual void onPress() = 0; // action to take when debouncer says button is pressed
virtual void onRelease() = 0; // action to take when debouncer says button is realeased
private:
bool stableButtonState; // false=button released, true=button pressed
unsigned long lastBounceTime;
unsigned debounceTimeInMilliseconds;
};
//-------------------------------------------------------------------------------------------------
const int TOUCH_THRESHOLD = 500;
class AnalogTouchSensor: public DebouncedButton {
public:
AnalogTouchSensor (byte _analogInputPin, byte _digitalOutputPin):
DebouncedButton (10), // pass debounce time in milliseconds to DebouncedButton class
analogInputPin (_analogInputPin),
digitalOutputPin (_digitalOutputPin),
digitalOutputState (false)
{
pinMode (digitalOutputPin, OUTPUT);
}
virtual bool isButtonPressed()
{
return analogRead(analogInputPin) < TOUCH_THRESHOLD;
}
virtual void onPress()
{
digitalOutputState = !digitalOutputState;
digitalWrite (digitalOutputPin, digitalOutputState);
}
virtual void onRelease()
{
// do nothing
}
private:
byte analogInputPin;
byte digitalOutputPin;
byte digitalOutputState;
};
//-------------------------------------------------------------------------------------------------
AnalogTouchSensor sensor(5, 13); // monitor analog pin 5, toggle LED on pin 13
void setup()
{
}
void loop()
{
sensor.update();
}
//-------------------------------------------------------------------------------------------------
/*
$Log: touch_sensor.pde,v $
Revision 1.1 2007/01/01 02:30:14 dcross
Almost works, but needs debounce.
*/