Rainbow effect on Adafruit RGB Matrix

Hello Guys,

Some days ago I got an Arduino Uno and an Adafruit 8x5 LED Matrix shield. I learned to write code for it, like generating lines or rectangles. Now i want to create a colorvariable so a rectangle could change its color.
I¬īm using following librarys: Adafruit_GFX.h, Adafruit_NeoMatrix.h, Adafruit_NeoPixel.h.
My problem is that the colors in Adafruit_GFX are in RGB565 hex code.
I tried to solve it with a for loop and counting i from the blue value (0x001F) to the green (0x07E0) value and from that to the red value (0xF800).
It was flickering and there were no smoth transitions

  // Blue to green
  for (int i = 0x001F; i < 0x07E0; i++){

Does anyone know a solution to it? I searched for 2 days trough the whole internet and found nothing…

Thanks

Please follow the advice on posting code in Read this before posting a programming question

In particular note the advice to post a complete sketch

Here is my complete sketch:

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#ifndef PSTR
#define PSTR // Make Arduino Due happy
#endif

#define PIN 13

#define BLUE     0x001F   //31
#define GREEN    0x07E0   //2016
#define RED      0xF800   //63488


Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(8, 5, PIN,
  NEO_MATRIX_TOP     + NEO_MATRIX_LEFT +
  NEO_MATRIX_ROWS    + NEO_MATRIX_PROGRESSIVE,
  NEO_GRB            + NEO_KHZ800);


void setup() {
  matrix.begin();
  matrix.setBrightness(10);
}


void loop() {
    //blue to green
    for (int i = 0x001F; i < 0x07E0; i++){
    matrix.drawLine(0, 0, 7, 0, i);
    matrix.drawLine(0, 1, 7, 1, i);
    matrix.drawLine(0, 2, 7, 2, i);
    matrix.drawLine(0, 3, 7, 3, i);
    matrix.drawLine(0, 4, 7, 4, i);
    matrix.show();
    delay(0.1);
  } 
}
    delay(0.1);

For a start, delay() take an unsigned long as its parameter. If you really want a delay of less than one millisecond then consider using delay.Microseconds()

UKHeliBob:
For a start, delay() take an unsigned long as its parameter. If you really want a delay of less than one millisecond then consider using delay.Microseconds()

Okay, thanks. But i also tried with 1, 10, and 100.

@yeti01

Other post/duplicate DELETED
Please do NOT cross post / duplicate as it wastes peoples time and efforts to have more than one post for a single topic.

Continued cross posting could result in a time out from the forum.

Could you also take a few moments to Learn How To Use The Forum.
It will help you get the best out of the forum in the future.
Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

You were already sent the link for a helpful topic and maybe did not use it.
Let these links serve you well.

tried to solve it with a for loop and counting i from the blue value (0x001F) to the green (0x07E0) value and from that to the red value (0xF800).

But that will not make a smooth transition between the colours.

Colours consist of three values red, green and blue. They represent a point in cubic space, so to get colours to blend from one point to the other you need to connect these two points with a straight line and use colours that lie on this straight line.

So you have to work out the distance between the two colours for each colour component, that is a red difference, green difference and blue difference. Then divide that difference by the number of steps you want to use to fade between the two colours, you will need float variables for this. Then take the start colour and using a for loop add this divided step increment to each of the colour components. Using a show and delay of at least 50 at the end of the loop.

Thank you for replying.

Grumpy_Mike:
Colours consist of three values red, green and blue.

I didn¬īt thought this way, this is a good starting point. I think even with this in mind it is not that easy. the board uses RGB565 code. This code only has 4 digits. RGB888 has 6 digits so you can save #RRGGBB, but in RGB565 it is mixed up in the 4 digits. So thats my problem now.

ballscrewbob:
@yeti01

Other post/duplicate DELETED
Please do NOT cross post / duplicate as it wastes peoples time and efforts to have more than one post for a single topic.

Continued cross posting could result in a time out from the forum.

Could you also take a few moments to Learn How To Use The Forum.
It will help you get the best out of the forum in the future.
Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

You were already sent the link for a helpful topic and maybe did not use it.
Let these links serve you well.

I understand.
I¬īm sorry for the mistake.

This code only has 4 digits. RGB888 has 6 digits so you can save #RRGGBB, but in RGB565 it is mixed up in the 4 digits.

Suppose you have three eight bit values R, G & B, you can make that into a 5, 6, 5 format with

RGB565 = (( B >>3 ) & 0x1F) | ( ( G  & 0xFC) << 4) | (( R & 0xF8) << 8);

is shift right
<< is shift left
| is the bitwise OR function
& is the bitwise AND function

To obtain a smooth transition from one color to another, one approach is to convert the RGB color scheme to HSV or HSB/L (hue, saturation and value or brightness).

Alternatively, you can linearly interpolate between colors to make a color map, as described here: Code - heatmaps and color gradients - NoskeWiki

Grumpy_Mike:
Suppose you have three eight bit values R, G & B, you can make that into a 5, 6, 5 format with

RGB565 = (( B >>3 ) & 0x1F) | ( ( G  & 0xFC) << 4) | (( R & 0xF8) << 8);

is shift right
<< is shift left
| is the bitwise OR function
& is the bitwise AND function

Sadly I¬īm not that much into coding. I kind of understand the code, but i don¬īt know how to implement it into my code so that it works the way i want it to‚Ķ

jremington:
To obtain a smooth transition from one color to another, one approach is to convert the RGB color scheme to HSV or HSB/L (hue, saturation and value or brightness).

Alternatively, you can linearly interpolate between colors to make a color map, as described here: Code - heatmaps and color gradients - NoskeWiki

I¬īve read both articles, I think it would be the easiest way to convert HSV into Hex and just letting the HSV angle rotate.

But i have no idea how to convert HSV to the correct HEX value.

but i don¬īt know how to implement it into my code so that it works the way i want it to.

But i have no idea how to convert HSV to the correct HEX value.

You are going to have to try and learn what code does. Start off by reading the code you have and seeing what each line does. Use the simple examples given in the IDE to get you going with the basics.

Code is a story, a list of instructions that get done one at a time. The fact that you don't know what to do with help means that the project you are trying to do is way too complex for you at your current state of knowledge. Code is a lot simpler than you think at the moment.

A bit like my wife a few years back spent a lot of time learning the German for asking for where places were. When we arrived in Germany these phrases worked, but unfortunately, as she could not understand German, the responses she got were useless.

I think it would be the easiest way to convert HSV into Hex and just letting the HSV angle rotate.

Sure do that, but understand when that is done you will still need to do the process I described in reply #9 because you said you need a number in a 5, 6, 5 format.

But i have no idea how to convert HSV to the correct HEX value.

Use the hsv2rgb function to output RGB values for given HSV values, then the line in reply #9 to convert RGB output to a 565 value.

As Mike says, if this is a struggle, you need to spend some time with the basics. Study the examples that come with the Arduino IDE, and relevant on line tutorials.

+++PART ONE+++

So i have pondered for two weeks and finally came up with a solution. It was not easy, i had to find a completely new way to code the matrix.
I didn¬īt convert color codes neither build a cubic space with color vectors. I would like to, but im not that far in coding.
I ditched the delay() function and startet to work with millis(), the internal clock.

Here is my code:

#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#ifndef PSTR
#define PSTR // Make Arduino Due happy
#endif

#define PIN 13

// Color definitions
#define BLACK   0x0000
#define RED     0xF800
#define ORANGE  0xfba0
#define YELLOW  0xFFE0 
#define LIME    0xc7e0
#define GREEN   0x07E0
#define CYAN    0x07FF
#define AQUA    0x05ff
#define BLUE    0x001F
#define PURPLE  0xb01f
#define MAGENTA 0xF81F
#define PINK    0xf814
#define WHITE   0xFFFF

Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(8, 5, PIN,
  NEO_MATRIX_TOP     + NEO_MATRIX_LEFT +
  NEO_MATRIX_ROWS    + NEO_MATRIX_PROGRESSIVE,
  NEO_GRB            + NEO_KHZ800);

long ColVar[192]={63488, 63552, 63616, 63680, 63744, 63808, 63872, 63936, 64000, 64064, 64128, 64192, 64256, 64320, 64384, 64448, 64512, 64576, 64640, 64704, 64768, 64832, 64896, 64960, 65024, 65088, 65152, 65216, 65280, 65344, 65408, 65472, 
                  65504, 63456, 61408, 59360, 57312, 55264, 53216, 51168, 49120, 47072, 45024, 42976, 40928, 38880, 36832, 34784, 32736, 30688, 28640, 26592, 24544, 22496, 20448, 18400, 16352, 14304, 12256, 10208, 8160,  6112,  4064,  2016, 
                  2016,  2017,  2018,  2019,  2020,  2021,  2022,  2023,  2024,  2025,  2026,  2027,  2028,  2029,  2030,  2031,  2032,  2033,  2034,  2035,  2036,  2037,  2038,  2039,  2040,  2041,  2042,  2043,  2044,  2045,  2046,  2047, 
                  2015,  1951,  1887,  1823,  1759,  1695,  1631,  1567,  1503,  1439,  1375,  1311,  1247,  1183,  1119,  1055,  991,   927,   863,   799,   735,   671,   607,   543,   479,   415,   351,   287,   223,   159,   95,    31, 
                  31,    2079,  4127,  6175,  8223,  10271, 12319, 14367, 16415, 18463, 20511, 22559, 24607, 26655, 28703, 30751, 32799, 34847, 36895, 38943, 40991, 43039, 45087, 47135, 49183, 51231, 53279, 55327, 57375, 59423, 61471, 63519, 
                  63519, 63518, 63517, 63516, 63515, 63514, 63513, 63512, 63511, 63510, 63509, 63508, 63507, 63506, 63505, 63504, 63503, 63502, 63501, 63500, 63499, 63498, 63497, 63496, 63495, 63494, 63493, 63492, 63491, 63490, 63489, 63488};

int Col1 = 0;
int Col2 = 5;
int Col3 = 10;
int Col4 = 15;
int Col5 = 20;
int Col6 = 25;
int Col7 = 30;
int Col8 = 35;
int Col9 = 40;
int Col10 = 45;
int Col11 = 50;
int Col12 = 55;

unsigned long startMillis;  
unsigned long ColMillis1;
unsigned long ColMillis2;
unsigned long ColMillis3;
unsigned long ColMillis4;
unsigned long ColMillis5;
unsigned long ColMillis6;
unsigned long ColMillis7;
unsigned long ColMillis8;
unsigned long ColMillis9;
unsigned long ColMillis10;
unsigned long ColMillis11;
unsigned long ColMillis12;
unsigned long currentMillis;

void setup() {
  startMillis = millis();  //initial start time
  ColMillis1 = millis();
  ColMillis2 = millis();
  ColMillis3 = millis();
  ColMillis4 = millis();
  ColMillis5 = millis();
  ColMillis6 = millis();
  ColMillis7 = millis();
  ColMillis8 = millis();
  ColMillis9 = millis();
  ColMillis10 = millis();
  ColMillis11 = millis();
  ColMillis12 = millis();
  matrix.begin();
  matrix.setBrightness(20);
}

//===============================================================================================
//===========================================LOOP================================================

void loop() {
  currentMillis = millis();  //get the current "time" (actually the number of milliseconds since the program started)
  fastRect();
  colSpectr();
  timer();
  HueControll();
}

//===============================================================================================
//====================================Kombined Funktions=========================================
//===============================================================================================

void fastRect() {
  if ((currentMillis - startMillis >= 0) && (currentMillis - startMillis <= 250)) {
    bigRect();
  }
  if ((currentMillis - startMillis >= 250) && (currentMillis - startMillis <= 500)) {
    medRect();
  }
  if ((currentMillis - startMillis >= 500) && (currentMillis - startMillis <= 750)) {
    smolRect();
  }
  if ((currentMillis - startMillis >= 750) && (currentMillis - startMillis <= 1000)) {
    medRect();
  }
    if ((currentMillis - startMillis >= 1000) && (currentMillis - startMillis <= 1250)) {
    bigRect();
  }
  if ((currentMillis - startMillis >= 1250) && (currentMillis - startMillis <= 1500)) {
    medRect();
  }
  if ((currentMillis - startMillis >= 1500) && (currentMillis - startMillis <= 1750)) {
    smolRect();
  }
  if ((currentMillis - startMillis >= 1750) && (currentMillis - startMillis <= 2000)) {
    medRect();
  }
    if ((currentMillis - startMillis >= 2000) && (currentMillis - startMillis <= 2250)) {
    bigRect();
  }
  if ((currentMillis - startMillis >= 2250) && (currentMillis - startMillis <= 2500)) {
    medRect();
  }
  if ((currentMillis - startMillis >= 2500) && (currentMillis - startMillis <= 2750)) {
    smolRect();
  }
  if ((currentMillis - startMillis >= 2750) && (currentMillis - startMillis <= 3000)) {
    medRect();
  }
    if ((currentMillis - startMillis >= 3000) && (currentMillis - startMillis <= 3250)) {
    bigRect();
  }
  if ((currentMillis - startMillis >= 3250) && (currentMillis - startMillis <= 3500)) {
    medRect();
  }
  if ((currentMillis - startMillis >= 3500) && (currentMillis - startMillis <= 3750)) {
    smolRect();
  }
  if ((currentMillis - startMillis >= 3750) && (currentMillis - startMillis <= 4000)) {
    medRect();
  }
    if ((currentMillis - startMillis >= 4000) && (currentMillis - startMillis <= 4250)) {
    bigRect();
  }
  if ((currentMillis - startMillis >= 4250) && (currentMillis - startMillis <= 4500)) {
    medRect();
  }
  if ((currentMillis - startMillis >= 4500) && (currentMillis - startMillis <= 4750)) {
    smolRect();
  }
  if ((currentMillis - startMillis >= 4750) && (currentMillis - startMillis <= 5000)) {
    medRect();
  }
}

//===============================================================================================
//===============================================================================================

void colSpectr(){
  if ((currentMillis - startMillis >= 5000) && (currentMillis - startMillis <= 15000)) {
    colSpectrH();
  }
  if ((currentMillis - startMillis >= 15000) && (currentMillis - startMillis <= 25000)) {
    colSpectrV();
  }
  if ((currentMillis - startMillis >= 25000) && (currentMillis - startMillis <= 35000)) {
    colSpectrD();
  }
}

//===============================================================================================
//===============================================================================================

void timer() {
  //Reset Loop-Timer
  if (currentMillis - startMillis > 35000) {
    startMillis = currentMillis;
  }
}

+++PART TWO+++

//===============================================================================================
//===============================================================================================

void HueControll(){
  #define HueSpeed 10

  //ColVar-Array-Steuerung
  if (currentMillis - ColMillis1 >= HueSpeed) {       //Geschwindigkeit, kleiner = Schneller
    Col1++;                                           //Arrayzahl +1
    ColMillis1 = currentMillis;                       //Reset Array-Timer
  }
  if (currentMillis - ColMillis2 >= HueSpeed) {       //Geschwindigkeit, kleiner = Schneller
    Col2++;                                           //Arrayzahl +1
    ColMillis2 = currentMillis;                       //Reset Array-Timer
  }
  if (currentMillis - ColMillis3 >= HueSpeed) {       //Geschwindigkeit, kleiner = Schneller
    Col3++;                                           //Arrayzahl +1
    ColMillis3 = currentMillis;                       //Reset Array-Timer
  }
  if (currentMillis - ColMillis4 >= HueSpeed) {       //Geschwindigkeit, kleiner = Schneller
    Col4++;                                           //Arrayzahl +1
    ColMillis4 = currentMillis;                       //Reset Array-Timer
  }
  if (currentMillis - ColMillis5 >= HueSpeed) {       //Geschwindigkeit, kleiner = Schneller
    Col5++;                                           //Arrayzahl +1
    ColMillis5 = currentMillis;                       //Reset Array-Timer
  }
  if (currentMillis - ColMillis6 >= HueSpeed) {       //Geschwindigkeit, kleiner = Schneller
    Col6++;                                           //Arrayzahl +1
    ColMillis6 = currentMillis;                       //Reset Array-Timer
  }
  if (currentMillis - ColMillis7 >= HueSpeed) {       //Geschwindigkeit, kleiner = Schneller
    Col7++;                                           //Arrayzahl +1
    ColMillis7 = currentMillis;                       //Reset Array-Timer
  }
  if (currentMillis - ColMillis8 >= HueSpeed) {       //Geschwindigkeit, kleiner = Schneller
    Col8++;                                           //Arrayzahl +1
    ColMillis8 = currentMillis;                       //Reset Array-Timer
  }
  if (currentMillis - ColMillis9 >= HueSpeed) {       //Geschwindigkeit, kleiner = Schneller
    Col9++;                                           //Arrayzahl +1
    ColMillis9 = currentMillis;                       //Reset Array-Timer
  }
  if (currentMillis - ColMillis10 >= HueSpeed) {      //Geschwindigkeit, kleiner = Schneller
    Col10++;                                          //Arrayzahl +1
    ColMillis10 = currentMillis;                      //Reset Array-Timer
  }
  if (currentMillis - ColMillis11 >= HueSpeed) {      //Geschwindigkeit, kleiner = Schneller
    Col11++;                                          //Arrayzahl +1
    ColMillis11 = currentMillis;                      //Reset Array-Timer
  }
  if (currentMillis - ColMillis12 >= HueSpeed) {      //Geschwindigkeit, kleiner = Schneller
    Col12++;                                          //Arrayzahl +1
    ColMillis12 = currentMillis;                      //Reset Array-Timer
  }
  
 ¬†if (Col1 >= 192) { ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬†//Verhindert "√ľberlaufen" vom Array
    Col1 = 0;
  }
 ¬†if (Col2 >= 192) { ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬†//Verhindert "√ľberlaufen" vom Array
    Col2 = 0;
  }
 ¬†if (Col3 >= 192) { ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬†//Verhindert "√ľberlaufen" vom Array
    Col3 = 0;
  }
 ¬†if (Col4 >= 192) { ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬†//Verhindert "√ľberlaufen" vom Array
    Col4 = 0;
  }
 ¬†if (Col5 >= 192) { ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬†//Verhindert "√ľberlaufen" vom Array
    Col5 = 0;
  }
 ¬†if (Col6 >= 192) { ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬†//Verhindert "√ľberlaufen" vom Array
    Col6 = 0;
  }
 ¬†if (Col7 >= 192) { ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬†//Verhindert "√ľberlaufen" vom Array
    Col7 = 0;
  }
 ¬†if (Col8 >= 192) { ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬†//Verhindert "√ľberlaufen" vom Array
    Col8 = 0;
  }
 ¬† ¬†if (Col9 >= 192) { ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬†//Verhindert "√ľberlaufen" vom Array
    Col9 = 0;
  }
 ¬† ¬†if (Col10 >= 192) { ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† //Verhindert "√ľberlaufen" vom Array
    Col10 = 0;
  }
 ¬† ¬†if (Col11 >= 192) { ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† //Verhindert "√ľberlaufen" vom Array
    Col11 = 0;
  }
 ¬† ¬†if (Col12 >= 192) { ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† ¬† //Verhindert "√ľberlaufen" vom Array
    Col12 = 0;
  }
}

//===============================================================================================
//====================================Basic Funktions============================================
//===============================================================================================

void colSpectrD() {
  matrix.fillScreen(0);
  matrix.drawLine(0, 0, 0, 0, ColVar[Col1]);
  matrix.drawLine(0, 1, 1, 0, ColVar[Col2]);
  matrix.drawLine(0, 2, 2, 0, ColVar[Col3]);
  matrix.drawLine(0, 3, 3, 0, ColVar[Col4]);
  matrix.drawLine(0, 4, 4, 0, ColVar[Col5]);
  matrix.drawLine(0, 5, 5, 0, ColVar[Col6]);
  matrix.drawLine(0, 6, 6, 0, ColVar[Col7]);
  matrix.drawLine(0, 7, 7, 0, ColVar[Col8]);
  matrix.drawLine(0, 8, 8, 0, ColVar[Col9]);
  matrix.drawLine(0, 9, 9, 0, ColVar[Col10]);
  matrix.drawLine(0, 10, 10, 0, ColVar[Col11]);
  matrix.drawLine(0, 11, 11, 0, ColVar[Col12]);
  matrix.show();
}

//===============================================================================================

void colSpectrV() {
  matrix.fillScreen(0);
  matrix.drawLine(0, 0, 0, 4, ColVar[Col1]);
  matrix.drawLine(1, 0, 1, 4, ColVar[Col2]);
  matrix.drawLine(2, 0, 2, 4, ColVar[Col3]);
  matrix.drawLine(3, 0, 3, 4, ColVar[Col4]);
  matrix.drawLine(4, 0, 4, 4, ColVar[Col5]);
  matrix.drawLine(5, 0, 5, 4, ColVar[Col6]);
  matrix.drawLine(6, 0, 6, 4, ColVar[Col7]);
  matrix.drawLine(7, 0, 7, 4, ColVar[Col8]);
  matrix.show();
}

//===============================================================================================

void colSpectrH() {
  matrix.fillScreen(0);
  matrix.drawLine(0, 0, 7, 0, ColVar[Col1]);
  matrix.drawLine(0, 1, 7, 1, ColVar[Col2]);
  matrix.drawLine(0, 2, 7, 2, ColVar[Col3]);
  matrix.drawLine(0, 3, 7, 3, ColVar[Col4]);
  matrix.drawLine(0, 4, 7, 4, ColVar[Col5]);
  matrix.show();
}

//===============================================================================================

void bigRect() {
  matrix.fillScreen(0);
  matrix.drawRect(0, 0, 8, 5, ColVar[Col1]);
  matrix.show();
}

//===============================================================================================

void medRect() {
  matrix.fillScreen(0);
  matrix.drawRect(1, 1, 6, 3, ColVar[Col1]);
  matrix.show();
}

//===============================================================================================

void smolRect() {
  matrix.fillScreen(0);
  matrix.drawRect(2, 2, 4, 1, ColVar[Col1]);
  matrix.show();
}

And here is the result of my work.

1 Like

Thanks for getting back to us.
Well done :slight_smile:
I assume you are happy with this?

Have a Karma point

Thanks for getting back to us.
Well done :slight_smile:
I assume you are happy with this?

Have a Karma point

Thank you.

Yes I am very happy with the result.