Continue to Site

Welcome to

Welcome to our site! is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[AVR] Problem with row scanning of led matrix

Not open for further replies.


Member level 3
Jan 15, 2015
Reaction score
Trophy points
Activity points
I had build a 120*12 led matrix using Atmega16. shift register 74HC595 for column (data) and 12 lines from micro controller via ULN2003 to the rows (for scanning). The problem I'm facing is the brightness of the display. I'm currently setting a delay time of 0.05 ms (_delay_ms(0.05);) for relatively flicker free display but the brightness is decreased to its half. If i set the delay to 10ms then the led will be of full brightness but i can see the row scanning one by one very slowly. What should i do to get both brightness and a flicker less display.

If the said delay is per row, 10 ms is surely too slow, 1 ms (= about 80 Hz refresh frequency) should be suffcient for flicker-free operation. To be sure that we are talking about the same thing, you should better describe the row and column signal sequence. May there something wrong.

I suggest you use the highest crystal frequency your micro can handle and restrict your delay to 1ms or thereabouts as FvM mentioned. Its a wage between flicker and brightness, so feel free to try out different values. Ensure the micro is not wasting time checking for external inputs by utilizing interrupts.

On the other hand, with 12 rows scanning, the duty cycle is 8.3 which according to me is so little. Personally, I use 8 rows and though the brightness is acceptable indoors, its not usually bright enough outdoors. I once boosted the output circuitry with transistors for use with 12volts but found it to be too cumbersome. A 16 row chinese module I looked into scans only 4 rows with multiple 595s to fill the entire width. Btw, i wouldnt mind if you shared your font with me if any of this was helpful.

On the other hand, with 12 rows scanning, the duty cycle is 8.3 which according to me is so little.
You get average LED currents of 1 mA or so, no really amazing. If I remember right, we had a discussion about duty cycles, peak and average LED currents a few months before.

I must confess that I don't understand exactly why the brightness should depend strongly on the refresh frequency. HC595 allows to shift in next row data while the current row is displayed. The display must be only turned off for a short interval according to the ULN2003 rise and fall time to avoid crosstalk between rows. But that's a matter of a few microseconds maximal.

If we just wanted to see row-A, then brightness would not have been an issue. However, with many rows, row-A remains off for (numberOfRows-1) x delayPerRow. What we then perceive as Brightness is just the average which according to my experiments is why
the brightness should depend strongly on the refresh frequency.
Btw how did you come up with 1mA average LED currents?

Thanks all for the reply. I've set the frequency at 20mhz. If I decrease the frequency the display will start to flicker and if I increase the brightness goes down. As FVM said, the data should be sent to hc595 at the same time the row gets displayed. Since mine is a long 120 led column display having 15 hc595 connected (15*8=120). So the microcontroller have to sent 120bits of data to hc595 which would take some time. The row get lit up only after sending all the data to hc595. I think the trick is that data should be sent to hc595 simultaneously when the row gets lit up. But how can I do that?

- - - Updated - - -

Bmuigai, the font I have are.

