Go Down

Topic: LDR with 7 seg display and PWM output (Read 13561 times) previous topic - next topic

cjcj

Mar 15, 2015, 01:34 am Last Edit: Mar 22, 2015, 11:23 am by cjcj
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:

Code: [Select]

  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:
Code: [Select]

  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;

UKHeliBob

Quote
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 ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

Paul__B

#2
Mar 15, 2015, 10:19 pm Last Edit: Mar 15, 2015, 10:19 pm by Paul__B
Need to read the "How to Post".

All of it.

Seriously!

cjcj

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!

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.

cjcj

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.

PaulRB

Hi,

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.

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

cjcj

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.

PaulRB

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.

cjcj

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?

PaulRB

#9
Mar 19, 2015, 12:19 am Last Edit: Mar 19, 2015, 12:27 am by PaulRB
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!

cjcj

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).

PaulRB

#11
Mar 19, 2015, 05:02 pm Last Edit: Mar 19, 2015, 05:25 pm by PaulRB
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.

cjcj

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.

cjcj

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

  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).

PaulRB

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.

Go Up