Arduino Forum

Using Arduino => LEDs and Multiplexing => Topic started by: Onions on Jan 26, 2011, 06:55 pm

Title: Charlieplexing
Post by: Onions on Jan 26, 2011, 06:55 pm
Hello everybody!
This is my first post on this forum, so forgive me if I put it in the wrong section.  :.
I have been reading about charlieplexing on

http://www.instructables.com/id/Charlieplexing-LEDs--The-theory/

The concept sounded incredibly interesting, so I set about designing some software and
hardware for it, both of which are shown below:

Hardware schematic:

(http://i.imgur.com/UH0JC.png)
http://i.imgur.com/UH0JC.png

Software code:

Code: [Select]
int previousByte;
int incomingByte;        //variable used for storing incoming data

void setup(){
  Serial.begin(9600);    //start serial communication
}

void loop(){
  if(Serial.available() > 0){      //if there is data available...
    previousByte = incomingByte;   //store the old data as previousbyte
    incomingByte = Serial.read();  //read the new data
    incomingByte = incomingByte - 48;    //Subtract 48 form it - 0 has the ASCII value 48, so to get it back to 0, we take away 48
    Serial.flush();                      //clear the serial 'data bank'
  }
 
  if(incomingByte != previousByte){    //if the new data is different to the old suuff...
   //turn all pins to output, so we can turn them to low.
   pinMode(4, OUTPUT);
   pinMode(3, OUTPUT);
   pinMode(2, OUTPUT);
    digitalWrite(2, LOW);      //turn all the pins low
    digitalWrite(3, LOW);
    digitalWrite(4, LOW);
    switch(incomingByte){      //turn on the correct pins for the LED selected:
   
      case 1:
      pinMode(4, INPUT);
      pinMode(3, OUTPUT);
      pinMode(2, OUTPUT);
      digitalWrite(3, LOW);
      digitalWrite(2, HIGH);
      break;
     
      case 2:
      pinMode(4, INPUT);
      pinMode(3, OUTPUT);
      pinMode(2, OUTPUT);
      digitalWrite(3, HIGH);
      digitalWrite(2, LOW);
      break;
     
      case 3:
      pinMode(2, INPUT);
      pinMode(3, OUTPUT);
      pinMode(4, OUTPUT);
      digitalWrite(3, HIGH);
      digitalWrite(4, LOW);
      break;
     
      case 4:
      pinMode(2, INPUT);
      pinMode(3, OUTPUT);
      pinMode(4, OUTPUT);
      digitalWrite(4, HIGH);
      digitalWrite(3, LOW);
      break;
     
      case 5:
      pinMode(3, INPUT);
      pinMode(4, OUTPUT);
      pinMode(2, OUTPUT);
      digitalWrite(2, HIGH);
      digitalWrite(4, LOW);
      break;
     
      case 6:
      pinMode(3, INPUT);
      pinMode(4, OUTPUT);
      pinMode(2, OUTPUT);
      digitalWrite(4, HIGH);
      digitalWrite(4, LOW);
      break;
     
      default:
      Serial.println("Please select a number between 1 and 6");
      break;
    }
   previousByte = incomingByte;  //this makes the code more efficient, by only repeating the above when needed
  }
}
     
     



The code is simple, and compiles without problems. The hardware schematic was drawn in
express PCB and has the pin connections and resistor values labelled. The reason I posted this
is because I was worried about the pins. I did not want to end up breaking anything by mistake,
so:



I know I probably shouldn't worry about the input pins breaking, as they are being supplied
with less current than the outputs can provide. The thing I am concerned about is, surely
using a low pin as a ground pin will pour in power that is not neeeded or wanted, and wreck
havock with the inner workings of the microcontroller?


Thanks in advance for any help!
Onions.




Title: Re: Charlieplexing
Post by: baum on Jan 26, 2011, 07:17 pm
Hook a transistor to the pin (preferably a FET) and you can have more current.
I don't think that the pins are actually tied to ground. Test it by connecting a "LOW" digital output to an analog input and read off the values over Serial. To fix it, just put a 10k pull-down resistor between the output pin and ground.ß
Title: Re: Charlieplexing
Post by: cmiyc on Jan 26, 2011, 07:21 pm
You might consider using more than 80 ohms, especially while you are testing.  This way you can ensure you don't accidentally have a setup where you Source or Sink >20mA from a single pin.  Another number to keep in mind is the absolute max current rating for the VCC and GND pins.  The max is 200mA.  Which means you probably don't want it to be more than 150mA.

Your comment: "The thing I am concerned about is, surely using a low pin as a ground pin will pour in power that is not neeeded or wanted, and wreck
havock with the inner workings of the microcontroller
?"

I'm not sure what any of that means.  When a pin goes "HIGH", it is connected to VCC through a transistor.  When a pin goes "LOW", it is connected to Ground through a transistor.  Look at the functional diagrams for an i/o pin in the datasheet.  What is the source of this "power" that will "pour"?  If you Source or Sink 40mA or more though the pin, you are likely to burn out the pin's drivers.  There isn't much else to wreck.

Title: Re: Charlieplexing
Post by: Binette228 on Jan 26, 2011, 07:37 pm
Hi,

To answer you two questions:
1. (I'm assuming you talk about the I/O pins in general).
Quote
Will I break the input pins by feeding too much current through them?

Yes you will, the maximum sink or drive current per I/O pin is 40 mA, according to the Arduino hardware section. You should take a look at the datasheet for more precise information, I think some groups of pins have their own maximum current ratings. But always be careful, sinking or driving 40 mA for a long period of time COULD harm the arduino, especially if you are using LEDs, which forward voltage changes with the temperature, also changing the current passing throught them...

2.
Quote
Does writing a pin as low couple it to ground, rather than just stopping it from being high?

Writing a pin LOW will sort of "connect" it to ground, so you can sink current with it.

Don't take what I say as absolute truth, I may have done mistakes. Seriously, you should read some parts of the datasheet and take notes from it. There is all the information about current and voltage ratings.

Good luck!
Title: Re: Charlieplexing
Post by: Onions on Jan 26, 2011, 07:54 pm
Hello again!

Quote
Hook a transistor to the pin (preferably a FET) and you can have more current.

I was considering using transistors, but I decided aganst it to save space, time and money.
Then again, 20p of money, less than a minute more to set it all up... Maybe I will use some
spare transistors I have.  :)

Quote
You might consider using more than 80 ohms, especially while you are testing.  This way you can ensure you don't accidentally have a setup where you Source or Sink >20mA from a single pin.  Another number to keep in mind is the absolute max current rating for the VCC and GND pins.  The max is 200mA.  Which means you probably don't want it to be more than 150mA.


That's probably definately a good idea. Some 330 ohm resistors should sort it?

Quote
When a pin goes "HIGH", it is connected to VCC through a transistor.  When a pin goes "LOW", it is connected to Ground through a transistor.


That sums it all up nicely, thanks!

Quote
Seriously, you should read some parts of the datasheet and take notes from it.


That is something I will do!

Thanks everyone!
Onions.

Title: Re: Charlieplexing
Post by: Valalvax on Jan 26, 2011, 10:06 pm
I've done this already (up to 30 LEDs using 6 inputs, due to some crappy wiring 6 or so didn't work, but I never bothered fixing it)

Yes, you can break the input pins, I'd use 100? or higher resistors

When a pin is set to output and low it is indeed a ground, your code is much more fancy than mine, but works the same
Title: Re: Charlieplexing
Post by: Onions on Jan 26, 2011, 10:25 pm
Quote
Yes, you can break the input pins, I'd use 100? or higher resistors


I think I'll use 330 ohms, just to be on the safe side. Some day, I would
like to charlieplex 30+ LEDs, though I would have no use (yet!).
Title: Re: Charlieplexing
Post by: Valalvax on Jan 27, 2011, 04:10 am

Quote
Yes, you can break the input pins, I'd use 100? or higher resistors


I think I'll use 330 ohms, just to be on the safe side. Some day, I would
like to charlieplex 30+ LEDs, though I would have no use (yet!).


Well, I had used a couple 100 and a couple 330s actually, because I didn't have enough of one type

I didn't have a USE for the 30 LEDs, just wanted to build up from the simple 3 Pin 6 LED circuit, should have probably stopped before hitting 6 though because I ran out of breadboard room and had a couple shorts, thinking of getting some high gauge wire and pulling the insulation off of it, then sliding it onto the LEDs legs to solve that problem in the future
Title: Re: Charlieplexing
Post by: cmiyc on Jan 27, 2011, 04:12 am
Adafruit sells the LoLshield which is a high-number of charliplexed LEDs.

I found with matrixes once I got bigger than 5x5, it was easier to design a PCB.
Title: Re: Charlieplexing
Post by: Onions on Jan 27, 2011, 06:37 pm
Quote
I didn't have a USE for the 30 LEDs


XD That's such a goods reason, you've tempted me to build one!  :)
I will probobly buy the parts this weekend.

Quote
Adafruit sells the LoLshield which is a high-number of charliplexed LEDs.
I found with matrixes once I got bigger than 5x5, it was easier to design a PCB.


The shield looks cool, but it takes away part of the fun - making it!  :)
Although, it looks a brilliant option for bigger numbers of LEDs, and,
as you said, it would be better to just use a PCB for big numbers of LEDs.
Title: Re: Charlieplexing
Post by: Grumpy_Mike on Jan 27, 2011, 07:11 pm
Quote
The thing I am concerned about is, surely
using a low pin as a ground pin will pour in power that is not neeeded or wanted, and wreck
havoc with the inner workings of the microcontroller?

This is called current sinking and is a perfectly normal way to drive an output from a logic pin.

Quote
Will I break the input pins by feeding too much current through them?

No you can't put too much current into an input pin if the voltage is restricted to the supply voltage.
HOWEVER
You can feed too much current into an output pin or draw too much current out of one.
You might have been confused because each pin on the arduino can be input OR output, it is only in the output mode that they are susceptible to excess current.

Title: Re: Charlieplexing
Post by: Onions on Jan 27, 2011, 08:49 pm
Quote
No you can't put too much current into an input pin if the voltage is restricted to the supply voltage.
HOWEVER
You can feed too much current into an output pin or draw too much current out of one.


So, as long as I use the correct value (or higher - within reason) resistors, it should be fine?

Thanks, Onions.
Title: Re: Charlieplexing
Post by: Valalvax on Jan 27, 2011, 09:57 pm

Quote
No you can't put too much current into an input pin if the voltage is restricted to the supply voltage.
HOWEVER
You can feed too much current into an output pin or draw too much current out of one.


So, as long as I use the correct value (or higher - within reason) resistors, it should be fine?

Thanks, Onions.


Yep
Title: Re: Charlieplexing
Post by: MarkT on Jan 28, 2011, 02:20 am

Hook a transistor to the pin (preferably a FET) and you can have more current.
I don't think that the pins are actually tied to ground. Test it by connecting a "LOW" digital output to an analog input and read off the values over Serial. To fix it, just put a 10k pull-down resistor between the output pin and ground.ß


