Avoid 100% LED duty cycle when uploading new program

Hi all,

I'm prototyping an 8x8x8 LED cube. For now I've got a simple 8 LED circuit (2 layers of each 4 LEDs) connected to my arduino uno as per this schematic:

The arduino makes sure each layer gets a 50% duty cycle. VCC is 5V

To scale up to an 8x8x8 cube I'll change the design to have 8 layers with 64 LEDs per layer (and 9 daisy chained shift registers instead of 1).

I noticed that when I upload a new program to my arduino, the previous program hangs for a while (I'm guessing close to half a second), visibly leaving some LEDs hanging in a 100% duty cycle for longer than I'd like.

In the current prototype this doesn't matter, but when scaling up to 8x8x8 I'd like to lower the LED resistors from 220 to 100 Ohm to make up for the duty cycle of only 12.5%. Increasing that temporarily to 100% while uploading would be dangerous.

How can I guard against this 100% duty cycle in the arduino code? Can I somehow programmatically turn all LEDs off before the upload?

The code running on the arduino:

int latchPin = 5;
int clockPin = 6;
int dataPin = 4;
int outputEnablePin = 3;

byte leds = 0;

byte layer1Leds = 0;
byte layer2Leds = 0;

void setup() {
  pinMode(latchPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(outputEnablePin, OUTPUT);

  setBrightness(255);
}

// Delay between different pattern steps.
int delayPatternStepMillis = 200;

// Delay for the duty cycle of the LEDs.
int delayBetweenLayersMicros = 500;

void loop() {
  layer1Leds = 0;
  layer2Leds = 0;
  showLeds(delayPatternStepMillis);

  for (int i = 0; i < 4; i++) {
    bitSet(layer1Leds, i);
    showLeds(delayPatternStepMillis);
  }

  for (int i = 0; i < 4; i++) {
    bitSet(layer2Leds, i);
    showLeds(delayPatternStepMillis);
  } 
}

void showLeds(int millis) {
  int max_i = int (millis * 1000L / delayBetweenLayersMicros);
  for (long i = 0; i < max_i; i += 2) {
    leds = layer1Leds;
    bitSet(leds, 4);
    updateShiftRegister();
    delayMicroseconds(delayBetweenLayersMicros);
    
    leds = layer2Leds;
    bitSet(leds, 5);
    updateShiftRegister();
    delayMicroseconds(delayBetweenLayersMicros);
  }
}

void updateShiftRegister() {
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, leds);
  digitalWrite(latchPin, HIGH);
}

void setBrightness(byte brightness) {
  analogWrite(outputEnablePin, 255-brightness);
}

I suggest adding an external pullup resistor to the outputEnablePin (which is active LOW) so that you could set this pin as INPUT to disable the LEDs. This could be done just prior to uploading. Also, while uploading is occurring, all pins are set to input, and the LEDs should remain off.

Ah thanks a ton. That is much simpler than I thought.

What resistance should I go for? I tried 10k Ohm, which seemed to work (at 5V, yielding a max current of 0.5mA).

10K is perfect, but someone once said "640k is all you'll ever need".

Why do you use such a complicated way of wiring and programming? Each layer can be controlled by only one MAX7219, so with only 8 such chips will be enough for the whole LED cube. In this way, even programming will be much easier.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.