Hi all, I'm encountering a problem that I cannot figure out the solution to on my own.
I have a Neopixel matrix (2 actually, one being a mirror of the other) made from WS2813 strips. The objective is simple:
- It should display a scrolling quote from the Matrix movie 10x
- Then a custom matrix/digital rain kind of animation is played for a minute or so
- Then 10x text again
- Digital rain
etc. etc. etc. looping 'forever'
The strips are wired like described in the Adafruit Uberguide with the resistors and the capacitor in place of the correct values. The strips and Arduino are powered by a seperate 10A Meanwell 5V PSU. The grounds of the PSU and Arduino are connected.

I have a switch with which I can toggle if I want the rain effect to display or only the scrolling text. And some potentiometers to control speed, brightness and saturation. That all works fine.
When there is only the scrolling text, it performs exactly like expected. However, when the matrix effect is also on, sometimes a problem is introduced. Every other LED is ignored and remains turned off, while the animations continue to work fine behind that. So where 1-2-3-4-5-6 need to be on for example, only 1-3-5 are on. Beware, I say sometimes, because it does not always happen, which makes me think it is not due to an 'obvious' code error.
The best way to show what is supposed to happen and where it goes wrong is with some videos. Embedding from Vimeo doesn't seem to work so lets do it like this:
This is the working text effect (Vimeo link)
Then this is the matrix digital rain effect (Vimeo link)
When I then unplug the power and plug it back in after some seconds, this is shown (Vimeo link)
I cannot explain why this behavior occurs. I really hope some of you might have an explanation and maybe even a possible fix for this. Thanks in advance!
Below is the Arduino code used (I know, I know.. It is huge for what it does as there is a lot of similar code blocks that could have probably (definitely) be written more efficiently, but that is a bit outside of my skill level, so since this works (apart form the problem described) it works for me. My apologies, but hopefully it is at least readable enough)
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
#include <Fonts/Picopixel.h>
#ifndef PSTR
#define PSTR // Make Arduino Due happy
#endif
#define data_pin_left 19
#define data_pin_right 18
const int pixels_per_row = 41;
int switch_pin = 17;
const int POT_L_PIN = A1;
const int POT_M_PIN = A0;
const int POT_R_PIN = A2;
int speed;
float brightness;
int saturation;
//CONTROLABLE VARIABLES -----------------
int number_of_text_scrolls_before_rain = 10;
unsigned long duration_of_rain_in_seconds = 30;
int rain_frequency = 85; //0=never rain, 100=everytime a new rain when last rain is gone
int minimum_x_steps_per_rain = 20;
int maximum_x_steps_per_rain = 150;
int minimum_tail_length = 6;
int maximum_tail_length = 20;
//---------------------------------------
bool rain_effect_turned_on = true;
int switch_state;
int white_pixel_brightness_offset = 20;
int tail_pixel_brightness_offset = 20;
unsigned long time;
unsigned long last_millis_rain_started;
bool rain_effect_active = false;
bool text_effect_active = true;
int number_of_completed_text_scrolls = 0;
bool fade_between_rain_and_text = false;
float x_1 = 0;
int line_1_starting_x = 0;
int line_1_round = 0;
int line_1_x_limit_for_this_rain = random(40, 100);
float line_1_fade_factor = 0;
bool line_1_brightness_needs_fade_in = true;
int line_1_curent_white_LED_pos;
float line_1_amount_of_tail_pixels = 8;
bool line_1_active = true;
float line_1_speed_for_next_rain = 1;
float x_2 = 0;
int line_2_starting_x = 0;
int line_2_round = 0;
int line_2_x_limit_for_this_rain = random(40, 100);
float line_2_fade_factor = 0;
bool line_2_brightness_needs_fade_in = true;
int line_2_curent_white_LED_pos;
float line_2_amount_of_tail_pixels = 8;
bool line_2_active = true;
float line_2_speed_for_next_rain = 1;
float x_3 = 0;
int line_3_starting_x = 0;
int line_3_round = 0;
int line_3_x_limit_for_this_rain = random(40, 100);
float line_3_fade_factor = 0;
bool line_3_brightness_needs_fade_in = true;
int line_3_curent_white_LED_pos;
float line_3_amount_of_tail_pixels = 8;
bool line_3_active = true;
float line_3_speed_for_next_rain = 1;
float x_4 = 0;
int line_4_starting_x = 0;
int line_4_round = 0;
int line_4_x_limit_for_this_rain = random(40, 100);
float line_4_fade_factor = 0;
bool line_4_brightness_needs_fade_in = true;
int line_4_curent_white_LED_pos;
float line_4_amount_of_tail_pixels = 8;
bool line_4_active = true;
float line_4_speed_for_next_rain = 1;
float x_5 = 0;
int line_5_starting_x = 0;
int line_5_round = 0;
int line_5_x_limit_for_this_rain = random(40, 100);
float line_5_fade_factor = 0;
bool line_5_brightness_needs_fade_in = true;
int line_5_curent_white_LED_pos;
float line_5_amount_of_tail_pixels = 8;
bool line_5_active = true;
float line_5_speed_for_next_rain = 1;
float x_1L = 0;
int line_1L_starting_x = 0;
int line_1L_round = 0;
int line_1L_x_limit_for_this_rain = random(40, 100);
float line_1L_fade_factor = 0;
bool line_1L_brightness_needs_fade_in = true;
int line_1L_curent_white_LED_pos;
float line_1L_amount_of_tail_pixels = 8;
bool line_1L_active = true;
float line_1L_speed_for_next_rain = 1;
float x_2L = 0;
int line_2L_starting_x = 0;
int line_2L_round = 0;
int line_2L_x_limit_for_this_rain = random(40, 100);
float line_2L_fade_factor = 0;
bool line_2L_brightness_needs_fade_in = true;
int line_2L_curent_white_LED_pos;
float line_2L_amount_of_tail_pixels = 8;
bool line_2L_active = true;
float line_2L_speed_for_next_rain = 1;
float x_3L = 0;
int line_3L_starting_x = 0;
int line_3L_round = 0;
int line_3L_x_limit_for_this_rain = random(40, 100);
float line_3L_fade_factor = 0;
bool line_3L_brightness_needs_fade_in = true;
int line_3L_curent_white_LED_pos;
float line_3L_amount_of_tail_pixels = 8;
bool line_3L_active = true;
float line_3L_speed_for_next_rain = 1;
float x_4L = 0;
int line_4L_starting_x = 0;
int line_4L_round = 0;
int line_4L_x_limit_for_this_rain = random(40, 100);
float line_4L_fade_factor = 0;
bool line_4L_brightness_needs_fade_in = true;
int line_4L_curent_white_LED_pos;
float line_4L_amount_of_tail_pixels = 8;
bool line_4L_active = true;
float line_4L_speed_for_next_rain = 1;
float x_5L = 0;
int line_5L_starting_x = 0;
int line_5L_round = 0;
int line_5L_x_limit_for_this_rain = random(40, 100);
float line_5L_fade_factor = 0;
bool line_5L_brightness_needs_fade_in = true;
int line_5L_curent_white_LED_pos;
float line_5L_amount_of_tail_pixels = 8;
bool line_5L_active = true;
float line_5L_speed_for_next_rain = 1;
// MATRIX DECLARATION:
// Parameter 1 = width of NeoPixel matrix
// Parameter 2 = height of matrix
// Parameter 3 = pin number (most are valid)
// Parameter 4 = matrix layout flags, add together as needed:
// NEO_MATRIX_TOP, NEO_MATRIX_BOTTOM, NEO_MATRIX_LEFT, NEO_MATRIX_RIGHT:
// Position of the FIRST LED in the matrix; pick two, e.g.
// NEO_MATRIX_TOP + NEO_MATRIX_LEFT for the top-left corner.
// NEO_MATRIX_ROWS, NEO_MATRIX_COLUMNS: LEDs are arranged in horizontal
// rows or in vertical columns, respectively; pick one or the other.
// NEO_MATRIX_PROGRESSIVE, NEO_MATRIX_ZIGZAG: all rows/columns proceed
// in the same order, or alternate lines reverse direction; pick one.
// See example below for these values in action.
// Parameter 5 = pixel type flags, add together as needed:
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
// NEO_GRBW Pixels are wired for GRBW bitstream (RGB+W NeoPixel products)
// NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
// Example for NeoPixel Shield. In this application we'd like to use it
// as a 5x8 tall matrix, with the USB port positioned at the top of the
// Arduino. When held that way, the first pixel is at the top right, and
// lines are arranged in columns, progressive order. The shield uses
// 800 KHz (v2) pixels that expect GRB color data.
Adafruit_NeoMatrix matrix_right = Adafruit_NeoMatrix(pixels_per_row, 5, data_pin_right,
NEO_MATRIX_TOP + NEO_MATRIX_RIGHT + NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG,
NEO_GRBW + NEO_KHZ800);
Adafruit_NeoMatrix matrix_left = Adafruit_NeoMatrix(pixels_per_row, 5, data_pin_left,
NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_ROWS + NEO_MATRIX_ZIGZAG,
NEO_GRBW + NEO_KHZ800);
const uint16_t green = matrix_left.Color(0, 255, 0);
int x = matrix_right.width();
void setup() {
pinMode(POT_L_PIN, INPUT);
pinMode(POT_M_PIN, INPUT);
pinMode(POT_R_PIN, INPUT);
pinMode(switch_pin, INPUT_PULLUP);
matrix_right.begin();
matrix_left.begin();
matrix_right.setTextWrap(false);
matrix_left.setTextWrap(false);
//A value of 255 is full brightness, a value of 127 is half brightness, 63 is quarter brightness, etc.
matrix_right.setBrightness(100);
matrix_left.setBrightness(100);
matrix_right.setTextColor(green);
matrix_left.setTextColor(green);
matrix_right.setFont(&Picopixel);
matrix_left.setFont(&Picopixel);
matrix_right.clear();
matrix_left.clear();
line_1_amount_of_tail_pixels = random(5, 12);
line_1_starting_x = random(1, (pixels_per_row-1));
line_2_amount_of_tail_pixels = random(5, 12);
line_2_starting_x = random(1, (pixels_per_row-1));
line_3_amount_of_tail_pixels = random(5, 12);
line_3_starting_x = random(1, (pixels_per_row-1));
line_4_amount_of_tail_pixels = random(5, 12);
line_4_starting_x = random(1, (pixels_per_row-1));
line_5_amount_of_tail_pixels = random(5, 12);
line_5_starting_x = random(1, (pixels_per_row-1));
line_1L_amount_of_tail_pixels = random(5, 12);
line_1L_starting_x = random(1, (pixels_per_row-1));
line_2L_amount_of_tail_pixels = random(5, 12);
line_2L_starting_x = random(1, (pixels_per_row-1));
line_3L_amount_of_tail_pixels = random(5, 12);
line_3L_starting_x = random(1, (pixels_per_row-1));
line_4L_amount_of_tail_pixels = random(5, 12);
line_4L_starting_x = random(1, (pixels_per_row-1));
line_5L_amount_of_tail_pixels = random(5, 12);
line_5L_starting_x = random(1, (pixels_per_row-1));
}
void loop() {
time = millis();
// matrix_right.fillScreen(0);
// matrix_left.fillScreen(0);
matrix_right.clear();
matrix_left.clear();
if (fade_between_rain_and_text == false) {
brightness = analogRead(POT_L_PIN);
brightness = map(brightness, 0, 1023, 255, 10);
}
saturation = analogRead(POT_M_PIN);
speed = analogRead(POT_R_PIN);
saturation = map(saturation, 0, 1023, 0, 255);
speed = map(speed, 0, 1023, 3, 1000);
switch_state = digitalRead(switch_pin);
if (switch_state == 1)
rain_effect_turned_on = true;
else
rain_effect_turned_on = false;
//TEXT EFFECT START =============================================
if (text_effect_active == true) {
matrix_right.setBrightness(0.5 * brightness);
matrix_left.setBrightness(0.5 * brightness);
matrix_right.setTextColor(matrix_right.Color(0 + saturation, 255, 0 + saturation));
matrix_left.setTextColor(matrix_left.Color(0 + saturation, 255, 0 + saturation));
//LEFT
matrix_left.setCursor(x, 4);
matrix_left.print(F("FREE YOUR MIND"));
//RIGHT
matrix_right.setCursor(x, 4);
matrix_right.print(F("WELCOME TO THE REAL WORLD"));
x = x - 1;
if (x < -100) {
x = matrix_right.width();
number_of_completed_text_scrolls++;
}
}
//TEXT EFFECT END =============================================
if ((number_of_completed_text_scrolls > (number_of_text_scrolls_before_rain - 1)) && rain_effect_turned_on == true) {
text_effect_active = false;
rain_effect_active = true;
last_millis_rain_started = millis();
number_of_completed_text_scrolls = 0;
line_1_fade_factor = 0;
line_2_fade_factor = 0;
line_3_fade_factor = 0;
line_4_fade_factor = 0;
line_5_fade_factor = 0;
line_1_brightness_needs_fade_in = true;
line_2_brightness_needs_fade_in = true;
line_3_brightness_needs_fade_in = true;
line_4_brightness_needs_fade_in = true;
line_5_brightness_needs_fade_in = true;
line_1L_fade_factor = 0;
line_2L_fade_factor = 0;
line_3L_fade_factor = 0;
line_4L_fade_factor = 0;
line_5L_fade_factor = 0;
line_1L_brightness_needs_fade_in = true;
line_2L_brightness_needs_fade_in = true;
line_3L_brightness_needs_fade_in = true;
line_4L_brightness_needs_fade_in = true;
line_5L_brightness_needs_fade_in = true;
}
if ((millis() - last_millis_rain_started > (duration_of_rain_in_seconds * 1000)) && rain_effect_active == true) {
fade_between_rain_and_text = true;
brightness = brightness - 2;
}
if (brightness < -1 * (white_pixel_brightness_offset) && brightness < -1 * (tail_pixel_brightness_offset)) {
text_effect_active = true;
rain_effect_active = false;
fade_between_rain_and_text = false;
x = matrix_right.width();
line_1_fade_factor = 0;
line_2_fade_factor = 0;
line_3_fade_factor = 0;
line_4_fade_factor = 0;
line_5_fade_factor = 0;
line_1L_fade_factor = 0;
line_2L_fade_factor = 0;
line_3L_fade_factor = 0;
line_4L_fade_factor = 0;
line_5L_fade_factor = 0;
delay(1000);
}
if (rain_effect_active == true) {
matrix_left.setBrightness(255);
matrix_right.setBrightness(255);
rainRightEye();
rainLeftEye();
}
matrix_right.show();
matrix_left.show();
if (rain_effect_active == true)
delay(43);
if (text_effect_active == true)
delay(speed);
}
void rainRightEye() {
drawRainPixelsR();
calculateRainLine1R();
calculateRainLine2R();
calculateRainLine3R();
calculateRainLine4R();
calculateRainLine5R();
x_1 = x_1 + line_1_speed_for_next_rain;
x_2 = x_2 + line_2_speed_for_next_rain;
x_3 = x_3 + line_3_speed_for_next_rain;
x_4 = x_4 + line_4_speed_for_next_rain;
x_5 = x_5 + line_5_speed_for_next_rain;
}
void rainLeftEye() {
drawRainPixelsL();
calculateRainLine1L();
calculateRainLine2L();
calculateRainLine3L();
calculateRainLine4L();
calculateRainLine5L();
x_1L = x_1L + line_1L_speed_for_next_rain;
x_2L = x_2L + line_2L_speed_for_next_rain;
x_3L = x_3L + line_3L_speed_for_next_rain;
x_4L = x_4L + line_4L_speed_for_next_rain;
x_5L = x_5L + line_5L_speed_for_next_rain;
}
void drawRainPixelsR() {
if (line_1_fade_factor > 1)
line_1_fade_factor = 1;
if (line_1_active == true) {
int whiteLedBrightness = ((brightness + white_pixel_brightness_offset) * line_1_fade_factor);
if (whiteLedBrightness > 255)
whiteLedBrightness = 255;
if (whiteLedBrightness < 0)
whiteLedBrightness = 0;
matrix_right.drawPixel(line_1_curent_white_LED_pos, 0, matrix_right.Color(whiteLedBrightness, whiteLedBrightness, whiteLedBrightness));
for (int i = 1; i <= line_1_amount_of_tail_pixels; i++) {
float tail_brightness = (brightness + tail_pixel_brightness_offset) * (1 - (i / line_1_amount_of_tail_pixels));
if (tail_brightness > 254)
tail_brightness = 254;
if (tail_brightness < 0)
tail_brightness = 0;
matrix_right.drawPixel(line_1_curent_white_LED_pos - i, 0, matrix_right.Color(0, tail_brightness * line_1_fade_factor, 0));
if (line_1_curent_white_LED_pos - i < 0) {
matrix_right.drawPixel(pixels_per_row + (line_1_curent_white_LED_pos - i), 0, matrix_right.Color(0, tail_brightness * line_1_fade_factor, 0));
}
}
}
if (line_2_fade_factor > 1)
line_2_fade_factor = 1;
if (line_2_active == true) {
int whiteLedBrightness = ((brightness + white_pixel_brightness_offset) * line_2_fade_factor);
if (whiteLedBrightness > 255)
whiteLedBrightness = 255;
if (whiteLedBrightness < 0)
whiteLedBrightness = 0;
matrix_right.drawPixel(line_2_curent_white_LED_pos, 1, matrix_right.Color(whiteLedBrightness, whiteLedBrightness, whiteLedBrightness));
for (int i = 1; i <= line_2_amount_of_tail_pixels; i++) {
float tail_brightness = (brightness + tail_pixel_brightness_offset) * (1 - (i / line_2_amount_of_tail_pixels));
if (tail_brightness > 254)
tail_brightness = 254;
if (tail_brightness < 0)
tail_brightness = 0;
matrix_right.drawPixel(line_2_curent_white_LED_pos - i, 1, matrix_right.Color(0, tail_brightness * line_2_fade_factor, 0));
if (line_2_curent_white_LED_pos - i < 0) {
matrix_right.drawPixel(pixels_per_row + (line_2_curent_white_LED_pos - i), 1, matrix_right.Color(0, tail_brightness * line_2_fade_factor, 0));
}
}
}
if (line_3_fade_factor > 1)
line_3_fade_factor = 1;
if (line_3_active == true) {
int whiteLedBrightness = ((brightness + white_pixel_brightness_offset) * line_3_fade_factor);
if (whiteLedBrightness > 255)
whiteLedBrightness = 255;
if (whiteLedBrightness < 0)
whiteLedBrightness = 0;
matrix_right.drawPixel(line_3_curent_white_LED_pos, 2, matrix_right.Color(whiteLedBrightness, whiteLedBrightness, whiteLedBrightness));
for (int i = 1; i <= line_3_amount_of_tail_pixels; i++) {
float tail_brightness = (brightness + tail_pixel_brightness_offset) * (1 - (i / line_3_amount_of_tail_pixels));
if (tail_brightness > 254)
tail_brightness = 254;
if (tail_brightness < 0)
tail_brightness = 0;
matrix_right.drawPixel(line_3_curent_white_LED_pos - i, 2, matrix_right.Color(0, tail_brightness * line_3_fade_factor, 0));
if (line_3_curent_white_LED_pos - i < 0) {
matrix_right.drawPixel(pixels_per_row + (line_3_curent_white_LED_pos - i), 2, matrix_right.Color(0, tail_brightness * line_3_fade_factor, 0));
}
}
}
if (line_4_fade_factor > 1)
line_4_fade_factor = 1;
if (line_4_active == true) {
int whiteLedBrightness = ((brightness + white_pixel_brightness_offset) * line_4_fade_factor);
if (whiteLedBrightness > 255)
whiteLedBrightness = 255;
if (whiteLedBrightness < 0)
whiteLedBrightness = 0;
matrix_right.drawPixel(line_4_curent_white_LED_pos, 3, matrix_right.Color(whiteLedBrightness, whiteLedBrightness, whiteLedBrightness));
for (int i = 1; i <= line_4_amount_of_tail_pixels; i++) {
float tail_brightness = (brightness + tail_pixel_brightness_offset) * (1 - (i / line_4_amount_of_tail_pixels));
if (tail_brightness > 254)
tail_brightness = 254;
if (tail_brightness < 0)
tail_brightness = 0;
matrix_right.drawPixel(line_4_curent_white_LED_pos - i, 3, matrix_right.Color(0, tail_brightness * line_4_fade_factor, 0));
if (line_4_curent_white_LED_pos - i < 0) {
matrix_right.drawPixel(pixels_per_row + (line_4_curent_white_LED_pos - i), 3, matrix_right.Color(0, tail_brightness * line_4_fade_factor, 0));
}
}
}
if (line_5_fade_factor > 1)
line_5_fade_factor = 1;
if (line_5_active == true) {
int whiteLedBrightness = ((brightness + white_pixel_brightness_offset) * line_5_fade_factor);
if (whiteLedBrightness > 255)
whiteLedBrightness = 255;
if (whiteLedBrightness < 0)
whiteLedBrightness = 0;
matrix_right.drawPixel(line_5_curent_white_LED_pos, 4, matrix_right.Color(whiteLedBrightness, whiteLedBrightness, whiteLedBrightness));
for (int i = 1; i <= line_5_amount_of_tail_pixels; i++) {
float tail_brightness = (brightness + tail_pixel_brightness_offset) * (1 - (i / line_5_amount_of_tail_pixels));
if (tail_brightness > 254)
tail_brightness = 254;
if (tail_brightness < 0)
tail_brightness = 0;
matrix_right.drawPixel(line_5_curent_white_LED_pos - i, 4, matrix_right.Color(0, tail_brightness * line_5_fade_factor, 0));
if (line_5_curent_white_LED_pos - i < 0) {
matrix_right.drawPixel(pixels_per_row + (line_5_curent_white_LED_pos - i), 4, matrix_right.Color(0, tail_brightness * line_5_fade_factor, 0));
}
}
}
}
void drawRainPixelsL() {
if (line_1L_fade_factor > 1)
line_1L_fade_factor = 1;
if (line_1L_active == true) {
int whiteLedBrightness = ((brightness + white_pixel_brightness_offset) * line_1L_fade_factor);
if (whiteLedBrightness > 255)
whiteLedBrightness = 255;
if (whiteLedBrightness < 0)
whiteLedBrightness = 0;
matrix_left.drawPixel(line_1L_curent_white_LED_pos, 0, matrix_left.Color(whiteLedBrightness, whiteLedBrightness, whiteLedBrightness));
for (int i = 1; i <= line_1L_amount_of_tail_pixels; i++) {
float tail_brightness = (brightness + tail_pixel_brightness_offset) * (1 - (i / line_1L_amount_of_tail_pixels));
if (tail_brightness > 254)
tail_brightness = 254;
if (tail_brightness < 0)
tail_brightness = 0;
matrix_left.drawPixel(line_1L_curent_white_LED_pos - i, 0, matrix_left.Color(0, tail_brightness * line_1L_fade_factor, 0));
if (line_1L_curent_white_LED_pos - i < 0) {
matrix_left.drawPixel(pixels_per_row + (line_1L_curent_white_LED_pos - i), 0, matrix_left.Color(0, tail_brightness * line_1L_fade_factor, 0));
}
}
}
if (line_2L_fade_factor > 1)
line_2L_fade_factor = 1;
if (line_2L_active == true) {
int whiteLedBrightness = ((brightness + white_pixel_brightness_offset) * line_2L_fade_factor);
if (whiteLedBrightness > 255)
whiteLedBrightness = 255;
if (whiteLedBrightness < 0)
whiteLedBrightness = 0;
matrix_left.drawPixel(line_2L_curent_white_LED_pos, 1, matrix_left.Color(whiteLedBrightness, whiteLedBrightness, whiteLedBrightness));
for (int i = 1; i <= line_2L_amount_of_tail_pixels; i++) {
float tail_brightness = (brightness + tail_pixel_brightness_offset) * (1 - (i / line_2L_amount_of_tail_pixels));
if (tail_brightness > 254)
tail_brightness = 254;
if (tail_brightness < 0)
tail_brightness = 0;
matrix_left.drawPixel(line_2L_curent_white_LED_pos - i, 1, matrix_left.Color(0, tail_brightness * line_2L_fade_factor, 0));
if (line_2L_curent_white_LED_pos - i < 0) {
matrix_left.drawPixel(pixels_per_row + (line_2L_curent_white_LED_pos - i), 1, matrix_left.Color(0, tail_brightness * line_2L_fade_factor, 0));
}
}
}
if (line_3L_fade_factor > 1)
line_3L_fade_factor = 1;
if (line_3L_active == true) {
int whiteLedBrightness = ((brightness + white_pixel_brightness_offset) * line_3L_fade_factor);
if (whiteLedBrightness > 255)
whiteLedBrightness = 255;
if (whiteLedBrightness < 0)
whiteLedBrightness = 0;
matrix_left.drawPixel(line_3L_curent_white_LED_pos, 2, matrix_left.Color(whiteLedBrightness, whiteLedBrightness, whiteLedBrightness));
for (int i = 1; i <= line_3L_amount_of_tail_pixels; i++) {
float tail_brightness = (brightness + tail_pixel_brightness_offset) * (1 - (i / line_3L_amount_of_tail_pixels));
if (tail_brightness > 254)
tail_brightness = 254;
if (tail_brightness < 0)
tail_brightness = 0;
matrix_left.drawPixel(line_3L_curent_white_LED_pos - i, 2, matrix_left.Color(0, tail_brightness * line_3L_fade_factor, 0));
if (line_3L_curent_white_LED_pos - i < 0) {
matrix_left.drawPixel(pixels_per_row + (line_3L_curent_white_LED_pos - i), 2, matrix_left.Color(0, tail_brightness * line_3L_fade_factor, 0));
}
}
}
if (line_4L_fade_factor > 1)
line_4L_fade_factor = 1;
if (line_4L_active == true) {
int whiteLedBrightness = ((brightness + white_pixel_brightness_offset) * line_4L_fade_factor);
if (whiteLedBrightness > 255)
whiteLedBrightness = 255;
if (whiteLedBrightness < 0)
whiteLedBrightness = 0;
matrix_left.drawPixel(line_4L_curent_white_LED_pos, 3, matrix_left.Color(whiteLedBrightness, whiteLedBrightness, whiteLedBrightness));
for (int i = 1; i <= line_4L_amount_of_tail_pixels; i++) {
float tail_brightness = (brightness + tail_pixel_brightness_offset) * (1 - (i / line_4L_amount_of_tail_pixels));
if (tail_brightness > 254)
tail_brightness = 254;
if (tail_brightness < 0)
tail_brightness = 0;
matrix_left.drawPixel(line_4L_curent_white_LED_pos - i, 3, matrix_left.Color(0, tail_brightness * line_4L_fade_factor, 0));
if (line_4L_curent_white_LED_pos - i < 0) {
matrix_left.drawPixel(pixels_per_row + (line_4L_curent_white_LED_pos - i), 3, matrix_left.Color(0, tail_brightness * line_4L_fade_factor, 0));
}
}
}
if (line_5L_fade_factor > 1)
line_5L_fade_factor = 1;
if (line_5L_active == true) {
int whiteLedBrightness = ((brightness + white_pixel_brightness_offset) * line_5L_fade_factor);
if (whiteLedBrightness > 255)
whiteLedBrightness = 255;
if (whiteLedBrightness < 0)
whiteLedBrightness = 0;
matrix_left.drawPixel(line_5L_curent_white_LED_pos, 4, matrix_left.Color(whiteLedBrightness, whiteLedBrightness, whiteLedBrightness));
for (int i = 1; i <= line_5L_amount_of_tail_pixels; i++) {
float tail_brightness = (brightness + tail_pixel_brightness_offset) * (1 - (i / line_5L_amount_of_tail_pixels));
if (tail_brightness > 254)
tail_brightness = 254;
if (tail_brightness < 0)
tail_brightness = 0;
matrix_left.drawPixel(line_5L_curent_white_LED_pos - i, 4, matrix_left.Color(0, tail_brightness * line_5L_fade_factor, 0));
if (line_5L_curent_white_LED_pos - i < 0) {
matrix_left.drawPixel(pixels_per_row + (line_5L_curent_white_LED_pos - i), 4, matrix_left.Color(0, tail_brightness * line_5L_fade_factor, 0));
}
}
}
}
void calculateRainLine1R() {
//------------------------------------------------------- START LINE 1
//Current white light is the x counter plus the starting point offset
line_1_curent_white_LED_pos = line_1_starting_x + x_1;
while (line_1_curent_white_LED_pos > (pixels_per_row-1)) {
line_1_curent_white_LED_pos = line_1_curent_white_LED_pos - pixels_per_row;
// line_1_starting_x = 0;
}
//If fading brightness is below 1 and brightness needs to be faded to on again, increase the fade brightness
if (line_1_fade_factor < 1 && line_1_brightness_needs_fade_in == true) {
line_1_fade_factor = line_1_fade_factor + 0.03;
}
if (x_1 > line_1_x_limit_for_this_rain) {
line_1_brightness_needs_fade_in = false;
line_1_fade_factor = line_1_fade_factor - 0.03;
if (line_1_fade_factor < 0) {
line_1_fade_factor = 0;
line_1_brightness_needs_fade_in = true;
line_1_starting_x = random(0, (pixels_per_row-1));
line_1_x_limit_for_this_rain = line_1_starting_x + random(minimum_x_steps_per_rain, maximum_x_steps_per_rain);
line_1_amount_of_tail_pixels = random(minimum_tail_length, maximum_tail_length);
int speedpicker = random(1, 4);
if (speedpicker == 1)
line_1_speed_for_next_rain = 1;
if (speedpicker == 2)
line_1_speed_for_next_rain = 0.5;
if (speedpicker == 3)
line_1_speed_for_next_rain = 0.34;
x_1 = 0;
//RANDOMIZING IF THE NEXT RAIN WILL BE VISIBLE OR HIDDEN
int r = random(0, 100);
if (r < rain_frequency) {
line_1_active = true;
} else {
line_1_active = false;
}
}
}
//------------------------------------------------------- END LINE 1
}
void calculateRainLine2R() {
//------------------------------------------------------- START LINE 2
//Current white light is the x counter plus the starting point offset
line_2_curent_white_LED_pos = line_2_starting_x + x_2;
while (line_2_curent_white_LED_pos > (pixels_per_row-1)) {
line_2_curent_white_LED_pos = line_2_curent_white_LED_pos - pixels_per_row;
// line_2_starting_x = 0;
}
//If fading brightness is below 1 and brightness needs to be faded to on again, increase the fade brightness
if (line_2_fade_factor < 1 && line_2_brightness_needs_fade_in == true) {
line_2_fade_factor = line_2_fade_factor + 0.03;
}
if (x_2 > line_2_x_limit_for_this_rain) {
line_2_brightness_needs_fade_in = false;
line_2_fade_factor = line_2_fade_factor - 0.03;
if (line_2_fade_factor < 0) {
line_2_fade_factor = 0;
line_2_brightness_needs_fade_in = true;
line_2_starting_x = random(0, (pixels_per_row-1));
line_2_x_limit_for_this_rain = line_2_starting_x + random(minimum_x_steps_per_rain, maximum_x_steps_per_rain);
line_2_amount_of_tail_pixels = random(minimum_tail_length, maximum_tail_length);
int speedpicker = random(1, 4);
if (speedpicker == 1)
line_2_speed_for_next_rain = 1;
if (speedpicker == 2)
line_2_speed_for_next_rain = 0.5;
if (speedpicker == 3)
line_2_speed_for_next_rain = 0.34;
x_2 = 0;
//RANDOMIZING IF THE NEXT RAIN WILL BE VISIBLE OR HIDDEN
int r = random(0, 100);
if (r < rain_frequency) {
line_2_active = true;
} else {
line_2_active = false;
}
}
}
//------------------------------------------------------- END LINE 2
}
void calculateRainLine3R() {
//------------------------------------------------------- START LINE 3
//Current white light is the x counter plus the starting point offset
line_3_curent_white_LED_pos = line_3_starting_x + x_3;
while (line_3_curent_white_LED_pos > (pixels_per_row-1)) {
line_3_curent_white_LED_pos = line_3_curent_white_LED_pos - pixels_per_row;
// line_3_starting_x = 0;
}
//If fading brightness is below 1 and brightness needs to be faded to on again, increase the fade brightness
if (line_3_fade_factor < 1 && line_3_brightness_needs_fade_in == true) {
line_3_fade_factor = line_3_fade_factor + 0.03;
}
if (x_3 > line_3_x_limit_for_this_rain) {
line_3_brightness_needs_fade_in = false;
line_3_fade_factor = line_3_fade_factor - 0.03;
if (line_3_fade_factor < 0) {
line_3_fade_factor = 0;
line_3_brightness_needs_fade_in = true;
line_3_starting_x = random(0, (pixels_per_row-1));
line_3_x_limit_for_this_rain = line_3_starting_x + random(minimum_x_steps_per_rain, maximum_x_steps_per_rain);
line_3_amount_of_tail_pixels = random(minimum_tail_length, maximum_tail_length);
int speedpicker = random(1, 4);
if (speedpicker == 1)
line_3_speed_for_next_rain = 1;
if (speedpicker == 2)
line_3_speed_for_next_rain = 0.5;
if (speedpicker == 3)
line_3_speed_for_next_rain = 0.34;
x_3 = 0;
//RANDOMIZING IF THE NEXT RAIN WILL BE VISIBLE OR HIDDEN
int r = random(0, 100);
if (r < rain_frequency) {
line_3_active = true;
} else {
line_3_active = false;
}
}
}
//------------------------------------------------------- END LINE 3
}
void calculateRainLine4R() {
//------------------------------------------------------- START LINE 4
//Current white light is the x counter plus the starting point offset
line_4_curent_white_LED_pos = line_4_starting_x + x_4;
while (line_4_curent_white_LED_pos > (pixels_per_row-1)) {
line_4_curent_white_LED_pos = line_4_curent_white_LED_pos - pixels_per_row;
// line_4_starting_x = 0;
}
//If fading brightness is below 1 and brightness needs to be faded to on again, increase the fade brightness
if (line_4_fade_factor < 1 && line_4_brightness_needs_fade_in == true) {
line_4_fade_factor = line_4_fade_factor + 0.03;
}
if (x_4 > line_4_x_limit_for_this_rain) {
line_4_brightness_needs_fade_in = false;
line_4_fade_factor = line_4_fade_factor - 0.03;
if (line_4_fade_factor < 0) {
line_4_fade_factor = 0;
line_4_brightness_needs_fade_in = true;
line_4_starting_x = random(0, (pixels_per_row-1));
line_4_x_limit_for_this_rain = line_4_starting_x + random(minimum_x_steps_per_rain, maximum_x_steps_per_rain);
line_4_amount_of_tail_pixels = random(minimum_tail_length, maximum_tail_length);
int speedpicker = random(1, 4);
if (speedpicker == 1)
line_4_speed_for_next_rain = 1;
if (speedpicker == 2)
line_4_speed_for_next_rain = 0.5;
if (speedpicker == 3)
line_4_speed_for_next_rain = 0.34;
x_4 = 0;
//RANDOMIZING IF THE NEXT RAIN WILL BE VISIBLE OR HIDDEN
int r = random(0, 100);
if (r < rain_frequency) {
line_4_active = true;
} else {
line_4_active = false;
}
}
}
//------------------------------------------------------- END LINE 4
}
void calculateRainLine5R() {
//------------------------------------------------------- START LINE 5
//Current white light is the x counter plus the starting point offset
line_5_curent_white_LED_pos = line_5_starting_x + x_5;
while (line_5_curent_white_LED_pos > (pixels_per_row-1)) {
line_5_curent_white_LED_pos = line_5_curent_white_LED_pos - pixels_per_row;
// line_5_starting_x = 0;
}
//If fading brightness is below 1 and brightness needs to be faded to on again, increase the fade brightness
if (line_5_fade_factor < 1 && line_5_brightness_needs_fade_in == true) {
line_5_fade_factor = line_5_fade_factor + 0.03;
}
if (x_5 > line_5_x_limit_for_this_rain) {
line_5_brightness_needs_fade_in = false;
line_5_fade_factor = line_5_fade_factor - 0.03;
if (line_5_fade_factor < 0) {
line_5_fade_factor = 0;
line_5_brightness_needs_fade_in = true;
line_5_starting_x = random(0, (pixels_per_row-1));
line_5_x_limit_for_this_rain = line_5_starting_x + random(minimum_x_steps_per_rain, maximum_x_steps_per_rain);
line_5_amount_of_tail_pixels = random(minimum_tail_length, maximum_tail_length);
int speedpicker = random(1, 4);
if (speedpicker == 1)
line_5_speed_for_next_rain = 1;
if (speedpicker == 2)
line_5_speed_for_next_rain = 0.5;
if (speedpicker == 3)
line_5_speed_for_next_rain = 0.34;
x_5 = 0;
//RANDOMIZING IF THE NEXT RAIN WILL BE VISIBLE OR HIDDEN
int r = random(0, 100);
if (r < rain_frequency) {
line_5_active = true;
} else {
line_5_active = false;
}
}
}
}
//------------------------------------------------------- END LINE 5
void calculateRainLine1L() {
//------------------------------------------------------- START LINE 1
//Current white light is the x counter plus the starting point offset
line_1L_curent_white_LED_pos = line_1L_starting_x + x_1L;
while (line_1L_curent_white_LED_pos > (pixels_per_row-1)) {
line_1L_curent_white_LED_pos = line_1L_curent_white_LED_pos - pixels_per_row;
// line_1L_starting_x = 0;
}
//If fading brightness is below 1 and brightness needs to be faded to on again, increase the fade brightness
if (line_1L_fade_factor < 1 && line_1L_brightness_needs_fade_in == true) {
line_1L_fade_factor = line_1L_fade_factor + 0.03;
}
if (x_1L > line_1L_x_limit_for_this_rain) {
line_1L_brightness_needs_fade_in = false;
line_1L_fade_factor = line_1L_fade_factor - 0.03;
if (line_1L_fade_factor < 0) {
line_1L_fade_factor = 0;
line_1L_brightness_needs_fade_in = true;
line_1L_starting_x = random(0, (pixels_per_row-1));
line_1L_x_limit_for_this_rain = line_1L_starting_x + random(minimum_x_steps_per_rain, maximum_x_steps_per_rain);
line_1L_amount_of_tail_pixels = random(minimum_tail_length, maximum_tail_length);
int speedpicker = random(1, 4);
if (speedpicker == 1)
line_1L_speed_for_next_rain = 1;
if (speedpicker == 2)
line_1L_speed_for_next_rain = 0.5;
if (speedpicker == 3)
line_1L_speed_for_next_rain = 0.34;
x_1L = 0;
//RANDOMIZING IF THE NEXT RAIN WILL BE VISIBLE OR HIDDEN
int r = random(0, 100);
if (r < rain_frequency) {
line_1L_active = true;
} else {
line_1L_active = false;
}
}
//------------------------------------------------------- END LINE 1
}
}
void calculateRainLine2L() {
//------------------------------------------------------- START LINE 1
//Current white light is the x counter plus the starting point offset
line_2L_curent_white_LED_pos = line_2L_starting_x + x_2L;
while (line_2L_curent_white_LED_pos > (pixels_per_row-1)) {
line_2L_curent_white_LED_pos = line_2L_curent_white_LED_pos - pixels_per_row;
// line_2L_starting_x = 0;
}
//If fading brightness is below 1 and brightness needs to be faded to on again, increase the fade brightness
if (line_2L_fade_factor < 1 && line_2L_brightness_needs_fade_in == true) {
line_2L_fade_factor = line_2L_fade_factor + 0.03;
}
if (x_2L > line_2L_x_limit_for_this_rain) {
line_2L_brightness_needs_fade_in = false;
line_2L_fade_factor = line_2L_fade_factor - 0.03;
if (line_2L_fade_factor < 0) {
line_2L_fade_factor = 0;
line_2L_brightness_needs_fade_in = true;
line_2L_starting_x = random(0, (pixels_per_row-1));
line_2L_x_limit_for_this_rain = line_2L_starting_x + random(minimum_x_steps_per_rain, maximum_x_steps_per_rain);
line_2L_amount_of_tail_pixels = random(minimum_tail_length, maximum_tail_length);
int speedpicker = random(1, 4);
if (speedpicker == 1)
line_2L_speed_for_next_rain = 1;
if (speedpicker == 2)
line_2L_speed_for_next_rain = 0.5;
if (speedpicker == 3)
line_2L_speed_for_next_rain = 0.34;
x_2L = 0;
//RANDOMIZING IF THE NEXT RAIN WILL BE VISIBLE OR HIDDEN
int r = random(0, 100);
if (r < rain_frequency) {
line_2L_active = true;
} else {
line_2L_active = false;
}
}
//------------------------------------------------------- END LINE 1
}
}
void calculateRainLine3L() {
//------------------------------------------------------- START LINE 1
//Current white light is the x counter plus the starting point offset
line_3L_curent_white_LED_pos = line_3L_starting_x + x_3L;
while (line_3L_curent_white_LED_pos > (pixels_per_row-1)) {
line_3L_curent_white_LED_pos = line_3L_curent_white_LED_pos - pixels_per_row;
// line_3L_starting_x = 0;
}
//If fading brightness is below 1 and brightness needs to be faded to on again, increase the fade brightness
if (line_3L_fade_factor < 1 && line_3L_brightness_needs_fade_in == true) {
line_3L_fade_factor = line_3L_fade_factor + 0.03;
}
if (x_3L > line_3L_x_limit_for_this_rain) {
line_3L_brightness_needs_fade_in = false;
line_3L_fade_factor = line_3L_fade_factor - 0.03;
if (line_3L_fade_factor < 0) {
line_3L_fade_factor = 0;
line_3L_brightness_needs_fade_in = true;
line_3L_starting_x = random(0, (pixels_per_row-1));
line_3L_x_limit_for_this_rain = line_3L_starting_x + random(minimum_x_steps_per_rain, maximum_x_steps_per_rain);
line_3L_amount_of_tail_pixels = random(minimum_tail_length, maximum_tail_length);
int speedpicker = random(1, 4);
if (speedpicker == 1)
line_3L_speed_for_next_rain = 1;
if (speedpicker == 2)
line_3L_speed_for_next_rain = 0.5;
if (speedpicker == 3)
line_3L_speed_for_next_rain = 0.34;
x_3L = 0;
//RANDOMIZING IF THE NEXT RAIN WILL BE VISIBLE OR HIDDEN
int r = random(0, 100);
if (r < rain_frequency) {
line_3L_active = true;
} else {
line_3L_active = false;
}
}
//------------------------------------------------------- END LINE 1
}
}
void calculateRainLine4L() {
//------------------------------------------------------- START LINE 1
//Current white light is the x counter plus the starting point offset
line_4L_curent_white_LED_pos = line_4L_starting_x + x_4L;
while (line_4L_curent_white_LED_pos > (pixels_per_row-1)) {
line_4L_curent_white_LED_pos = line_4L_curent_white_LED_pos - pixels_per_row;
// line_4L_starting_x = 0;
}
//If fading brightness is below 1 and brightness needs to be faded to on again, increase the fade brightness
if (line_4L_fade_factor < 1 && line_4L_brightness_needs_fade_in == true) {
line_4L_fade_factor = line_4L_fade_factor + 0.03;
}
if (x_4L > line_4L_x_limit_for_this_rain) {
line_4L_brightness_needs_fade_in = false;
line_4L_fade_factor = line_4L_fade_factor - 0.03;
if (line_4L_fade_factor < 0) {
line_4L_fade_factor = 0;
line_4L_brightness_needs_fade_in = true;
line_4L_starting_x = random(0, (pixels_per_row-1));
line_4L_x_limit_for_this_rain = line_4L_starting_x + random(minimum_x_steps_per_rain, maximum_x_steps_per_rain);
line_4L_amount_of_tail_pixels = random(minimum_tail_length, maximum_tail_length);
int speedpicker = random(1, 4);
if (speedpicker == 1)
line_4L_speed_for_next_rain = 1;
if (speedpicker == 2)
line_4L_speed_for_next_rain = 0.5;
if (speedpicker == 3)
line_4L_speed_for_next_rain = 0.34;
x_4L = 0;
//RANDOMIZING IF THE NEXT RAIN WILL BE VISIBLE OR HIDDEN
int r = random(0, 100);
if (r < rain_frequency) {
line_4L_active = true;
} else {
line_4L_active = false;
}
}
//------------------------------------------------------- END LINE 1
}
}
void calculateRainLine5L() {
//------------------------------------------------------- START LINE 1
//Current white light is the x counter plus the starting point offset
line_5L_curent_white_LED_pos = line_5L_starting_x + x_5L;
while (line_5L_curent_white_LED_pos > (pixels_per_row-1)) {
line_5L_curent_white_LED_pos = line_5L_curent_white_LED_pos - pixels_per_row;
// line_5L_starting_x = 0;
}
//If fading brightness is below 1 and brightness needs to be faded to on again, increase the fade brightness
if (line_5L_fade_factor < 1 && line_5L_brightness_needs_fade_in == true) {
line_5L_fade_factor = line_5L_fade_factor + 0.03;
}
if (x_5L > line_5L_x_limit_for_this_rain) {
line_5L_brightness_needs_fade_in = false;
line_5L_fade_factor = line_5L_fade_factor - 0.03;
if (line_5L_fade_factor < 0) {
line_5L_fade_factor = 0;
line_5L_brightness_needs_fade_in = true;
line_5L_starting_x = random(0, (pixels_per_row-1));
line_5L_x_limit_for_this_rain = line_5L_starting_x + random(minimum_x_steps_per_rain, maximum_x_steps_per_rain);
line_5L_amount_of_tail_pixels = random(minimum_tail_length, maximum_tail_length);
int speedpicker = random(1, 4);
if (speedpicker == 1)
line_5L_speed_for_next_rain = 1;
if (speedpicker == 2)
line_5L_speed_for_next_rain = 0.5;
if (speedpicker == 3)
line_5L_speed_for_next_rain = 0.34;
x_5L = 0;
//RANDOMIZING IF THE NEXT RAIN WILL BE VISIBLE OR HIDDEN
int r = random(0, 100);
if (r < rain_frequency) {
line_5L_active = true;
} else {
line_5L_active = false;
}
}
//------------------------------------------------------- END LINE 1
}
}