Recalling text words from an array for LED color

Go To Last Post
19 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey fellow freaks,

 

I am working with some WS2812B led's and the Arduino driver and an example sketch.  The example sketch comes with a .h file that has the values for about 150 different colors(File attached), and all I need to do to set a color is the following in the code:

 

 leds.setPixelColor(0, BLUE);  // Set LED 0 to the color BLUE
    leds.show();  //activates the color(s)

If I want to set the color of two led's I can do this the hard way:

 leds.setPixelColor(0, BLUE);  // Set LED 0 to the collor BLUE
 leds.setPixelColor(1, YELLOW);  // Set LED 1 to teh color YELLOW
    leds.show();

I have been successful in getting the LED's to work, but I was trying to figure out a way to have one LED cycle through some of, if not all the colors in the .h file. 

 

As a test I thought I would just create an array of the color names like this:

char clrs[ ] = {"RED", "GREEN", "BLUE", "WHITE", "YELLOW"};

But this gives me an error:

too many initializers for 'char []'

I looked through the Arduino help page and changed the above line to:

 

char* clrs[ ] = {"RED", "GREEN", "BLUE", "WHITE", "YELLOW"};

But this gives me the following:

Z:\SERVER_Data_Drive\Datasheets\Displays\51f1806cce395fcd20000004\Arduino\WS2812_Breakout_Example\WS2812_Breakout_Example.ino:34:59: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

 char* clrs[ ] = {"RED", "GREEN", "BLUE", "WHITE", "YELLOW"};

                                                           ^

Z:\SERVER_Data_Drive\Datasheets\Displays\51f1806cce395fcd20000004\Arduino\WS2812_Breakout_Example\WS2812_Breakout_Example.ino:34:59: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

Z:\SERVER_Data_Drive\Datasheets\Displays\51f1806cce395fcd20000004\Arduino\WS2812_Breakout_Example\WS2812_Breakout_Example.ino:34:59: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

Z:\SERVER_Data_Drive\Datasheets\Displays\51f1806cce395fcd20000004\Arduino\WS2812_Breakout_Example\WS2812_Breakout_Example.ino:34:59: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

Z:\SERVER_Data_Drive\Datasheets\Displays\51f1806cce395fcd20000004\Arduino\WS2812_Breakout_Example\WS2812_Breakout_Example.ino:34:59: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]

Z:\SERVER_Data_Drive\Datasheets\Displays\51f1806cce395fcd20000004\Arduino\WS2812_Breakout_Example\WS2812_Breakout_Example.ino:52:35: warning: invalid conversion from 'char**' to 'uint32_t {aka long unsigned int}' [-fpermissive]

     leds.setPixelColor(0, &clrs[i]);  // Set just this one

                                   ^

In file included from Z:\SERVER_Data_Drive\Datasheets\Displays\51f1806cce395fcd20000004\Arduino\WS2812_Breakout_Example\WS2812_Breakout_Example.ino:1:0:

C:\Users\james\Documents\Arduino\libraries\Adafruit_NeoPixel/Adafruit_NeoPixel.h:48:5: note: initializing argument 2 of 'void Adafruit_NeoPixel::setPixelColor(uint16_t, uint32_t)'

     setPixelColor(uint16_t n, uint32_t c),

     ^

 

Which has me scratching my head as to what is going on.......

 

If I can get this resolved, my intent is to have a FOR loop cycle through the colors in the  array.  Something like:

for(int i = 0; i < 4; i++)
   {leds.setPixelColor(0, &clrs[i]);

       delay(200);
    }

 

But for the moment all I get is a blue/green LED that varies it's intensity.

 

 

Here is the current application:

#include <Adafruit_NeoPixel.h>

