Trying to translate this to arduino

Two parts within this project:

  1. I've got 14 blue LEDs that I want to repeatedly "fill up" like a bar graph.

  2. I have 4 red LEDs that I want to essentially turn on and off consecutively, as seen in the video.

The pot to adjust the speed is unnecessary for me, at this time.

So I've been able to, in two separate sketches, achieve each of these things individual by simply using the most basic programming, setting each LED to high and low, but of course that doesn't really allow me to put them together.

I'm an absolute noob at arduino, and programming in general, and I've been told that the best way of achieving this would be to use two separate for loops nested inside of another loop.

So I'm taking baby steps to at least see if I can get the two for loops functioning individually, starting with the 'bar graph'. I started by doing a few lessons using the "knightrider" lights example, and I can get that working the way it's supposed to. I can add code to change the speed of the chase, add lights to extend the travel length, etc. So from there, I modified the sketch:

I took out the for loop that causes the chaser light to 'bounce back and forth", and now it only travels in one direction, repeatedly.

From there, I then attempted to modify the code in such a way that each previous light in the sequence actually stays on instead of only one light being on at a time. After doing this, the blue LEDs now behave like a bar graph. That is, they 'fill up'. The issue that I'm running into is that I'm trying to figure out how to get that to repeat indefinitely. Because at the moment, after the code is uploaded to the mega, the bar graph 'fills up' but then stops. No repeat.

