TL;DR: I tried to have a random fading pattern on several leds and it leads to flickering.
Edited following @chrisl answer.
I am in the process of creating a simple lamp that show some light patterns using 6 led and an arduino uno. The goal is that depending on some inputs and a bit of randomisation, the patterns will change. For instance, only 2 lights at the same time but fading up and down randomly on all 6 led. Or 4 lights fading up and down randomly on the 6 leds.
I decided to create a struct that would be a light pattern named a particle, and this particle have a variable named led_position that shows which led it is on at a certain moment. The particle can change its position to light up an other led.
I know this is not the clearest of explanation but I hope my code will be more straightforward:
Main code #include "MyTypes.h"
int led1 = 9; // the PWM pin the LED is attached to
int led2 = 10;
int led3 = 11;
int led4 = 6;
int led5 = 3;
int led6 = 5;
//int led;
int brightness;
int fadeAmount;
// Definition of the different particles
particle_type particle[]={
{ 0,led1,0, 2, false },
{ 1,led2,50, 2, false },
{ 2,led3,100, 2, false },
{ 3,led4,80, 2, false },
{ 4,led5,30, 2, false},
{ 5, led6,70, 2, false},
};
led_type led[]={
{ 3,false },
{ 5,false },
{ 6,false },
{ 9,false },
{ 10,false },
{ 11,false },
};
//initiation of the particles
void initiate_particle(particle_type& particle_example,led_type led[]){
//take a random led from list of led
int number=random(5);
led[number];
if (led[number].busy == false){ //if led non-occupied
particle_example.led_position=led[number].led_position;
led[number].busy = true ;//take this led as output
}
else{
// particle_example.led_position=particle_example.led_position; //keep same led
}
particle_example.reset = false; //reset turned off
// delay(30);
}
void update_light(particle_type& particle_example,led_type led[]){ //updating led brightness
analogWrite(particle_example.led_position, particle_example.brightness); //updating led brightness
if (particle_example.brightness >= 160) {
particle_example.fadeAmount = -particle_example.fadeAmount;
}
if (particle_example.brightness <= 160 && particle_example.brightness >= 100 ) {
particle_example.brightness = particle_example.brightness + 2*particle_example.fadeAmount;
}
if (particle_example.brightness >= 50 && particle_example.brightness <= 100){
particle_example.brightness = particle_example.brightness + particle_example.fadeAmount;
}
if (particle_example.brightness >= 0 && particle_example.brightness <= 50){
particle_example.brightness = particle_example.brightness + 0.5*particle_example.fadeAmount;
}
if (particle_example.brightness <= 0){
particle_example.reset= true;
int number = particle_example.led_position;
led[number].busy=false;
particle_example.fadeAmount = -particle_example.fadeAmount;
}
}
void activate_particle(particle_type& particle_example,led_type led[]){ //function to keep led activated
if (particle_example.reset==true){ //if led not initiated or has finished its dimming down
initiate_particle(particle_example, led); //initiate it again
;}
else {
update_light(particle_example,led); //update its brightness
}
}
void setup() { //create led outputs
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(led5, OUTPUT);
pinMode(led6, OUTPUT);
Serial.begin(9600); //serial for debug
}
void loop() {
activate_particle(particle[0],led);
// activate_particle(particle[1],led);
// activate_particle(particle[2],led);
// activate_particle(particle[3],led);
// activate_particle(particle[4],led);
// activate_particle(particle[5],led);
//
delay(5); // 20-17-15-12-10-7-2
}
Mytypes.h
typedef struct {
int id;
int led_position;
int brightness;
int fadeAmount;
bool reset;
} particle_type;
typedef struct {
int led_position;
bool busy;
} led_type;
This seems to work more or less but I still have the problem of particles "choosing" the same led to light up and it make the led flickers.
I am struggling on this. I have tried to add a data field for busy and create a new struct for led to no avail.
Even when only one particle is on, the different leds seems to deactivate after a few rounds.
Let me know if you figure it out, thanks!
EDIT 2:
#include "MyTypes.h"
int led0 = 3; // the PWM pin the LED is attached to
int led1 = 5;
int led2 = 6;
int led3 = 9;
int led4 = 10;
int led5 = 11;
//int led;
int brightness;
int fadeAmount;
// Definition of the different particles
particle_type particle[]={
{ 0,led0,0, 4, false },
{ 1,led1,50, 4, false },
{ 2,led2,100, 4, false },
{ 3,led3,80, 4, false },
{ 4,led4,30, 4, false},
{ 5,led5,70, 4, false},
};
led_type led[]={
{ 3,false },
{ 5,false },
{ 6,false },
{ 9,false },
{ 10,false },
{ 11,false },
};
//initiation of the particles
void initiate_particle(particle_type& particle_example,led_type led[]){
//take a random led from list of led
int number=random(6);
Serial.println(number);
led[number];
if (led[number].busy == false){ //if led non-occupied
for (int i=0;i<6;i++){
if (led[i].led_position==particle_example.led_position){
led[i].busy=false;
Serial.println("success");
Serial.println(led[i].led_position);
}
}
particle_example.led_position=led[number].led_position;
Serial.println(particle_example.led_position);
led[number].busy = true ;//take this led as output
particle_example.reset = false; //reset turned off
}
else{
// initiate_particle( particle_example,led);
}
delay(30);
}
void update_light(particle_type& particle_example,led_type led[]){ //updating led brightness
analogWrite(particle_example.led_position, particle_example.brightness); //updating led brightness
if (particle_example.brightness >= 160) {
particle_example.fadeAmount = -particle_example.fadeAmount;
particle_example.brightness = particle_example.brightness + 2*particle_example.fadeAmount;
}
else if (particle_example.brightness < 160 && particle_example.brightness >= 100 ) {
particle_example.brightness = particle_example.brightness + 1.5*particle_example.fadeAmount;
}
else if (particle_example.brightness > 50 && particle_example.brightness <= 100){
particle_example.brightness = particle_example.brightness + particle_example.fadeAmount;
}
else if (particle_example.brightness > 0 && particle_example.brightness <= 50){
particle_example.brightness = particle_example.brightness + 0.25*particle_example.fadeAmount;
}
else if (particle_example.brightness <= 0){
particle_example.reset= true;
particle_example.brightness =0;
int number = particle_example.led_position;
if (particle_example.fadeAmount<0){
particle_example.brightness = 0;
particle_example.fadeAmount = -particle_example.fadeAmount;
}
else{
particle_example.brightness = particle_example.brightness + 0.5*particle_example.fadeAmount;
}
}
}
void activate_particle(particle_type& particle_example,led_type led[]){ //function to keep led activated
if (particle_example.reset==true){ //if led not initiated or has finished its dimming down
initiate_particle(particle_example, led); //initiate it again
;}
else {
update_light(particle_example,led); //update its brightness
}
}
void setup() { //create led outputs
pinMode(led0, OUTPUT);
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(led5, OUTPUT);
Serial.begin(9600); //serial for debug
}
void loop() {
activate_particle(particle[0],led);
activate_particle(particle[1],led);
activate_particle(particle[2],led);
// activate_particle(particle[3],led);
// activate_particle(particle[4],led);
// activate_particle(particle[5],led);
//
delay(10); // 20-17-15-12-10-7-2
}
void loop() {
activate_particle(particle[0],led);
activate_particle(particle[1],led);
activate_particle(particle[2],led);
activate_particle(particle[3],led);
// activate_particle(particle[4],led);
// activate_particle(particle[5],led);
//
delay(10); // 20-17-15-12-10-7-2
}
Now the code works well up to 3 particles but messes things up for 4,5,6 particles with flickering and absence of light.