//defines 8x8 ASCII characters 0x20-0x7F (32-127) unsigned const char font[96][8] = {         {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, //         {0x00,0x60,0xfa,0xfa,0x60,0x00,0x00,0x00}, // !         {0x00,0xe0,0xe0,0x00,0xe0,0xe0,0x00,0x00}, // "         {0x28,0xfe,0xfe,0x28,0xfe,0xfe,0x28,0x00}, // #         {0x24,0x74,0xd6,0xd6,0x5c,0x48,0x00,0x00}, // $         {0x62,0x66,0x0c,0x18,0x30,0x66,0x46,0x00}, // %         {0x0c,0x5e,0xf2,0xba,0xec,0x5e,0x12,0x00}, // &         {0x20,0xe0,0xc0,0x00,0x00,0x00,0x00,0x00}, // '         {0x00,0x38,0x7c,0xc6,0x82,0x00,0x00,0x00}, // (         {0x00,0x82,0xc6,0x7c,0x38,0x00,0x00,0x00}, // )         {0x10,0x54,0x7c,0x38,0x38,0x7c,0x54,0x10}, // *         {0x10,0x10,0x7c,0x7c,0x10,0x10,0x00,0x00}, // +         {0x00,0x05,0x07,0x06,0x00,0x00,0x00,0x00}, // ,         {0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00}, // -         {0x00,0x00,0x06,0x06,0x00,0x00,0x00,0x00}, // .         {0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00}, // /         {0x7c,0xfe,0x9a,0xb2,0xfe,0x7c,0x00,0x00}, // 0         {0x42,0x42,0xfe,0xfe,0x02,0x02,0x00,0x00}, // 1         {0x46,0xce,0x9a,0x92,0xf6,0x66,0x00,0x00}, // 2         {0x44,0xc6,0x92,0x92,0xfe,0x6c,0x00,0x00}, // 3         {0x18,0x38,0x68,0xc8,0xfe,0xfe,0x08,0x00}, // 4         {0xe4,0xe6,0xa2,0xa2,0xbe,0x9c,0x00,0x00}, // 5         {0x3c,0x7e,0xd2,0x92,0x9e,0x0c,0x00,0x00}, // 6         {0xc0,0xc6,0x8e,0x98,0xf0,0xe0,0x00,0x00}, // 7         {0x6c,0xfe,0x92,0x92,0xfe,0x6c,0x00,0x00}, // 8         {0x60,0xf2,0x92,0x96,0xfc,0x78,0x00,0x00}, // 9         {0x00,0x00,0x36,0x36,0x00,0x00,0x00,0x00}, // :         {0x00,0x05,0x37,0x36,0x00,0x00,0x00,0x00}, // ;         {0x10,0x38,0x6c,0xc6,0x82,0x00,0x00,0x00}, // <         {0x28,0x28,0x28,0x28,0x28,0x28,0x00,0x00}, // =         {0x00,0x82,0xc6,0x6c,0x38,0x10,0x00,0x00}, // >         {0x40,0xc0,0x8a,0x9a,0xf0,0x60,0x00,0x00}, // ?         {0x7c,0xfe,0x82,0xba,0xba,0xf8,0x78,0x00}, // @         {0x3e,0x7e,0xc8,0xc8,0x7e,0x3e,0x00,0x00}, // A         {0x82,0xfe,0xfe,0x92,0x92,0xfe,0x6c,0x00}, // B         {0x38,0x7c,0xc6,0x82,0x82,0xc6,0x44,0x00}, // C         {0x82,0xfe,0xfe,0x82,0xc6,0xfe,0x38,0x00}, // D         {0x82,0xfe,0xfe,0x92,0xba,0x82,0xc6,0x00}, // E         {0x82,0xfe,0xfe,0x92,0xb8,0x80,0xc0,0x00}, // F         {0x38,0x7c,0xc6,0x82,0x8a,0xce,0x4e,0x00}, // G         {0xfe,0xfe,0x10,0x10,0xfe,0xfe,0x00,0x00}, // H         {0x00,0x82,0xfe,0xfe,0x82,0x00,0x00,0x00}, // I         {0x0c,0x0e,0x02,0x82,0xfe,0xfc,0x80,0x00}, // J         {0x82,0xfe,0xfe,0x10,0x38,0xee,0xc6,0x00}, // K         {0x82,0xfe,0xfe,0x82,0x02,0x06,0x0e,0x00}, // L         {0xfe,0xfe,0x60,0x30,0x60,0xfe,0xfe,0x00}, // M         {0xfe,0xfe,0x60,0x30,0x18,0xfe,0xfe,0x00}, // N         {0x38,0x7c,0xc6,0x82,0xc6,0x7c,0x38,0x00}, // O         {0x82,0xfe,0xfe,0x92,0x90,0xf0,0x60,0x00}, // P         {0x78,0xfc,0x84,0x8e,0xfe,0x7a,0x00,0x00}, // Q         {0x82,0xfe,0xfe,0x98,0x9c,0xf6,0x62,0x00}, // R         {0x64,0xe6,0xb2,0x9a,0xde,0x4c,0x00,0x00}, // S         {0xc0,0x82,0xfe,0xfe,0x82,0xc0,0x00,0x00}, // T         {0xfe,0xfe,0x02,0x02,0xfe,0xfe,0x00,0x00}, // U
0xf8,0xfc,0x06,0x06,0xfc,0xf8,0x00,0x00}, // V         {0xfe,0xfe,0x0c,0x18,0x0c,0xfe,0xfe,0x00}, // W         {0xc6,0xee,0x38,0x10,0x38,0xee,0xc6,0x00}, // X         {0xe0,0xf2,0x1e,0x1e,0xf2,0xe0,0x00,0x00}, // Y         {0xe6,0xce,0x9a,0xb2,0xe2,0xc6,0x8e,0x00}, // Z         {0x00,0xfe,0xfe,0x82,0x82,0x00,0x00,0x00}, // [         {0x80,0xc0,0x60,0x30,0x18,0x0c,0x06,0x00}, // "\"         {0x00,0x82,0x82,0xfe,0xfe,0x00,0x00,0x00}, // ]         {0x10,0x30,0x60,0xc0,0x60,0x30,0x10,0x00}, // ^         {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, // _         {0x00,0x00,0xc0,0xe0,0x20,0x00,0x00,0x00}, // `         {0x04,0x2e,0x2a,0x2a,0x3c,0x1e,0x02,0x00}, // a         {0x82,0xfc,0xfe,0x22,0x22,0x3e,0x1c,0x00}, // b         {0x1c,0x3e,0x22,0x22,0x36,0x14,0x00,0x00}, // c         {0x0c,0x1e,0x12,0x92,0xfc,0xfe,0x02,0x00}, // d         {0x1c,0x3e,0x2a,0x2a,0x3a,0x18,0x00,0x00}, // e         {0x12,0x7e,0xfe,0x92,0xc0,0x40,0x00,0x00}, // f         {0x19,0x3d,0x25,0x25,0x1f,0x3e,0x20,0x00}, // g         {0x82,0xfe,0xfe,0x10,0x20,0x3e,0x1e,0x00}, // h         {0x00,0x22,0xbe,0xbe,0x02,0x00,0x00,0x00}, // i         {0x02,0x23,0x21,0xbf,0xbe,0x00,0x00,0x00}, // j         {0x82,0xfe,0xfe,0x08,0x1c,0x36,0x22,0x00}, // k         {0x00,0x82,0xfe,0xfe,0x02,0x00,0x00,0x00}, // l         {0x3e,0x3e,0x30,0x18,0x30,0x3e,0x1e,0x00}, // m         {0x3e,0x3e,0x20,0x20,0x3e,0x1e,0x00,0x00}, // n         {0x1c,0x3e,0x22,0x22,0x3e,0x1c,0x00,0x00}, // o         {0x21,0x3f,0x1f,0x25,0x24,0x3c,0x18,0x00}, // p         {0x18,0x3c,0x24,0x25,0x1f,0x3f,0x21,0x00}, // q         {0x22,0x3e,0x1e,0x22,0x38,0x18,0x00,0x00}, // r         {0x12,0x3a,0x2a,0x2a,0x2e,0x24,0x00,0x00}, // s         {0x00,0x20,0x7c,0xfe,0x22,0x24,0x00,0x00}, // t         {0x3c,0x3e,0x02,0x02,0x3c,0x3e,0x02,0x00}, // u         {0x38,0x3c,0x06,0x06,0x3c,0x38,0x00,0x00}, // v         {0x3c,0x3e,0x06,0x0c,0x06,0x3e,0x3c,0x00}, // w         {0x22,0x36,0x1c,0x08,0x1c,0x36,0x22,0x00}, // x         {0x39,0x3d,0x05,0x05,0x3f,0x3e,0x00,0x00}, // y         {0x32,0x26,0x2e,0x3a,0x32,0x26,0x00,0x00}, // z         {0x10,0x10,0x7c,0xee,0x82,0x82,0x00,0x00}, // {         {0x00,0x00,0x00,0xee,0xee,0x00,0x00,0x00}, // |         {0x82,0x82,0xee,0x7c,0x10,0x10,0x00,0x00}, // }         {0x40,0xc0,0x80,0xc0,0x40,0xc0,0x80,0x00}, // ~         {0x1e,0x3e,0x62,0xc2,0x62,0x3e,0x1e,0x00},//


Look at 595 datasheet.
There are independent control lines for the shift register and for the output latch.

Just perform the shift, then update the output latches.


Thanks for the font codename25. I'll see how I can put it to good use. What is your project progress, were you able to solve your brightness problem?

Btw how did you come up with 1mA average LED currents?
I assumed 12 mA HC595 output current per pin and 12:1 mux scheme.

I see however, that the calculation is flawed, because HC595 allows only for 70 mA total VCC or GND current in the maximum ratings. So the LED series resistors must limit the LED current safely below 8 mA not to damage the devices, gives 0.65 mA average current if blanking times could be ignored.

Regarding reasonable shift register usage for minimum blanking time, KlausST has explained everything.

Thanks for the reply fvm, bmigai, klauseST, but fvm, the display has the best brightness if the delay is 10ms ( takes one sec interval for each row scanning) . If it is an issue of current then it may not get this bright. I assume. I am trying to ad an internal interrupt ie: Sending data to hc595 when row is lit on. Any help will be appreciated.


If you need help, then please send schematic and code.


Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to