Switching digital outputs to limit current draw.

I'm Ignacio from Uruguay, software developer getting into electronics as a hobbie. I have a question about max current draw from digital outputs on an Arduino Uno. I know there are other ways to wire this kind of circuit but I'm trying to use the minimum amount of components for controlling a 7 segments display.

If I connect the 7 leds of the display (only 4 showing in the diagram) when 0 is high and 1 is low D1 would lit, when 0 is high and 2 is low D2 would lit, etc.
If I lit only one LED at a time and use a small delay between loop cycles it would look like all the segments are on.

Here's the code for two LEDs (I didn't try to add more LEDs before asking, I'm scared of blowing up my Arduino)

void setup() {

  pinMode(0, OUTPUT);      
  pinMode(1, OUTPUT);      
  pinMode(2, OUTPUT);      
}
int d = 10;
void loop()
{
  //Make sure everything is off at the beggining
  digitalWrite(0, HIGH);  
  digitalWrite(1,HIGH);
  digitalWrite(2,HIGH);
  while(1)
  {
    
    digitalWrite(1,HIGH); //Turn OFF LED 1
    digitalWrite(2,LOW);  //Turn ON LED 2
    delay(d);

    digitalWrite(2,HIGH); //Turn OFF LED 2
    digitalWrite(1,LOW);  /Turn ON LED 1
    delay(d);
  }

}

Do you see anything wrong with this design?
Thanks in advance!

leds.JPG

You should avoid drawing more than 20 mA from a digital output, and NEVER exceed 40 mA. Doing so will sooner or later destroy the Arduino.

Always use current limiting resistors with LEDs; switching does not limit the current.

The image link was broken, sorry. There I'm limiting the current with the resistor, If there's only one lit at a time the current draw will be OK. Am I wrong?
Thanks :slight_smile:

Resistors are cheap, Arduinos aren't. (Well, they are, but not compared to resistors).

I get what you're trying to do... and if done correctly this will lower your overall current power usage and provide the illusion that all the LEDs/segments are lit simultaneously. As mentioned above, though, this will NOT lower the current on a pin, only the resistors will do that.

I'm questioning your code, though... actually, I guess your design... Why not run to ground instead of pin0? Then for each led/segment, you're sending LOW for off, and HIGH for on.

void setup() {
    
  pinMode(1, OUTPUT);      
  pinMode(2, OUTPUT);      
  digitalWrite(1,LOW);
  digitalWrite(2,LOW);
}
int d = 10;
void loop()
{ 
    digitalWrite(1,LOW); //Turn OFF LED 1
    digitalWrite(2,HIGH);  //Turn ON LED 2
    delay(d);

    digitalWrite(2,LOW); //Turn OFF LED 2
    digitalWrite(1,HIGH);  /Turn ON LED 1
    delay(d);
}

Stay away from pins 0 and 1 as they are dedicated for serial. These pins are used for USB programming and communicating with the PC.

In the diagram provided, you could add as many LEDs as there are available pins, there is no danger of current overload. Just make sure they are all installed correctly (not reversed).

Tkrain:
Resistors are cheap, Arduinos aren't. (Well, they are, but not compared to resistors).

I get what you're trying to do... and if done correctly this will lower your overall current power usage and provide the illusion that all the LEDs/segments are lit simultaneously. As mentioned above, though, this will NOT lower the current on a pin, only the resistors will do that.

I'm questioning your code, though... actually, I guess your design... Why not run to ground instead of pin0? Then for each led/segment, you're sending LOW for off, and HIGH for on.

void setup() {

pinMode(1, OUTPUT);     
  pinMode(2, OUTPUT);     
  digitalWrite(1,LOW);
  digitalWrite(2,LOW);
}
int d = 10;
void loop()
{
    digitalWrite(1,LOW); //Turn OFF LED 1
    digitalWrite(2,HIGH);  //Turn ON LED 2
    delay(d);

digitalWrite(2,LOW); //Turn OFF LED 2
    digitalWrite(1,HIGH);  /Turn ON LED 1
    delay(d);
}

I didn't tell the whole story, I don't run ground because the display has 4 characters, I need a pin for each common anode to select the character that will be lit.

@dlloyd I'll leave those pins alone then.

Thanks!

Remember also the maximum current for all pins is 200mA. Add up all the LEDS that may be lit at the same time and select series resistors that will limit to that current.

Weedpharma

That diagram is wrong. Each LED segment needs its own resistor, otherwise the brightness of the segments will change depending on how many are on.

The pin 0 will supply the sum of all the segments and this will be too much for it, as said do not use pins 0&1 at all.
You need a PNP transistor to control the anodes to get sufficient current into the display.

Well Mike, are you still Grumpy at me?
It is possible to do as NachoMK suggest.
Well, only one of 28 segments can be lit, but in dark with superbright LED display i can work.

NachoMK, connect your display as you suggest and report how it works.

Pelle

Well, only one of 28 segments can be lit,

OK true but I normally ignore pedantic stupid impractical solutions.

but in dark with superbright LED display i can work

Well at a 28:1 duty cycle and all that processing power for the very rapid multiplexing the trade off between that and a transistor is a no brainier.

It worked the display is not as bright as it could be but I think it's still OK. A bit too much code to just write "hello", but it was fun to do it anyway.

At the beggining I thought about coding a function to show characters but it was a bit too much work for just a little experiment, so the code is dirty, sorry about that.

Here is the datasheet for the display, I just added a 330 resistor between each common cathode and the arduino pins.
I used pins 2-5 to select the character and 6-13 to select segments.

