Go Down

Topic: Multiple LED's on separate pins, switches and functions - need guidance (Read 7876 times) previous topic - next topic

HolidayV

Let me just start by saying, I'm a noob. I am trying to understand arduino code but my brain just isn't wrapping around it very fast.
Here's the scenario :
4 separate LED's - we'll call them L1, L2, L3, and L4.
4 separate switches - we'll call them S1, S2, S3, and S4
I need L1 and L2 to flash in unison in 3 or 4 TBD different sequences to be set by toggling using a momentary switch (S1). While these are flashing in any of the above mentioned sequences, I need L3 and L4 lit to HIGH.
If I press S2, I need L1 and L2 to stop performing their flashing sequence and immediately light to HIGH, and then resume the flashing sequence upon release of S2.
If I press S3, I need L1 to stop it's flashing sequence and begin a different flashing sequence in unison with L3. Upon release of S3, L1 will return to the unison sequence with L2 and L3 will return to HIGH.
If I press S4, I need L2 to stop it's flashing sequence and begin a different flashing sequence in unison with L4. Upon release of S4, L2 will return to the unison sequence with L1 and L4 will return to HIGH.

I have already written a program that fades L1 and L2 up and down and turns them to HIGH when S1 is pressed, while L3 and L4 remain in HIGH state. However, the addition of the S1 button press messes with the code and changes the timing of the fade and if I make the fade timing too short, the HIGH state of L1 and L2 flicker while S1 is pressed.

Any help would be appreciated.

HolidayV

Here's what my NOOB code looks like so far...

Code: [Select]

// Delay time: sets the time in milliseconds between loop iterations.
// Make this value large for slower transitions.
#define DELAY_TIME 0

// Maximum Brightness: the maximum level the pins will reach.
#define MAX_BRIGHT 255

// The pins which each color value is output to.
#define PIN_RED 9
#define PIN_RED2 10
#define PIN_FR 7
#define PIN_FL 6


//Switch Pins
#define BRAKE_SWITCH 8

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

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

// 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);
  analogWrite(PIN_FR, white);
  analogWrite(PIN_FL, white);
 

}


void setup()
{
pinMode(BRAKE_SWITCH, INPUT);
pinMode(PIN_RED, OUTPUT);
pinMode(PIN_RED2, OUTPUT);
}

void loop()
{
  brakelights();
  transition();
  setColor();

}

void brakelights()
{

if (digitalRead(BRAKE_SWITCH) == HIGH)

analogWrite(PIN_RED, MAX_BRIGHT);



if (digitalRead(BRAKE_SWITCH) == HIGH)

analogWrite(PIN_RED2, MAX_BRIGHT);




delay (5);

}


PaulRB

Hi HolidayV,

Well done on that description of your requirements. Much better than most noobs. But there are still some missing details. As an example, while S4 is pressed, what is L1 doing? Do we have two separate flashing sequences running in parallel? Also your sketch is doing stuff you did not describe in your first post, like fading the leds. Is that really what you wanted, or just what some code you copied already did?

Can I suggest an approach?

Starting from a completely blank sketch each time, write just enough code to get the leds to light up or flash in  just one of the sequences you want. Repeat this for each sequence. Don't worry for the moment that they are in separate sketches, or how you will detect button presses or move between the sketches.

Then post all the sketches on this thread and we can then move on to the next step of merging them.

Paul

MAS3

Hi and welcome.

First of all, you are describing your problem using different names for the variables (Lx, Sx) than the ones used in your sketch (RED, RED2, BRAKE_SWITCH).
This doesn't help in tackling your problem.

You have decided to put each step in its own function and are calling all functions in loop().
I'm assuming S1 is your BRAKE switch.
The function brakelights checks that switch, and sets one (set of) LED(s) to maximum value.
After that you are blocking any operation by doing a delay for 5 milliseconds, which is what messes with your timing.
If the switch isn't on, this part is skipped and so is the blocking part.

When you're done doing this, you go to the function setColor, and probably set PIN_RED2 to some other value.

To solve this, you need to use a different approach.
First of all, dump the delay right away.
Only set all LEDs once, during setColor, do not interfere with that at some other time.
At this moment, you seem to be at the same PWM level for both red LEDs all the time, except while braking.
To have it work correctly, keep your counters running all the time, but have the LED brightness dependent on the brake switch.
You need to have an extra variable, that will make you decide RED2 will be set to max value, or to the counter's value during setColor.
It is up to you in what function you will make this decision and set the value of red2.

(Do you see the importance of choosing good variable names here ?)
Have a look at "blink without delay".
Did you connect the grounds ?
Je kunt hier ook in het Nederlands terecht: http://arduino.cc/forum/index.php/board,77.0.html

HolidayV