In the grand scheme of things, I wanted it to behave like this:

  1. The 14 blue LEDs (pins 2-15) each turn on consecutively and stay on until the last blue LED (pin 15) is activated. They then turn off and immediately repeat the cycle indefinitely.

  2. Each time the blue LEDs loop back around and start over, I was hoping to use the first blue LED (pin 2) as a trigger to turn on (and off) each of the 4 red LEDS (we'll call them A,B,C,D on pins 16, 17, 18, and 19). In other words:

-Pin 2 activates the first LED in the bar graph, which also activates the LED A at pin 16.
-Pin 16 stays on for the duration of the 2-15 loop/fill up. Once the bar graph fills/illuminates fully, it turns off and begins the loop again.
-Pin 2 is activated a second time, once the loop begins, this time turning off LED A, and activating pin 17 (LED B). The bar graph fills up, and turns off.
-Pin 2 is activated a third time, starting the loop, turning off LED B, activating pin 18 (C). Bar graph fills up, and turns off.
-Same thing happens one more time. This time, pin 2 turns off pin 18, and activates pin 19. Bar graph fills up and turns off.

And I want that whole mess to repeat indefinitely, until I power it off.

Does that make sense?

I understand how a for loop works in the example of the chaser/knightrider. It's just transposing those concepts to fit what I'm trying to achieve. I'm too right-brained for my own good, it seems.

Can anyone shed some light on this? I could post my very remedial code if you need to see it.

Hi knightsoftheround

From there, I then attempted to modify the code in such a way that each previous light in the sequence actually stays on instead of only one light being on at a time. After doing this, the blue LEDs now behave like a bar graph. That is, they 'fill up'. The issue that I'm running into is that I'm trying to figure out how to get that to repeat indefinitely. Because at the moment, after the code is uploaded to the mega, the bar graph 'fills up' but then stops. No repeat.

To break things down into smaller problems, could you post the program you had at this stage? First thing to fix is the "no repeat" problem. (Use code tags when you post - the '#' button above the row of smileys).

I was hoping to use the first blue LED (pin 2) as a trigger to turn on (and off) each of the 4 red LEDS

It may confuse things to think of it as being pin 2 which controls the red LEDs. Pin 2 is an output that changes in response to your program. You are aiming for a particular event (switching on the first bar chart LED) to also move to the next red LED. It may be that two for loops is a good solution to this.

Question for you. Do you need the Arduino to do anything else while the blue and red LEDs are being animated? Does it need to respond to switches or other inputs, for example?

Regards

Ray

Post the datasheet or a link for the leds so we know how much current they draw.
How come your not using a TLC5940 or a 74HC595 or the high current version ?

SEE ATTACHED DATASHEETS.

TPIC6C595.pdf (971 KB)

74HC_HCT595.pdf (367 KB)

tlc5940.pdf (1.3 MB)

TLC5940_USER_GUIDE.pdf (1.25 MB)

Thanks for the response! To answer your last question, at the moment, I don't need it to do anything else. This is the beginning of a larger project, and I'm hoping to take it in stages beginning with the most basic behaviors, and working my way to the more complex stuff as I become accustomed to the environment, the coding, the components, etc.

So in breaking this down into portions, this is what I've managed with the bar graph:

int timer = 55;           // The higher the number, the slower the timing.

void setup() {
  // use a for loop to initialize each pin as an output:
  for (int thisPin = 2; thisPin < 16; thisPin++) {
    pinMode(thisPin, OUTPUT);
  }
}

void loop() {
  // loop from the lowest pin to the highest:
  for (int thisPin = 2; thisPin < 16; thisPin++) {
    // turn the pin on:
    digitalWrite(thisPin, HIGH);
    delay(timer);
    // turn the pin off:
    digitalWrite(thisPin, LOW);
  }

  // loop from the highest pin to the lowest:
  for (int thisPin = 16; thisPin >= 2; thisPin--) {
    // turn the pin on:
    digitalWrite(thisPin, HIGH);
    delay(timer);
    // turn the pin off:
    digitalWrite(thisPin, LOW);
  }
}

This gives me a nice little knightrider chaser that runs the span of pins 2 to 15. I should note that the only way I could get the LED at pin 15 to participate in the chase was by setting the if statement in the for loop to thisPin <16. Otherwise, it would only chase between pins 2 and 14.

From there, I tried to modify the code to prevent it from running backwards. I did this by removing the second for loop. Shown here:

int timer = 55;           // The higher the number, the slower the timing.

void setup() {
  // use a for loop to initialize each pin as an output:
  for (int thisPin = 2; thisPin < 16; thisPin++) {
    pinMode(thisPin, OUTPUT);
  }
}

void loop() {
  // loop from the lowest pin to the highest:
  for (int thisPin = 2; thisPin < 16; thisPin++) {
    // turn the pin on:
    digitalWrite(thisPin, HIGH);
    delay(timer);
    // turn the pin off:
    digitalWrite(thisPin, LOW);
  }
}

So now, it chases in the same direction, indefinitely. Getting there!

The next thing I attempted was to get each light to stay on as the chase progressed, thus giving the appearance of a bar graph filling. I was kind of shooting from the hip, at this point. In my mind, I thought, "Well, if I simply remove the digitalWrite low from the loop, they should stay on. And they certainly do that. But they remain on, and the loop doesn't continue beyond that point. Here's the code for that:

int timer = 55;           // The higher the number, the slower the timing.

void setup() {
  // use a for loop to initialize each pin as an output:
  for (int thisPin = 2; thisPin < 16; thisPin++) {
    pinMode(thisPin, OUTPUT);
  }
}

void loop() {
  // loop from the lowest pin to the highest:
  for (int thisPin = 2; thisPin < 16; thisPin++) {
    // turn the pin on:
    digitalWrite(thisPin, HIGH);
    delay(timer);

  }
}

I thought that maybe the delay was preventing it from starting it over. But if I remove that, then the bar doesn't fill up at all. It just all illuminates simultaneously and remains as such.

raschemmel:
Post the datasheet or a link for the leds so we know how much current they draw.
How come your not using a TLC5940 or a 74HC595 or the high current version ?

SEE ATTACHED DATASHEETS.

I do not yet have the knowledge or skill set to answer this question. I hope that doesn't render me completely unfit for Arduino, hahaha.

void loop() {
  // loop from the lowest pin to the highest:
  for (int thisPin = 2; thisPin < 16; thisPin++) {
    // turn the pin on:
    digitalWrite(thisPin, HIGH);
    delay(timer);
  }
}

The second time round loop(), the LEDs are already on, so turning them on seems to do nothing :slight_smile:

Add this after delay(timer);

 for (int thisPin = 2; thisPin < 16; thisPin++) {
    // turn the pins off:
    digitalWrite(thisPin, LOW);
  }

This is the beginning of a larger project,

As your project grows, using delay() will cause you real problems. When you call delay, nothing else can happen in the program until the delay period ends. This is known as "blocking". It will make it harder to add the other functionality you need.

Once you get the blue LEDs working, I suggest you look at the BlinkWithoutDelay example program. The technique in that program will let you make things happen at defined intervals without stopping everything else you want to happen at the same time.

My suggestion would be for you to convert the blue LED program to blink without delay approach. When that's working, add code for the red LEDs.

Some blink without delay and program design resources:

http://forum.arduino.cc/index.php?topic=223286.0
http://forum.arduino.cc/index.php?topic=261445.0

Post the datasheet or a link for the leds so we know how much current they draw.
How come your not using a TLC5940 or a 74HC595 or the high current version ?

SEE ATTACHED DATASHEETS.

I do not yet have the knowledge or skill set to answer this question. I hope that doesn't render me completely unfit for Arduino, hahaha.

How about telling us WHERE you got the leds. If you can't post the link that means you didn't buy them online or you forgot where you bought them ?

I should note that the only way I could get the LED at pin 15 to participate in the chase was by setting the if statement in the for loop to thisPin <16.

That's exactly how it is supposed to work.

The next thing I attempted was to get each light to stay on as the chase progressed, thus giving the appearance of a bar graph filling.

]

