1843

With a 24V LED system garlands with fixed brightness, animate them with a controller for variable and random brightness with an Arduino.

See also my projects:

The basis: 24V system of multi-coloured LED garlands for Christmas trees with 220V transformer and rectifier. The brightness of the garlands is fixed.

 Project: animate the LED lights with an Arduino to have variations in on-off and variations in brightness, and random choice.

 The components:
 - 1 Arduino Nano
 - 1 Arduino support for tests
 - 1 power supply for the Arduino from 24V (Internet shop)
 - 1 FET module for garland control (Internet shop)
 - 1 interface driver for the FET module with the Arduino
 - 1 printed circuit board with holes for mounting
 - several connectors for garlands
 - 1 plastic box to encapsulate the project
For information, I found 24V LED garlands at lumitronix web site, with transformer and rectifier.

 At this stage of the project, I choose to program Arduino to control only one PWM output.
 Also, I choose to set seven different control light programs in two sets :
 - one set to control ON/OFF light with different ON time and OFF;
 - one set to control variable PWM light with different time.

 Each program is selected randomly. In my first tests I saw that Arduino random is not so random. So I added a new lib for TrueRandom. With it I saw selected random program is more random.

 For PWM control, I choose 32 steps for ON and the same for OFF variations in sine wave because eye light perception is not linear.

 Here is the listing:

 //
 //
 /*
     Name:       Led_Guirlandes.ino
     Created:    05/01/2019 20:18:18
     Author:     Sergio
     Gestion et animation d'1 guirlande LED sous 24V
     Base : Arduino Nano + tampon de commande + module avec IRF520 transistor + module alim abaisseur tension 24V > 8V for arduino nano
     Animation en ON/OFF et en variations lumineuses

 1- clignotement
     ON 500ms
     OFF 1500ms - 30% lum
     durée 10000ms - as X 5

 2- clignotement
     ON 500ms
     OFF 500ms - 0%
     durée 10000ms - as X 10

 3- clignotement
     ON 1000ms
     OFF 500ms - 0%
     durée 15000ms - as X 10

 4- clignotement
     ON 2500ms
     OFF 500ms - 0%
     durée 18000ms - as X 6

 5- var
     OFF-ON 1024ms    multiple of 32
     ON-OFF 1024ms    multiple of 32 may be different from ON
     wait OFF 0ms
     durée as X 7

 6- var
     OFF-ON 3008ms    multiple of 32
     ON-OFF 3008ms    multiple of 32 may be different from ON
     wait OFF 0ms
     durée as X 4

 7- var
   OFF-ON 1984ms multiple of 32
   ON-OFF 3520ms multiple of 32 may be different from ON
   wait OFF 0ms
   durée as X 5

     Var will varying following sine wave values in 32 steps from 0 to max and reverse (analog output) :
     0, 13, 26, 38, 51, 63, 76, 88, 100, 111, 123, 134, 145, 155, 165, 175, 184, 192, 200, 208, 215, 222, 228, 233, 238, 243, 246, 249, 252, 253, 254, 255

 */

 #include < truerandom.h >

 // Defining User Types
 //    1 guirlande for this project
 #define GUIRL_A  5        // pin for guirlande A digital 5 pin 8 PWM

 // #define GUIRL_B  6        // pin for guirlande B digital 6 pin 9 PWM

 #define MAXPROGR 7        // Max value of Nb programs



 // 32 half sine values for var program led :
 int varoutvalue[] = { 0, 13, 26, 38, 51, 63, 76, 88, 100, 111, 123, 134, 145, 155, 165, 175, 184, 192, 200, 208, 215, 222, 228, 233, 238, 243, 246, 249, 252, 253, 254, 255 };

 // Guirlande status 0 inactive, pgm ended - 1 pgm selected -
 int guirl_status = 0;

 // selected program for guirlande 0 to MAXPROGR-1
 int sel_guirl_pgm = 0;


 // struct for program led
 typedef struct     /* programled définition de la structure */
 {
     int ledvar;        /* 0 clignotement flashing ; 1 variation de la luminosité */
     int ledon;        /* time ON */
     int ledoff;        /* time OFF */
     int ledvaloff;    /* value for OFF status different of 0 */
     int ledxtime;    /* repeat x time this program */
 } pled_t;

 pled_t pled [MAXPROGR];  /* reserve memory for the multiple programs for led */


 // values for each step in Var program for leds, 32 steps for OFF to ON and same for ON to OFF
 const int varval[] = { 0, 13, 26, 38, 51, 63, 76, 88, 100, 111, 123, 134, 145, 155, 165, 175, 184, 192, 200, 208, 215, 222, 228, 233, 238, 243, 246, 249, 252, 253, 254, 255 };


 // Defining Function Prototypes that use User Types
 //


 // Defining Functions below here or use other .ino or cpp files
 //
 // select a random program for guirlande
 int guirl_pgm_select(void)
 {
     randomSeed(TrueRandom.random());
     return random(MAXPROGR);
 //  return TrueRandom.random(MAXPROGR);
 }


 // The setup() function runs once each time the micro-controller starts
 void setup(void)
 {
 // init for the MAXPROGR programs led
  
     pled[0].ledvar = 0;
     pled[0].ledon = 500;
     pled[0].ledoff = 1500;
     pled[0].ledvaloff = 112;
     pled[0].ledxtime = 5;

     pled[1].ledvar = 0;
     pled[1].ledon = 500;
     pled[1].ledoff = 500;
     pled[1].ledvaloff = 0;
     pled[1].ledxtime = 10;

     pled[2].ledvar = 0;
     pled[2].ledon = 1000;
     pled[2].ledoff = 500;
     pled[2].ledvaloff = 0;
     pled[2].ledxtime = 10;

     pled[3].ledvar = 0;
     pled[3].ledon = 2500;
     pled[3].ledoff = 500;
     pled[3].ledvaloff = 0;
     pled[3].ledxtime = 6;

     pled[4].ledvar = 1;
     pled[4].ledon = 1024;
     pled[4].ledoff = 1024;
     pled[4].ledvaloff = 0;
     pled[4].ledxtime = 7;

     pled[5].ledvar = 1;
     pled[5].ledon = 3008;
     pled[5].ledoff = 3008;
     pled[5].ledvaloff = 0;
     pled[5].ledxtime = 4;

     pled[6].ledvar = 1;
     pled[6].ledon = 1984;
     pled[6].ledoff = 3520;
     pled[6].ledvaloff = 0;
     pled[6].ledxtime = 5;

     
 pinMode(GUIRL_A,OUTPUT);    // pin for guirlande A
 analogWrite(GUIRL_A, 0);    // set output to 0

 Serial.begin(115200);        // begin serial print for debug

 }   // end setup

 // Add the main program code into the continuous loop() function
 void loop()
 {
     switch (guirl_status)
     {
     case 0:
         // last program has ended, so select a random program for guirlande, or the first time
         sel_guirl_pgm = guirl_pgm_select();
         guirl_status = 1;
         Serial.println(sel_guirl_pgm);        // print the selected program
         break;

     case 1:
         // do the guirlande program
         if (pled[sel_guirl_pgm].ledvar == 0)    // clignotement, flashing, not varying
         {                                                                // not var program
             for (int iter = 0; iter < pled[sel_guirl_pgm].ledxtime; iter++)
             {
                 analogWrite(GUIRL_A, 255);                                // switch led to ON
                 delay(pled[sel_guirl_pgm].ledon);                        // delay ON state
                 analogWrite(GUIRL_A, pled[sel_guirl_pgm].ledvaloff);    // switch led to OFF value
                 delay(pled[sel_guirl_pgm].ledoff);                        // delay OFF state
             }
         }
         else
         {    // var program
             int stepon, stepoff;
             // calcul du délai du pas ON
             stepon = pled[sel_guirl_pgm].ledon / 32;        // 32 steps ON, may be different from OFF

             // calcul du délai du pas OFF
             stepoff = pled[sel_guirl_pgm].ledoff / 32;        // 32 steps OFF, may be different from ON

             for (int iter = 0; iter < pled[sel_guirl_pgm].ledxtime; iter++)    // do loop x time this program led
             {
                 for (int i = 0; i < 32; i++)
                 {
                     analogWrite(GUIRL_A, varval[i]);    // switch led to var value
                     delay(stepon);                        // delay between each step
                 }

                 for (int i = 31; i > -1; i--)
                 {
                     analogWrite(GUIRL_A, varval[i]);    // switch led to var value
                     delay(stepoff);                        // delay between each step
                 }
             }
         }

         guirl_status = 0;    // program ended, next select a new one

         break;


     default:
     guirl_status = 0;  // program ended, next select a new one
         break;
     }
 }