LED Matrix refresh rate
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
LED Matrix refresh rate
Hi all,
I'm still working on my final years project. For those who haven't seen my previous posts, it is a Game of Life on 16x16 LED Matrix.
If you saw my youtube video (http://www.youtube.com/watch?v=Nrz2ezQr3fY), you've realised that the LEDs aren't giving much light.
I'd like to know how I could change this, without changing the hardware.
If a row is on, this one stays 400µs on but then stays off for (400µs * 15 + "I²C data send time" * 15).
(I²C used at 400kHz)
BR,
Nicolas L. F.
PS: I edited the stopbit macro. The 10ms delay has been changed to a 10µs delay.
I'm still working on my final years project. For those who haven't seen my previous posts, it is a Game of Life on 16x16 LED Matrix.
If you saw my youtube video (http://www.youtube.com/watch?v=Nrz2ezQr3fY), you've realised that the LEDs aren't giving much light.
I'd like to know how I could change this, without changing the hardware.
If a row is on, this one stays 400µs on but then stays off for (400µs * 15 + "I²C data send time" * 15).
(I²C used at 400kHz)
BR,
Nicolas L. F.
PS: I edited the stopbit macro. The 10ms delay has been changed to a 10µs delay.
-
- Matrix Staff
- Posts: 9520
- Joined: Sat May 05, 2007 2:27 pm
- Location: Northamptonshire, UK
- Has thanked: 2585 times
- Been thanked: 3815 times
- Contact:
Re: LED Matrix refresh rate
Hi Nicolas,
Not sure if want what I'm going to say you already know, so this may not be of much help:
I believe the problem is due to LED's supplied with average of 1/2 of their normal voltage.
The average voltage of a PWM can be simplified to D*max_Voltage.
Whereas D = Duty
=Ton/(Ton+Toff)
In your case Ton = Time_on = 400uS
Time_off = 400uS
In effect you have a 50% duty cycle 400/(400+400)*100 = 50
So
Average supply Voltage to LED's are 400/(400+400) *5 = 2.5V
So instead of supplying 5V to LEDs via resistors you are in effect only supplying 2.5V LEDs hence roughly 1/2 or less brightness
The way to make LED's brighter = decrease supply resistor which you have ruled out.
Or Increase the value of Ton ie. the time LED's are on compared to Time LED's are off.
Can you place a delay to increase time on or will that affect the timing of receiving comms?
E.g you could have a decision branch, for LED's on and LED's off
Delay can be any amout, but the higher the value up to 400us the brighter LEDS should be.
Martin
Not sure if want what I'm going to say you already know, so this may not be of much help:
I believe the problem is due to LED's supplied with average of 1/2 of their normal voltage.
The average voltage of a PWM can be simplified to D*max_Voltage.
Whereas D = Duty
=Ton/(Ton+Toff)
In your case Ton = Time_on = 400uS
Time_off = 400uS
In effect you have a 50% duty cycle 400/(400+400)*100 = 50
So
Average supply Voltage to LED's are 400/(400+400) *5 = 2.5V
So instead of supplying 5V to LEDs via resistors you are in effect only supplying 2.5V LEDs hence roughly 1/2 or less brightness
The way to make LED's brighter = decrease supply resistor which you have ruled out.
Or Increase the value of Ton ie. the time LED's are on compared to Time LED's are off.
Can you place a delay to increase time on or will that affect the timing of receiving comms?
E.g you could have a decision branch, for LED's on and LED's off
Code: Select all
If LED_ON = 1, then LED's on : delay 300us
Else LED's off: no delay
Martin
Martin
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: LED Matrix refresh rate
Using a value higher than 400µs will make the refresh rate too slow, and we'll see each row going on and off.
The duty cycle is 400µs/(400µs*LED_MATRIX_ROWS) = 400µs/(400µs*16) => 6.25%
Average supply would then be 5*6.25/100 = 0.3125V
That doesn't look really good ... ^^"
The duty cycle is 400µs/(400µs*LED_MATRIX_ROWS) = 400µs/(400µs*16) => 6.25%
Average supply would then be 5*6.25/100 = 0.3125V
That doesn't look really good ... ^^"
-
- Matrix Staff
- Posts: 9520
- Joined: Sat May 05, 2007 2:27 pm
- Location: Northamptonshire, UK
- Has thanked: 2585 times
- Been thanked: 3815 times
- Contact:
Re: LED Matrix refresh rate
My thought is flicker frequency is from about 5 to 55Hz = 0.2sec to 18.2ms So you could either use a higher number e.g 70Hz * 16 = 1120Hz so slowest delay = 892.8uSSpanish_dude wrote:Using a value higher than 400µs will make the refresh rate too slow, and we'll see each row going on and off.
So you could try increasing on time delay by at least 892uS. Also is it possible to reduce off time e.g 400µs*LED_MATRIX_ROWS to 200µs*LED_MATRIX_ROWS. I'm only guessing at this stage, as not got hardware you have got.
You got nothing to loose as you can always go back to original values if it does not work.
Ahh of course I did not even take the *16 into account so I agree, it's even worseSpanish_dude wrote:The duty cycle is 400µs/(400µs*LED_MATRIX_ROWS) = 400µs/(400µs*16) => 6.25%
Have you got a meter/scope that can confirm all of this? You will need to check the spec of the meter as it will have to work at 400KHz.
Martin
Martin
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: LED Matrix refresh rate
You need to add the time the data is sent to the port expander. I haven't checked that but the Toff is > (400µs * 16).
I can't reduce the Toff value as it's determined by the Ton value. T = Ton * 16 + I²C data time * 16, Toff = T - Ton, Ton = 400µs.
If what I think is right, I'll always get a 1/16 ratio.
I can't reduce the Toff value as it's determined by the Ton value. T = Ton * 16 + I²C data time * 16, Toff = T - Ton, Ton = 400µs.
If what I think is right, I'll always get a 1/16 ratio.
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Re: LED Matrix refresh rate
Hello,
Any chance you can add a second resistor in parallel with the original resistors to allow more current to drive the LEDs. This way you can solder the extra resistors to the existing ones without reworking the board.
Any chance you can add a second resistor in parallel with the original resistors to allow more current to drive the LEDs. This way you can solder the extra resistors to the existing ones without reworking the board.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: LED Matrix refresh rate
Yes but if the program freezes when LEDs are turned on, the current will be to much for it to handle.
I'm afraid of burning the LEDs.
I'm afraid of burning the LEDs.
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Re: LED Matrix refresh rate
Hello,
Fair enough I see your point.
How about waiting until the firmware is nice and stable, adding watchdog functionality to your program in case of random freezing and then fitting the extra resistors?
Downside to this is that if the LEDs blow anyway with the extra resistors then you have nice stable firmware but no LEDs to demonstrate it. Maybe you could add nice large resistors so your only upping the current to the LEDs slightly.
Fair enough I see your point.
How about waiting until the firmware is nice and stable, adding watchdog functionality to your program in case of random freezing and then fitting the extra resistors?
Downside to this is that if the LEDs blow anyway with the extra resistors then you have nice stable firmware but no LEDs to demonstrate it. Maybe you could add nice large resistors so your only upping the current to the LEDs slightly.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: LED Matrix refresh rate
Hi,
I already changed the 500 Ohm resistors to 220 Ohm to up the current a bit.
How do they manage to control a 16x16 LED Matrix without display problems like I'm having. (check this video : http://www.youtube.com/watch?v=Q7BnNd86 ... re=related )
I already changed the 500 Ohm resistors to 220 Ohm to up the current a bit.
How do they manage to control a 16x16 LED Matrix without display problems like I'm having. (check this video : http://www.youtube.com/watch?v=Q7BnNd86 ... re=related )
- Benj
- Matrix Staff
- Posts: 15312
- Joined: Mon Oct 16, 2006 10:48 am
- Location: Matrix TS Ltd
- Has thanked: 4803 times
- Been thanked: 4314 times
- Contact:
Re: LED Matrix refresh rate
Hello,
Its probably mainly down the the rate you scan through the LEDs. Unfortunatley I2C is a slow protocol which means there is a lot of overhead for transactions. Is there a way you can use the I2C in streaming mode rather then having to setup and end the transaction every time?
For my propeller display I essentially have 360 columns of 24 LEDs. As the propeller circles around each of the LEDs are given their data for the current column. By increasing the drive current and being careful with the PWM brightness on the LEDs I have been able to get very bright LEDs which then persist in vision until the propeller makes it back around again. This is also partially down to the LEDs and the way I am driving them using a MOSFET rather then an output pin.
Its probably mainly down the the rate you scan through the LEDs. Unfortunatley I2C is a slow protocol which means there is a lot of overhead for transactions. Is there a way you can use the I2C in streaming mode rather then having to setup and end the transaction every time?
For my propeller display I essentially have 360 columns of 24 LEDs. As the propeller circles around each of the LEDs are given their data for the current column. By increasing the drive current and being careful with the PWM brightness on the LEDs I have been able to get very bright LEDs which then persist in vision until the propeller makes it back around again. This is also partially down to the LEDs and the way I am driving them using a MOSFET rather then an output pin.
Regards Ben Rowland - MatrixTSL
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
Flowcode Product Page - Flowcode Help Wiki - Flowcode Examples - Flowcode Blog - Flowcode Course - My YouTube Channel
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: LED Matrix refresh rate
If I could change the hardware I think I'll use the SPI protocol but I'm still thinking I'll get a 1/16 ratio.
I thought of making a system like a tv screen, first sending the data to the odd rows and then to the even, but that won't change the refresh rate.
I just thought about something.
Would it be possible to switch between 2 rows during Xµs ?
I think I can then have a 1/8 ratio as I'm lighting 2 rows "at the same time".
I thought of making a system like a tv screen, first sending the data to the odd rows and then to the even, but that won't change the refresh rate.
I just thought about something.
Would it be possible to switch between 2 rows during Xµs ?
I think I can then have a 1/8 ratio as I'm lighting 2 rows "at the same time".
-
- Posts: 594
- Joined: Thu Sep 17, 2009 7:52 am
- Location: Belgium
- Has thanked: 63 times
- Been thanked: 102 times
- Contact:
Re: LED Matrix refresh rate
Good news everyone.
The way I made my "SendData" macro makes all LEDs light up with an equal intensity, unlike my youtube video.
All LEDs light up pretty good.
What I've done is:
First, I deleted the "if (write_ports == 0)" because as far as I calculated the I²C data send time I needed 4.8ms time. The interrupt is executed every 5.461ms, so there's 800µs that's added to Toff.
The SendData is now in the "main loop" and the interrupt is only used to know when to make a new cycle for the Game of Life.
The second thing I have done is this piece of code :
This is my SendData macro and I'm able to write the 16 rows with half of the time needed than before, as I'm lighting 2 rows "at the same time".
I still need to see what's the actual delay so I can calculate the duty cycle.
This is a major improvement !!
The way I made my "SendData" macro makes all LEDs light up with an equal intensity, unlike my youtube video.
All LEDs light up pretty good.
What I've done is:
First, I deleted the "if (write_ports == 0)" because as far as I calculated the I²C data send time I needed 4.8ms time. The interrupt is executed every 5.461ms, so there's 800µs that's added to Toff.
The SendData is now in the "main loop" and the interrupt is only used to know when to make a new cycle for the Game of Life.
The second thing I have done is this piece of code :
Code: Select all
FCV_COUNTER = 0;
FCV_J = 0;
for (FCV_I = 0; FCV_I < 8; FCV_I++)
{
while (FCV_COUNTER < 3) // Seems like counter < 3 is a good value for the display to be refreshed fast enough
{
// clear column ports
FCM_MCP23018_Write(0, 0x13, 0xFF);
FCM_MCP23018_Write(0, 0x12, 0xFF);
// check which row will be detected : 0 for the 8 higher rows, 1 for the 8 lower rows
FCV_J = FCV_COUNTER % 2;
if (FCV_J == 0)
{
// clear lower 8 rows and enable one of the first rows
FCM_MCP23018_Write(7, 0x13, 0);
FCM_MCP23018_Write(7, 0x12, FCV_ROW_SELECT[FCV_I]);
}
else
{
// clear 8 higher rows and enable one of the last rows
FCM_MCP23018_Write(7, 0x12, 0);
FCM_MCP23018_Write(7, 0x13, FCV_ROW_SELECT[FCV_I]);
}
// get the higher byte and lower byte of an integer variable
FCV_HIGHER_BYTE = ~((FCV_GAME_OF_LIFE_PREV[FCV_I + FCV_J * 8] >> 8 ) & 0xFF);
FCV_LOWER_BYTE = ~(FCV_GAME_OF_LIFE_PREV[FCV_I + FCV_J * 8] & 0xFF);
// send the data to the port expanders (column data)
FCM_MCP23018_Write(0, 0x13, FCV_HIGHER_BYTE);
FCM_MCP23018_Write(0, 0x12, FCV_LOWER_BYTE);
// delay for 10ms
delay_10us(1);
// counter = counter + 1
++FCV_COUNTER;
}
// reset counter
FCV_COUNTER = 0;
}
// clear column ports
FCM_MCP23018_Write(0, 0x13, 0xFF);
FCM_MCP23018_Write(0, 0x12, 0xFF);
I still need to see what's the actual delay so I can calculate the duty cycle.
This is a major improvement !!