-1

The aim of the project was to be able to show two "kinds" of LEDs in a 8x8 single color LED matrix. I used a MAX7219 chip to drive the LEDs using my Arduino UNO R3 as the driver (with the usual connections).

Despite the frequency of the blackupdate() function being near to a 100Hz, why do I see the LEDs corresponding to currentblack() flickering? 100Hz is much beyond the resolution of the eye, as I understand it. The multiplexing frequency of the MAX7219 chip is also much beyond resolution (800Hz). Why do the "white" LEDs not flicker?

Here's the code with Serial.println() added for debugging:

int DataPin = 2; // Pin 1 on MAX
int LoadPin = 3; // Pin 12 on MAX
int ClockPin = 4; // Pin 13 on MAX
int currentwhite[8]={B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};
int currentblack[8]={B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000};

#define SCAN_LIMIT_REG 0x0B
#define DECODE_MODE_REG 0x09
#define SHUTDOWN_REG 0x0C
#define INTENSITY_REG 0x0A
#define DISPLAY_CHECK_REG 0x0F

void setup() {
  pinMode(DataPin, OUTPUT);
  pinMode(LoadPin, OUTPUT);
  pinMode(ClockPin, OUTPUT);
  digitalWrite(LoadPin, LOW);
  shiftOut(DataPin, ClockPin, MSBFIRST, SCAN_LIMIT_REG); // scan limit set to 0:7
  shiftOut(DataPin, ClockPin, MSBFIRST, B00000111);
  digitalWrite(LoadPin, HIGH);
  digitalWrite(LoadPin, LOW);
  shiftOut(DataPin, ClockPin, MSBFIRST, DECODE_MODE_REG);
  shiftOut(DataPin, ClockPin, MSBFIRST, B00000000);
  digitalWrite(LoadPin, HIGH);
  digitalWrite(LoadPin, LOW);
  shiftOut(DataPin, ClockPin, MSBFIRST, SHUTDOWN_REG);
  shiftOut(DataPin, ClockPin, MSBFIRST,  B00000001);
  digitalWrite(LoadPin, HIGH);
  digitalWrite(LoadPin, LOW);
  shiftOut(DataPin, ClockPin, MSBFIRST, DISPLAY_CHECK_REG);
  shiftOut(DataPin, ClockPin, MSBFIRST, B00000000);
  digitalWrite(LoadPin, HIGH);
  digitalWrite(LoadPin, LOW);
  shiftOut(DataPin, ClockPin, MSBFIRST, INTENSITY_REG);
  shiftOut(DataPin, ClockPin, MSBFIRST, 0);
  digitalWrite(LoadPin, HIGH);
  Serial.begin(9600);

  currentblack[3]=B00001000;
  currentblack[4]=B00010000;
  currentwhite[3]=B00010000;
  currentwhite[4]=B00001000; 
}

void blackupdate() {
  digitalWrite(LoadPin, LOW);
    shiftOut(DataPin, ClockPin, MSBFIRST, INTENSITY_REG);
    shiftOut(DataPin, ClockPin, MSBFIRST, 0);
    digitalWrite(LoadPin, HIGH);
  for (byte row=0; row<8; row++){
    digitalWrite(LoadPin, LOW);
    shiftOut(DataPin, ClockPin, MSBFIRST, row+1);
    shiftOut(DataPin, ClockPin, MSBFIRST, (currentblack[row]));
    digitalWrite(LoadPin, HIGH);
  }
}

void whiteupdate() {
  digitalWrite(LoadPin, LOW);
    shiftOut(DataPin, ClockPin, MSBFIRST, INTENSITY_REG);
    shiftOut(DataPin, ClockPin, MSBFIRST, 15);
    digitalWrite(LoadPin, HIGH);
  for (byte row=0; row<8; row++){
    digitalWrite(LoadPin, LOW);
    shiftOut(DataPin, ClockPin, MSBFIRST, row+1);
    shiftOut(DataPin, ClockPin, MSBFIRST, (currentwhite[row]));
    digitalWrite(LoadPin, HIGH);
  }
}

void loop() {
  Serial.print("A");
  Serial.println(millis());
  blackupdate();
  Serial.print("B");
  Serial.println(millis());
  whiteupdate();
  delay(5);
  Serial.print("C");
  Serial.println(millis());  
} 

And the Serial output was as follows:

