The animation frames The charlieplexing mapping The loop The led handler

{ B 1 0 1 0 1 0 1 0, B 1 0 1 0 1 0 1 0, B 1 0 1 0 1 0 1 0, B 1 0 1 0 1 0 1 0, B 1 0 1 0 1 0 1 0, B 1 0 1 0 1 0 1 0, B 1 0 1 0 1 0 1 0, B 1 0 1 0 1 0 1 0 }, { B 11111111 , B00000000, B 11111111 , B00000000, B 11111111 , B00000000, B 11111111 , 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 }

The code has four main parts:To make it easy to program what is shown on our little display, I've made the code so you can just type in whatever you want displayed like what is shown in the next lines. 1 means that the light is on and 0 off. The B character is meant to Arduino knows it is binary code instead of one thousand hunder etc. etc.This is an array indicating which pins need to be connected to each other. The beauty of this table is that you can still make this same device work, even if you have made mistakes in wiring or have some other IO pins in use. If so, just change the values in the array!The loop does nothing more than changing the frame number after a set amount of time. It calls the led handler as often as possible as to avoid flicker. You could easily combine the program with something else by just adding it here.This is where the magic happens. Basically, it steps through every LED, and checks if the current animation frame wants it on or off. Something which was hard to grasp for me earlier, was the bitlogic used to do this check. If you don't get the explanation at the comments, try this tutorial: http://arduino.cc/en/Tutorial/BitMaskCode: