Ok, I’ll look at the switch_case this morning. Would I still use the click button library, or time the button presses to differentiate between clicks and presses?
Thanks for the help peeps!
Ok, I’ll look at the switch_case this morning. Would I still use the click button library, or time the button presses to differentiate between clicks and presses?
Thanks for the help peeps!
It probably doesn’t matter whether you use the library or not. If you are comfortable with the button click library, you’ll likely make faster progress using it. State machine organization using switch just makes the code easier to organize.
Why not continue to use the click button library, it seems to work. All you need to do is put a ``` button.tick(); ``` at the top of your *loop()* function, before you run the state machine code, and it should be OK.piesoup:
Would I still use the click button library, or time the button presses to differentiate between clicks and presses?
Thanks, I’m having a go at manipulating Lyndon’s code, with the click button library and my ledPins. Getting
errors relating to enum ‘MESSAGES’ was not declared in this scope, but I will persevere and probably come grovelling soon!
Thanks again for the assistance
I don’t use the Arduino IDE much, so I haven’t come across this problem before. Apparently, it has to do with how they infer function prototypes and enums don’t work well with that process. I changed the enums to ints (gritting teeth!!!).
Try this:
// Digital output definitions
#define RED_OUTPUT 0
#define BLUE_OUTPUT 1
#define GREEN_OUTPUT 2
// Digital input definitions
#define SWITCH_INPUT 3
// Define states
#define RED 800
#define BLUE 801
#define GREEN 802
// Define message types
#define NONE 901
#define CLICK 902
#define PRESS 903
// Global state
int _state = GREEN;
// One-time call to initialize system
void setup()
{
pinMode(SWITCH_INPUT, INPUT_PULLUP);
pinMode(RED_OUTPUT, OUTPUT);
pinMode(BLUE_OUTPUT, OUTPUT);
pinMode(GREEN_OUTPUT, OUTPUT);
// Enable GREEN state
digitalWrite(GREEN_OUTPUT, HIGH);
}
// Continuously called by Arduino runtime
void loop()
{
// Read pushbutton
int message = readSwitch();
// Update LEDs and hydraulic valve if state changed
if (processState(message))
{
activateOutput(_state);
}
}
// Read pushbutton and return the result
int readSwitch()
{
const int CLICK_UPPER_LIMIT = 200;
const int CLICK_LOWER_LIMIT = 25;
const int PRESS_LOWER_LIMIT = 1000;
const int PRESS_UPPER_LIMIT = 2000;
int switchMessage = NONE;
unsigned long start = micros();
while (digitalRead(SWITCH_INPUT) == LOW);
unsigned long duration = micros() - start;
if (duration < CLICK_UPPER_LIMIT && duration > CLICK_LOWER_LIMIT)
{
switchMessage = CLICK;
}
else if (duration > PRESS_LOWER_LIMIT && duration < PRESS_UPPER_LIMIT)
{
switchMessage = PRESS;
}
return switchMessage;
}
bool processState(int message)
{
static int lastState = GREEN;
int retVal = 0;
// PRESS overrides CLICK in all states
if (message == PRESS)
{
_state = GREEN;
}
else
{
// Process states
switch (_state)
{
case RED:
if (message == CLICK)
{
_state = BLUE;
}
break;
case BLUE:
if (message == CLICK)
{
_state = RED;
}
break;
case GREEN:
if (message == CLICK)
{
_state = RED;
}
break;
default:
break;
}
}
// Did state change?
retVal = (lastState == _state);
// Remember this state
lastState = _state;
// Return state changed information
return retVal;
}
void activateOutput(int thisState)
{
// Since this is only called on state change, OK to turn everything off first
digitalWrite(RED_OUTPUT, LOW);
digitalWrite(GREEN_OUTPUT, LOW);
digitalWrite(BLUE_OUTPUT, LOW);
// Turn on only the output corresponding to the state
switch (thisState)
{
case RED:
digitalWrite(RED_OUTPUT, HIGH);
break;
case BLUE:
digitalWrite(BLUE_OUTPUT, HIGH);
break;
case GREEN:
digitalWrite(GREEN_OUTPUT, HIGH);
break;
default:
break;
}
}
Still haven’t had a chance to test it, but at least it compiles
Haha! Thanks Lyndon. Now seeing the ‘int’ statement, it all reads better in my head. Is enum a ‘non arduino’ type of int. Or byte like you mentioned above?
Thanks, I will have another look at it later.
piesoup:
Haha! Thanks Lyndon. Now seeing the ‘int’ statement, it all reads better in my head. Is enum a ‘non arduino’ type of int. Or byte like you mentioned above?Thanks, I will have another look at it later.
An enum is an enumerated list of constants. Its purpose is to indicate to the compiler that a variable can only have that particular set of values and if you attempt to assign the variable a value that’s not on the enum list, the compiler will complain.
Arduino does support enums, but it has trouble recognizing them when they are passed as parameters to functions, hence this problem. There is supposed to be a workaround, but I couldn’t get it to work.