Page 1 of 1
Forum

Welcome to the Tweaking4All community forums!
When participating, please keep the Forum Rules in mind!

Topics for particular software or systems: Start your topic link with the name of the application or system.
For example “MacOS X – Your question“, or “MS Word – Your Tip or Trick“.

Please note that switching to another language when reading a post will not bring you to the same post, in Dutch, as there is no translation for that post!



Assistance request ...
 
Share:
Notifications
Clear all

[Solved] Assistance request with Arduino LED sketch

19 Posts
3 Users
1 Reactions
7,213 Views
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2741
Topic starter  

This is a request placed in the comment of one of the articles.
To keep things clean, I've moved it into the forum.
Original comment: link.


Hello

I really appreciate the amount of work you put into creating this site. it has lots of useful information.

could you please kindly look at my sketch and tell me if you find any issue with it.

it is for running leds from side to center with white color.

I have been told the left side is moving faster than right.I appreciate if you could take a look and tell me how to fix it?

here is my code (cleanup):

#include “FastLED.h”

#define NUM_LEDS 12
#define PIN 7

CRGB leds[NUM_LEDS];

void setup() {
FastLED.addLeds < WS2812, PIN, GRB > (leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
}

// REPLACE FROM HERE

void loop() {
// colorWipe(0x00,0xff,0x00, 50);
// colorWipe(0x00,0x00,0xff, 50);
// colorWipe(0xff,0x00,0x00, 50);
// colorWipe(0x0f,0xff,0x0f, 50);
// colorWipe(0,255,50, 50);
// colorWipe(0xff,0x24,0xf8, 50);

colorWipe(0xe9, 0xff, 0x21, 50);
colorWipe(0, 255, 255, 255);

// colorWipe(0x1f,0x0f,0xff, 50);
// colorWipe(0x12,0xff,0x88, 50);
// colorWipe(0xff,0xff,0xff, 50);
}

void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {
for (int i = 0; i < (NUM_LEDS / 2) + 1; i++) {
setPixel(i, red, red, red);
setPixel(NUM_LEDS– i, red, red, red);
showStrip();
delay(150);
}

setAll(0x00, 0x00, 0x00);
}

// REPLACE TO HERE

void showStrip() {
#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strip.show();
#endif

#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
FastLED.show();
#endif
}

void setPixel(int Pixel, byte red, byte green, byte blue) {

#ifdef ADAFRUIT_NEOPIXEL_H
// NeoPixel
strip.setPixelColor(Pixel, strip.Color(red, green, blue));
#endif

#ifndef ADAFRUIT_NEOPIXEL_H
// FastLED
leds[Pixel].r = red;
leds[Pixel].g = green;
leds[Pixel].b = blue;
#endif
}

void setAll(byte red, byte green, byte blue) {
for (int i = 0; i < NUM_LEDS; i++) {
setPixel(i, red, green, blue);
}
showStrip();
}

   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2741
Topic starter  
Posted by: @hans

void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {
for (int i = 0; i < (NUM_LEDS / 2) + 1; i++) {
setPixel(i, red, red, red);
setPixel(NUM_LEDS– i, red, red, red);
showStrip();
delay(150);
}

setAll(0x00, 0x00, 0x00);
}

Considering that the code is relying on a loop, where both left and right are set at the same time, I honestly wouldn't know why left would be faster than right.
What can happen though is that the perception is like that since LEDs 0 to NUM_LEDS are turned on one at a time.
This is because of how the LED strips work - in sequence.

So in the code all "data" for the strip is set, then calling ShowStrip is actually pushing that "data" to the strip, starting with the first LED.
Maybe this is what they are seeing as left being faster than right?


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2741
Topic starter  

p.s. doing some testing and cleaned up your code a little:

#include "FastLED.h"

#define NUM_LEDS 12
#define PIN 7

CRGB leds[NUM_LEDS];

void setup() {
FastLED.addLeds<WS2812, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
}

void loop() {
colorWipe(0xe9, 0xe9, 0xe9, 150);
colorWipe(0x00, 0x00, 0x00, 150);
}

void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {

FastLED.clear();

for (int i = 0; i <= (NUM_LEDS / 2); i++) {
leds[i] = CRGB(red, green, blue);
leds[NUM_LEDS-i] = CRGB(red, green, blue);
FastLED.show();
delay(SpeedDelay);
}

FastLED.clear(); // alternative: fill_solid(leds, NUM_LEDS, CRGB(0,0,0));
FastLED.show();
}

In this code, I removed all generic functions and made it just for FastLED (since you're using that library).

For reference why left may look faster than right:

WS2812 strips are slow for writing data, with a data rate of just 800khz, it takes 30µs to write out a single led's worth of data.

Link: https://github.com/FastLED/FastLED/wiki/Parallel-Output

 

If you're looking for a way to "fix" this, then one approach could be this:

  1. Cut the strip in 2 pieces, each with 6 LEDs.
  2. Connect from both strip in parallel.
    Eg. the data pin of both strips should go to pin 7.
    +5 and GND connected as before, now for both strips.
  3. Install the 2 strips mirrored, so with the "end" of the strip towards each other.
    So something like this:
    Strip1:           Strip2:
    [0 1 2 3 4 5] [5 4 3 2 1 0]

Now both strips will do exactly the same thing, at the same time.
You'll need to modify your code to accommodate that:

#include "FastLED.h"

#define NUM_LEDS 6 // we only have 6 leds per side now
#define PIN 7

CRGB leds[NUM_LEDS];

void setup() {
FastLED.addLeds<WS2812, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
}

void loop() {
colorWipe(0xe9, 0xe9, 0xe9, 150);
colorWipe(0x00, 0x00, 0x00, 150);
}

void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {

FastLED.clear();

for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = CRGB(red, green, blue); // removed the "mirror" leds
FastLED.show();
delay(SpeedDelay);
}

FastLED.clear(); // alternative: fill_solid(leds, NUM_LEDS, CRGB(0,0,0));
FastLED.show();
}

Note: I have not tested this, since I didn't want to cut my LED strip in small pieces


   
ReplyQuote
(@saeidans)
Active Member
Joined: 4 years ago
Posts: 8
 

@hans Wow  this is really quick turn around. thank you so much for all you did for me.

I tried the new code with 12 LED and it still shows the issue with left and right led. the on

your suggestion of splitting LED strip into 2 group of 6 in parallel is good idea too. on second thought I was thinking if we could fix this issue in the code buy applying some delay to LED on the left so they can wait until the ones on the right turn on.other word give a delay of 30 micro sec to leds on the left before they start working.

is it possible?

 

thanks

 


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2741
Topic starter  

You're welcome - I had some time on my hands 😊 

You will not able to fix this in code.

Keep in mind: each of the white little squares on the strip contain a controller, and 3 LEDs (one for red, green and blue).

When all the data is send to the strip, data for all 12 leds will arrive at #1.
The controller of #1 will remove the first data block and set the the 3 leds of that LED block, since they were intended for #1 anyway.
After that controller #1 passes the remaining 11 data blocks to the 2nd led block.

The led controller of #2 will do the same thing: remove the first data block, set the leds, and pass on the remaining data (10 data blocks) and pass it on to #3, etc.

So the speed in which this happens, is your limiting factor. So this part is something we cannot really influence that much.

Now when putting 2 smaller strips in parallel, you'd actually get the exact same speed (theoretically anyway).


   
ReplyQuote
(@saeidans)
Active Member
Joined: 4 years ago
Posts: 8
 

@hans understood

thanks again


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2741
Topic starter  

You're welcome! 👍 


   
ReplyQuote
(@saeidans)
Active Member
Joined: 4 years ago
Posts: 8
 

@hans

 

I was able to fix it by changing the code in the loop like this

 

leds[i]=leds[NUM_LEDS-i-1] = CRGB(red, green, blue);

 

both sides are now in sync

 


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2741
Topic starter  

Hmm, that would be strange ... glad it worked of course, but strange ...
The LEDs are not yet actually set to this new value when you assign it to the leds array.

The "leds" is an array of colors, not assigned to anything.
When calling FastLED.show, only then the values in the array will be send to the LED strip, in sequence.

So filling the array either way should not make a difference. 😳 


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2741
Topic starter  

Oh wait,... I see where things went sideways,...

 

In my code I made a calculation mistake in this section:

leds[i]          = CRGB(red, green, blue);
leds[NUM_LEDS-i] = CRGB(red, green, blue);

See, the leds are counted as such (0,1,2,3,4,5,6): 

0 and 12 (12-0 = 12, which is 1 too many)
1 and 11 (12-1)
2 and 10 (12-2)
3 and 9 (12-3)
4 and 8 (12-4)
5 and 7 (12-5)
6 and 6 (12-6)

This however should have been (0,1,2,3,4,5):

0 and 11 (to get 11: 12-1)
1 and 10 (12-2)
2 and 9 (12-3)
3 and 8 (12-4)
4 and 7 (12-5)
5 and 6 (12-6)

So the counter went to far as well both sides counted out of pace.

 👍  Your solution fixed that! Excellent find! 👍 

 

Just for completeness, my own code corrected:

#include "FastLED.h"

#define NUM_LEDS 12
#define PIN 7

CRGB leds[NUM_LEDS];

void setup() {
FastLED.addLeds<WS2812, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
}

void loop() {
colorWipe(0xe9, 0xe9, 0xe9, 150);
}

void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {

FastLED.clear();

for (int i = 0; i < (NUM_LEDS / 2); i++) {
leds[i] = CRGB(red, green, blue);
leds[NUM_LEDS-i-1] = CRGB(red, green, blue);
FastLED.show();
delay(SpeedDelay);
}

FastLED.clear(); // alternative: fill_solid(leds, NUM_LEDS, CRGB(0,0,0));
FastLED.show();
}

   
ReplyQuote
(@saeidans)
Active Member
Joined: 4 years ago
Posts: 8
 

@hans

bits me

My brother who is a software engineer told me do it this way.

He said C language is a bit different. this is going to be sequence in which the LEDs will turn on

0 and 11

1 and 10

2 and 9

.

.

.

in previous code the there was a confusion on what the program should do with number LED of 12 in the formula, or something like that.

 

Here is the whole code for your reference:

#include "FastLED.h"

#define NUM_LEDS 12
#define PIN 7

CRGB leds[NUM_LEDS];

void setup() {
FastLED.addLeds<WS2812, PIN, GRB>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
}

void loop() {
colorWipe(0xe9, 0xe9, 0xe9, 150);
colorWipe(0x00, 0x00, 0x00, 150);
}

void colorWipe(byte red, byte green, byte blue, int SpeedDelay) {

FastLED.clear();

for (int i = 0; i < (NUM_LEDS / 2); ++i) {
leds[i]=leds[NUM_LEDS-i-1] = CRGB(red, green, blue);
FastLED.show();
delay(SpeedDelay);
}

FastLED.clear(); // alternative: fill_solid(leds, NUM_LEDS, CRGB(0,0,0));
FastLED.show();
}

 

 

Thanks again


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2741
Topic starter  

Cool! 👍 


   
ReplyQuote
(@saeidans)
Active Member
Joined: 4 years ago
Posts: 8
 

@hans

I need your help again

I want to make few chnages to the code

1- the leds are currently turing on from outside to center and suddenly turn off. I want them to turn of in same sequence.

turn on from out to center then turn off from out to center

 

2- I want to be able to add multipe effects in my code by reading diffrent digital pin

for exmple if pin 10 = High then turn on lead from 0 to 11 and if pin== High then turn on LED 11 to 1  ( imagine these effects are going to be used in car turn signal )

 

Thanks

 


   
ReplyQuote
 Hans
(@hans)
Famed Member Admin
Joined: 11 years ago
Posts: 2741
Topic starter  

Filing and then turning off the LEDs from the outside could be done with something like this:

for (int i = 0; i < (NUM_LEDS / 2); ++i) {
  leds[i]=leds[NUM_LEDS-i-1] = CRGB(red, green, blue);
  FastLED.show();
  delay(SpeedDelay);
}

for (int i = 0; i < (NUM_LEDS / 2); ++i) {
  leds[i]=leds[NUM_LEDS-i-1] = CRGB(0, 0, 0);
  FastLED.show();
  delay(SpeedDelay);
}

The "FastLED.clear()" blanks them all, so you'd want to remove that line.

Selecting an effect based on what button has been pressed could be done with something like this (use "#define buttonPin1 10" to define the pins used for the buttons):

void setup() {
// set pins to be able to read an inpiut
pinMode(buttonPin1, INPUT);
pinMode(buttonPin2, INPUT);
pinMode(buttonPin3, INPUT);
}

void loop() {
int button1State = digitalRead(buttonPin1);
int button2State = digitalRead(buttonPin2);
  int button3State = digitalRead(buttonPin3);

  if (button1State == HIGH) {
  // start effect 1
  } else if (button2State == HIGH) {
  // start effect 2
  } else if (button3State == HIGH) {
  // start effect 3
  }

...

}

Note that this approach could come with little issues - for example when multiple buttons were pressed.
More details on reading buttons: Arduino - Button.


   
ReplyQuote
(@saeidans)
Active Member
Joined: 4 years ago
Posts: 8
 

I just tested the filling and turning off LEDs , it seems there is a 3 second delay between each cycle.

is there a way to get rid of it?


   
ReplyQuote
Page 1 / 2
Share: