Go Down

Topic: Charlieplexing - Trouble with illuminating multiple LEDs (Read 2273 times) previous topic - next topic

bigjetphlane

Hi guys,

I'm trying to charlieplex 10 LEDs with the atmega328p. So far it works fine when I illuminate the LED's individually. However, it gets a bit strange when I try to illuminate multiple LEDs.

For example, when I try the drive LEDs 2 and 4, LED 3 is also illuminated.

Here is the circuit and code that I'm using:




Code: [Select]
int count = 0;

void setup() {
  // put your setup code here, to run once:

}

void loop() {


led2();
led4();

}

void led1()
{
    pinMode(16, INPUT);
  digitalWrite(16, LOW);
  pinMode(17, INPUT);
  digitalWrite(17, LOW);
  pinMode(18, OUTPUT);
  pinMode(19, OUTPUT);
 
  digitalWrite(19, HIGH);
  digitalWrite(18, LOW);
}

void led2()
{
    pinMode(16, INPUT);
  digitalWrite(16, LOW);
  pinMode(17, INPUT);
  digitalWrite(17, LOW);
  pinMode(18, OUTPUT);
  digitalWrite(18, HIGH);
  pinMode(19, OUTPUT);
  digitalWrite(19, LOW); 
}

void led3()
{
    pinMode(16, INPUT);
  digitalWrite(16, LOW);
  pinMode(19, INPUT);
  pinMode(19, LOW);
  pinMode(17, OUTPUT);
  pinMode(18, OUTPUT);
 
  digitalWrite(18, HIGH);
  digitalWrite(17, LOW);


void led4()
{
    pinMode(16, INPUT);
  digitalWrite(16, LOW);
  pinMode(19, INPUT);
  digitalWrite(19, LOW); 
  pinMode(17, OUTPUT);
  digitalWrite(17, HIGH);
  pinMode(18, OUTPUT);
  digitalWrite(18, LOW);

}

void led5()
{
  pinMode(16, INPUT);
  digitalWrite(16, LOW);
  pinMode(18, INPUT);
  digitalWrite(18, LOW);
  pinMode(17, OUTPUT);
  digitalWrite(17, LOW);
  pinMode(19, OUTPUT);
  digitalWrite(19, HIGH); 
}

void led6()
{
    pinMode(16, INPUT);
  digitalWrite(16, LOW);
  pinMode(18, INPUT);
  digitalWrite(18, LOW);
  pinMode(17, OUTPUT);
  digitalWrite(17, HIGH);
  pinMode(19, OUTPUT);
  digitalWrite(19, LOW); 
}

void led7()
{
  pinMode(19, INPUT);
  digitalWrite(19, LOW); 
  pinMode(18, INPUT);
  digitalWrite(18, LOW);
 
  pinMode(17, OUTPUT);
  digitalWrite(17, HIGH);
  pinMode(16, OUTPUT);
  digitalWrite(16, LOW);
}

void led8()
{
  pinMode(19, INPUT);
  digitalWrite(19, LOW); 
  pinMode(18, INPUT);
  digitalWrite(18, LOW);
 
  pinMode(17, OUTPUT);
  digitalWrite(17, LOW);
  pinMode(16, OUTPUT);
  digitalWrite(16, HIGH);
}

void led9()
{
  pinMode(19, INPUT);
  digitalWrite(19 ,LOW); 
  pinMode(17, INPUT);
  digitalWrite(17, LOW);

  pinMode(18, OUTPUT);
  digitalWrite(18, HIGH);
  pinMode(16, OUTPUT);
  digitalWrite(16, LOW); 
}

void led10()
{
  pinMode(19, INPUT);
  digitalWrite(19, LOW); 
  pinMode(17, INPUT);
  digitalWrite(17, LOW);

  pinMode(18, OUTPUT);
  digitalWrite(18, LOW);
  pinMode(16, OUTPUT);
  digitalWrite(16, HIGH); 
}



I can't figure out why this would be happening, any ideas?

Grumpy_Mike

The point about charlyplexing is that you only light one LED up at a time. If you want more you then multiplex them, that is flash them on and off rapidly so it looks like there is more than one on at once.

PaulRB

when I try the drive LEDs 2 and 4, LED 3 is also illuminated.

I can't figure out why this would be happening, any ideas?
Yes, I can see why. In reality, only one of your leds is on at any instant in time. First, D2 is on, but only for a very short time before it goes off again. Then D3 comes on, but again only for a very short time before going off. Finally D4 comes on for a very short time and goes off. This sequence is repeated hundreds, maybe thousands of times per second. Much too fast for the eye to notice, so it appears all 3 are on at the same time. This is the multiplexing that Mike referred to.

If we simplify your sketch, you can see how this is happening. Your sketch boils down to this. I have put comments showing where each led goes on or off.

Code: [Select]
void setup() {
}


void loop() {

  //led2()
 
    pinMode(16, INPUT);
  digitalWrite(16, LOW);
  pinMode(17, INPUT);
  digitalWrite(17, LOW);
  pinMode(18, OUTPUT);
  digitalWrite(18, HIGH);
  pinMode(19, OUTPUT);
  //D2 is now on
  digitalWrite(19, LOW); 
  //D2 still on

  //led4()
 
    pinMode(16, INPUT);
  digitalWrite(16, LOW);
  pinMode(19, INPUT);
  //D2 now off
  digitalWrite(19, LOW); 
  //D2 still off
  pinMode(17, OUTPUT);
  //D3 now on
  digitalWrite(17, HIGH);
  //D3 off again
  pinMode(18, OUTPUT);
  //D4 now on
  digitalWrite(18, LOW);

  //led2()
 
    pinMode(16, INPUT);
  digitalWrite(16, LOW);
  pinMode(17, INPUT);
  //D4 goes off
  digitalWrite(17, LOW);
  pinMode(18, OUTPUT);
  digitalWrite(18, HIGH);
  pinMode(19, OUTPUT);
  //D2 is now on
  digitalWrite(19, LOW); 
  //D2 still on

  //led4()
 
    pinMode(16, INPUT);
  digitalWrite(16, LOW);
  pinMode(19, INPUT);
  //D2 now off
  digitalWrite(19, LOW); 
  //D2 still off
  pinMode(17, OUTPUT);
  //D3 now on
  digitalWrite(17, HIGH);
  //D3 off again
  pinMode(18, OUTPUT);
  //D4 now on
  digitalWrite(18, LOW);


}


Note that I put two copies of the code from the led2() and led4() functions into loop() just to make it easy to see where D4 goes off again.

An important thing to understand is that when you set a pin to OUTPUT, it either defaults to LOW, or whatever it was set to last time is was set to OUTPUT.

Paul


PaulRB

The point about charlyplexing is that you only light one LED up at a time.
Actually, you can light more than one led at once when charliplexing.

In the OP's diagram, if pin 18 was high and pins 17 and 19 were low, then both D2 and D3 would be on. The OP's code never actually does this, but if it did, those 2 leds would light, although there is a danger that too much current would be sourced from pin 18, potentially damaging it or shortening its life. However, if a non-inverting current booster was connected to pin 18 (such as an npn as an emitter-follower) then no problem.

Only certain combinations of leds could be on at once, though. To achieve any combination, you would also need to multiplex, as you say

In this circuit, I light up to 8 of the 32 leds at any instant, and multiplex with a 1:4 ratio to make it appear all 32 are on.

http://forum.arduino.cc/index.php?topic=188135.0

bigjetphlane

Thanks Paul, really appreciate you breaking down the operation of the code.

An important thing to understand is that when you set a pin to OUTPUT, it either defaults to LOW, or whatever it was set to last time is was set to OUTPUT.
That I didn't know, now it makes sense why LED 3 is illuminating.

PaulRB

Here's my top tip for understanding charlieplexing.

That diagram in your first post: I've seen similar ones before. I found them a little confusing when I first learned about charlieplexing. You can just about get your head around them, but imagine one drawn for 8 or 9 Arduino outputs, controlling perhaps 64 leds... nightmare!

I find it much easier to think of them with all the leds drawn in a straight line. The lines from the Arduino outputs run underneith the leds, in parallel. The leds are organised into groups. Each group contains one fewer leds than the number of Arduino outputs. In your example you use 4 Arduino outputs, so organise the leds into groups of 3. Each group is connected with common anodes to one of the Arduino outputs, each group to a different output. The cathodes in each group connect to the other Arduino outputs.

Hopefully my attached diagram makes this easier to understand. I think it makes it very much easier to understand with larger numbers of leds and Arduino outputs!

Paul

Paul__B

And that circuit also is completely wrong.

Your other circuit is correct, the resistors must go only to either anodes or cathodes, depending on whether you wish to drive it as common cathode or common anode; the other ("common") LED terminal must go directly to the driver pin or as in that other circuit, to an emitter follower.

With the wrong circuit, you cannot effectively multiplex it.


PaulRB

Paul, it is not "completely wrong". Its not a great way to do it if you want to achieve a low multiplex ratio, I grant you.

I was attempting to re-draw the OP's original circuit, but using my preferred "linear" arrangement.

Multiplexing does work with resistors on both anodes and cathodes, the OP already found this out by accident. The current has to pass through 2 resistors, so those resistors should be a lower value to maintain good brightness/current. But it would effectivrly restrict you to lighting one led at once, ie a 1:10 multiplex ratio to light all 10 leds, which might be bright enough, depending how bright the leds are. Not much good for 64 leds though, for example!

If the common anodes were connected directly to the Arduino outputs, more than one led in each group could be lit at once, reducing the multiplex ratio down to 1:4. But the series resistors would need to be higher to avoid overloading the Arduino output driving the anodes. So for good, low ratio multiplexing, transistors would be the way to go, giving a bright, evenly lit display.

I have read Tom's blogs before and found them interesting. His charlieplexing explanation is good, but I still find my linear idea easier to understand, personally.

Paul__B

Paul, it is not "completely wrong". Its not a great way to do it if you want to achieve a low multiplex ratio, I grant you.
Which is in fact, the point I was making.

Achieving a low multiplex ratio is exactly what people are going to want to do, so citing a circuit that "explains the principle" but works poorly is what concerns me, the more so if they actually propose to use it in practice..

Go Up