As described in the charlieplexing article a specific wiring is needed to get the right effect. First Arduino pin goes to all the – pins of the LEDS on the first row, the + pins of these LEDs go to Arduino pin 2, 3, 4 etc. The second Arduino pin goes to all the – pins of the LEDS on the second row, the + pins of these LEDs go to Arduino pin 1, 3, 4 etc. And so on for all the other pins.
First add the nine current limiting resistors at the pins of the Arduino. In the software I gave them a value of 100 Ohm, but in reality, 10 Ohm or even no resistor is preferred. This is because each LED will flash only very shortly, so it isn’t at much risk for burning up.
The work in 123D is very tedious, so after the resistors start with duplicating a whole lot of LEDs in a grid. I started with red LEDs, but later on I found that the blinking of green was more visible in the software, so I changed them all.
With the leds in place, start wiring. This needs to be done very neatly, or else you will lose track of everything. I started with all the direct connections of each resistor horizontally, followed by the connections vertically.
With this done, we can work on the code!
{ B10101010, B10101010, B10101010, B10101010, B10101010, B10101010, B10101010, B10101010 }, { B11111111, B00000000, B11111111, B00000000, B11111111, B00000000, B11111111, B00000000 }
int limiter = 100000;//us (this allows you to delay the action of charlieplexing, //allowing to tweak the speed or see the effect in simulation) int animationDelay = 200;//ms ( 1/(animationDelay/1000)=fps => 5fps ) //this does not really work if the charlieplexing is limited char animationLength = 4;//match this number to the number of frames you've used //this array is filled with all the frames you want to animate, 1 is on and 0 is off char animation[4][8]={ { B10101010, B10101010, B10101010, B10101010, B10101010, B10101010, B10101010, B10101010 }, { B01010101, B01010101, B01010101, B01010101, B01010101, B01010101, B01010101, B01010101 }, { B00000000, B11111111, B00000000, B11111111, B00000000, B11111111, B00000000, B11111111 }, { B11111111, B00000000, B11111111, B00000000, B11111111, B00000000, B11111111, B00000000 } }; const int UPPERPIN = 13; //upmost pin const int LOWERPIN = 5; //lowest pin //this is the charlieplexing mapping, see for more info: //http://wealoneonearth.blogspot.nl/2013/03/design-note-charlieplexing-led-matrices.html char mapping[8][8]={ {2,3,4,5,6,7,8,9}, {1,3,4,5,6,7,8,9}, {1,2,4,5,6,7,8,9}, {1,2,3,5,6,7,8,9}, {1,2,3,4,6,7,8,9}, {1,2,3,4,5,7,8,9}, {1,2,3,4,5,6,8,9}, {1,2,3,4,5,6,7,9} }; //two variables used for timekeeping int animationFrame=0; long animationTimer = 0; void setup() { //nothing to set up } void loop() { //a timer, so you can do some other stuff at the same time if(millis() - animationTimer > animationDelay) { animationFrame++; if (animationFrame>animationLength)animationFrame=0; } updatePins();//update the leds } //the function which manages the leds void updatePins(){ for(int i = 0;i<8;i++){ for(int j = 0;j<8;j++){ if(animation[animationFrame][i]& 1<<j){ //This function works in two parts // 1<<j makes 00000001 for j=1, 00000010 for j=2, etc // then the & operator compares that bit with what is in animation[] //so in total, it checks a specific bit in animiation[], //if it's 1, a led will light, if it's 0, it will not resetAllPins(); //turn off everything pinMode(UPPERPIN-mapping[i][j]+1, OUTPUT);//+1 for offset digitalWrite(UPPERPIN-mapping[i][j]+1, HIGH); pinMode(UPPERPIN-i, OUTPUT); digitalWrite(UPPERPIN-i, LOW); //the mapping array makes sure the right pins are turned on and off delayMicroseconds(limiter); //to be able to see the effect, we limit the speed } else resetAllPins(); } } } void resetAllPins(){ for(int i=LOWERPIN;i<=UPPERPIN;i++){ pinMode(i, INPUT); digitalWrite(i, LOW); } //set everything to high impendance, so it will not function in the circuit }
With the code in place and everything functioning as I want it to, I could make the PCB to turn this into a shield. This is a very tedious task, but rewarding when done. I can't wait until it arrives and it actually works!
When you enter PCB view, everything is chaos. My design is quite simple, so I just started with gathering all the resistors and putting them nicely in place.
Now for the LEDs. Somehow 123D Circuit made a really strange ordering of my LEDs. So what I did was go back to breadboard view, check all the numbers of the LEDs and write them down. Now in PCB view I simply copied the layout.
With the LEDs generally in place, align them carefully so the grid is really accurate.
Now on to wiring. I started again at the resistors. Just click the red pad and a green wire will show where you have to go. Be careful not to hit any other pads or that you don't get too close to anything. For the LEDs I went for the vertical connections first.
For the horizontal connections, I needed to make use of the second layer of the PCB. I wasted a lot of time here because I tried to make the vias (connections between the two layers) with the via tool. But as it turned out, this does not work, you have to have this done automatically by drawing a wire and switching layers in the menu on the right. So now just draw the horizontal wires with vias next to the pads to get to the front side again.
After some work you're done! You've got a nice PCB of a Arduino shield ready for production! My design still showed some errors which don't seem a problem to me but which I can't get fixed in the software, these are the yellow spots.
That's it, an 8x8 charlieplexed grid using only 9 pins! Doing it the 'ordinary way would have cost 16 pins!
I hope this Instructable was informative and let me know if you use it for anything!
Check the source here: http://123d.circuits.io/circuits/102918-charlieplexed-arduino-8x8-led-grid-display-shield