PaulMurrayCbr:
I'm thinking of writing some classes to make event-driven coding a bit easier, and I'm wondering if someone else has already done this.
I'm thinking that a Thing would listen to events and be able to fire events. There'd be a root object whose job it is to fire "loop() is being executed", and most of the basic components would listen to that.
The key to the system would be a listener list class. I'm not a C++ programmer, but something like:
........
Anyway - has someone already done this?
Not just the way you outlined, that I know of. Other ways, yes sort of.
But generally you want to trim code on small machines and avoid going into Microsloth featurism.
I thought I was going to have use for patterning IO code starting this year but it's not working out that way yet. What it would replace, works. I'd rather see it work on LESS hardware, maybe it will happen.
I did make a start with 1 output class and 1 input class. Haven't finished more, might get back to it when weather improves and I'm not coughing my head off so much.
// ioclasses library, ongoing work Dec 21, 2014 by GoForSmoke
#ifndef ioclasses16_h
#define ioclasses16_h
class ioblinker
{
private:
unsigned int startMillis;
unsigned int waitMillis;
unsigned char arduPin;
char port;
unsigned char pinsToggleMask;
public:
ioblinker( unsigned int, unsigned char, char, unsigned char );
void setBlinker( unsigned int wM ); // wM == 0UL turns the blink off
void startBlinker( void );
void setPin( unsigned char );
void runBlinker( void ); // this runs every time loop() runs
unsigned int getWait( void );
};
class iobutton
{
private:
unsigned char arduPin;
unsigned char stateHistory; // bit 0 = now, bit 1 = prev
unsigned int startMillis;
unsigned int debounceMillis;
char buttonOut; // 5-state as below
char retButton;
public:
iobutton( char, unsigned int ); // pin, debounce millis
void startButton( void );
void runButton( void );
char readOutput( void ); // 5-state as below
// 5-state UNDECIDED = -1, OFF = 0, ON = 1, justOFF = 2, justON = 3
};
#endif
// ioclasses library, ongoing work Dec 21, 2014 by GoForSmoke
#include "Arduino.h"
#include "ioclasses16.h"
// blinker =================================================
ioblinker::ioblinker( unsigned int w, unsigned char a, char p, unsigned char m )
{
startMillis = 0;
waitMillis = w;
arduPin = a;
port = p;
pinsToggleMask = m;
};
void ioblinker::setBlinker( unsigned int w )
{
waitMillis = w;
};
void ioblinker::startBlinker( void )
{
pinMode( arduPin, OUTPUT );
startMillis = millis();
};
void ioblinker::setPin( unsigned char s )
{
waitMillis = 0;
digitalWrite( arduPin, s );
};
void ioblinker::runBlinker( void )
{
if ( !waitMillis ) return;
if (( millis() & 0xFFFF ) - startMillis >= waitMillis )
{
switch ( port | 32 )
{
case 'b' :
PINB = pinsToggleMask; // writes 1 to each bit in the PINSB register that will get toggled
break;
case 'c' :
PINC = pinsToggleMask; // writes 1 to each bit in the PINSB register that will get toggled
break;
case 'd' :
PIND = pinsToggleMask; // writes 1 to each bit in the PINSB register that will get toggled
break;
default :
waitMillis = 0UL;
}
startMillis += waitMillis;
}
};
unsigned int ioblinker::getWait( void )
{
return waitMillis;
};
// end blinker =============================================
// button ================================================
iobutton::iobutton( char ap, unsigned int dbm )
{
arduPin = ap;
debounceMillis = dbm;
buttonOut = -1;
};
void iobutton::startButton( void )
{
pinMode( arduPin, INPUT_PULLUP );
}
void iobutton::runButton( void )
{
stateHistory &= 1; // clears all but the last read
stateHistory <<= 1; // shifts last read to bit 1
stateHistory += digitalRead( arduPin ); // current state to bit 0
switch ( stateHistory ) // set for INPUT_PULLUP
{
case 0 : // low - low pressed
case 3 : // high - high released
if ( buttonOut < 0 )
{
if ( millis() - startMillis >= debounceMillis )
{
if ( stateHistory == 0 )
{
buttonOut = 3; // button pressed - just changed
}
else
{
buttonOut = 2; // button released - just changed
}
}
}
break;
case 1 : // high - low if state change, debounce!
case 2 : // low - high
buttonOut = -1;
startMillis = millis() & 0xFF;
}
};
char iobutton::readOutput( void )
{
if ( buttonOut < 0 ) return buttonOut;
retButton = buttonOut;
if ( buttonOut > 1 ) buttonOut -= 2; // see change only once
return retButton;
};
// end button ============================================