Software is not my specialty (I a hardware guy) but I think you need to use flags for this part and set them where you want that led stay on and clear them when you turn it to go off. Or rather I should say, you should have two flags , one for sequence UPDIR and one for sequence DOWNDIR. Set the UPDIR at the beginning of the part where you want them to stay on
and clear them after the UPDIR portion completes and then set the DOWNDIR and clear the UPDIR .
Have a conditional before the turn off code that only turns it off if DOWNDIR ==1 OR UPDIR ==0.

Hackscribble:

void loop() {

// loop from the lowest pin to the highest:
 for (int thisPin = 2; thisPin < 16; thisPin++) {
   // turn the pin on:
   digitalWrite(thisPin, HIGH);
   delay(timer);
 }
}




The second time round `loop()`, the LEDs are already on, so turning them on seems to do nothing :)

Add this after `delay(timer);`



for (int thisPin = 2; thisPin < 16; thisPin++) {
   // turn the pins off:
   digitalWrite(thisPin, LOW);
 }

This just reverts the behavior back to when I first modified the for loop to only move in one direction. i.e. a single light runs at a time, in the same direction, indefinitely. I know how to do this, it's just not what I'm trying to do. I'm trying to get it to progressively 'fill' from pin 2 to pin 15 with each prior LED staying on, as if a bar graph or meter was filling from bottom to top. After it fills to the top, I want it to start over again from pin 2.

Example, here: Homebrew Proton Pack Lights - YouTube

This is essentially what I'm trying to achieve on the breadboard at the moment. But just with the blue LEDs.

Bad explanation on my part. I should have said "add this after the } after delay(timer)". Try this ...

void loop() 
{
  // Turn on each LED with delay after each one
  for (int thisPin = 2; thisPin < 16; thisPin++)
  {
    digitalWrite(thisPin, HIGH);
    delay(timer);
  }
  // Turn off all LEDs
  for (int thisPin = 2; thisPin < 16; thisPin++) 
  {
    digitalWrite(thisPin, LOW);
  }
}

Oh man, we're getting close! :slight_smile:

I'm gonna sit here and digest this code for a minute, and make sense of it.

I notice, now, that pin 2 stays on the entire time. DON'T TELL ME. I'm gonna see if I can figure out how to get it to shut off as well, on my own. I'll let you know if I throw in the towel.

You guys rule. I'm grateful for such a supportive community.

Update: So I managed to get pin 2 to turn off in the sequence as well by originally designating 'thisPin' as 1 instead of 2. A previous person told me to avoid using pins 1 and 0, at least for this project. Should I be concerned, here? Right now, it's basically doing exactly what I want it to do. And I'm ecstatic.

Now I move on to the 4 blinked red LEDs.

So I managed to get pin 2 to turn off in the sequence as well by originally designating 'thisPin' as 1 instead of 2.

That might be OK but it's safer not to write to a pin that is being used for something else.

The LED on pin 2 appears never to go off (in your previous code) because it is turned off in the for loop at the end of loop(). When the Arduino gets to the end of loop(), it goes immediately back to the start of loop() and executes the code there. That code turns pin 2 on. So the pin is only off for microseconds.

So maybe I should just bump them all forward a pin, so it goes from pin 3 to pin 16?

I would add a delay after the second for loop. All the pins including 2 will be visibly off before they start to go on again.

When you say second for loop, are you referring to the one that will control the 4 red LEDs?

No, the second of your current two for loops. The first one turns each red LED on and pauses after each one. The second for loop turns all the LEDs off. I was suggesting a delay immediately after (not in) that second loop.