Strobe

Quick question, is there a point where the value of Serial.Available becomes high enough that the arduino deletes some bytes?

The serial buffer on the arduino is 128 bytes, and with 15 per rgb led thats only 60 bytes. So If I add one more led thats 75 bytes. But I am using a teensy++, and this section in the manual might provide an answer to why, but not how to solve the problem. The Teensy++ can only have 64 bytes in the buffer at a time? How do I solve this?

Receive Buffering

When the PC transmits, usually the host controller will send at least the first USB packet within the next 1ms. Both Teensyduino and the FTDI chip on Arduino receive a full USB packet (and verify its CRC check). The FTDI chip then sends the data to a standard Arduino via slow serial. A sketch repetitively calling Serial.available() and Serial.read() will tend to see each byte, then many calls to Serial.availble() will return false until the next byte arrives via the serial communication.

On a Teensy, the entire packet, up to 64 bytes, becomes available all at once. Sketches that do other work while receiving data might depend on slow reception behavior, where successive calls to Serial.available() are very unlikely to return true. On a Teensy receiving large amounts of data, it may be necessary to add a variable to count the number of bytes processed and limit the delay before other important work must be done.

Ok this works

#include <Tlc5940.h>


/* Blink Multiple LEDs without Delay
*
* Turns on and off several light emitting diode(LED) connected to a digital
* pin, without using the delay() function.  This means that other code
* can run at the same time without being interrupted by the LED code.
*/





const int NUMRGBLEDS = 56;    //number of rgb leds
const int pin[NUMRGBLEDS] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,67,70,73,76,79,82,85,88,91,94,97,100,103,106,109,112,115,118,121,124,127,130,133,136,139,142,145,148,151,154,157,160,163,166};  //   first tlc5940 pin of every rgb led
const int NUMCHANNELS = 280; //# of rgb led's times 5







byte state[NUMRGBLEDS];   //  Leave this alone
unsigned int RedVal[NUMRGBLEDS];   //  Leave this alone
unsigned int GreenVal[NUMRGBLEDS];   //  Leave this alone
unsigned int BlueVal[NUMRGBLEDS];   //  Leave this alone
unsigned int Value[NUMCHANNELS];   //  Leave this alone
unsigned long time[NUMRGBLEDS];    //  Leave this alone

void setup()
{
  Serial.begin(115200);
  Serial.println("Initializing...");
Tlc.init();
Serial.println("Ready");
}

void loop()
{ 
 if (Serial.available() == (64)) {
   for (unsigned int i=0; i < NUMCHANNELS; ++i){
    Value[i] = (Serial.read() - '0') * 100;
    Value[i] = Value[i] + (Serial.read() - '0') * 10;
    Value[i] = Value[i] + (Serial.read() - '0');
    
    
   }
 Serial.print("You Sent: ");
 for (unsigned int i=0; i < NUMCHANNELS; ++i){
 Serial.print(Value[i] , DEC);
 Serial.print("-");

 }
 Serial.println();
 }
  
   for (unsigned int i=0; i<NUMRGBLEDS; ++i){
   RedVal[i] = Value[i*5] * Value[i*5 + 3] / 255;
   GreenVal[i] = Value[(i*5) + 1] * Value[(i*5) + 3] / 255;
   BlueVal[i] = Value[(i*5) + 2] * Value[(i*5) + 3] / 255;
   } 
   

  
  
  
 for (unsigned int i=0; i<NUMRGBLEDS; ++i){ 
if (Value[((i*5)+4)] > 0){  
  unsigned long m = millis();
   if (state[i] == 1){
      if (m - time[i] > 15)
   {
     time[i] = m;
     state[i] = 0;
     Tlc.set(pin[i], 0);
     Tlc.set(pin[i] + 1, 0);
     Tlc.set(pin[i] + 2, 0);

   }}
   else{
   if (m - time[i] > (Value[((i*5)+4)] * 8) - 15)
   {
     time[i] = m;
     state[i] = 1;
     Tlc.set(pin[i], map(RedVal[i], 0,255,0,4095));
     Tlc.set(pin[i] + 1, map(GreenVal[i], 0,255,0,4095));
     Tlc.set(pin[i] + 2, map(BlueVal[i], 0,255,0,4095));
   }
   }
 
 }
      
else{
   

     Tlc.set(pin[i], (map(RedVal[i], 0,255,0,4095)));
     Tlc.set(pin[i] + 1, (map(GreenVal[i], 0,255,0,4095)));
     Tlc.set(pin[i] + 2, (map(BlueVal[i], 0,255,0,4095)));
   
   
}
    Tlc.update();
   }
  
 
   }

Grumpy_Mike do you see any ways I could streamline the code? Specifically the refresh speed?

if (Serial.available() == (64))

Do not wait until all the bytes are sitting in the buffer. Pull them out when there are three or more in the buffer and keep a count of how many you read. Stop looking for stuff to arrive once you have counted the right number of bytes.

Instead of using:-

map(RedVal[i], 0,255,0,4095)[code]
Just shift the number 4 places to the left, in effect multiplying by 16 like this:-
[code]RedVal[i] << 4

It is much faster.[/code][/code]

On the first suggestion, the teensy provides 64 bytes an one time because it is a native usb device. Does that still apply then?

the teensy provides 64 bytes an one time because it is a native usb device

Well the packet size of a USB device is 1K, if it only fills 64 bytes of it then it is because of memory constraints. I still think you are better off taking them out a few at a time then the driver can manage the request for more data in a way that is probably going to increase the throughput.

Ok. And is there any more I can do? The strobe needs to be faster because it cant go as fast as I'd like it to.

How fast does it need to be?
You could do something like pre load the shift registers and toggle the blank pin, but you probbly need to hack into the libary for that.

Not that much faster, but as fast as possible

Well don't send the data as ASCII numbers, just send byte pairs, so that is one less serial transfer per LED and you don't have to do multiplying.

How would I do that? And since the sketch won't permanently be serial based, couldnt I just find the ascii value of the input number for now? Evuntually it will use dmx

What exactly is the time you are trying to minimise?
You could skip the bit that spits all the values back to the serial port.

I am not sure what this is doing:-

   RedVal[i] = Value[i*5] * Value[i*5 + 3] / 255;
   GreenVal[i] = Value[(i*5) + 1] * Value[(i*5) + 3] / 255;
   BlueVal[i] = Value[(i*5) + 2] * Value[(i*5) + 3] / 255;

but a multiply and then a dived by 255 is time consuming. Why 255? I would have though 256 and then you can do it with a simple shift.
Have you remove the map() function, I spoke about before?

Since the program also has a dimmer that dims the whole rgb mix, that code has to be there. It calculates the values for rgb for the leds. If I used two atmega chips where one works with dmx and calculates those values and the other updates the leds, how much would the speed increase?

If I used two atmega chips where one works with dmx and calculates those values and the other updates the leds, how much would the speed increase?

No idea,
Try it by removing those calculations and see the speed.