Hi, I was referred here from mp3car.com and was told this microcontroller could be what Im looking for. What Im looking to do is by using a standard spst normally open mom switch is as so
from OFF
STEP 1) press and release switch and pin x goes hi
STEP 2) press and release switch a second time and pin x stays hi and pin y goes hi
STEP 3) press and HOLD switch third time pin x goes lo, pin y stays hi and pin z goes hi
STEP 4) release switch pin x goes hi, pin y stays hi and pin z goes lo
STEP 5) press and release switch and all pins go lo
then start over
AS WELL AS....
press and hold switch for 2 seconds from off and program starts at STEP 3 and goes to STEP 4 then STEP 5
I also need to be able to debounce the switch used
I must explain that I have very little experience with programming language but I do understand the hardware side of things. I asked in the other forum for something fairly user friendly for someone that doesnt understand programming and I was referred here. Im only looking to do this one thing with a microcontroller. Ive looked through the tutorials and other than one about debouncing a switch I didnt see anything I thought would help me with my particular application. If anyone can help me with this Id appreciate it, thanks
That should be a pretty straight forward task to perform. A 'state machine' is probably the best model to utilize. Each transistion of the input switch, both low to high and high to low would increment a state counter variable. On reading your detailed sequence there seems to be 8 states including the off state (0-7 states). A case statement would decide which outputs to turn on or off depending on which state the counter has moved to. Step 1 would also need to start a timer to jump to step 3 if 2 seconds has elapsed without moving to step 1.
That make sense?
Although a state machine would certainly work, there are other approaches that will also work. Your application is similar to something I am working on so here are some ideas that may be of help.
You could use a routine that returns how long a switch is pressed to drive your logic as well as debounce the switch. swPressed() is a function that returns the duration in milliseconds that a switch has been pressed. It returns 0 if a switch is not pressed for at least the debounce period.
I have outlined some code that uses this function to implement logic similar to your application. I hope its of some help.
#define swPin 2 // the switch pin to monitor
#define DEBOUNCE_TIME 40 // switch must be pressed at least this number of ms
#define NO_SWITCH 255
void loop(){
unsigned int dur,prevDur;
dur = prevDur = swPressed(swPin);
if(dur > 0){
// here if switch pressed for the first time
while(1){
if(dur >= prevDur){
// still wating for first release
prevDur = dur;
dur = swPressed(swPin); // update duration so we can tell if its been held for over 2000ms
}
else{ // switch released
if(prevDur < 2000){
// only do steps 1 and 2 if switch held less than 2000ms
// do step 1
while(swPressed(swPin) == 0) ; // wait for switch to be pressed
while(swPressed(swPin) != 0) ; // wait for switch to be released
// do step 2
}
while(swPressed(swPin) == 0) ; // wait for switch to be pressed
// do step 3
while(swPressed(swPin) != 0) ; // wait for switch to be released
while(swPressed(swPin) == 0) ; // wait for switch to be pressed
while(swPressed(swPin) != 0) ; // wait for switch to be released
// do step 4
while(swPressed(swPin) == 0) ; // wait for switch to be pressed
while(swPressed(swPin) != 0) ; // wait for switch to be released
// do step 5
}
}
}
}
unsigned int swPressed(byte sw){
// returns duration button pressed in ms, returns 0 if not pressed for DEBOUNCE period
// this logic only supports one button pressed at a time
static byte prevswitch = NO_SWITCH;
static unsigned long startTime;
unsigned int dur;
dur = 0;
if(digitalRead(sw) == LOW){
if(sw != prevswitch ){
startTime = millis();
prevswitch = sw;
delay(DEBOUNCE_TIME);
if(digitalRead(sw) == LOW)
dur = DEBOUNCE_TIME;
}
else if (sw == prevswitch ){
Serial.println(millis() - startTime);
if( millis() - startTime > 60000)
dur = 60000; // this prevents overflowing return value
else{
dur = millis() - startTime;
if( dur < DEBOUNCE_TIME)
dur = 0; // return 0 if duration less than debounce time
}
}
}
else if (sw == prevswitch ){ // was previous switch released?
prevswitch = NO_SWITCH; // yes, so clear switch indicator
}
return dur;
}