A1
B3
C10
A10
B12
C19
A19
B21
C28
A28
B30
C37
A37
B39
C47
A47
B49
C56
A56
B59
C65
A66
B68
C75
A75
B77
C84
A84
B87
C94
A94
B96
C105
A105
B112
C123
A123
B131
C142
A143
B150
C161
A161
B168
C180
A180
B187
C198
A198
B205
C217
A218
B225
C236
A236
B243
C254
A254
B262
C273
A274
B281
C292
A292
B300
C311
A311
B318
C329
A329
B336
C348
A349
B356
C367
A367
B374
C386
A386
B393
C404
A404
B412
C422
A423
B431
C442
A442
B449
C460
A460
B467
C479
A480
B487
C498
A498
B505
C517
A517
B524
C535
A535
B542
C553
A555
B562
C573
A573
B580
C591
A591
B599
C610
A611
B618
C629
A629
B636
C648
A648
B655
C666
A666
B673
C685
A686
B693
C704
A704
B711
C722
A722
B730
C741
  • You're trying to implement two different brightness's for each led. I think the problem is that the update rate of the MAX7219 and the update rate of your Arduino code are not in sync, causing some variations in the brightness. Also you are setting the brightness of the MAX7219 to max, before updating the pixel data, which would cause the 'black' pixels from being a lot brighter for a short while. I'd move the first 4 lines in whiteupdate to the end of the function. PS you only need to do digitalWrite(LoadPin, LOW);...;digitalWrite(LoadPin, HIGH); once per function. No need to do this 9x. – Gerben Jan 28 '17 at 16:52
  • I tried putting the intensity function at the end of the fuction, but it changed nothing. Even if the black LEDs are bright for a while, the entire function takes only 2 milliseconds to happen, so shouldn't be visible. Can you expand on what you mean by the two devices not being in sync? – stochastic13 Jan 29 '17 at 7:30
  • Wouldn't we need to latch the data by putting the loadpin to high every time? Otherwise the data would simply be outputted through the Dout pin? – stochastic13 Jan 29 '17 at 7:31
  • The max7219 updates the display at around 800hz. Your code updates the display data around 100hz. But not exactly. So ideally the max would multiplex every column 8 times between every update. But is it's slightly slower, it might have done the last column only 7 times. Which would make it less bright. – Gerben Jan 29 '17 at 8:46
  • But then the entire black set invariably flickers irrespective of the position. – stochastic13 Jan 30 '17 at 14:36
0

The hardware setup isn't clear. For example, do you have two matrix's or one? In any event, the effect of black update() stays on much shorter than the effect of white update() due to the delay inserted in the main loop.

| improve this answer | |
  • One matrix. And I agree, but the functions still cycle at a very high frequency, and should be indistinguishable by eye. Only the average should be visible, right? – stochastic13 Jan 28 '17 at 15:44
  • The pattern of white update is briefly interrupted by the pattern of blaackkuodate. That's the flickering you see. You can test this by commenting out one of the patterns. The MCU ISS doing what your code wants it to Do. What do you want your code to do? – dannyf Jan 28 '17 at 15:59
  • I see only the blackupdated LEDs flickering. If the interrupts were a problem, the whiteupdated LEDs should flicker, right? – stochastic13 Jan 28 '17 at 16:01
  • The white leds are probably too bright to see them flicker. – Gerben Jan 29 '17 at 8:41
0

You are correct that this is updating at about 100 Hz. The clue is in the serial output:

A1
B3  <<
C10 <<
A10
B12 <<
C19 <<
A19
B21 <<
C28 <<
A28
B30 <<
C37 <<
A37

There is always a big gap between the ms reading between B and C. This is due to the delay in after the whiteupdate().

void loop() {
    Serial.print("A");
    Serial.println(millis());
    blackupdate();
    Serial.print("B");
    Serial.println(millis());
    whiteupdate();
    delay(5);    // <-- DELAY HERE
    Serial.print("C");
    Serial.println(millis());  
} 

There is no update between the blackupdate() and the whiteupdate(), so even though 5ms is just on the border of what your eyes can determine, due to the repeating pattern and persistence of vision, your eyes do notice it.

You will find that your flicker will dissapear if you split the delay so you have an equal delay between your blackupdate()->whiteupdate() and whiteupdate()->blackupdate().

void loop() {
    Serial.print("A");
    Serial.println(millis());
    blackupdate();
    delay(2);    // <-- DELAY HERE
    Serial.print("B");
    Serial.println(millis());
    whiteupdate();
    delay(2);    // <-- DELAY HERE
    Serial.print("C");
    Serial.println(millis());  
} 

Removing the serial debug lines give you:

void loop() {
    blackupdate();
    delay(2);
    whiteupdate();
    delay(2);
} 
| improve this answer | |
  • I tried doing that. I still found the LEDs flickering. I set both the delays at delay(10). – stochastic13 May 4 '17 at 14:54
0

There may be some more physiology at work here, too. Did you notice the flickering while staring fixedly at one LED, or while looking around your project area ("scanning" as it were, with your eyes)? If you scan your vision past a flickering LED, even one that flickers at a rate beyond our perception, you can see a streak of dots cross your vision, where a steadily lit one would make a solid streak. I noticed it driving at night, when LED tail-lights were still new and unusual. Those cars stood out because their tail-lights left the same trail of dots across my vision (although some people have told me they do not see this phenomenon or aren't aware of it...).

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.