Thanks for your time.

int del = 150;

int pinChar1 = 5;
int pinChar2 = 4;
int pinChar3 = 3;
int pinChar4 = 2;

//Segment pins
int A = 6;
int B = 7;
int C = 8;
int D = 9;
int E = 10;
int F = 11;
int G = 12;
int Dot = 13;


void setup() {

  pinMode(pinChar1, OUTPUT);
  pinMode(pinChar2, OUTPUT);     
  pinMode(pinChar3, OUTPUT);     
  pinMode(pinChar4, OUTPUT);     

  pinMode(A, OUTPUT);     
  pinMode(B, OUTPUT);     
  pinMode(C, OUTPUT);     
  pinMode(D, OUTPUT);   
  pinMode(E, OUTPUT);  
  pinMode(F, OUTPUT);  
  pinMode(G, OUTPUT);  
  pinMode(Dot, OUTPUT);    

  digitalWrite(pinChar1, LOW);  
  digitalWrite(pinChar2,LOW);
  digitalWrite(pinChar3,LOW);
  digitalWrite(pinChar4,LOW);

  digitalWrite(A,LOW);
  digitalWrite(B,LOW);
  digitalWrite(C,LOW);
  digitalWrite(D,LOW);
  digitalWrite(E,LOW);
  digitalWrite(F,LOW);
  digitalWrite(G,LOW);
  digitalWrite(Dot,LOW);

}

void loop()
{  

  digitalWrite(pinChar1,LOW);
  digitalWrite(pinChar2,HIGH);
  digitalWrite(pinChar3,HIGH);
  digitalWrite(pinChar4,HIGH);  

  digitalWrite(E,HIGH);
  delay(del);

  digitalWrite(E,LOW);
  digitalWrite(F,HIGH);
  delay(del);

  digitalWrite(F,LOW);
  digitalWrite(G,HIGH);
  delay(del);

  digitalWrite(G,LOW);
  digitalWrite(C,HIGH);
  delay(del);
  digitalWrite(C,LOW);

  digitalWrite(pinChar1,HIGH);
  digitalWrite(pinChar2,LOW);

  digitalWrite(A,HIGH);
  delay(del);

  digitalWrite(A,LOW);
  digitalWrite(F,HIGH);
  delay(del);

  digitalWrite(F,LOW);
  digitalWrite(E,HIGH);
  delay(del);  

  digitalWrite(E,LOW);
  digitalWrite(F,HIGH);
  delay(del);

  digitalWrite(F,LOW);
  digitalWrite(G,HIGH);
  delay(del);

  digitalWrite(G,LOW);
  digitalWrite(D,HIGH);
  delay(del);

  digitalWrite(D,LOW);


  digitalWrite(pinChar2,HIGH);
  digitalWrite(pinChar3,LOW);

  digitalWrite(F,HIGH);

  delay(del);

  digitalWrite(F,LOW);
  digitalWrite(E,HIGH);
  delay(del);

  digitalWrite(E,LOW);
  digitalWrite(B,HIGH);
  delay(del);

  digitalWrite(B,LOW);
  digitalWrite(C,HIGH);
  delay(del);
  digitalWrite(C,LOW);

  digitalWrite(pinChar3,HIGH);
  digitalWrite(pinChar4,LOW);


  digitalWrite(G,HIGH);
  delay(del);

  digitalWrite(G,LOW);
  digitalWrite(C,HIGH);
  delay(del);

  digitalWrite(C,LOW);
  digitalWrite(D,HIGH);
  delay(del);

  digitalWrite(D,LOW);
  digitalWrite(E,HIGH);
  delay(del);

  digitalWrite(E,LOW);

  del = 1;
}

I just added a 330 resistor between each common cathode and the arduino pins.

So that limits the current to just under 10mA per segment. So that means the maximum current through the common anode pin is 75mA. You start to damage the Arduino when you draw 40mA or more. So while it might work the question is for how long.

Grumpy_Mike:
So that limits the current to just under 10mA per segment. So that means the maximum current through the common anode pin is 75mA. You start to damage the Arduino when you draw 40mA or more. So while it might work the question is for how long.

But I lit only one segment at a time.

The current would be limited to just under 10mA per digit, no matter how many segments are turned on, except only one segment on at a time would work correctly.

The problem with this setup, ultimately, is what Grumpy Mike was talking about with the 1/28th duty cycle.

  • Each segment is getting the equivilant of DigitalWrite(9)... i.e. dim to begin with
  • You're spending a lot of clock cycling through your display... time your arduino will not be spending doing whatever the display is supposed to be reading...

In other words, this is neat for practice, but not all that practical in the real world.
For just a couple more resistors, you could write each complete digit at once, have a brighter display and more time in the loop for processing.

Tkrain:
The problem with this setup, ultimately, is what Grumpy Mike was talking about with the 1/28th duty cycle.

  • Each segment is getting the equivilant of DigitalWrite(9)... i.e. dim to begin with
  • You're spending a lot of clock cycling through your display... time your arduino will not be spending doing whatever the display is supposed to be reading...

In other words, this is neat for practice, but not all that practical in the real world.
For just a couple more resistors, you could write each complete digit at once, have a brighter display and more time in the loop for processing.

Totally agree, it was just an experiment.

If you are only switching on one segment at a time then there is no need for resistors on each segment, just in each common connector. Also the current of 10mA can be increased to 20mA by changing the resistor, if you have not got a lower value then put two of your 330R resistors in parallel.