If you are Charlieplexing you can't just naively use a transistor to amplify the current - Charlieplexing relies on tri-state outputs - ie the pin can be
either LOW, HIGH or INPUT (high-impedance).  To drive more current both LOW and HIGH you'll need two transistors and the circuit will need to be high-impedance if the pin is - rather tricky.  In practice with LEDs its good enough to use a class-B amp thus:
(http://www.mythic-beasts.com/~markt/charlieplex.png)

Note that there is voltage drop across the transistors - but for 5V logic there's enough headroom to drive LEDs of most colours (possibly not UV ones).
Title: Re: Charlieplexing
Post by: Valalvax on Jan 28, 2011, 02:26 am
Hey Onions have you gotten around to running the script yet?
Title: Re: Charlieplexing
Post by: cloney03nunez on Jan 28, 2011, 10:29 am
Using transistor will be of some help, or just waste of money.
Title: Re: Charlieplexing
Post by: Onions on Jan 28, 2011, 05:47 pm
Quote
Hey Onions have you gotten around to running the script yet?


Not yet... I have been going through LEDs thick and fast recently, using 40 of them
in several LED cubes (one of them is still in progress), and as signal lights in other projects.
I will need to go out this weekend to buy in some more, as I do not have enough lieing
around  :(.

Just a quick note:
A 10X10X10 LED cube can be controlled by an arduino duemillanove / Uno!
Using 11 pins, all charlieplexed into an grid, will give control 110 LEDs for the coloumbs.
Use all the analog inputs as two seperate charlieplexing grids, or just use the 10
spare from the main ones and you can control all the layers too!

Using 1000 LEDs for a cube is slightly out of my budget though, so I will
not build it, and the atmega328 might not have enough memory, but
I posted it so anyone else can try, should they want to!

Onions.  :D

Title: Re: Charlieplexing
Post by: Valalvax on Jan 28, 2011, 08:53 pm
Hmm.. I've just been tearing down projects after building them, I only have one 600 pin breadboard and one 30 or so

But my projects are so far limited to make a led flash, turn it on with a button, make two flash oh crap that didn't work, use two inputs to make two flash, make a row of 10 or so and light them in order, charlieplex some together and light them, LCD screen, charlieplex using 6 outputs..


Haven't done anything since then, should probably do something this weekend
Title: Re: Charlieplexing
Post by: Onions on Jan 29, 2011, 10:15 pm
Hello again!

I've finally got round to buying some LEDs and running the code. It
works nicely, but it is a bit boring. As a result, I had the LED select
chosen by a random number. This did not seem to be random though,
so I went onto random.org to create some true random number
strings. I then used these as the LED select numbers. This makes it
completely un-random, or pre selected, but it seems quite the opposite.

The new code is here:

Code: [Select]
int number;
int position = 0;
char sequence[] = {5,4,2,6,3,1,6,5,3,2,4,1,6,5,4,1,3,2,4,5,3,6,2,1,4,2,6,3,5,1,1,4,3,2,5,6,4,1,5,6,2,3,0};

void setup(){}

void loop(){
 number = sequence[position];
 if(number == false){
   position = 0;
   number = sequence[position];
 }
 
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(2, OUTPUT);
   digitalWrite(2, LOW);      //turn all the pins low
   digitalWrite(3, LOW);
   digitalWrite(4, LOW);
     
   switch(number){      //turn on the correct pins for the LED selected:
   
     case 1:
     pinMode(2, INPUT);
     pinMode(3, OUTPUT);
     pinMode(4, OUTPUT);
     digitalWrite(3, LOW);
     digitalWrite(4, HIGH);
     break;
     
     case 2:
     pinMode(2, INPUT);
     pinMode(3, OUTPUT);
     pinMode(4, OUTPUT);
     digitalWrite(3, HIGH);
     digitalWrite(4, LOW);
     break;
     
     case 3:
     pinMode(3, INPUT);
     pinMode(2, OUTPUT);
     pinMode(4, OUTPUT);
     digitalWrite(2, HIGH);
     digitalWrite(4, LOW);
     break;
     
     case 4:
     pinMode(3, INPUT);
     pinMode(2, OUTPUT);
     pinMode(4, OUTPUT);
     digitalWrite(4, HIGH);
     digitalWrite(2, LOW);
     break;
     
     case 5:
     pinMode(4, INPUT);
     pinMode(3, OUTPUT);
     pinMode(2, OUTPUT);
     digitalWrite(2, HIGH);
     digitalWrite(3, LOW);
     break;
     
     case 6:
     pinMode(4, INPUT);
     pinMode(3, OUTPUT);
     pinMode(2, OUTPUT);
     digitalWrite(3, HIGH);
     digitalWrite(2, LOW);
     break;
     
     default:
     break;
   }
   delay(100);
   position++;
}
     
     


And some pictures...

(http://i.imgur.com/cctyb.jpg)                                   (http://i.imgur.com/6TKbw.jpg)

Plus a video (if it works):

(http://www.youtube.com/watch?v=NygWErZJHTY)

http://www.youtube.com/watch?v=NygWErZJHTY


Although it looks bad in the video, it is due to the poor video quality of my camera.
Onions.
Title: Re: Charlieplexing
Post by: WizenedEE on Feb 02, 2011, 08:45 am

Hello again!

I've finally got round to buying some LEDs and running the code. It
works nicely, but it is a bit boring. As a result, I had the LED select
chosen by a random number. This did not seem to be random though,
so I went onto random.org to create some true random number
strings. I then used these as the LED select numbers. This makes it
completely un-random, or pre selected, but it seems quite the opposite.


Wow that's pretty neat! I want to try that sometime. Maybe I'll use one of my spare 328's to build something cool.

Also, I think that what you did is basically what the normal kind of random number generator does. As far as I know, they get a ton of truly random numbers and cycle through them (they might vary the length of the cycles, but you get the idea).
Title: Re: Charlieplexing
Post by: whytei on May 07, 2011, 04:36 pm
Nice work! Just began dabbling in the whole Arduino world. Excellent way to keep my brain moving. Have been trying charlieplexing to do some basic LED stuff and was having problems driving 5 or more. Upon stumbling on your post and seeing your code it all became clear! Once again, build on!