/* SparkFun WS2812 Breakout Board Example
  SparkFun Electronics
  date: July 25, 2013
  license: GNU GENERAL PUBLIC LICENSE

  Requires the Adafruit NeoPixel library. It's awesome, go get it.
  https://github.com/adafruit/Adafruit_NeoPixel

  This simple example code runs three sets of animations on a group of WS2812
  breakout boards. The more boards you link up, the better these animations
  will look. 

  For help linking WS2812 breakouts, checkout our hookup guide:
  https://learn.sparkfun.com/tutorials/ws2812-breakout-hookup-guide

  Before uploading the code, make sure you adjust the two defines at the
  top of this sketch: PIN and LED_COUNT. Pin should be the Arduino pin
  you've got connected to the first pixel's DIN pin. By default it's
  set to Arduino pin 4. LED_COUNT should be the number of breakout boards
  you have linked up.
*/
#include <Adafruit_NeoPixel.h>
#include "WS2812_Definitions.h"

#define PIN 4
#define LED_COUNT 2

// Create an instance of the Adafruit_NeoPixel class called "leds".
// That'll be what we refer to from here on...
Adafruit_NeoPixel leds = Adafruit_NeoPixel(LED_COUNT, PIN, NEO_GRB + NEO_KHZ800);

char* clrs[ ] = {"RED", "GREEN", "BLUE", "WHITE", "YELLOW"};

void setup()
{
  leds.begin();  // Call this to start up the LED strip.
  clearLEDs();   // This function, defined below, turns all LEDs off...
  leds.show();   // ...but the LEDs don't actually update until you call this.
}

void loop()
{
   clearLEDs();
   leds.show();

   delay(500);

   for(int i = 0; i < 4; i++)
   {
    leds.setPixelColor(0, &clrs[i]);  // Set just this one
    leds.show();

    delay(500);
   }

}

// Sets all LEDs to off, but DOES NOT update the display;
// call leds.show() to actually turn them off after this.
void clearLEDs()
{
  for (int i=0; i<LED_COUNT; i++)
  {
    leds.setPixelColor(i, 0);
  }
}

 

Any suggestions on this would be helpful.  This is the foundation for a possible paying project...Just thought I would make that known up front

 

Jim

Attachment(s): 

This topic has a solution.

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

Last Edited: Wed. Dec 6, 2017 - 02:33 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If the named colours are macros, you can't use them as strings anyway, so I wouldn't try to get this to work with a character array.

 

Here's an excerpt from the header you attached:
 

#define BLACK			0x000000
#define NAVY			0x000080
#define DARKBLUE		0x00008B
#define MEDIUMBLUE		0x0000CD
#define BLUE			0x0000FF
#define DARKGREEN		0x006400
#define GREEN			0x008000

They're 24-bit integers.  That's what leds.setPixelColor() expects.

 

So:

__uint24 clrs[] = {RED, GREEN, BLUE, WHITE, YELLOW};

 

Then ust use the array:

for(int i = 0; i < 4; i++)
   {leds.setPixelColor(0, clrs[i]);  <--- note: not &clrs[i]

       delay(200);
    }

 

