Arduino MEGA driving 45 LEDs with PWM without transistors

Hello, I am trying to use the MEGA to drive 15 RGB LED-s. I’m using the single LED-s with series resitances: 200 Ohms for blue and green, and 300 for red.

The problem, when I’m changing the colors through changing the pwm signal the LED connected to pin 13 behaves strance, it’s blinking, when it shouldn’t. Every other LEDs are okay, so I’m almost sure it has nothing to do with the code but with the PWM output maybe.

#include "config.h"
#include "TypeDefs.h"

LED led5;
LED led3;
LED led2;
LED led1a;
LED led1b;
/*
typedef struct {
  color initial_color;
  color actual_color; 
  color prescribed_color;
  byte pin_red;
  byte pin_green;
  byte pin_blue;
  byte value;
  } LED;
  */
  
LED leds[5] = {
  {{0,0,0}, {0,0,0}, {0,0,0}, PINFIVERED, PINFIVEGREEN, PINFIVEBLUE, 5}, //5-ös led
  {{0,0,0}, {0,0,0}, {0,0,0}, PINTHREERED, PINTHREEGREEN, PINTHREEBLUE, 3}, //3-as led
  {{0,0,0}, {0,0,0}, {0,0,0}, PINTWORED, PINTWOGREEN, PINTWOBLUE, 2}, //2-es led
  {{0,0,0}, {0,0,0}, {0,0,0}, PINONEARED, PINONEAGREEN, PINONEABLUE, 1}, //1-es A led
  {{0,0,0}, {0,0,0}, {0,0,0}, PINONEBRED, PINONEBGREEN, PINONEBBLUE, 1} //1-es B led  
};
#define NUMLEDS (sizeof(leds) / sizeof(LED))

boolean transition_flag = false;
boolean changed_flag = false;
boolean finished = true;
color random_color;

//function prototypes
void transition(long time = 5000000, byte mode = 0);
void refresh(long time = 0, byte mode = 0); 

void setup() {

  Serial.begin(9600);

}

void loop() {

  for (int i = 0; i < NUMLEDS; i++) transition(10000, 2, i);

  refresh(1000000, 0);

}

void transition (long time, byte mode, byte led) {
  if (!transition_flag) {
  switch (mode) {
    case 0: randomize0();
    break;
    case 1: randomize1();
    break;
    case 2: randomize2();
    break;
    }
  leds[led].prescribed_color = random_color;
  changed_flag = true;
  }
}



void randomize0 () { //rendes RGB random
  long RGB = random(0xFFFFFF);
    random_color.R = RGB >> 16;
    random_color.G = RGB >> 8 & 0xFF;
    random_color.B = RGB & 0xFF;
  }
void randomize1 () {random_color = {random(255), random(255), random(255)};} //nagy mértékben fehéret, fakó színeket ad

void randomize2 () { //manipulált random
  int RGB;
  byte inner_mode = random(6);
  static const byte dim_value = 50;
  static const byte min_value = 100;

  switch (inner_mode) {
    case 0:
      random_color.R = min_value + random(255 - min_value);
      random_color.G = random(dim_value);
      random_color.B = random(dim_value);
    break;
    case 1:
      random_color.R = random(dim_value);
      random_color.G = min_value + random(255 - min_value);
      random_color.B = random(dim_value);
    break;
    case 2:
      random_color.R = random(dim_value);
      random_color.G = random(dim_value);
      random_color.B = min_value + random(255 - min_value);
    break;
    case 3:
      random_color.R = min_value + random(255 - min_value);
      random_color.G = min_value + random(255 - min_value);
      random_color.B = random(dim_value);
    break;
    case 4:
      random_color.R = min_value + random(255 - min_value);
      random_color.G = random(dim_value);
      random_color.B = min_value + random(255 - min_value);
    break;
    case 5:
      random_color.R = random(dim_value);
      random_color.G = min_value + random(255 - min_value);
      random_color.B = min_value + random(255 - min_value);
    break;
    case 6:
      random_color.R = random(255);
      random_color.G = random(255);
      random_color.B = random(255);
    break;
  }
}
    

