Multiple LED's on separate pins, switches and functions - need guidance

OK, here are some suggested (and untested) code fragments:

int currentPattern = 4;
int patternButtonState = HIGH;
unsigned long delayTime = 50;

Note I have assumed the button to change pattern is normally LOW and you have a pull-down resistor on the input to prevent if from floating. This patternButtonState variable is set initially to HIGH, but as soon as the sketch starts running and detects the button state is LOW, it will act as though the button has just been released and set up the first flashing pattern.

  if (digitalRead(patternButton) != patternButtonState)  { //the button state has changed

    if (patternButtonState == LOW) { //the button state must have just gone high
      patternButtonState = HIGH;  //record that button has just been pressed but do nothing for now, wait for release

    else { //it was high, so the button must have just been released

      //record the fact that be button has now gone low ie. not pressed
      patternButtonState = LOW;

      switch (currentPattern) {

        case 1: //Pattern 1 has been running
          //set up pattern 2
          currentPattern = 2;
          red = ...;
          red2 = ...;
          incR = ...;
          incR2 = ...;
          delayTime = ...;
          break;

        case 2:
          ...

        case 3:
          ...

        case 4:
          //set up pattern 1
          currentPattern = 1;
          red = ...;
          red2 = ...;
          incR = ...;
          incR2 = ...;
          delayTime = ...;
          break;

      }
    }

Hope this makes at least some sense!

Paul

Well, it looked like it would work. But, I probably screwed it up entering into the existing code.

byte BRAKE_SWITCH = 8; //Set Pin 8 as Brake Switch
byte Right_Turn= 4; //Set Pin 4 as Switch
byte PIN_RED = 11;  //Right Rear Set Pin 11 as LED
byte PIN_FR = 7;  //Right Front Set Pin 7 as LED
byte Left_Turn = 5 ; //Set Pin 5 as Switch
byte PIN_RED2 = 10;  //Left Rear Set Pin 10 as LED
byte PIN_FL = 6;  //Left Front Set Pin 6 as LED
byte PIN_TOGG = 2; //Toggle Fades set Pin 2
boolean buttonstate; //Integer variable named buttonstate Left Turn Switch
boolean button_state; //Integer variable named button_state Right Turn Switch
boolean button__state; //Integer variable named button__state Brake Switch

// Delay time: sets the time in milliseconds between loop iterations.
// Make this value large for slower transitions.
unsigned long delayTime = 10;

int currentPattern = 4;
int patternButtonState = HIGH;

// The initial values of each color.
int red = 175;
int red2 = 20;

// Indicates whether a color is incrementing (1) or decrementing (0).
int incR = 1;
int incR2 = 1;



void setup()
{
  
  pinMode(PIN_TOGG, INPUT);
  pinMode(Left_Turn, INPUT);
  pinMode(PIN_RED2, OUTPUT);
  pinMode(PIN_FL, OUTPUT);
  pinMode(Right_Turn, INPUT);
  pinMode(PIN_RED, OUTPUT);
  pinMode(PIN_FR, OUTPUT);
  pinMode(BRAKE_SWITCH, INPUT);
}
 
void turnLeft()//turnLeft function 
{
  analogWrite(PIN_FR, 255);
  analogWrite(PIN_RED, 125); 
analogWrite(PIN_RED2, 125);
buttonstate = HIGH; //the micro the switch is now HIGH

while (buttonstate == HIGH) //While the switch is NOT pressed do the following
{

buttonstate = digitalRead(Left_Turn); //Continually look at the switch to see if its pressed
analogWrite(PIN_RED2, 255); //Set the Rear Left LED to maximum brightness
analogWrite(PIN_FL, 255); //Set the Front Left LED to maximum brightness
delay(100); 
analogWrite(PIN_RED2, 0); //turn the LED off for a blinking effect
analogWrite(PIN_FL, 0); //turn the LED off for a blinking effect
delay(100);

}
//Once the switch is pressed again, break out of the loop above and then break out of the function completely and go back to our main loop
buttonstate = LOW; //First we tell the micro the switch is now LOW
analogWrite(PIN_RED2, 0); //We turn the LED off before leaving our custom function
analogWrite(PIN_FL, 0); //We turn the LED off before leaving our custom function
}

void turnRight()//turnRight function 
{
    analogWrite(PIN_FL, 255);
    analogWrite(PIN_RED, 125); 
analogWrite(PIN_RED2, 125);
button_state = HIGH; //the micro the switch is now HIGH

while (button_state == HIGH) //While the switch is NOT pressed do the following
{
button_state = digitalRead(Right_Turn); //Continually look at the switch to see if its pressed
analogWrite(PIN_RED, 255); //Set the Rear Right LED to maximum brightness
analogWrite(PIN_FR, 255); //Set the Front Right LED to maximum brightness
delay(100); 
analogWrite(PIN_RED, 0); //turn the LED off for a blinking effect
analogWrite(PIN_FR, 0); //turn the LED off for a blinking effect
delay(100);
}
//Once the switch is pressed again, break out of the loop above and then break out of the function completely and go back to our main loop
button_state = LOW; //First we tell the micro the switch is now LOW
analogWrite(PIN_RED, 0); //We turn the LED off before leaving our custom function
analogWrite(PIN_FR, 0); //We turn the LED off before leaving our custom function
}

void brakelights()
{

analogWrite(PIN_FL, 255);
analogWrite(PIN_FR, 255);
button__state = HIGH; //the micro switch is now HIGH

while (button__state == HIGH) //While the switch is NOT pressed do the following
{
  button__state = digitalRead(BRAKE_SWITCH); //Continually look at the switch to see if its pressed
  analogWrite(PIN_RED, 255); //Set the Rear Right LED to maximum brightness
  analogWrite(PIN_RED2, 255); //Set the Rear Left LED to maximum brightness
  
}
//Once the switch is pressed again, break out of the loop above and then break out of the function completely and go back to our main loop
button_state = LOW; //First we tell the micro the switch is now LOW
analogWrite(PIN_RED, 125); //We turn the LED off before leaving our custom function
analogWrite(PIN_RED2, 125); //We turn the LED off before leaving our custom function
}

// Smoothly changes the color values
void transition()
{
  if (red >= 175)
    incR = 0;
  else if (red <= 20)
    incR = 1;
  if (red2 >= 175)
    incR2 = 0;
  else if (red2 <= 20)
    incR2 = 1;
  
  if (incR)
    red++;
  else
    red--;
  if(incR2)
    red2++;
  else
    red2--;
}

// Sets the output voltage on the LED pins.
void setColor()
{
  analogWrite(PIN_RED, red);
  analogWrite(PIN_RED2, red2);
}
 
 
void loop()
{
 analogWrite(PIN_FR, 255);
 analogWrite(PIN_FL, 255);
  transition();
  setColor();
  delay(delayTime);
  
  button__state = digitalRead(BRAKE_SWITCH); //Continually look at the switch to see if its pressed
if (button__state == HIGH) //If the switch goes HIGH, act on it
{
  brakelights(); //new function called brakelights
}
  
buttonstate = digitalRead(Left_Turn); //Continually look at the switch to see if its pressed
if (buttonstate == HIGH) //If the switch goes HIGH, act on it
{
turnLeft(); //new function called turnLeft
}
button_state = digitalRead(Right_Turn); //Continually look at the switch to see if its pressed
if (button_state == HIGH) //If the switch goes HIGH, act on it
{

turnRight(); //new function called turnRight

}
  
  if (digitalRead(PIN_TOGG) != patternButtonState)  { //the button state has changed

    if (patternButtonState == LOW) { //the button state must have just gone high
      patternButtonState = HIGH;  //record that button has just been pressed but do nothing for now, wait for release
    }
    else { //it was high, so the button must have just been released

      //record the fact that be button has now gone low ie. not pressed
      patternButtonState = LOW;

      switch (currentPattern) {

        case 1: //Pattern 1 has been running
          //set up pattern 2
          currentPattern = 2;
          red = 175;
          red2 = 20;
          incR = 1;
          incR2 = 1;
          delayTime = 5;
          break;

        case 2://Pattern 2 has been running
          //set up pattern 3
          currentPattern = 3;
          red = 175;
          red2 = 20;
          incR = 1;
          incR2 = 1;
          delayTime = 2;

        case 3://Pattern 3 has been running
          //set up pattern 4
          currentPattern = 4;
          red = 20;
          red2 = 20;
          incR = 1;
          incR2 = 1;
          delayTime = 1;

        case 4:
          //set up pattern 1
          currentPattern = 1;
          red = 20;
          red2 = 20;
          incR = 1;
          incR2 = 1;
          delayTime = 10;
          break;


      }
    }
  }
}

It really helps when you have the toggling switch plugged into pin 3 but set it to pin 2. The code is working with exception of the delay time on the patterns is not changing.

I tinkered with the code, and added a couple more cases. Now I have 7 in total but the funny thing is, it's only outputting 5?

digitalRead(PIN_TOGG);
  if (digitalRead(PIN_TOGG) != patternButtonState)  { //the button state has changed

    if (patternButtonState == LOW) { //the button state must have just gone high
      patternButtonState = HIGH;  //record that button has just been pressed but do nothing for now, wait for release
    }
    else { //it was high, so the button must have just been released

      //record the fact that be button has now gone low ie. not pressed
      patternButtonState = LOW;

      switch (currentPattern) {

case 1: //Pattern 1 has been running
          //set up pattern 2
          currentPattern = 2;
          red = 175;
          red2 = 175;
          incR = 1;
          incR2 = 1;
          delayTime = 5;
          break;

case 2://Pattern 2 has been running
          //set up pattern 3
          currentPattern = 3;
          red = 175;
          red2 = 175;
          incR = 1;
          incR2 = 1;
          delayTime = 1;

case 3://Pattern 3 has been running
          //set up pattern 4
          currentPattern = 4;
          red = 175;
          red2 = 20;
          incR = 1;
          incR2 = 1;
          delayTime = 10;

case 4://Pattern 4 has been running
          //set up pattern 5
          currentPattern = 5;
          red = 175;
          red2 = 20;
          incR = 1;
          incR2 = 1;
          delayTime = 5;
          break;
          
case 5://Pattern 5 has been running
          //set up pattern 6
          currentPattern = 6;
          red = 175;
          red2 = 20;
          incR = 1;
          incR2 = 1;
          delayTime = 1;
          break;
          
case 6://Pattern 6 has been running
          //set up pattern 7
          currentPattern = 7;
          red = 175;
          red2 = 175;
          incR = 0;
          incR2 = 0;
          delayTime = 0;
          break;
          
case 7:
          //set up pattern 1
          currentPattern = 1;
          red = 175;
          red2 = 175;
          incR = 1;
          incR2 = 1;
          delayTime = 10;
          break;
// Delay time: sets the time in milliseconds between loop iterations.
// Make this value large for slower transitions.
unsigned long delayTime = 10;

int currentPattern = 7;
int patternButtonState = HIGH;

// The initial values of each color.
int red = 175;
int red2 = 175;

// Indicates whether a color is incrementing (1) or decrementing (0).
int incR = 1;
int incR2 = 1;

You need a "break;" for each "case". There are 2 missing.

Ahhhh! That probably happened with copy and paste. I'll check it tonight when I get home. Thank you so much for all your help on this. You are awesome.

It WORKS!!! HOORAY!!!

Here's the working code if anybody wants it:

//////Bicycle Light System v1.0////////////

/////Author: Christopher Valentine 2014
/////Special Thanks to: PaulRB of the Arduino support forum!!!

////This is a full blown bicyle light system with 
////headlights, turn signals (front and back), 
////brakelights, and multi-function flashing tail lights
////Although this set up is designed for a bike,
////with the use of a wireless remote control it could 
////Also be used on a remote control car or other things


byte BRAKE_SWITCH = 8; //Set Pin 8 as Brake Switch
byte Right_Turn= 4; //Set Pin 4 as Switch
byte PIN_RED = 11;  //Right Rear Set Pin 11 as LED
byte PIN_FR = 7;  //Right Front Set Pin 7 as LED
byte Left_Turn = 5 ; //Set Pin 5 as Switch
byte PIN_RED2 = 10;  //Left Rear Set Pin 10 as LED
byte PIN_FL = 6;  //Left Front Set Pin 6 as LED
byte PIN_TOGG = 3; //Toggle Fades set Pin 3
boolean buttonstate; //Integer variable named buttonstate Left Turn Switch
boolean button_state; //Integer variable named button_state Right Turn Switch
boolean button__state; //Integer variable named button__state Brake Switch

// Delay time: sets the time in milliseconds between loop iterations.
// Make this value large for slower transitions.
unsigned long delayTime = 10;

int currentPattern = 7;
int patternButtonState = HIGH;

// The initial values of each color.
int red = 175;
int red2 = 175;

// Indicates whether a color is incrementing (1) or decrementing (0).
int incR = 1;
int incR2 = 1;

void setup()
{
  pinMode(PIN_TOGG, INPUT);
  pinMode(Left_Turn, INPUT);
  pinMode(PIN_RED2, OUTPUT);
  pinMode(PIN_FL, OUTPUT);
  pinMode(Right_Turn, INPUT);
  pinMode(PIN_RED, OUTPUT);
  pinMode(PIN_FR, OUTPUT);
  pinMode(BRAKE_SWITCH, INPUT);
}
 
void turnLeft()//turnLeft function 
{
analogWrite(PIN_FR, 255);
analogWrite(PIN_RED, 125); 
analogWrite(PIN_RED2, 125);
buttonstate = HIGH; //the micro the switch is now HIGH

while (buttonstate == HIGH) //While the switch is NOT pressed do the following
{

buttonstate = digitalRead(Left_Turn); //Continually look at the switch to see if its pressed
analogWrite(PIN_RED2, 255); //Set the Rear Left LED to maximum brightness
analogWrite(PIN_FL, 255); //Set the Front Left LED to maximum brightness
delay(100); 
analogWrite(PIN_RED2, 0); //turn the LED off for a blinking effect
analogWrite(PIN_FL, 0); //turn the LED off for a blinking effect
delay(100);

}
//Once the switch is pressed again, break out of the loop above and then break out of the function completely and go back to our main loop
buttonstate = LOW; //First we tell the micro the switch is now LOW
analogWrite(PIN_RED2, 0); //We turn the LED off before leaving our custom function
analogWrite(PIN_FL, 0); //We turn the LED off before leaving our custom function
}

void turnRight()//turnRight function 
{
analogWrite(PIN_FL, 255);
analogWrite(PIN_RED, 125); 
analogWrite(PIN_RED2, 125);
button_state = HIGH; //the micro the switch is now HIGH

while (button_state == HIGH) //While the switch is NOT pressed do the following
{
button_state = digitalRead(Right_Turn); //Continually look at the switch to see if its pressed
analogWrite(PIN_RED, 255); //Set the Rear Right LED to maximum brightness
analogWrite(PIN_FR, 255); //Set the Front Right LED to maximum brightness
delay(100); 
analogWrite(PIN_RED, 0); //turn the LED off for a blinking effect
analogWrite(PIN_FR, 0); //turn the LED off for a blinking effect
delay(100);
}
//Once the switch is pressed again, break out of the loop above and then break out of the function completely and go back to our main loop
button_state = LOW; //First we tell the micro the switch is now LOW
analogWrite(PIN_RED, 0); //We turn the LED off before leaving our custom function
analogWrite(PIN_FR, 0); //We turn the LED off before leaving our custom function
}

void brakelights()
{

analogWrite(PIN_FL, 255);
analogWrite(PIN_FR, 255);
button__state = HIGH; //the micro switch is now HIGH

while (button__state == HIGH) //While the switch is NOT pressed do the following
{
  button__state = digitalRead(BRAKE_SWITCH); //Continually look at the switch to see if its pressed
  analogWrite(PIN_RED, 255); //Set the Rear Right LED to maximum brightness
  analogWrite(PIN_RED2, 255); //Set the Rear Left LED to maximum brightness
  
}
//Once the switch is pressed again, break out of the loop above and then break out of the function completely and go back to our main loop
button_state = LOW; //First we tell the micro the switch is now LOW
analogWrite(PIN_RED, 125); //We turn the LED off before leaving our custom function
analogWrite(PIN_RED2, 125); //We turn the LED off before leaving our custom function
}

// Smoothly changes the color values
void transition()
{
  if (red >= 175)
    incR = 0;
  else if (red <= 20)
    incR = 1;
  if (red2 >= 175)
    incR2 = 0;
  else if (red2 <= 20)
    incR2 = 1;
  
  if (incR)
    red++;
  else
    red--;
  if(incR2)
    red2++;
  else
    red2--;
}

// Sets the output voltage on the LED pins.
void setColor()
{
  analogWrite(PIN_RED, red);
  analogWrite(PIN_RED2, red2);
}
 
 
void loop()
{
 analogWrite(PIN_FR, 255);
 analogWrite(PIN_FL, 255);
 transition();
 setColor();
 delay(delayTime);
  
 button__state = digitalRead(BRAKE_SWITCH); //Continually look at the switch to see if its pressed
if (button__state == HIGH) //If the switch goes HIGH, act on it
{
  brakelights(); //new function called brakelights
}
  
buttonstate = digitalRead(Left_Turn); //Continually look at the switch to see if its pressed
if (buttonstate == HIGH) //If the switch goes HIGH, act on it
{
turnLeft(); //new function called turnLeft
}
button_state = digitalRead(Right_Turn); //Continually look at the switch to see if its pressed
if (button_state == HIGH) //If the switch goes HIGH, act on it
{
turnRight(); //new function called turnRight
}

digitalRead(PIN_TOGG);
  if (digitalRead(PIN_TOGG) != patternButtonState)  { //the button state has changed

    if (patternButtonState == LOW) { //the button state must have just gone high
      patternButtonState = HIGH;  //record that button has just been pressed but do nothing for now, wait for release
    }
    else { //it was high, so the button must have just been released

      //record the fact that be button has now gone low ie. not pressed
      patternButtonState = LOW;

      switch (currentPattern) {

case 1: //Pattern 1 has been running
          //set up pattern 2
          currentPattern = 2;
          red = 175;
          red2 = 175;
          incR = 1;
          incR2 = 1;
          delayTime = 5;
          break;

case 2://Pattern 2 has been running
          //set up pattern 3
          currentPattern = 3;
          red = 175;
          red2 = 175;
          incR = 1;
          incR2 = 1;
          delayTime = 1;
          break;

case 3://Pattern 3 has been running
          //set up pattern 4
          currentPattern = 4;
          red = 175;
          red2 = 20;
          incR = 1;
          incR2 = 1;
          delayTime = 10;
          break;

case 4://Pattern 4 has been running
          //set up pattern 5
          currentPattern = 5;
          red = 175;
          red2 = 20;
          incR = 1;
          incR2 = 1;
          delayTime = 5;
          break;
          
case 5://Pattern 5 has been running
          //set up pattern 6
          currentPattern = 6;
          red = 175;
          red2 = 20;
          incR = 1;
          incR2 = 1;
          delayTime = 1;
          break;
          
case 6://Pattern 6 has been running
          //set up pattern 7
          currentPattern = 7;
          red = 175;
          red2 = 175;
          incR = 0;
          incR2 = 0;
          delayTime = 0;
          break;
          
case 7:
          //set up pattern 1
          currentPattern = 1;
          red = 175;
          red2 = 175;
          incR = 1;
          incR2 = 1;
          delayTime = 10;
          break;

      }
    }
  }
}

Well done HolidayV, you did it!

So does it now do everything you set out to do? Reading your first few posts, I thought there was more, for example two flash requences running in parallel, which would have meant taking out the delay() functions.

Paul

Yes, it all works now. Originally, I wanted to have the non-turning tail light to continue with it's flash sequence while the opposing tail light indicated the turn, but I changed it up so that it just lights solid.

HolidayV:
Yes, it all works now. Originally, I wanted to have the non-turning tail light to continue with it's flash sequence while the opposing tail light indicated the turn, but I changed it up so that it just lights solid.

Thought so. That small change made a big simplification to the sketch.

So what next? Are you going to build one for real? If so, an interesting challenge would be to run your sketch on an ATtiny84.

Paul

I'm just waiting on the rest of the parts to arrive in the mail. My first prototype will be on an arduino compatible pro mini. I'm using light strips on the front and back forks from strips that are 120 LEDs/meter. I've got a wireless controller coming for the switches and I stole the brake switch off a cheap bike light I got off ebay that clips to the brake line. I've got a 4 channel 12v relay board coming to drive the light strips. All in all, it will have 60 LEDs on the front and 54 on the back. I even have a 12v to 5v converter to charge my cell phone using the same 12v battery. I've never played with the ATtiny 84, only the 85, but now that I've looked at it, that would shrink my board down to practically nothing and probably cost even less. Thanks again!

Relays? They will work ok for your flashing turn lights, but not for your fading patterns on the brake lights. The fading uses pwm which is much too fast for mechanical relays to keep up with, and will quickly wear them out trying. You need transistors. Depending on the current needed, maybe just 4 x bc337 npn transistors or some logic level power fets like stp16nf06l.

Well, that sucks. I really didn't want to have to build a MOSFET board. Oh well. It'll take up less space. I guess I'll just find another use for the 4ch relay I ordered.

What is/will be the current draw of your led strips? Bc337 will be ok up to 800mA and they are tiny and cheap. 60 leds @ 20mA each might be only 200mA if they are arranged into groups of 3 in series for the 12V supply. An ATtiny84, 4 x BC337, a 78L05 and a few caps and resistors won't take up much space on a bit of stripboard or tripad board!

Car lights have one end at Ground.
They're on/off by interrupting +V to the lamp (not Ground.)

I guess it's a good thing this light set up is for a bicycle and not a car.

PaulRB:
Relays? They will work ok for your flashing turn lights, but not for your fading patterns on the brake lights. The fading uses pwm which is much too fast for mechanical relays to keep up with, and will quickly wear them out trying. You need transistors. Depending on the current needed, maybe just 4 x bc337 npn transistors or some logic level power fets like stp16nf06l.

I got the MOSFETs and they drive the strips just fine, but now I just realized that if the brake switch is pressed, the turn signal won't work simultaneously. It doesn't matter if the turn signal is turned on first because the rear LEDs are set to high when not flashing in the turn signal circuit, but if someone is riding the brake while approaching the turn, the signal doesn't flash. How can I fix this?

MAS3:
To solve this, you need to use a different approach.
First of all, dump the delay right away.

So dump the delays.
Your Arduino runs through loop very fast (at least hundreds of times per second), unless you are using blocking code like delay().
There are more blocking instructions, but delay() is the worst ever.
Study blink without delay, you can find that in your IDE examples.
If you use that technique, you will be able to use brake and keep blinking the turn indicator.

HolidayV:
I just realized that if the brake switch is pressed, the turn signal won't work simultaneously. It doesn't matter if the turn signal is turned on first because the rear LEDs are set to high when not flashing in the turn signal circuit, but if someone is riding the brake while approaching the turn, the signal doesn't flash. How can I fix this?

Can you see now why I was surprised when you said it was working? I said at the time I thought there was more to do.

Like MAS3 says, the delay() functions have to go, as will the while() loops. These will need to be replaced with more variables to record the current states of the various lights and the times that the last or next changes have to happen.

Think of it like this. You have 6 states:

  1. Normal, no buttons pressed, fading light pattern running
  2. Braking
  3. Left turn
  4. Left turn and braking
  5. Right turn
  6. Right turn and braking

Make a new variable to hold that state, or determine it from the button states.

HolidayV:

[quote author=Runaway Pancake link=topic=235787.msg1707357#msg1707357 date=1399139091]
Car lights have one end at Ground.
They're on/off by interrupting +V to the lamp (not Ground.)

I guess it's a good thing this light set up is for a bicycle and not a car.
[/quote]

If Frame == Ground then that's one less wire to run. Just sayin'.

> > > Or you could make frame == +V