I have designed and built a GPS time derived six digit digital clock using an Arduino. the digits are LED 2.3 inch common anode 12 V devices (because that's what I had!) and, after much work to drive the 74LS47 decoders with the Arduino's outputs it's working really well! Dead accurate time always. Problem is, if the room is dark and I turn the light off, it looks like the room is on fire. I am not an analog guy. I don't understand transistors. I should have paid more attention in school. Since these are common anode devices, I have discovered I need to use a PNP transistor to control the power going IN to the displays, not the drain coming OUT. The drains are connected to the LS47's.

I have tried heaps of different circuits using an LDR and a BD140 and can dim a LED (with an LDR) linearly at 5 V, but cannot seem to translate the circuit's values to 12 V.

Info. I am using 12 V common anode seven segment devices. When all six of the displays are showing '8', the current drawn is about 380 mA.

The cathodes of the individual segments are connected the the LS47's via 470R resistors.

The LDR is from an Australian electronics retailer. Specs are Dark resistance: 0.5 MΩ min. Light resistance: 2.8-8.4 kΩ.

I've got heaps of BD140 transistors in hand.

I need the display to automatically dim by - say - 90% when the room is dark, and be about 90% of full brightness during the day.

I would like to avoid using PWM if possible. An LDR, a couple of resistors and a transistor would be much simpler.

As a side note, all the Googling I've done returns voltage or current control on the drain of the LED, or uses a potentiometer. There seems very little info or guides on controlling the source side of common anode displays.

If a kind person could design a simple dimmer for me I'd really appreciate it. I have no circuits to upload - they're all NPN based drain designs.



  • \$\begingroup\$ Two possibilities are commonly found. (1) Going with the common anode, as stated, don't control the anode current but keep on switching it (if muxing multi-digits.) Then control the cathode currents at each and every segment using a configurable current sink (two modes may be enough.) Or (2) Use PWM. But you say you don't want that. So it is back to (1). There are ICs that do all this and can tolerate 12 V, as well. But you probably don't have any on hand. So you could just use BJTs. But you will need a few of them. \$\endgroup\$ Commented Aug 17, 2023 at 3:37
  • \$\begingroup\$ NPN for the low side is what you want. Do you have heaps of those, too? Are you also asking for a circuit with hysteresis that automatically adjusts, using the LDR, and affects the current sinks? \$\endgroup\$ Commented Aug 17, 2023 at 3:40
  • \$\begingroup\$ With your current configuration, the display segment current is determined mostly by your supply voltage and the 470R segment resistors. So my suggestion would be to use your LDR & transistor(s) to build a crude "light-controlled voltage regulator" and use the output of that to supply your displays' common anodes. \$\endgroup\$
    – brhans
    Commented Aug 17, 2023 at 9:11

3 Answers 3


Simon shows a good approach - feed anodes with a DC supply voltage that varies. One may take care that the photocell only sees ambient daylight, and doesn't see light from the LEDs, otherwise there might not be a smooth day/night transition.

In an effort to simplify Simon's idea, consider a day/night switch in brightness. Since you have a +5V DC supply for logic, that may give a sufficiently-dim anode supply for LEDs. LED current would flow through D2 to supply LEDs. During day, close the switch SWday to enable the +12V source for LEDs, (through Q1) giving much brighter display.
The +5V logic supply should be able to source an extra hundred mA or so during night operation.
If the +5V supply path is still too bright at night, add another series diode to D2, or use a silicon diode like 1N4001 or two.
If you want to get fancy, a Light-Dependent-Resistor circuit might be substituted for SWday.


simulate this circuit – Schematic created using CircuitLab


You can't control current at the common anodes using a resistor or constant current source, since that current would be shared between however many LEDs are lit, resulting in an "8" (all seven segments lit) being dimmer than a "1" (only 2 segments lit).

If you wish to approach this problem by controlling current, then I think you'll have to have every single segment individually current limited at their cathodes, which is a lot of hard work and transistors.

However, you can control the voltage at the anodes. By reducing anode potential, you reduce the voltage across the current limiting resistors (at the cathodes) by a similar amount, resulting in a commensurate reduction in LED current through all LEDs equally.

This approach would be compatible with the open-collectors of the 74LS47 segment outputs, since they don't care what positive supply potential is on the other side of their loads; all they do is pull down.

So the idea is to have a low impedance variable supply voltage for the common anodes. How much variation depends on what voltage exists across the 470Ω resistors, when their corresponding LED is lit. I will estimate this as follows: You mentioned 380mA flows when 6×7 segments are lit, which corresponds to each LED (and its resistor) passing:

$$ I_{LED} = \frac{380mA}{6\times 7} = 9mA $$

The voltage \$V_R\$ across an individual 470Ω resistance \$R\$ will be:

$$ V_R = I_{LED} \times R = 9mA \times 470\Omega \approx 4V $$

Assuming the voltage across the LEDs remains fairly constant as current changes, we can estimate that any reduction in total supply voltage will cause a roughly equal reduction in voltage across \$R\$.

If you wished to reduce current through the LEDs by a factor of, say 2, to 4.5mA, you must halve the voltage across \$R\$, from 4V to 2V, corresponding to a reduction of supply voltage from 12V to 10V. So, as a rough starting point, we should aim to build a power supply that is variable between 12V and 10V. Obviously, I've plucked this "factor of 2" out of thin air; you should perform some experiments to find what voltage reduction is appropriate in the dimmed state.

How you go about this depends on how you derive the 12V supply in the first place, and whether you want analogue control of the dimming amount, or simple digital switching between "dim" and "bright" is sufficient.

For digitally switched dimming, assuming that you require either the full 12V or only 10V, we could employ something that "drops" 2V, rather like how a zener diode drops a fixed voltage, placing it in the current path so that only the remaining 10V appears across the all the active loads. Then we may use a simple transistor to "short-circuit" that dropping element, for full brightness:


simulate this circuit – Schematic created using CircuitLab

The red boxed region is our active "zener" diode, developing 2V between supply node S and OUT. The actual voltage dropped is controlled by R3. Increase R3 to increase the potential difference between S and OUT. With the components shown, the drop is about 2V, and the potential at OUT is therefore \$V_{OUT} = V_S - 2V = 10V \$. It regulates well for loads up to 1A, so will work for your 380mA maximum current.

Q2 bypasses (short-circuits) the red box when node BR is high, at about 4V or more. With \$V_{BR} > 4V\$ Q2 raises \$V_{OUT}\$ to within 0.2V or so of \$V_S\$, so the LED+resistor pairs all have (almost) the entire 12V across them.

Almost all of the load current passes via Q5, so we should find out what kind of power dissipation to expect in Q5. With current in each LED at 4.5mA, total collector current will be:

$$ I_C = 6 \times 7 \times 4.5mA \approx 200mA $$

Power dissipated in Q5 will be:

$$ P_{Q5} = I_C\times V_{CE} = 200mA \times 2V = 400mW $$

Q5 will get quite hot, but probably not hot enough to require a heat sink. Of course, you will choose your required voltage drop, to achieve the required dimming, and you should make measurements and recalculate this power dissipation, just to ensure that you don't fry Q5.

As far as interfacing node BR to your LDR, that's another story. We require a system that will take node BR low in the dark (LEDs dimmed), and leave it high otherwise. The simplest setup I can think of right now:


simulate this circuit

The idea here is to form a potential divider between the supply rails with the LDR, and buffer its output potential with an emitter follower. I then use a zener diode to subtract 3.3V from that signal, so node BR only begins to rise above 0V when Q6's base rises to 4V or so. In other words, BR follows Q6's base but about 4V lower. The LDR will have to produce a base potential of above 7V to bring BR high enough to switch the LED circuit to high-brightness mode. R10 is adjustable, to set the illumination level at which the switch-over takes place.

Of course I have no way of testing any of this, short of building it. At the very least you have some ideas to play with.


I checked my email this morning and discovered kind and knowledgeable people HAVE been responding to my initial post! I thought S.O. sent a notification each time someone responded.

Anyway, this dimmer problem has been around longer than you would think. A few months ago, I was playing with an Arduino and the GPS module. Since I wanted more than just the NMEA sentences on the serial monitor, I got the basic GPS code to work with a 2.3" LCD module. Nicely formatted, it displayed the time, the date, and the number of satellites it was receiving data from.

With that design, I had to be within a few feet of the display to read the time, which was irritating. In the back of my mind, I knew I had 20 or more common anode 2.3" 7-segment displays 'recovered' from a previous work place, I set about designing an Arduino MEGA circuit that could:-

Get the time from the satellites

Massage the data (the time) to generate BCD outputs via pins 22 to 53

Drive the 2.3" LED displays using LS47 decoders

This idea was too complex for stripboard. But I didn't know how to use a PCB designer.

"Hey Google, what are some good PCB designers?"

I was directed to KiCad. A free PCB deseigner with good community support, and lots of 'how to' YouTube clips.

Over the next month or so, I got the hang of KiCad's environment, and put together a complete schematic of what I wanted to achieve. I didn't care which Arduino output pin was connected to which BCD decoder, I could fix that in code.

I spent the next week or so getting the hang of the PCB editor and, unbelievable even to me, managed to layout the PCB with no track jumpers. It's a double sided PCB.

"Hey Google, what are some PCB manufacturers for hobbyists?"

I was directed to PCBWay. (Yes, there are lots of others, but went with these guys).

My first upload was rejected. "Where are the drill files?"

Drill what now?

More effort, exported the drill files, and uploaded again. Rejected again, due to poorly laid out and unconnected tracks. (Right! Is THAT what that means!)

More fixing, and uploaded again. Success! My design was accepted.

I uploaded this design, knowing FULL WELL:

My PCB layout did not provide power to the Arduino

The Arduino had to connected to the PCB using a ribbon cable

There was no dimmer circuit

The tracks were probably not beefy enough to carry the current

The GPS module connections were not catered for on the PCB

But I was impatient. Remember, this is my first time ever using a PCB designer and having PCBs actually manufactured.

A week or so later, the PCBs arrived. Wow. Impressive stuff.

I quickly assembled a PCB, and fired it up. No problems, except NONE of the displays showed meaningful numbers. Oh right, the BCD-output-connected-to-any-pin problem.

A day or so later, I had the Arduino code fixed, and the clock was displaying dead accurate time. And as a bonus, the number of satellites was being shown on a separate, 0.5" 7-segment display. 0 through 9.

I got to work with the version 2 PCB design.

I moved the header for the Arduino to the centre of the board, and provided pins for power and ground. Moving that header meant a complete re-layout of the PCB tracks, but I am proud to say I still got it done with no track jumpers.

I connected the GPS module to pins on the Mega which support serial comms.

I slightly reworked the 12v power to the display anodes so I could 'bog in' a dimmer circuit later.

That's how it sat for a few weeks, as I got angry for not being able to make (find) a suitable dimmer circuit. I finally relented and posted my stupid sounding problem here, expecting no replies.

My email didn't show any replies to my S.O. query, so I battled on. I finally cobbled together a circuit around driving the base of a BD140 with 5v, rather than the 12v I was saturating it with.

That worked MUCH better. With full light, I got 11.2v at the collector, and fully black I got close to 0v! Hopefully I can figure out how to upload images. I'd also like to upload my KiCad schematic and PCB. There's absolutely no etiquette to the schematic, it was laid out so my brain could follow it.

With all the fabulous answers provided here (thankyou all so much!) I will probably lump for the simplest suggestion shown by glen_geek.

A circuit I found lifted straight from KiCad

My version 1 clock design

The clock is mounted in a merbau timber box, with red acrylic, and with the GPS antenna, the num-of-sats display, and the LDR on top.

The version 2 PCB is ready to send to the manufacturers. I will test, then integrate glen_geek's circuit.

Thankyou again evewryone, for providing answers to such a newbie problem!


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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