I'm currently working on a 10x10 LED Matrix which is controlled by 5 Shift registers using multiplexing. I've the problem that the Teensy 3.6 is too fast/slow.

One part of my code is the Shiftout function. If I use normal digitalWrite() its working perfectly fine, but its slow. If I use digitalWirteFast() or something like GPIOA_PSOR = (1 << 12); the matrix starts to display crap.

Teensy 3.6 180MHz

74HC595 shift register

SS8050 BJT's to protect the whole thing

scematic here: circuits.io

void ShiftOut(uint8_t myDataOut) {
// This shifts 8 bits out lngMsLoopstartB first,
//on the rising edge of the clock,
//clock idles low
//internal function setup
uint8_t i = 0;
//clear everything out just in case to
//prepare shift register for bit shifting

//digitalWriteFast(dataPin, LOW);//Data aus
GPIOA_PCOR = (1 << 12); // Datapin low

//digitalWriteFast(clockPin, LOW);//Clock aus
GPIOA_PCOR = (1 << 13); // Clockpin low

//for each bit in the uint8_t myDataOut
//This means that %00000001 or "1" will go through such
//that it will be pin Q0 that lights.
for (i = 0; i <= 7; i++)  {

//digitalWrite(clockPin, LOW);//Clock aus
GPIOA_PCOR = (1 << 13); // Clockpin low

//if the value passed to myDataOut and a bitmask result
// true then... so if we are at i=6 and our value is
// %11010100 it would the code compares it to %01000000
// and proceeds to set pinState to 1.
if ( myDataOut & (1 << i) ) {
  //digitalWriteFast(dataPin, HIGH);//Data an
  GPIOA_PSOR = (1 << 12); // Datapin high

} else {
  digitalWrite(dataPin, LOW);//Data aus
  //GPIOA_PCOR = (1 << 12); // Datapin low

//register shifts bits on upstroke of clock pin
digitalWrite(clockPin, HIGH);//Clock an
//GPIOA_PSOR = (1 << 13); // Clockpin high

digitalWrite(clockPin, LOW);//Clock aus
//GPIOA_PCOR = (1 << 13); // Clockpin low

//zero the data pin after shift to prevent bleed through
digitalWrite(dataPin, LOW);//Data aus
//GPIOA_PCOR = (1 << 12); // Datapin low

if somebody needs the complete code, please let me know!

  1. How it looks like when I use GPIO 2.Picture how it should look like: Imgur


The thing I want is to make the whole multiplexing faster. Currently 1 Time all 10 rows takes about 480 microseconds. Then add a 4 Bit Bit angle modulation (480*16) its: 7680 microseconds (7.68ms). So if you now divide 1000 by 7.68 = 130,2 Hz refresh rate. Thats ok and Im fine with that.

The main problem is that I want 8 bit. so same thing again 480 * 256 = 112880 (112,88ms). So now divide 1000 by 112,88 = 8,86 Hz refresh rate. That looks really bad. I would like to get about 60-100.

The Problem is not the big LED array or setting each value every frame new. This only takes 80 microseconds.

1 Answer 1


I have also written a driver for LED matrices based on shift registers. To quickly shift out the bits to the shift registers for each scan update, I used SPI. On the Teensy 3.6, this works quite well.

But what I suspect your issue is (since you didn't post your whole code) is that you are calculating each of the bit updates in between each shifting out. If you are doing this, I suggest that you don't. Instead, buffer the bit calculations, and use a timer interrupt to shift out each row update. This approach takes advantage of the fact that you are likely to recalculate the bit layout for the matrix overall at a much slower frequency than the need to send our row updates to effect the multiplexing of the LED rows. I explain this design in much more detail in this Instructable.

Using the interrupt allows you to cleanly do the heavy lifting of recalculating the bit layout into a buffer while the row updates will consistently go out, creating a very stable image. It's the closest thing you'd to true threading on Arduino-like platforms. Also, this approach will allow a much smaller base interval for row updates. In my code, I use a 5 µs update interval, that gets modulated in order to be able to create a 12-bit color palette. I probably could get a richer color depth on the Teensy 3.6 given it's clock speed, but I wanted my code to be universal, so I am able to get the 12-bit color on 8-bit AVR micro controllers too (e.g., Arduino Mega).

You can study (or use) my code at this GitHub repository, and read more about my LED matrices (hardware and software) at my website.

  • wow! Thanks for that. Will have a look in to that. Using interrupts makes sense :D. Well in the meanwhile I built a new LED Matrix. But this time with TLC5940 LED Drivers: scholliyt.github.io/LED-Matrix-16x16
    – Tom Stein
    Commented Jan 6, 2018 at 22:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.