Hello,
I have a library that I got off the internet. It allows me to control RGB LED modules. The library makes use of the timer 1 to send data.
My problem is that I can't get millis() to work in my loop(). I am assigning millis() to a long int and then printing the value and it is always 0! I think it has something to do with the library's timer and interrupt routines. I can't figure it out though.
I have an arduino pro mini and I am outputting to 2 strands of 100 LEDs each.
Please help!
This is what is in the library I am using:
// Globals used by interrupt code.
char SendMode=0; // Used in interrupt 0=start,1=header,2=data,3=data done
char BitCount=0; // Used in interrupt
char LedIndex=0; // Used in interrupt - Which LED we are sending.
char BlankCounter=0; //Used in interrupt.
unsigned int BitMask; //Used in interrupt.
LEDPixels LP1; //Preinstatiate
ISR(TIMER1_OVF_vect) // interrupt service routine that wraps a user defined function supplied by attachInterrupt
{
LP1.doOutput();
}
void LEDPixels::show()
{
// The interrupt routine will see this as re-send LED color data.
SendMode = 0;
}
void LEDPixels::initialize(long microseconds, int * DisplayAddress,unsigned int LEDCount , char clkPin, char dPin, char dPin2 ) //MRW - for 2nd data pin (the last argument)
{
byte Counter;
clockPin = clkPin;
dataPin = dPin;
dataPin2 = dPin2; //MRW - for 2nd data ping
Display = DisplayAddress;
NoOfLEDs = LEDCount;
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
// Adjust as you please. Too slow makes LEDs flicker.
// Too fast and the interrupt may chew into your processing speed!
//Timer1.attachInterrupt( LedOut ) ; // attaches routine to drive LEDs
show(); // Kick off display.
TCCR1A = 0; // clear control register A
TCCR1B = _BV(WGM13); // set mode as phase and frequency correct pwm, stop the timer
if(microseconds > 0) setPeriod(microseconds);
//isrCallback = isr; // register the user's callback with the real ISR
TIMSK1 = _BV(TOIE1); // sets the timer overflow interrupt enable bit
sei(); // ensures that interrupts are globally enabled
start();
}
void LEDPixels::setPeriod(long microseconds)
{
long cycles = (F_CPU * microseconds) / 2000000; // the counter runs backwards after TOP, interrupt is at BOTTOM so divide microseconds by 2
if(cycles < RESOLUTION) clockSelectBits = _BV(CS10); // no prescale, full xtal
else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11); // prescale by /8
else if((cycles >>= 3) < RESOLUTION) clockSelectBits = _BV(CS11) | _BV(CS10); // prescale by /64
else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12); // prescale by /256
else if((cycles >>= 2) < RESOLUTION) clockSelectBits = _BV(CS12) | _BV(CS10); // prescale by /1024
else cycles = RESOLUTION - 1, clockSelectBits = _BV(CS12) | _BV(CS10); // request was out of bounds, set as maximum
ICR1 = pwmPeriod = cycles; // ICR1 is TOP in p & f correct pwm mode
TCCR1B &= ~(_BV(CS10) | _BV(CS11) | _BV(CS12));
TCCR1B |= clockSelectBits; // reset clock select register
}
void LEDPixels::doOutput()
{
switch(SendMode)
{
case 3: //Done..just send clocks with zero data
digitalWrite(dataPin, 0); //You'll need 255 clocks for a LED to diplsay 1 color pwm.
digitalWrite(dataPin2, 0); //MRW - for 2nd data pin
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
break;
case 2: //Sending Data
if (BitCount==0) //First bit is always 1 followed by 15 bits of LED color.
{
digitalWrite(dataPin, 1);
digitalWrite(dataPin2, 1); //MRW - for 2nd data pin
BitMask=0x8000;//Init bit mask
}
else
{
if(BitMask & Display[LedIndex]) //If not the first bit then output the next bits (Starting with MSB bit 15 down.)
{
digitalWrite(dataPin, 1);
}else
{
digitalWrite(dataPin, 0);
//MRW - this entire if-else block is for the 2nd data pin
if(BitMask & Display[LedIndex+100]) //If not the first bit then output the next bits (Starting with MSB bit 15 down.)
{
digitalWrite(dataPin2, 1);
}else
{
digitalWrite(dataPin2, 0);
}
//end of new code
}
}
BitMask>>=1;
BitCount++;
if(BitCount == 16) //Last bit?
{
LedIndex++; //Move to next LED
if (LedIndex < NoOfLEDs) //Still more leds to go or are we done?
{
BitCount=0; //Start from the fist bit of the next LED
}
else
SendMode=3; //No more LEDs to go, we are done!
}
// Clock out data.
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
break;
case 1: //Header
if (BitCount < 32)
{
digitalWrite(dataPin, 0);
digitalWrite(dataPin2, 0); //MRW - for 2nd data pin
BitCount++;
if(BitCount==32)
{
SendMode++; //If this was the last bit of header then move on to data.
LedIndex=0;
BitCount=0;
}
}
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
break;
case 0: //Start
if(!BlankCounter) //AS SOON AS CURRENT pwm IS DONE. BlankCounter
{
BitCount=0;
LedIndex=0;
SendMode=1;
}
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
break;
}
//Keep track of where the LEDs are at in their pwm cycle.
BlankCounter++;
}
void LEDPixels::start()
{
TCCR1B |= clockSelectBits;
}