LDR with 7 seg display and PWM output

Hi.
I'm a bit new to Arduino and have a question on a project I'm doing. I created a project out of discrete components and now am trying to replicate it to code so that I can have more flexibility and simplify the electronics.

I've written code for a minute/second timer (mm:ss) via 4 off 7 segment displays. To minimize outputs, I've multiplexed the displays. Seems to work ok so far. I'm now trying to incorporate an LDR in the circuitry to control the intensity (darker at night and lighter during the day).

I've tried reading the LDR signal and feeding it to the commons in the mutiplex. Doesn't work properly. Is this because I'm using CC digits? Should they instead by CA? If so, in the short term, is there an easy way of re-coding to use my CC digits. Attached is the code. Part of the code (that I tried to alter) is as follows:

  if(stepMultiplex == 1 && (currentMillis - previousMillis) >= delayMp) {
    digitalWrite(commons [0],B);
    previousMillis=currentMillis;
    sevenSegWrite_1(sec_ones);
    digitalWrite(commons [3],A);
    stepMultiplex=2;

Tried to change to:

  if(stepMultiplex == 1 && (currentMillis - previousMillis) >= delayMp) {
    digitalWrite(commons [0],B);
    previousMillis=currentMillis;
    sevenSegWrite_1(sec_ones);
    digitalWrite(commons [3],dValue);  // where dValue is the mapped analog value from the LDR
    stepMultiplex=2;

_02_2015_02_23_clock_d.ino (7.58 KB)

Doesn't work properly.

What does it do that is wrong ? Does it work predictably if you set the value variable to a fixed number rather than calculating it ? Have you tried printing the value variable and if so what range of values do you get ? How is the LDR wired ?

Need to read the "How to Post".

All of it.

Seriously!

UKHeliBob:
What does it do that is wrong ? Does it work predictably if you set the value variable to a fixed number rather than calculating it ? Have you tried printing the value variable and if so what range of values do you get ? How is the LDR wired ?

Paul__B:
Need to read the "How to Post".

All of it.

Seriously!

Paul__B:
Need to read the "How to Post".

All of it.

Seriously!

Thanks Paul for that link and sorry - first time user in this forum. I'll use it in future.

UKHeliBob:
What does it do that is wrong ? Does it work predictably if you set the value variable to a fixed number rather than calculating it ? Have you tried printing the value variable and if so what range of values do you get ? How is the LDR wired ?

Hi HeliBob. Late yesterday I realized that my 7 segment digits being common cathode require a ground. I was trying to feed the converted analog signal (between 0 and 255) to these pins. So I replaced the digits with anode type, swapped the high and lows in the code and it started to work. It was a bit dim, but I assume I need to constrain the analog values. Sorry, I've been stumped for a week!

Can I just ask another question. Am I approaching this the right way? To minimize outputs I'm multiplexing via the commons of the digits delaying using the millis function. Then to alter the intensity I'm using an LDR. Ultimately I want to convert this to large LED sign run on 24V which will be run outdoors.

Hi,

cjcj:
Late yesterday I realized that my 7 segment digits being common cathode require a ground. I was trying to feed the converted analog signal (between 0 and 255) to these pins. So I replaced the digits with anode type, swapped the high and lows in the code and it started to work.

Assuming you mean you were connecting a pwm output to the common connection on the display, swapping the common cathode display for a common anode one can't be the reason it started working. Either type should work equally well.

cjcj:
Can I just ask another question. Am I approaching this the right way? To minimize outputs I'm multiplexing via the commons of the digits delaying using the millis function. Then to alter the intensity I'm using an LDR. Ultimately I want to convert this to large LED sign run on 24V which will be run outdoors.

For outdoor use you want to avoid multiplexing. It will be difficult enough to get them bright enough and multiplexing will make it much more difficult. Use common anode displays and drive each digit with a tpic6c595 high-current shift register.

Also, higher voltages will not give you any advantage if you are using manufactured displays. They must not be subjected to any voltage higher than their specification, or they will be damaged. For maximum brightness you need maximum current, but within the specification.

If you are making your own displays from individual leds, you can use many leds in series so that your 24V supply is appropriate.

Paul

PaulRB:
Assuming you mean you were connecting a pwm output...
For outdoor use you want to avoid multiplexing...
Paul

Hi Paul.
Thanks for the reply. It might therefore be that my resistance to the digits is not correct as it works for the anode (that end up dimming) but not for the cathode - that just stay bright. I'll measure them tonight.

The digits that I'll be using outdoors are about 400 x 250 with LEDs connected in series and parallel with resistors to suit 24V. It's just that these displays (a scoreboard) are driven by discrete components and I now what to drive it via code (for greater flexibility - and serviceability!). The LEDs I bought from OS are quite bright and I'm even dimming them a bit during the day - hence I though multiplexing should work. I might have to therefore test one before I go too far.

These are common anode. I've fiddled with a small shift register a bit. Why do you say this is a better way to go? Chris.

Chris, I'm not sure I understand your question.

Multiplexing will reduce the average current in your digits to one half or one quarter compared to without. Reducing to one quarter current will aproximately half the apparent brightness.

My reason for recommending common anode is that this enables you to use the tpic6c595 shift registers I was describing.

PaulRB:
Multiplexing will reduce the average current... apparent brightness.

My reason for recommending common anode is that this enables you to use the tpic6c595 shift registers I was describing.

Sorry for the confusion. History: I made a sign (scoreboard) that has 15 large displays. Each 7 segment digit is made up of an average 7 leds in series (with a 330 ohm resistor each) x 8 rows in parallel. I'm currently running each LED somewhere between 12 to 15mA only in full daylight (given these are fairly bright units). The total current draw per segment ends up either 120mA or 780mA. These are being driven by discrete components - the leds via ULN2003's. LED forward voltage is 2.7V. Overall, max of 11.7Amps to run all digits if displaying "8" on each.

Now that I've found "Arduino", I've fallen in love! I want to convert it to programming. I will have to change the drivers, but I'm just trying to work out the "easiest" way for me to do the programming, use existing Arduino boards with whatever drivers I need. But before that, I need to look at basics - yes as you said the display will be dimmer with multiplexing.

At this stage my idea is to drive only 4 of the digits with one Arduino Uno board, mulitiplexing only 4 digits. This will 1/4 the intensity I think, if I give the same current (i.e. end result of 12 to 15mA each LED). However, I "think" I can increase the current to 4 times as much (48 to 60mA?) as they are only on a quarter of the time. Is this correct? Would this give the same intensity?

Then comes the dimming during night time. Is my suggestion of an LDR the way to go?

Multiplexing 4 digits can be done two ways. First way is to light 2 digits, then the other 2. This gives a multiplex ratio of 1:2 or 50% because any digit is lit for 50% of the time. Second way is to light the first digit, then the second, then third and finally fourth digit. Multiplex ratio 1:4 or 25% because any digit is lit for 25% of the time. I assume you are suggesting the 1:4 ratio.

The level of brightness depends on the average current each led gets. To maintain the original brightness while changing to a 1:4 multiplex means that the instantaneous/peak current needs to be 4 times higher than it was without multiplexing.

The human eye is not linear. Half the average current does not look half as bright. One quarter of the average current will look around half as bright, very roughly speaking.

Your ldr idea should be ok. If using shift registers, they normally have an Output Enable pin. You can connect that to a pwm output on the arduino to dim the displays. If driving the displays with arduino pins, connect a separate pwm pin to each digit's common connection. Just be careful that the ldr is shielded from the light coming from the displays themselves, or wierd stuff will happen!

Paul thank you so much for you time and patience.
Yes, I am considering the option of 1:4 ratio. The spec sheet for the LEDs I have suggests a peak forward current of 50mA. Is it safe to push it to this limit in the 1:4 ratio, or should I be dropping it even further (if the intensity is still ok)?

I see what you mean about non - linear. That's why from 20mA to 12mA I can't really see too much difference. I never knew why.

Yes I did connect a separate pwm pin to each digit common. I'm not too confident however using a shift register. I'll do more homework on this then maybe ask you some more questions down the track once I've studied up on it (if that's ok).

Hi, on better quality data sheets for leds, it will give a duty cycle and maximum pulse length to go along with that peak current figure. E.g. max continuous current 30mA, peak current 150mA with a 1:10 duty cycle and 1ms max pulse. In other words you can go up to 150mA but only for 1ms out of every 10ms. This limit of a 1ms pulse prevents the led getting too hot, and the 9ms before the next pulse allow it to cool again. In your design, the duty cycle (=multiplex ratio) is 1:4, so you can't go as high as that max, even for 1ms. Does your data sheet give any info about max pulse and duty cycles for that peak current? If not, well... its up to you. The leds might seem ok at 50mA but you might be shortening their life.

My shift register suggestion could be your "plan B" if the leds are not bright enough with the 1:4 multiplex. You would replace your uln2803 with a tpic6c595 or tpic6b595 shift register for each digit. Common anodes connected direct to 24V, then dim them by connecting the Output enable pins of all 4 shift regs to an arduino pwm output. No multiplexing, so you maintain your 12 to 15mA.

Hi Paul. I bought 8000 odd LEDs directly from a company in China. They did send me a spec sheet at the time. There is a mention of pulse width, but I don't understand it - something about "Ifp Conditions : Pulse Width < 10ms < 1/10". Please see attached.

So the shift registers are in a way an extension of the arduino board pins (so that each pin can be individually wired rather than multiplexing). I'll do some "googling" to see this setup.

Φ5 flat top green tint .pdf (356 KB)

I did end up being able to dim the common cathode with an LDR by changing the code as follows:

  if(stepMultiplex == 1 && (currentMillis - previousMillis) >= delayMp) {
    digitalWrite(commons [0],B);  // Turn off the previous digit once time expires
    previousMillis=currentMillis;
    sevenSegWrite_1(sec_ones);
    analogWrite(commons [3],dValue);  // Turn on the sec_one digit
    stepMultiplex=2;

Above I set B to HIGH. To use the analogue value I change "digitalWrite" to "analogWrite".
To get the common anode working, the above also worked.

I'm now trying to work out how to work out the brightest I can make these (withing safety). I cant however put everthing together as I don't understand the numbers. The facts I have:

  • Using 0.5" common anodes 7 segment digits (to experiment)
  • Forward Voltage 2(typ) 2.5(max) (@20mA)
  • DC forward current 30mA
  • Peak forward current 160mA
  • Reverse voltage 5V
  • 1/10 duty cycle, 0.1ms pulse width
  • I'm multiplexing the common of the 4 off 7 segment digits
  • I'm cycling through each digit every 2ms via code
  • To adjust the brightness, I'm using an LDR. I'm mapping its read digital value from 0-1023 and converting to analog 0-255, then using this in to analogWrite (with the 2ms frequency above)
  • I've connected each like segment together then placed a 30ohm resistor between it and the arudino digital pins. I've done this for each segment - not sure if this is correct

I really don't know how to apply the 1/10 duty cycle, 0.1ms pulse width and 160mA above and how the LDR affects this. Can someone please explain it to me or point me to suitable link (as I can't find it clearly explained).

So, just let me check, we are now talking about driving these 0.5" 7 seg 4 digit displays directly with Arduino pins? No uln2803 like with the larger displays you began the thread with?

If so, the limiting factor will be the Arduino pins connected to the common anodes/cathodes. Max current should be 40mA for any output, but not continuous, or the Arduino's life may be shortened. You are multplexing 4 digits, so that max current will be on for 2ms off for 6ms for any one of those outputs, so not continuous.

40mA on the common anode/cathode means only 5.7mA per segment, when that digit is lit. With a 1:4 multiplex that corresponds to only 1.4mA per segment on average. May not be very bright, but see what you think of it.

So driving with the Arduino alone gets you nowhere near the max brightness of the display.

To increase the current to the display means using some transistors on those common anode/cathode pins. The limiting factor then becomes the overall current limit for the atmega328 or whatever chip your Arduino has. For atmega328 it is around 200mA. That limits us to around 7mA on average for each segment. Much better than 1.4mA, but still a long way from the max current for the display.

To reach the max current of the display segments, transistors will be needed on both anodes and cathodes.

Hi, I will write a longer explanation for you, hopefully tomorrow. For now, do not run your display with 20R series resistors. You may damage the Arduino.

Paul

Yes, given I can now see the displays change intensity, before I move onto my larger project (large digits), I want to first breadboard the smaller 0.5" 7 segment displays and understand them fully before moving on.

So if looking at a single digit, I connect a current limiting resistor to each segment - based on R=V/I = (5-2.5)/0.02 = 125 ohms. The 5V supply I connect directly to the anode pin.

I assume for full brightness, each digit should be delivered around 20mA. As you said in an earlier explanation, when multiplexing 4 digits, the "average current" to each is a 1/4. I don't understand why. Is it not still 20mA per digit and only on for 1/4 of the time? I do however understand the "time on" is only a quarter and this results as you said to probably closer to 1/2 the intensity.

So would the aim be to increase the current to 4 x 20mA (if possible) to get back to full brightness?

I understand not blowing up the arduino and using transistors - I'll do that next. But what I don't understand is how to push the digits to the suggested max 1/10 duty cycle & 0.1ms pulse width. I think as I said I'm running at 1/4 duty cycle. So from the digits specs is this correct:

If specifications say 160mA max at 1/10 duty cycle @ 0.1ms pulse width, then mine run at 80mA could be:

=>160/2 mA at (1/10)/2 @ 0.1ms
=> 80mA at 1/5 @ 0.1ms
=> 80mA at 1/4 @ (0.1)x1.25ms
=> 80mA at 1/4 @ 0.125ms

If this is by any chance correct, now I understand the 1/4 duty cycle. But how do I achieve a 0.125ms on value for each digit (in multiplexing). The millis only works at a minimum of 1ms (1/1000th second). The above 125ms is an 1/8 of that. This would be 125microseconds. I'm confused. I'd appreciate your help here.

cjcj:
As you said in an earlier explanation, when multiplexing 4 digits, the "average current" to each is a 1/4. I don't understand why. Is it not still 20mA per digit and only on for 1/4 of the time?

Exactly, yes. The current is 20mA for 1/4 of the time and zero for the other 3/4, so 5mA on average. Its the average that determines the brightness.

cjcj:
So would the aim be to increase the current to 4 x 20mA (if possible) to get back to full brightness?

But what I don't understand is how to push the digits to the suggested max 1/10 duty cycle & 0.1ms pulse width.

I don't think you neccessarily want to do that. It won't give maximum brightness. 160mA at 1/10 duty cycle is only 16mA on average. You are aiming for 20mA average.

cjcj:
So from the digits specs is this correct:

If specifications say 160mA max at 1/10 duty cycle @ 0.1ms pulse width, then mine run at 80mA could be:

=>160/2 mA at (1/10)/2 @ 0.1ms
=> 80mA at 1/5 @ 0.1ms
=> 80mA at 1/4 @ (0.1)x1.25ms
=> 80mA at 1/4 @ 0.125ms

Short answer is I don't know if your calculations give an answer that is safe for the leds. Most led data sheets give a max continuous current and a max current for a specified pulse width and duty cycle. Most don't show a graph or give a formula that tells us the max current for other duty cycles and pulse widths. What else if anything does your data sheet give? Can you post a link to it?

cjcj:
But how do I achieve a 0.125ms on value for each digit (in multiplexing). The millis only works at a minimum of 1ms (1/1000th second). The above 125ms is an 1/8 of that. This would be 125microseconds.

Yes, that would be awkward to achieve. There is micros() but it seems overkill to get what you want.

Maybe someone on the forum with more experience can explain how to calculate the max safe current for these leds with a 1/4 duty cycle and a pulse width of, say 1ms.

PaulRB:
I don't think you neccessarily want to do that. It won't give maximum brightness. 160mA at 1/10 duty cycle is only 16mA on average. You are aiming for 20mA average.

In this case, even if the digits end up at 16mA rather than 20mA, that would be fine. It would probably be hardly noticeable. What I therefore am not clear on, is the calculation and yes if someone could answer that, I'd appreciate it. My calculation is:

Data sheet says max 160mA at 1/10 duty cycle at 0.1ms pulse width, so is this correct:
160mA : 1/10 dc : 0.1 pw, is the same as...
80mA : 1/5 dc : 0.1 pw, which is the same as...
80mA : 1/4 dc : 0.08 pw
(Sorry, different to my previous calculation).

If 0.08ms pulse width is correct, how is this achieved in arduino code when cycling. Do I specify the delay duration in micros?

Ps. The link to the data sheet for these 7 segment displays is in this thread, post #12.

cjcj:
The link to the data sheet for these 7 segment displays is in this thread, post #12.

No, I think that's the DS for the 8000 round leds you bought from China, not the 0.5" 4-digit display...