Arduino Mega 2560 to run Programmable LED Strip, code difficulties

Dear LMRians,

I have bought an LED strip with chips WS2811, which has 3 wires, Data, 12V supply and Ground. According to the datasheet, the data had should be in the following way. I have some programming problems.

 

 

the problem is that, I would like to use Arduino Mega 2560 with 16 MHz clock. and the lenght of the required PWM is at most 2.5us which corresponds to just about 40 clock. and for 1 and 0 signal, required clocks are just, respectively, 19 and 8 clocks. This is few. and I guess there is no enough time for using interrupts or timer/counters.

Which procedure do you suggests?

The LED strip has 50 pixels ( 50 chips) the data which should be send, includs 50 (pixels) * 3 (R, G and B) * 8 (bits for each color) = 1200 bits of data. For the first step, just runing the system in the symplest way, I produced this array matrix and used timer/counter interrupt. In the interrupt, seems that there is no enough time to run all of the codes, See below:

 In this code I would like just make all the 50 pixels whith the same RGB setting ( r=255,g=3,b=55;)


 

 

static int led= 2, dutycylce[2]={8 , 19}; // PE4 ( OC3B/INT4 ) ,bitRead(,)

byte r=255,g=3,b=55;

static unsigned long RGB;

byte data[1200]; // the array matrix including all of data for all pixels.in this format {R(8bit)G(8bit)B(8bit)}-{R(8bit)G(8bit)B(8bit)}- .....

static int p=1200; // the counter shows which bit of data has been sent.

 

void setup() {

    pinMode(led, OUTPUT); // data pin

    RGB = r | (g << 8) | (b <<16);    // data form just for all pixels.

    OCR3A = 40;  // clocks for one bits of data

    TIMSK3 = 0;   // disable timer.counter interrupts

    TCCR3A = 0;

    TCCR3B = 0;

    TCCR3A |= (1 << WGM31) | (1 << WGM30);// using fast PWM with top = OCR3A

    TCCR3B |= (1 << WGM32) | (1 << WGM33);// using fast PWM with top = OCR3A

}

ISR(TIMER3_OVF_vect){ //overflow timer counter interrupt vecor

if (p<1200){  //bit number

  OCR3B = data[p++];

  }

else {          // if p= 1200

  TCCR3B &= 0b11111000;    // turning off the timer counter 3 after one cycle of sent data.  (1200 bits)

  TCCR3A &= 0b00000011;    // turning off the changes in pin 2 (OC3B)

  TIMSK3 = 0;

  }

}

 

void loop() {

  if (p == 1200)

  {

    for (int j = 0; j < 50; j++) // pixel counter

    {

      for (int i = 0; i < 24 ; i++) // RGB bits on one pixel

      {

        data[(i+(24*j))]= dutycylce[bitRead(RGB,i)];     //creating the data array variable just when PWM is off.

      }

    }

    p=0;

    delay(1000);

    TCNT3 = 0;

    TIFR3 = 0;

    TIMSK3 |= (1 << TOIE3);         // turning on timer counter overflow interrupt

    TCCR3A |= (1 << COM3B1); // turning on PWM on OC3B or pin 2

    TCCR3B |= (1 << CS30); // turning on the timer counter 3

  }

}


with this programm, logically, the length of a string of data should be 1200 bits * 2.5 us = 3000 us = 3 ms. But at the end I have about 6 ms of data. there some bits, extra. I guess there is not enough time to finish the interrupt vector each time. Is that right.? Whats my mistake?

actually I have bought a ready LED Driver which uses Xmega Microcontroller series and a SD memory card and also a software on computer to program it (using DB9). the thing it is strange, is that the Crystal Oscilator on the board is 16MHz also. So this means they managed to do that with the same speed.

I would like to change the pattern of the LED strip relative to some sensors. So this is the reason which I would like to develope my codes rather than using ready devices.

thanks