void refresh(long time, byte mode){
  static long start_time;
  static long end_time;
  static long actual_time;

  if (changed_flag && !transition_flag) { //ha most kezdjük az átmenetet
    transition_flag = true;
    start_time = micros();  
    end_time = start_time + time;  
    #ifdef DEBUG
      Serial.print("Transitioning. Start time: ");
      Serial.println(start_time);
      Serial.print("Transitioning. End time: ");
      Serial.println(end_time);      
    #endif 
    for (byte i = 0; i < NUMLEDS; i++){
      leds[i].initial_color.R = leds[i].actual_color.R;  
      leds[i].initial_color.G = leds[i].actual_color.G;
      leds[i].initial_color.B = leds[i].actual_color.B;
    }
  }
  if (transition_flag){ //ha az átmenet folyamatban van
    actual_time = micros();

    if (actual_time < end_time) {
      #ifdef DEBUG
        Serial.print("Transitioning. Actual time: ");
        Serial.println(actual_time);
      #endif
      for (byte i = 0; i < NUMLEDS; i++){
        leds[i].actual_color.R = map(constrain(actual_time, start_time, end_time), start_time, end_time, leds[i].initial_color.R, leds[i].prescribed_color.R);
        leds[i].actual_color.G = map(constrain(actual_time, start_time, end_time), start_time, end_time, leds[i].initial_color.G, leds[i].prescribed_color.G);
        leds[i].actual_color.B = map(constrain(actual_time, start_time, end_time), start_time, end_time, leds[i].initial_color.B, leds[i].prescribed_color.B);
      }
    }
    else {
      for (byte i = 0; i < NUMLEDS; i++){ 
        leds[i].actual_color.R = leds[i].prescribed_color.R;
        leds[i].actual_color.G = leds[i].prescribed_color.G;
        leds[i].actual_color.B = leds[i].prescribed_color.B;
      }
      transition_flag = false;
      changed_flag = false;
    }
    for (byte i = 0; i < NUMLEDS; i++){
      analogWrite(leds[i].pin_red, 255 - leds[i].actual_color.R);
      analogWrite(leds[i].pin_green, 255 - leds[i].actual_color.G);    
      analogWrite(leds[i].pin_blue, 255 - leds[i].actual_color.B);    
    }
  }    
}

TypeDefs.h:

#include "Arduino.h"

typedef struct {
  byte R;
  byte G;
  byte B;
}  color;
 
typedef struct {
  color initial_color;
  color actual_color; 
  color prescribed_color;
  byte pin_red;
  byte pin_green;
  byte pin_blue;
  byte value;
  } LED;
    
const color WHITE {255,255,255};
const color RED {255,0,0};
const color GREEN {0,255,0};
const color BLUE {0,0,255};

config.h

#define CHANGERESOLUTION 250;

#define PINFIVERED 2      //PE4
#define PINFIVEGREEN 3    //PE5

#define PINFIVEBLUE 4     //PG5

#define PINTHREERED 5     //PE3

#define PINTHREEGREEN 6   //PH3
#define PINTHREEBLUE 7    //PH4
#define PINTWORED 8       //PH5
#define PINTWOGREEN 9     //PH6

#define PINTWOBLUE 10     //PB4
#define PINONEARED 11     //PB5
#define PINONEAGREEN 12   //PB6   
#define PINONEABLUE 13    //PB7

#define PINONEBRED 44     //PL5
#define PINONEBGREEN 45   //PL4
#define PINONEBBLUE 46    //PL3

For now, I don’t want to use transistors, since the MEGA should be able to handle this I think, and for me this dim light is okay.
So the question is; what may cause the LED on pin 13 blinking while it should transition smoothly between two random colors?

Hi,

The trick I use in these situations is to simplify & isolate the problem. Remove all the leds that are working. Remove everything you can from the sketch so you have the shortest possible sketch that demonstrates the problem.

I find that 80% of the time, following that process reveals the source of the problem. In the other 20% of cases, you have something much simpler & shorter to post on the forum. Then other forum members will be able to quickly spot the problem for you.

Paul

Thanks Paul, you are right. I have isolated the problem.

10mm common anode RGB LED connected to pins: D11, D12, D13 through 3 seperate resistors. Common anode connected to GND.

code:

void setup() {

}
void loop() {
  // put your main code here, to run repeatedly:
  for (int i = 0; i <= 255; i++){
     for (byte pin = 11; pin <= 13; pin++) analogWrite(pin, i);
     delay(10);
     }
  for (int i = 255; i >= 0; i--){
     for (byte pin = 11; pin <= 13; pin++) analogWrite(pin, i);
     delay(10);
     }
     
}

Problem: LED is continously flickering while transitioning if i use D13 pin as the sink for one of the colors.
Facts:

  • Same LED working normally as it should on every other pins like D8, D9, D10
  • Same problem arises on UNO if D13 is used
  • Problem not visible if only D13 is transitioning, it doesn’t matter if the other two colors are “on” or “off”

On most arduino boards, D13 is used for the onboard led. Could that hardware connection be the cause of the problem?

Is the onboard led fading as the PWM changes?

Rather than having D13 as the last , maybe try

for (byte pin = 13; pin >= 11; pin--)

Okay, problem solved. But I still don’t understand it totally. It was in the hardware, and yes with, the onboard LED.
Part of the problem was, I used a resistor on the anode, to spare time, and another one on the cathode for red, so it wasn’t really seperate (my bad, sorry). With seperate resistor it is working. I think because of the onboard LED and/or it’s resistor, the LED attached to D13 does not get sufficient voltage or current. Don’t know. And strange becuse problem only arises while fading the 2 or 3 colors. and the same construction works if I don’t use D13 but another pin instead.

Thank you guys.

Attila