Hi HolidayV,

Well done on that description of your requirements. Much better than most noobs. But there are still some missing details. As an example, while S4 is pressed, what is L1 doing? Do we have two separate flashing sequences running in parallel? Also your sketch is doing stuff you did not describe in your first post, like fading the leds. Is that really what you wanted, or just what some code you copied already did?

Can I suggest an approach?

Starting from a completely blank sketch each time, write just enough code to get the leds to light up or flash in  just one of the sequences you want. Repeat this for each sequence. Don't worry for the moment that they are in separate sketches, or how you will detect button presses or move between the sketches.

Then post all the sketches on this thread and we can then move on to the next step of merging them.

Paul



While S4 is pressed, L1 is continuing with whatever it's existing flashing sequence is.  The fading effect is the first flashing sequence that I did. It's the first of several selectable (by toggling with S1). I will write the separate sketches and post them. Thank You.

HolidayV


Hi and welcome.

First of all, you are describing your problem using different names for the variables (Lx, Sx) than the ones used in your sketch (RED, RED2, BRAKE_SWITCH).
This doesn't help in tackling your problem.

You have decided to put each step in its own function and are calling all functions in loop().
I'm assuming S1 is your BRAKE switch.
The function brakelights checks that switch, and sets one (set of) LED(s) to maximum value.
After that you are blocking any operation by doing a delay for 5 milliseconds, which is what messes with your timing.
If the switch isn't on, this part is skipped and so is the blocking part.

When you're done doing this, you go to the function setColor, and probably set PIN_RED2 to some other value.

To solve this, you need to use a different approach.
First of all, dump the delay right away.
Only set all LEDs once, during setColor, do not interfere with that at some other time.
At this moment, you seem to be at the same PWM level for both red LEDs all the time, except while braking.
To have it work correctly, keep your counters running all the time, but have the LED brightness dependent on the brake switch.
You need to have an extra variable, that will make you decide RED2 will be set to max value, or to the counter's value during setColor.
It is up to you in what function you will make this decision and set the value of red2.

(Do you see the importance of choosing good variable names here ?)


I apologize for the inconsistencies in my variables. I was at work when I made the post, and did not have my sketch available to post. This code is for bicycle lights. The tail lights will flash in selectable patterns while the front lights stay on high. I have already designed a hardware based system, but I am trying to eliminate the separate lights for turn signals by using the arduino to flash the left and right front and tail lights instead.

PaulRB

So 2 different and simultaneous flashing sequences then. Tricky. But can be done. Definitely a case for the "blink without delay" technique. 3 things at once: 2 flash sequences plus checking for button presses.

HolidayV

OK, I've cleaned it up and set up separate sketches.
Task #1. Put the following 4 sketches together, toggled by a switch on pin TBD. While PIN_FL 6 and PIN_FR 7 are lit at (255)
Code: [Select]
//Fading Tail Lights


// Delay time: sets the time in milliseconds between loop iterations.
// Make this value large for slower transitions.
#define DELAY_TIME 10

// The pins which each color value is output to.
#define PIN_RED 9
#define PIN_RED2 10

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

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

// 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 setup()
{
 // Do nothing.
}

void loop()
{
 transition();
 setColor();
 delay(DELAY_TIME);
}


Code: [Select]
//Fading Tail Lights 2


// Delay time: sets the time in milliseconds between loop iterations.
// Make this value large for slower transitions.
#define DELAY_TIME 5

// The pins which each color value is output to.
#define PIN_RED 9
#define PIN_RED2 10

// 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;

// 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 setup()
{
 // Do nothing.
}

void loop()
{
 transition();
 setColor();
 delay(DELAY_TIME);
}


Code: [Select]
//Fading Tail Lights 3


// Delay time: sets the time in milliseconds between loop iterations.
// Make this value large for slower transitions.
#define DELAY_TIME 2

// The pins which each color value is output to.
#define PIN_RED 9
#define PIN_RED2 10

// 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;

// 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 setup()
{
 // Do nothing.
}

void loop()
{
 transition();
 setColor();
 delay(DELAY_TIME);
}


Code: [Select]
//Fading Tail Lights 4


// Delay time: sets the time in milliseconds between loop iterations.
// Make this value large for slower transitions.
#define DELAY_TIME 1

// The pins which each color value is output to.
#define PIN_RED 9
#define PIN_RED2 10

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

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

// 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 setup()
{
 // Do nothing.
}

void loop()
{
 transition();
 setColor();
 delay(DELAY_TIME);
}


PaulRB


HolidayV

Task #2. Brake Lights override the above selected sketches when button is pressed, while FR and FL remain lit, and when button is released, return to the above toggled sketch.

Code: [Select]
//////////////////////Brake Lights//////////////////

