RGB Tower - charlieplexing newbie

Ok, so I have written some code that successfully runs 4 LEDs from 4 pins using a sort of charlieplexing (i know i can have more LED's on four pins but there is a grander scheme to my plans which are currently irrelavent). I am pretty new at coding so my knowledge bank is pretty limited with respect to coding different ways to get the same result.

I attached a google sketch I made of an RGB LED tower comprised of 4 leds connected in a way that lets me charlieplex them (so you can get a better understanding of what im doing here). I got the idea from the Asherglick charliecube, and am trying to learn first on coding for one 'spire' (or tower). Each RGB LED sits atop the next, rotated 90degrees and then there are four verticle wires, each one connects one lead from each RGBLED in line (easier to just look at the picture).

For my purposes, I created some code to light up each LED in the tower for each color (R,G,B, and "Off" of course). I provided a sample of the code below. This code works just fine, and i call the functions to lightup the LED and all is well.

Now that ive rambled on and on (trying to give all the info needed!) I will get to my question...

Using the functions below is how I flip each led for each of the basic colors... what im wondering is, is there a way to code this differently so that i could use some sort of statement or something like that to identify the LED's and their color (an array maybe? i dont know) that lets me call the functions more easily and reduce the amount of code? An example of what i do to randomly flash all the LED's with random colors is use a case statement that has one case for EVERY LED/COLOR combination... so thats a bit annoying and i dont know how to reduce the code to do something like that.

Any help would be AWESOME. thanks in advance...marko

int ONEgreen()
{
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, INPUT);
pinMode(12, INPUT);
digitalWrite(9, LOW);
digitalWrite(10, HIGH);
digitalWrite(11, LOW);
digitalWrite(12, LOW);
}
int THREEred()
{
pinMode(9, INPUT);
pinMode(10, OUTPUT);
pinMode(11, INPUT);
pinMode(12, OUTPUT);
digitalWrite(9, LOW);
digitalWrite(10, LOW);
digitalWrite(11, LOW);
digitalWrite(12, HIGH);
}

etc......

You can make a function that takes arguments and then do math(or something) inside of the function to run the rest of the code. You'll end up with something pretty long probably, but it will be smaller and faster code wise, and easier to create animations programming wise. So something like

int r;
int g;
int b;
int x;
int y;
int z;
int state;

void setup(){
setup here;
}

void loop(){
led(0,128,255,2,2,2,1);
...;
}

void led(int r, int g, int b, int x, int y, int z, int state){
code to determine what to set as I/O and what pin to set high/low;
}

so when you want to turn an LED on, you call the function and give it the color and coordinates and whether to turn it on or off

Also read Arduino Reference - Arduino Reference
and http://tronixstuff.wordpress.com/2011/10/22/tutorial-arduino-port-manipulation/
This allows MUCH (nearly 80x) faster operation, but it's not as reliable and the output isn't as clean.

Thanks alot for the response, it really clears some basic things up for me and will give me alot more time... i will have to play around with the port manipulation to learn how it works, but i was also reaslly interested in that so thanks for the second link, it explains it more clearly for me.

One question though, just curious really, why is port manipulation less reliable? I did read that it can be more difficult to debug when you have some error, but I hadnt yet read that the output can be a bit less reliable.

Thanks again!
Marko

Hmm, I thought I had read that in one of the articles, but I guess not. I think the biggest thing was about being cautious about the serial pins

It is a lot easier to cause unintentional malfunctions with direct port access. Notice how the line DDRD = B11111110; above mentions that it must leave pin 0 as an input pin. Pin 0 is the receive line (RX) on the serial port. It would be very easy to accidentally cause your serial port to stop working by changing pin 0 into an output pin! Now that would be very confusing when you suddenly are unable to receive serial data, wouldn't it?

== from the arduino reference pages

Just on a note about port manipulation you usually never want to use the '=' operator.
To be safe you use &= or |= (binary and equals / binary or equals)

When you want to turn pins low you use &= because that will not change any of the 1's in the binary stream (A&1 = A) (A&0 = 0)
EG:

char port = B11110000;
port &= B10101010;
//port now equals 10100000

see how it left the second half alone and did not set them to 1's it can only change bits to 0

When you want to turn pins high you use |= because that will not change any of the 0s in the binary stream (A|1 = 1) (A|0 = A)

char port = B11110000;
port |= B10101010;
// port now equals 11111010

see how the first half did not change, or equals can only change bits to 1

By doing this you can safely ignore the serial pins.

  • Asher

I am trying to play with this same idea. I am confused about how you have this spire wired up to the arduino though. If you have 9-12 wired to the 4 legs of the spire, where are the wires for 5v and ground? I am also trying to figure out where you put the resistor in your 1 spire rig.

Thanks for your time.

Mike