I decided to do some more time checks with my POV code. As a refresher, this is doing a single read for 144 bytes from an SD card and pushing it out to FastSPI which is bitbanging it on pins 6 and 7 to a 48 pixels long WS2801 string. So I’m thinking, there are a few places for slowdowns there … reading the SD … bit banging … the WS2801 itself, why not figure it out. So this is what the timing code does:
while(1) {
unsigned int timeStart, timeMid, timeEnd;
for (int myCol = 0; myCol < columns; myCol++) {
timeStart = micros();
myFile.read((char*)leds, NUM_LEDS * 3); // read all 144 bytes
timeMid = micros();
LEDS.show(); // update string
timeEnd = micros();
cout << "Elapsed time to read SD: " << timeMid - timeStart << " micros.\n";
cout << "Elapsed time to push to string: " << timeEnd - timeMid << " micros.\n\n";
}
// Rewind back to the beginning of the file, AFTER the header
myFile.seekSet(3);
}
As you can see, I start the timer right before an SD read. I take a sample after the read is completed, and another at the end after LEDS.show();. This is the result:
Elapsed time to read SD: 108 micros.
Elapsed time to push to string: 1524 micros.
Elapsed time to read SD: 108 micros.
Elapsed time to push to string: 1564 micros.
Elapsed time to read SD: 108 micros.
Elapsed time to push to string: 1568 micros.
Elapsed time to read SD: 1292 micros.
Elapsed time to push to string: 1564 micros.
Elapsed time to read SD: 108 micros.
Elapsed time to push to string: 1572 micros.
Elapsed time to read SD: 108 micros.
Elapsed time to push to string: 1568 micros.
Elapsed time to read SD: 108 micros.
Elapsed time to push to string: 1564 micros.
Elapsed time to read SD: 1292 micros.
Elapsed time to push to string: 1564 micros.
Every 4th read, it takes a long time because it’s seeking for the next block on the card. This is expected. But what really surprised me was the time it takes to push the data out.
When I tested the same timing checks with the PROGMEM version of the program, same thing: pushing data out to the string is what’s taking a long time. The numbers were about 20-30 usecs faster. Big whoop. (The PROGMEM version is actually a tad slower in reading the data because I have to loop 48 times just to get a single column of data, and I also have to process each value to extract r, g, and b. The SD version is raw data with no processing needed. - Thanks to @Mark_Kriegsman for that suggestion.)
So, I’m back to wondering if it’s the WS2801 string that’s slow, or the fact that I’m bitbanging it on non-SPI pins. Or maybe both?
Unfortunately, I can’t (easily) put the string on the SPI bus because the SD card is on there. I say ‘easily’ because I could use a gate to add a select pin which will select between the card or the string but I have to believe that toggling back and forth between a read and string push will cause some delays … But I’m willing to entertain the possibilities … Does anyone have experience flipping back and forth between two SPI devices and do both still work fine at full speed?