/////////////LEDs controlled on 2 separate pins by one switch////////////////

// The pins which each color value is output to.
#define PIN_RED 9
#define PIN_RED2 10


//Switch Pins
#define BRAKE_SWITCH 8

void setup()
{
 pinMode(BRAKE_SWITCH, INPUT);
 pinMode(PIN_RED, OUTPUT);
 pinMode(PIN_RED2, OUTPUT);
}


void loop()
{
 brakelights();

}
/////////////////Reads the switch: if the switch is pressed, /////////////////
/////////////////the lights turn on, if the switch is not ////////////////////
////////////////pressed, the lights are off /////////////////////////////////
void brakelights()
{

 if (digitalRead(BRAKE_SWITCH) == HIGH)

   digitalWrite(PIN_RED, HIGH);

 else (digitalRead(BRAKE_SWITCH) == LOW);
 
digitalWrite(PIN_RED, LOW);

 if (digitalRead(BRAKE_SWITCH) == HIGH)

 digitalWrite(PIN_RED2, HIGH);

 else (digitalRead(BRAKE_SWITCH) == LOW);

 digitalWrite(PIN_RED2, LOW);
}


HolidayV

Task #3. Left and Right turn signals ONLY override the LEDs corresponding with that sketch. If FR and RED are in the turn sketch, then FL remains lit and RED2 continues with it's toggled sketch. (I'm so bad at this that I couldn't even get the two combined into one sketch):

Code: [Select]
/////////////Left Turn Signals/////////////


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
boolean buttonstate; //Integer variable named buttonstate

void setup()
{
  pinMode(Left_Turn, INPUT);
  pinMode(PIN_RED2, OUTPUT);
  pinMode(PIN_FL, OUTPUT);

}

void loop()
{
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
}
}

void turnLeft()//turnLeft function
{
buttonstate = HIGH; //the micro the switch is now HIGH
delay(200);
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 Right LED to maximum brightness
analogWrite(PIN_FL, 255); //Set the Front Right LED to maximum brightness
delay(200);
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(200);
}
//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
delay(200);
}


Code: [Select]
/////////////Right Turn Signals/////////////


byte Right_Turn= 4 ; //Set Pin 4 as Switch
byte PIN_RED = 9;  //Right Rear Set Pin 9 as LED
byte PIN_FR = 7;  //Right Front Set Pin 7 as LED
boolean buttonstate; //Integer variable named buttonstate

void setup()
{
  pinMode(Right_Turn, INPUT);
  pinMode(PIN_RED, OUTPUT);
  pinMode(PIN_FR, OUTPUT);

}

void loop()
{
buttonstate = digitalRead(Right_Turn); //Continually look at the switch to see if its pressed
if (buttonstate == HIGH) //If the switch goes HIGH, act on it
{
turnRight(); //new function called turnRight
}
}

void turnRight()//turnRight function
{
buttonstate = HIGH; //the micro the switch is now HIGH
delay(200);
while (buttonstate == HIGH) //While the switch is NOT pressed do the following
{
buttonstate = 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(200);
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(200);
}
//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_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
delay(200);
}

HolidayV



Code: [Select]
void setup()
{
 // Do nothing.
}


Really? Shouldn't you at least set some pins as outputs?


I'll be honest, I found this code originally designed for RGB's and modified it to work with two Red's and that's how the original sketch was written. I thought it was a little odd myself too, but it worked, so I didn't try to fix it.

PaulRB


Code: [Select]
// 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--;
}




Minor tip: if you used values of 1 and -1 instead of 0 and 1 for incR etc, you can simplify your code a little, e.g.:
Code: [Select]
// Smoothly changes the color values
void transition()
{
 if (red >= 175) || (red <= 20)
   incR = -incR;
 if (red2 >= 175) || (red2 <= 20)
   incR2 = -incR2;
 
 red += incR;
 red2 += incR2;
}

PaulRB


I thought it was a little odd myself too, but it worked, so I didn't try to fix it.


I guess analogWrite() must set the pins as output if they weren't already.

PaulRB


Task #1. Put the following 4 sketches together, toggled by a switch on pin TBD.


So is the only difference between these 4 sketches the delay values and the initial values and directions for the 2 red leds?


Task #3. Left and Right turn signals ONLY override the LEDs corresponding with that sketch.


And the only difference between these 2 sketches is the left vs right difference?

I like how you have broken the problem down. I suggest tackling merging the sketches in tasks #1 & 3 first. This should leave you with only 3 sketches to merge at the end.

If done correctly, that final merge should be really easy. Before that comes the more difficult task: Removing all the delay() commands from your 3 sketches! Read the "blink without delay" example, then have a go at just one of your 3 sketches. When that works without delays, work on the other two.

Go Up