EDIT:  typo (would should have been wouldn't!)

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Wed. Dec 6, 2017 - 02:32 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That worked!

 

Many thanks.  I see what my error is now. I started this around midnight and then walked away from it.  What you proposed makes sense.  

 

Now to set up a couple led's and see what happens, then move on to dimming the leds and refining the loop to set various led's without having to use multiple leds.setPixelColor() lines.

 

Thanks Joey

Jim

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

Last Edited: Wed. Dec 6, 2017 - 02:36 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I might also mention that this is an ideal candidate for const __flash:

const __flash __uint24 clrs[] = {RED, GREEN, BLUE, WHITE, YELLOW};

 

There are 140 colours in that header.  If you include them all, at three bytes each, that's 420 bytes.  Best not keep that in SRAM.

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Wed. Dec 6, 2017 - 02:59 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:
There are 140 colours in that header.

I thought 150, but yes I agree that storing the array in FLASH is a better idea.  This is just to get my feet wet on this.

 

Right now I am trying to figure out how to configure multiple LED's using only one instance of:

 leds.setPixelColor(LED, color);  // Set just this one

The intent is to make a 'Chaser' where each led lights with the color of the previous one.  Meaning on a 5 led strip I want to have LED 1 start RED, all others off, then LED 2 lights RED, led 1 lights GREEN, all other off, then LED 3 lights RED, LED 2 lights GREEN, LED1 lights BLUE all others off and so on.

 

I have my trusty Paper PC and pencil in front of me trying to come up with a solution.  I mean for 5 leds I could just out 5 lines and 5 variables, but as I said in my OP I am planning on using many LED's so coming up with a code efficient solution is paramount.

 

Gotta go find an eraser to compliment my pencil

 

Jim

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
#define NUM_LEDS 5

const __flash clrs[] = { BLACK, RED, GREEN, BLUE, WHITE, YELLOW };

for (color=1; color<(sizeof(clrs)/sizeof(*clrs)); color++) {
  for (led=0; led<NUM_LEDS; led++) {
    leds.setPixelColor(led, color >= led ? clrs[color-led] : clrs[0]);
  }
  // delay
}

Tested via:

#include <stdint.h>
#include <stdio.h>

#define BLACK     0x000000
#define RED       0xFF0000
#define GREEN     0x008000
#define BLUE      0x0000FF
#define WHITE     0xFFFFFF
#define YELLOW    0xFFFF00

#define NUM_LEDS  5

uint32_t clrs[] = { BLACK, RED, GREEN, BLUE, WHITE, YELLOW };

int main(void) {

  uint8_t color, led;

  for (color=1; color<(sizeof(clrs)/sizeof(*clrs)); color++) {
    for (led=0; led<NUM_LEDS; led++) {
      printf("led%u:0x%06X ", led, color >= led ? clrs[color-led] : clrs[0]);
    }
    putchar('\n');
  }

  return 0;

}

Which yields:

led0:0xFF0000 led1:0x000000 led2:0x000000 led3:0x000000 led4:0x000000 
led0:0x008000 led1:0xFF0000 led2:0x000000 led3:0x000000 led4:0x000000 
led0:0x0000FF led1:0x008000 led2:0xFF0000 led3:0x000000 led4:0x000000 
led0:0xFFFFFF led1:0x0000FF led2:0x008000 led3:0xFF0000 led4:0x000000 
led0:0xFFFF00 led1:0xFFFFFF led2:0x0000FF led3:0x008000 led4:0xFF0000 

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Wed. Dec 6, 2017 - 03:49 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

LOL, I was not asking for anyone to hand out a solution but thanks.

 

 printf("led%u:0x%06X ", led, color >= led ? clrs[color-led] : clrs[0]);

Gonna have to grab K&R for that one

 

I will try this out a little later.  Gotta try and earn a living

 

JIm

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

Last Edited: Wed. Dec 6, 2017 - 03:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Download and review the Adafruit Arduino library for NeoPixels.  They use a color wheel where an 8-bit value cycles through 256 of the rainbow colors that the WS2812B can generate.  This library also holds a good example of how to insert assembly language into Arduino programs. 

 

Separate the two parts of the situation, the LEDs and accessing the array of color values.  I suggest an array of long variables because each variable can hold the 8-bit values of the red, blue, and green  individual LEDs that are incorporated into the WS2812B​ module.   Long variables are 32-bits, so the top bits [31-24] can be all zeros.  If you have no way to display the text of the color name with the Arduino, then you don't need the color-name text in the array of LED colors.

 

 

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Good Information!

 

There seems to be several libraries for the Arduino on Adafruit...I'll download them all.

 

I am going to order a pre-made reel of these LED's to get a good feel for whats going on.

 

Thanks

 

JIm

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

Last Edited: Wed. Dec 6, 2017 - 04:40 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jim this demo video https://vimeo.com/231166523 contains some functions of the Adafruit library plus several custom ones. The panel is part of a larger installation running Beaglebones and Raspberry Pi for the animations (written in Java ...not by me, about 15,000 Neopixel LEDs).

 

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

John
At about the 1 minute mark where the leds fade from color to color is one of the things I am looking to be able to do along with the chase. The chase seems pretty straight forward, but I am a bit stumped on the colors fading from one to the other and seeminglY random on the panel,

Jim

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In my case it's a matter of filling up the LED buffer (900 bytes for 300 LEDs string), sending it out (a few ms) and repeat.

 

I will have to check if it is using an Adafruit function or a custom function where 3 waves intersect (either Sine, Square, Triangular or Saw-tooth).

 

The demo has been modified so that I can recall individual functions with a rotary switch for another project I'm looking at for a another client.

 

I'll email you some code as soon as I can determine how to split things.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fading a fixed color, (ignoring chroma and eye perception issues), is simply a matter of changing the 8-bit number for the 3 LEDs.

 

Remember how this LED works, it has three LED diodes inside it, and a 256 level driver for each LED.

 

To fade from a fully bright, pure Blue, dimmer and dimmer to off one just feeds the LED 0 for Green, 0 for red, and 255 for Blue.

That is the fullest intensity Blue the LED can be, and it has no other colors mixed in with in.

 

Now, in a timed loop, keep feeding it 0 for Green, 0 for Red, but count down the Blue value, 255 down to 0.

The LED will still be pure Blue, but the intensity will fade away, (non-linearly, as perceived by the human eye).

 

Full White is an equal mixture of G, R, and B, so you send the LED 255, 255, 255.

Want a dim White, send it 128, 128, 128.

You are sending the same ratio of G, R, and B, but with a lower intensity for each one.

 

The trick is dimming a color that is a mixture of the three base colors, at different levels.

e.g. DarkSlateBlue: 0x483D8B  (G=72 R=61, B=139 Dec)

To dim that you still need to keep the ratios of the three base colors the same.

So, while diming pure Blue you had 256 Blue intensity levels.

While diming Dark Slate Blue, you have at most 61 dec levels of the Red to work with.

And, as you dim it, the exact ratios will not be perfectly constant ratios.

e.g 1/2 intensity would be: G= 72/2  R = 61/2 B = 139/2

Note that your eye, in practice, won't likely appreciate the subtle change in the color as the intensity changes, (well, if you pick some "nice colors", anyways).

 

Finally , as you play with the LEDs you will quickly see that 1/2 intensity number-wise on the data fed the LED doesn't correspond to your human eye perception of 1/2 intensity.

 

There are many articles on RGB color mixing on the web, as this is also applicable to TV's and computer displays.

 

JC

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The trick is dimming a color that is a mixture of the three base colors, at different levels.

Which is exactly what 3 sine waves with different phases produce..... wink

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you want a 'color wheel' effect, you want to work in HSV or something similar.  That's 'Hue', 'Saturation', and 'Value'.  There's also HSL where L is 'Luminance', and HSI where I is 'Intensity', but they're similar in most respects.

 

Since the LEDs need RGB values, you need a means to convert the HSL working value into an associated RGB value.  There are several libraries which will do that for you, and lots of material on the interwebs to guide you w.r.t. algorithms and formulas if you want to roll your own.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"Read a lot.  Write a lot."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks all,

Right now all I have is 5 LED's that Doc sent me.  I am ordering a long tape of them which will be here in a few days so in the meantime I have some homework to do, but I have a job that I have been waiting months for to do and I will have to work the LED stuff in between.

 

Working for a living sucks sometimes.

 

@JS

Got the email thanks, have not given it a good read yet.

 

JIm

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What would be nice is if there was a C library for the AdaFruit library.

 

Unless there is a way I can mix C with the C++ library in Studio....

 

Jim

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It seems I have lost the Adafruit stuff. I simply took what I needed and changed it to "normal C" for my use, maybe the Wheel mentioned above, Rainbow?? (this you may just use),  colorChase and that's it I think.

 

The other stuff I have was written by me (why doesn't everyone have an Italian flag function??) or adapted from other client's demo code.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have actually managed to create some interesting little effects with just 5 LED's in the Arduino IDE, but I prefer Studio.  Upside to the Arduino IDE is the bootloader.  

 

Time to call it a night...thanks all, I will add to this tomorrow

 

Jim

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user