Hey guys:
As some of you may or may not know, I am working on a shift register PWM project for some RGB leds to go in my case fans. It works great (I'm gonna speed up the crystal when I get ahold of one, but thats a different story), except when I try to modify the brightness of any LEDS that have a higher address of 16 bits (2 bytes), the states are lost. In other words, the buffer that I am holding the frame in is not large enough for all of the bits to be held in. I need at least 3 bytes for my project to work (4 bytes would be great give me a little legroom) . When I use a LONG, any bytes above 16 bits get set to 0. WTFBOOM!??!
I have no idea whats goin on with these data types. I've tried all the 4 byte data types (the long and doubles cannot be read on the bit-level), to no avail. For some reason I cannot use __int32? It shows up as not defined.
Anybody know of some fancy-new 4 byte data types that can be bit-manipulated higher than 2 bytes?
Here is my code:
#define __dataPin 9
#define __clockPin 10
#define __latchPin 11
#define __numLedsInArray 8
#define __numPinsPerLed 3
#define __maxBrightness 100
#define __delayMultiplier .5
int ledPin = 13; // LED connected to digital pin 13
int i=0;
int tcnt2;
int isrCount = 0;
int ledStates[__numLedsInArray][__numPinsPerLed];
long currBuffer = 0; //I thought an INT was 4 bytes?
void setup() {
// initialize the shift reg control pins as outputs:
pinMode(__dataPin, OUTPUT);
pinMode(__clockPin, OUTPUT);
pinMode(__latchPin, OUTPUT);
digitalWrite(__latchPin, LOW);
for(int i=0; i<10; i++) //((int) (((__numLedsInArray*3))/s8)+1)
{
shiftOutDedicated(B00000000); //Set all of the regs to 0.
}
digitalWrite(__latchPin, HIGH);
Serial.begin(9600);
setupTimer();
}
ISR(TIMER2_OVF_vect) {
/* Reload the timer */
TCNT2 = 147; //This seems to not flicker very much. 205 for 4 LEDS, 147 for for 8 LEDS (Must shift out 3 bytes)
//New update code:
for(int isr_ledNumber=0; isr_ledNumber < __numLedsInArray; isr_ledNumber++)
{
for(int isr_loopCount=0; isr_loopCount < 3; isr_loopCount++)
{
if(ledStates[isr_ledNumber][isr_loopCount] <= isrCount)
{
currBuffer |= (1<<isr_loopCount+(isr_ledNumber*3));
}
else
{
currBuffer &= ~(1<<isr_loopCount+(isr_ledNumber*3));
}
}
}
//digitalWrite(__latchPin, LOW);
PORTB &= ~(1<<3);
shiftOutDedicated((byte)currBuffer); //First Byte
shiftOutDedicated((byte)(currBuffer>>8)); //Second
shiftOutDedicated((byte)(currBuffer>>16)); //Third to get a total of 24 bits (/3 pins = 8 RGB LEDS)
//digitalWrite(__latchPin, HIGH);
PORTB |= (1<<3);
isrCount++;
if(isrCount >= 100)
{
isrCount=0;
}
}
void shiftOutDedicated(byte val)
{
for (int i = 0; i < 8; i++) {
if(!!(val & (1<<i)))
{
PORTB |= (1<<1); //Set the dataPin bit
}
else
{
PORTB &= ~(1<<1); //Clear the dataPin bit
}
//digitalWrite(dataPin, !!(val & (1 << i)));
PORTB |= (1<<2); //Clock pin high
PORTB &= ~(1<<2); //Clear clock pin to low
//digitalWrite(clockPin, HIGH);
//digitalWrite(clockPin, LOW);
}
}
void setupTimer() //Set up the ISR.
{
unsigned int tcnt2;
TIMSK2 &= ~(1<<TOIE2);
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
TCCR2B &= ~(1<<WGM22);
ASSR &= ~(1<<AS2);
TIMSK2 &= ~(1<<OCIE2A);
TCCR2B |= (1<<CS22) | (1<<CS21) | (1<<CS20); // Set bits
//
//TCCR2B &= ~(1<<CS21);
//TCCR2B &= ~(1<<CS20);
TCCR2B &= ~(1<<CS22); //Clearing only this gives best timing.
TIMSK2 |= (1<<TOIE2);
}
void loop()
{
pattern_ledDebug();
//pattern_rainbow();
/*
easeAllRed(100, 0);
easeAllGreen(0, 0);
delay(0);
easeAllRed(50, 0);
easeAllGreen(50, 0);
delay(0);
easeAllGreen(100, 0);
easeAllRed(0, 0);
delay(0);
easeAllRed(50, 0);
easeAllGreen(50, 0);
delay(0);
*/
//easeAllBlue(100, 0);
//easeAllBlue(0, 0);
}
/*
void pattern_rainbow() //These values will give a roy-g-biv effect.
{
easeAll(100, 0, 0, 100, 0); //Have not implemented easeAll yet.
easeAll(100, 64, 0, 100, 0);
easeAll(100, 100, 0, 100, 0);
easeAll(00, 50, 0, 100, 0);
easeAll(0, 0, 100, 100, 0);
easeAll(93, 32, 93, 100, 0);
}
*/
void pattern_ledDebug() {
//This fades in and out the individual colors on the LED's.
for(int ledNumberID=0; ledNumberID < __numLedsInArray; ledNumberID++)
{
for(int ledLoopNum=0; ledLoopNum < 3; ledLoopNum++)
{
i=0;
while(i <= 100)
{
ledStates[ledNumberID][ledLoopNum]=i;
i++;
delay(1);
}
i=100;
while(i>=0)
{
ledStates[ledNumberID][ledLoopNum]=i;
i--;
delay(1);
}
}
}
}
void easeAllRed(int red, int ledToUsePrevValue)
{
int redDiff = red - ledStates[ledToUsePrevValue][0];
int loopsToRun = 100;
float redStep = (float)redDiff/(float)loopsToRun;
float redBuffer = ledStates[ledToUsePrevValue][0];
/* //Uncomment this to debug
Serial.print("Red is currently: ");
Serial.println(ledStates[ledToUsePrevValue][0]);
Serial.print("Red will ease to: ");
Serial.println(red);
Serial.print("The number of loops to run is: ");
Serial.println(loopsToRun);
Serial.print("redStep: ");
Serial.println(redStep);
Serial.print("redDiff: ");
Serial.println(redDiff);
*/
for(int i = 0; i<=loopsToRun; i++)
{
redBuffer += redStep;
//Serial.println(redBuffer);
for(int b = 0; b <= __numLedsInArray; b++)
{
ledStates[b][0] = redBuffer;
//Serial.print("The red LED is at state: ");
//Serial.println(ledStates[0][0]);
delayMicroseconds(15);
}
}
for(int b = 0; b <= __numLedsInArray; b++)
{
ledStates[b][0] == red;
}
//Serial.println("-------");
return;
}
void easeAllGreen(int green, int ledToUsePrevValue)
{
int greenDiff = green - ledStates[ledToUsePrevValue][1];
int loopsToRun = 100;
float greenStep = (float)greenDiff/(float)loopsToRun;
float greenBuffer = ledStates[ledToUsePrevValue][1];
for(int i = 0; i<=loopsToRun; i++)
{
greenBuffer += greenStep;
for(int b = 0; b <= __numLedsInArray; b++)
{
ledStates[b][1] = greenBuffer;
delayMicroseconds(15);
}
}
for(int b = 0; b <= __numLedsInArray; b++)
{
ledStates[b][1] == green;
}
//Serial.println("-------");
return;
}
void easeAllBlue(int blue, int ledToUsePrevValue)
{
int blueDiff = blue - ledStates[ledToUsePrevValue][2];
int loopsToRun = 100;
float blueStep = (float)blueDiff/(float)loopsToRun;
float blueBuffer = ledStates[ledToUsePrevValue][2];
for(int i = 0; i<=loopsToRun; i++)
{
blueBuffer += blueStep;
//Serial.println(blueBuffer);
for(int b = 0; b <= __numLedsInArray; b++)
{
ledStates[b][2] = blueBuffer;
delayMicroseconds(15);
}
}
for(int b = 0; b <= __numLedsInArray; b++)
{
ledStates[b][2] == blue;
}
return;
}
Thanks guys! ;D