Sequence switcher using a tactile switch.

Ok… I’ve tried for 4 days now and I’m pretty frustrated. I’ve searched and read, but I need some help. I’m still pretty much a noob at this stuff so don’t be afraid to explain some what should be obvious stuff.

here is the idea: I have a few different sequences that will flash Leds in different patterns. I want to have a forward and back button that goes forward threw the patterns and also backward. I want an on and off button too. I haven’t even been able to make it go forward yet…

here is the code.

#include <Utility.h>
const byte NUMBER_OF_PINS = 2; 
byte ledPin[NUMBER_OF_PINS] = {9,10};
int pulsewidth = 0;
const int ledpinG = 9;
const int ledpinO = 10;
const int ledpinHERD = 11;
int inpin = 3;
int x = 0;
int val;

void setup()  {
  pinMode(ledpinG, OUTPUT);
  pinMode(ledpinO, OUTPUT);
  pinMode(ledpinHERD, OUTPUT);
  pinMode(inpin, INPUT);
  foreach(ledPin, NUMBER_OF_PINS, pinMode, OUTPUT);
 pinMode(ledpinHERD,OUTPUT);
  Serial.begin(9600);
}

void loop()  {
  val = digitalRead(inpin);
  for(int x = 0; x<3; x++);{
  
  if(val == HIGH && x==1)      {
     Serial.print("G");
  digitalWrite(ledpinG, HIGH);
  delay(600);
  Serial.print("O");
  digitalWrite(ledpinO, HIGH);
  delay(600);
  Serial.print("HERD!!!");
  digitalWrite(ledpinHERD,HIGH);
  delay(600);
  digitalWrite(ledpinHERD, LOW);
  digitalWrite(ledpinG, LOW);
  digitalWrite(ledpinO,LOW);
  delay(600);
Serial.print("\n");  
                                }

if (val ==HIGH && x==2)  {
   Serial.print("\nGO\n");
  digitalWrite(ledpinG, HIGH);
  digitalWrite(ledpinO,HIGH);
  delay(600);
  digitalWrite(ledpinG, LOW);
  digitalWrite(ledpinO,LOW);
  Serial.print("\nHERD\n");
  digitalWrite(ledpinHERD, HIGH);
  delay(600);
  digitalWrite(ledpinHERD, LOW);
  Serial.print("\nGO!!!\n");
   digitalWrite(ledpinG, HIGH);
   digitalWrite(ledpinO,HIGH);
  delay(400);
  digitalWrite(ledpinG, LOW);
  digitalWrite(ledpinO,LOW);
  delay(1000);
}
if( val == HIGH && x==3)  {
 for (pulsewidth=0; pulsewidth<255; pulsewidth+=10){
   foreach(ledPin, NUMBER_OF_PINS, analogWrite, pulsewidth);
   delay(50);
 }

 foreach(ledPin, NUMBER_OF_PINS, digitalWrite, HIGH);
 delay(10);
 digitalWrite(ledpinHERD, HIGH);
 delay(300);
 digitalWrite(ledpinHERD, LOW);
 delay(300);
  digitalWrite(ledpinHERD, HIGH);
 delay(300);
 digitalWrite(ledpinHERD, LOW);
 delay(300);
  digitalWrite(ledpinHERD, HIGH);
 delay(300);
 digitalWrite(ledpinHERD, LOW);
 delay(300);
 digitalWrite(ledpinHERD, HIGH);
 delay(2000);
 digitalWrite(ledpinHERD, LOW);
 foreach(ledPin, NUMBER_OF_PINS, digitalWrite, LOW);
}

 
}
}

If I need to annotate this I can do it.

Thanks for the help. If you don’t want to use this code to demonstrate I don’t mind if you do a simple code for say 2 or 3 leds to light up after a button is pushed going from 1 to 2 to 3.

Thanks!

I see what you are trying to do… I also see the problem.

This line of code just increments ‘x’ and then does nothing because you have the semicolon right after the close parenthesis of the FOR loop.

for(int x = 0; x<3; x++)[glow];[/glow]{

Then it will go on to test your IF statements and ‘x’ will be equal to 3. If you hold your button down, and your switch delivers a HIGH logic level voltage to the input, it will execute only your last FOR loop with the pulsewidth stuff. I’m not sure about exactly what you are trying to do there, didn’t analyze it but I’m assuming that’s doing what you want it to for the sequence.

You basically just need to delete the FOR loop, but keep the IF statements that test for x==1, x==2, and x==3.


Ok, one way to switch forward and reverse through the sequence is to have two inputs, let’s call them FWD and RVS. When FWD is HIGH, you need to increment your ‘x’ counter from 1 to 2 or from 2 to 3, but if you are at 3, you have to test for that and set it to 1, instead of incrementing to 4. Likewise, you can go the opposite route for RVS, decrementing the same counter from 3 to 2, or 2 to 1, but then set it to 3 instead of decrementing to 0.

if(FWD) {
  if(x<3) x++;
  else x=1;
}
if(RVS) {
  if(x>1) x--;
  else x=3;
}

The way your code is set up, your input is only read once every time through the main loop. And then time is spent doing the LED sequences. So you’ll have to hold the FWD or RVS button down while a sequence is executing, so that when the inputs get read it sees one or more as HIGH, and inc’s or dec’s the counter appropriately.

If you want it to sample your button periodically in the background and switch to the next sequence right as you press the button, you’ll have to set up an interrupt to read the inputs and adjust the counter. With this setup, if you are sampling pretty fast, you may need to debounce the input as well. This is completely doable, but requires another counter scheme to be setup that makes sure the button is held down long enough before the code considers that input active. If you want more explanation on this, just ask and I’ll elaborate.

Hope that helps!

Brett

Thanks for the reply. I think that this for me is beyond the scope (lol). I think that when I have some more time to get this right I'll try again. I really appreciate your replay though. What I ended up doing was have 2 different switches for 2 different codes. It will work for now.