1

I've build a 10x10RGB (no WS2811..., the normal ones) LED Matrix with 5 shift registers and 1 arduino micro.

My Problem is now my code seems to be to slow or the arduino with its 16Mhz just cant handle a decent Hz rate. At the moment I get some flicker/lagging when I use the code down below. I think a Hz rate of about 60Hz-100Hz would be very good. I've already changed the Arduino IDE Compiler settings from -Os to -O3 to get better speed (it really worked).

The code has Bit angle modulation for brightness control and a multiplexing feature.

So my Question: Is it worth to create a Array where all the possible values (10 values, only int < 10) are predefined and then use them in line 312:

BitMapR1[intLayerSel / 10] = _byte;

I searched the internt and I found some articles telling that division on arduinos (or microcontrollers) is very slow.

setBitMaps() is where the Bit angle modulation happens myloop() is where the multiplexing happens

Code: http://pastebin.com/tkFZsVxS <-- better look here

class FLED {
private:
bool b;

public:
FLED();
void show();
};

FLED::FLED() : b(false) {

}

void FLED::show() {

}


class LED {
private:
uint8_t LEDname;
uint8_t R;
uint8_t G;
uint8_t B;

public:
LED();
uint8_t getR();
uint8_t getG();
uint8_t getB();
void setR(uint8_t _R);
void setG(uint8_t _G);
void setB(uint8_t _B);
};

LED::LED() : R(0), G(0), B(0) {

}

uint8_t LED::getR() {
return R;
}
uint8_t LED::getG() {
return G;
}
uint8_t LED::getB() {
return B;
}

void LED::setR(uint8_t _R) {
R = _R;
}
void LED::setG(uint8_t _G) {
G = _G;
}
void LED::setB(uint8_t _B) {
B = _B;
}

LED leds[100];
FLED FastLED;


void setup() {
//set pins to output so you can control the shift register
pinMode(2, OUTPUT);
pinMode(4, OUTPUT);
pinMode(3, OUTPUT);
pinMode(5, OUTPUT);
//Serial.begin(250000);
//noInterrupts();

}

unsigned long lngLast = 0;


uint8_t BitMapR1[10] = {
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000
};
uint8_t BitMapR2[10] = {
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000
};
uint8_t BitMapR3[10] = {
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000
};

uint8_t BitMapR4[10] = {
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000,
B00000000
};

LED CRGB(byte _R, byte _G, byte _B) {
LED _LED = LED();
_LED.setR(constrain(_R / 16, 0, 15));
_LED.setG(constrain(_G / 16, 0, 15));
_LED.setB(constrain(_B / 16, 0, 15));
return _LED;
}

void loop() {


//Serial.print(micros()); Serial.println(" Start");

leds[0] = CRGB(36, 0, 0);
leds[1] = CRGB(103, 0, 0);
leds[2] = CRGB(170, 0, 0);
leds[3] = CRGB(255, 0, 0);
leds[4] = CRGB(255, 0, 0);
leds[5] = CRGB(170, 0, 0);
..........
leds[96] = CRGB(103, 0, 0);
leds[97] = CRGB(36, 0, 0);
leds[98] = CRGB(0, 0, 0);
leds[99] = CRGB(0, 0, 0);


//Serial.print(micros()); Serial.println(" Objekte");
BAM();

//Serial.print(micros()); Serial.println(" BAM");

}

void BAM() {
for (byte cycle = 1; cycle <= 15; cycle++) {
//Serial.print(micros()); Serial.println(" bSetBitMaps");
setBitMaps(cycle, 1);
//Serial.print(micros()); Serial.println(" aSetBitMaps");

lngLast = micros();
myloop();
delayMicroseconds(50);
turnoff();





//Serial.print(micros()); Serial.println(" aMyloop");



}



}

void turnoff() {
PORTD &= ~_BV(PORTD2);

ShiftOut(B00000000);
ShiftOut(B00000000);
ShiftOut(B00000000);
ShiftOut(B00000000);
ShiftOut(B00000000);

PORTD |= _BV(PORTD2);//LatchPin
}

void setBitMaps(byte cycle, byte pos) {
//Register 1
for (byte intLayerSel = 0; intLayerSel < 100; intLayerSel += 10){        

byte _byte = 0;
for (byte i = intLayerSel; i < intLayerSel + 8; i++) {
  if (cycle == 1 && (leds[i].getR() & (1 << pos - 1)) != 0) {
    _byte = _byte << 1;
    _byte = _byte + B00000001;
  }
  else if ((cycle == 2 || cycle == 3) && (leds[i].getR() & (1 << pos)) != 0) {
    _byte = _byte << 1;
    _byte = _byte + B00000001;
  }
  else if (cycle >= 4 && cycle <= 7 && (leds[i].getR() & (1 << pos + 1 )) != 0)  {
    _byte = _byte << 1;
    _byte = _byte + B00000001;
  }
  else if (cycle >= 8 && cycle <= 15 && (leds[i].getR() & (1 << pos + 2)) != 0) {
    _byte = _byte << 1;
    _byte = _byte + B00000001;
  }
  else {
    _byte = _byte << 1;
    _byte = _byte + B00000000;
  }
}
BitMapR1[intLayerSel / 10] = _byte;
}
for (byte intLayerSel = 0; intLayerSel < 100; intLayerSel += 10) { 

byte _byte = 0;
for (byte i = intLayerSel + 8; i < intLayerSel + 10; i++) {
  if (cycle == 1 && (leds[i].getR() & (1 << pos - 1)) != 0) {
    _byte = _byte << 1;
    _byte = _byte + B00000001;
  }
  else if ((cycle == 2 || cycle == 3) && (leds[i].getR() & (1 << pos)) != 0) {
    _byte = _byte << 1;
    _byte = _byte + B00000001;
  }
  else if (cycle >= 4 && cycle <= 7 && (leds[i].getR() & (1 << pos + 1 )) != 0)  {
    _byte = _byte << 1;
    _byte = _byte + B00000001;
  }
  else if (cycle >= 8 && cycle <= 15 && (leds[i].getR() & (1 << pos + 2)) != 0) {
    _byte = _byte << 1;
    _byte = _byte + B00000001;
  }
  else {
    _byte = _byte << 1;
    _byte = _byte + B00000000;
  }
}
for (byte i = intLayerSel; i < intLayerSel + 6; i++) {
  if (cycle == 1 && (leds[i].getG() & (1 << pos - 1)) != 0) {
    _byte = _byte << 1;
    _byte = _byte + B00000001;
  }
  else if ((cycle == 2 || cycle == 3) && (leds[i].getG() & (1 << pos)) != 0) {
    _byte = _byte << 1;
    _byte = _byte + B00000001;
  }
  else if (cycle >= 4 && cycle <= 7 && (leds[i].getG() & (1 << pos + 1 )) != 0)  {
    _byte = _byte << 1;
    _byte = _byte + B00000001;
  }
  else if (cycle >= 8 && cycle <= 15 && (leds[i].getG() & (1 << pos + 2)) != 0) {
    _byte = _byte << 1;
    _byte = _byte + B00000001;
  }
  else {
    _byte = _byte << 1;
    _byte = _byte + B00000000;
  }
}
BitMapR2[intLayerSel / 10] = _byte;
}
}



void myloop() {

byte bLayerA;
byte bLayerB;



for (byte bLayerTop = 1; bLayerTop <= 10; bLayerTop++) {
//Serial.print(micros()); Serial.println(" startML");
bLayerA = B00000000;
bLayerB = B00000000;
switch (bLayerTop) {
  case 1:
    bLayerA = B10000000;
    break;
  case 2:
    bLayerA = B01000000;
    break;
  case 3:
    bLayerA = B00100000;
    break;
  case 4:
    bLayerA = B00010000;
    break;
  case 5:
    bLayerA = B00001000;
    break;
  case 6:
    bLayerA = B00000100;
    break;
  case 7:
    bLayerA = B00000010;
    break;
  case 8:
    bLayerA = B00000001;
    break;
  case 9:
    bLayerB = B00000010;
    break;
  case 10:
    bLayerB = B00000001;
    break;

  }
/*
  if (bLayerTop == 1) {
  bLayerA = B10000000;
  } else if (bLayerTop == 2) {
  bLayerA = B01000000;
  } else if (bLayerTop == 3) {
  bLayerA = B00100000;
  } else if (bLayerTop == 4) {
  bLayerA = B00010000;
  } else if (bLayerTop == 5) {
  bLayerA = B00001000;
  } else if (bLayerTop == 6) {
  bLayerA = B00000100;
  } else if (bLayerTop == 7) {
  bLayerA = B00000010;
  } else if (bLayerTop == 8) {
  bLayerA = B00000001;
  } else if (bLayerTop == 9) {
  bLayerB = B00000010;
  } else if (bLayerTop == 10) {
  bLayerB = B00000001;
  }
*/


//Serial.print(micros()); Serial.println(" bWait");
while (micros() - lngLast < 50) {
  //Serial.println("call");
}
//Serial.print(micros()); Serial.println(" aWait");
turnoff();

PORTD &= ~_BV(PORTD2); //Latch LOW
//OutPut Enable = False
PORTD |= _BV(PORTD5);

byte bLayer = bLayerTop - 1;
ShiftOut(bLayerA);                     //Register 5
ShiftOut(bLayerB + BitMapR4[bLayer]);  //Register 4
ShiftOut(BitMapR3[bLayer]);            //Register 3
ShiftOut(BitMapR2[bLayer]);            //Register 2
ShiftOut(BitMapR1[bLayer]);            //Register 1

//take the latch pin high so the LEDs will light up:

PORTD |= _BV(PORTD2);//Latch High
//OutPut Enable = True
PORTD &= ~_BV(PORTD5);
// pause before next value:

//delay(1);
//delayMicroseconds(100);
// Serial.print(micros()); Serial.println(" end");
lngLast = micros();

}

}

void ShiftOut(byte myDataOut) {
// This shifts 8 bits out MSB first,
//on the rising edge of the clock,
//clock idles low

//internal function setup
byte i = 0;

//clear everything out just in case to
//prepare shift register for bit shifting
PORTD &= ~_BV(PORTD3);//Data off
PORTD &= ~_BV(PORTD4);//Clock off

//for each bit in the byte myDataOutï
//NOTICE THAT WE ARE COUNTING DOWN in our for loop
//This means that %00000001 or "1" will go through such
//that it will be pin Q0 that lights.
for (i = 0; i <= 7; i++)  {
PORTD &= ~_BV(PORTD4);//Clock aus

//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.


/*
    //00001010 - 00000010 = true
    switch (myDataOut & (1 << i)) {
      case 0:
        Serial.println("0");
        PORTD &= ~_BV(PORTD3);//Data aus
        break;
      case 1: //case true
        Serial.println("1");
        PORTD |= _BV(PORTD3);//Data an

        break;
    }
*/

/*
  digitalWrite(3, myDataOut & (1 << i));
*/


if ( myDataOut & (1 << i) ) {
  PORTD |= _BV(PORTD3);//Data an
} else {
  PORTD &= ~_BV(PORTD3);//Data aus
}

//register shifts bits on upstroke of clock pin
PORTD |= _BV(PORTD4);//Clock an
//zero the data pin after shift to prevent bleed through
PORTD &= ~_BV(PORTD3);//Data aus
}
}
technosaurus
  • 7,676
  • 1
  • 30
  • 52
Tom Stein
  • 345
  • 2
  • 15

1 Answers1

1

There are many issues, like:

leds[0] = CRGB(36, 0, 0);

This means:

  • copy parameters to the stack
  • call CRBG function
  • create local LED object
  • setR on that local object by calling constraint
  • setG ...
  • setB ...
  • return a copy of local object
  • copy assigment operator on led[0]

Also using 8b wide variables for 12b colors is little bit redundant. So for the start I would recommend something like that:

class LED {
  public:
    uint16_t rgb;

    LED(uint8_t r=0, uint8_t g=0, uint8_t b=0) {
      setRGB(r,g,b);
    }

    void setRGB(uint8_t r=0, uint8_t g=0, uint8_t b=0) {
      r = r >> 4; 
      g = g&0xF0;
      rgb = b&0xF0;
      rgb = (rgb<<4) | g | r;
    }

    bool getBit(uint16_t mask) {
      return rgb & mask;
    }
};

LED leds[100];

void setup() {
  pinMode(2, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  Serial.begin(250000);
}

void loop() {
  leds[0].setRGB(36, 0, 0);
  leds[1].setRGB(103, 0, 0);
  leds[2].setRGB(170, 0, 0);
  leds[3].setRGB(255, 0, 0);
  leds[4].setRGB(255, 0, 0);
  leds[5].setRGB(170, 0, 0);
  leds[6].setRGB(103, 0, 0);
  leds[7].setRGB(36, 0, 0);
  leds[8].setRGB(0, 0, 0);
  leds[9].setRGB(0, 0, 0);
  leds[10].setRGB(36, 0, 0);
  leds[11].setRGB(103, 0, 0);
  leds[12].setRGB(170, 0, 0);
  leds[13].setRGB(255, 0, 0);
  leds[14].setRGB(255, 0, 0);
  leds[15].setRGB(170, 0, 0);
  leds[16].setRGB(103, 0, 0);
  leds[17].setRGB(36, 0, 0);
  leds[18].setRGB(0, 0, 0);
  leds[19].setRGB(0, 0, 0);
  leds[20].setRGB(36, 0, 0);
  leds[21].setRGB(103, 0, 0);
  leds[22].setRGB(170, 0, 0);
  leds[23].setRGB(255, 0, 0);
  leds[24].setRGB(255, 0, 0);
  leds[25].setRGB(170, 0, 0);
  leds[26].setRGB(103, 0, 0);
  leds[27].setRGB(36, 0, 0);
  leds[28].setRGB(0, 0, 0);
  leds[29].setRGB(0, 0, 0);
  leds[30].setRGB(36, 0, 0);
  leds[31].setRGB(103, 0, 0);
  leds[32].setRGB(170, 0, 0);
  leds[33].setRGB(255, 0, 0);
  leds[34].setRGB(255, 0, 0);
  leds[35].setRGB(170, 0, 0);
  leds[36].setRGB(103, 0, 0);
  leds[37].setRGB(36, 0, 0);
  leds[38].setRGB(0, 0, 0);
  leds[39].setRGB(0, 0, 0);
  leds[40].setRGB(36, 0, 0);
  leds[41].setRGB(103, 0, 0);
  leds[42].setRGB(170, 0, 0);
  leds[43].setRGB(255, 0, 0);
  leds[44].setRGB(255, 0, 0);
  leds[45].setRGB(170, 0, 0);
  leds[46].setRGB(103, 0, 0);
  leds[47].setRGB(36, 0, 0);
  leds[48].setRGB(0, 0, 0);
  leds[49].setRGB(0, 0, 0);
  leds[50].setRGB(36, 0, 0);
  leds[51].setRGB(103, 0, 0);
  leds[52].setRGB(170, 0, 0);
  leds[53].setRGB(255, 0, 0);
  leds[54].setRGB(255, 0, 0);
  leds[55].setRGB(170, 0, 0);
  leds[56].setRGB(103, 0, 0);
  leds[57].setRGB(36, 0, 0);
  leds[58].setRGB(0, 0, 0);
  leds[59].setRGB(0, 0, 0);
  leds[60].setRGB(36, 0, 0);
  leds[61].setRGB(103, 0, 0);
  leds[62].setRGB(170, 0, 0);
  leds[63].setRGB(255, 0, 0);
  leds[64].setRGB(255, 0, 0);
  leds[65].setRGB(170, 0, 0);
  leds[66].setRGB(103, 0, 0);
  leds[67].setRGB(36, 0, 0);
  leds[68].setRGB(0, 0, 0);
  leds[69].setRGB(0, 0, 0);
  leds[70].setRGB(36, 0, 0);
  leds[71].setRGB(103, 0, 0);
  leds[72].setRGB(170, 0, 0);
  leds[73].setRGB(255, 0, 0);
  leds[74].setRGB(255, 0, 0);
  leds[75].setRGB(170, 0, 0);
  leds[76].setRGB(103, 0, 0);
  leds[77].setRGB(36, 0, 0);
  leds[78].setRGB(0, 0, 0);
  leds[79].setRGB(0, 0, 0);
  leds[80].setRGB(36, 0, 0);
  leds[81].setRGB(103, 0, 0);
  leds[82].setRGB(170, 0, 0);
  leds[83].setRGB(255, 0, 0);
  leds[84].setRGB(255, 0, 0);
  leds[85].setRGB(170, 0, 0);
  leds[86].setRGB(103, 0, 0);
  leds[87].setRGB(36, 0, 0);
  leds[88].setRGB(0, 0, 0);
  leds[89].setRGB(0, 0, 0);
  leds[90].setRGB(36, 0, 0);
  leds[91].setRGB(103, 0, 0);
  leds[92].setRGB(170, 0, 0);
  leds[93].setRGB(255, 0, 0);
  leds[94].setRGB(255, 0, 0);
  leds[95].setRGB(170, 0, 0);
  leds[96].setRGB(103, 0, 0);
  leds[97].setRGB(36, 0, 0);
  leds[98].setRGB(0, 0, 0);
  leds[99].setRGB(255, 255, 255);


// show context
  for (uint16_t bitmask = 1U; bitmask < 0x400; bitmask <<= 1) {
    for (LED & led : leds) {
      Serial.print(led.getBit(bitmask), HEX);
      Serial.print(" ");
    }
    Serial.println();
  }

  do_cycle();
}

void do_cycle() {
  uint16_t bitmask_r = 0;  
  uint16_t bitmask_g = 0;  
  uint16_t bitmask_b = 0;  

  for (byte mag = 1; mag < 16; ++mag) { // magnitude
    for (byte row = 0; row < 10; ++row) { // mistake #2
      //uint32_t us = micros();

      if ((mag & (mag-1)) == 0) { // Is it power of two? Change bitmask
        bitmask_r = mag;
        bitmask_g = bitmask_r << 4;
        bitmask_b = bitmask_g << 4;
      }

      // shift out init:
      PORTD &= ~_BV(PD3); //Data aus
      PORTD &= ~_BV(PD4); //Clock aus

      for (int8_t cnt = 9; cnt >= 0; --cnt) {
        //Serial.print(cnt==row?1:0);
        shift1bit(cnt==row); // mistake #1
      }
      for (int8_t col = 9; col >= 0; --col) {
        //Serial.print(leds[row*10+col].getBit(bitmask_b));
        shift1bit(leds[row*10+col].getBit(bitmask_b));
      }
      for (int8_t col = 9; col >= 0; --col) {
        //Serial.print(leds[row*10+col].getBit(bitmask_g));
        shift1bit(leds[row*10+col].getBit(bitmask_g));
      }
      for (int8_t col = 9; col >= 0; --col) {
        //Serial.print(leds[row*10+col].getBit(bitmask_r));
        shift1bit(leds[row*10+col].getBit(bitmask_r));
      }
      PORTD |=  _BV(PD2); // LatchPin
      PORTD &= ~_BV(PD2); // disable LatchPin

      //Serial.println(micros()-us);
      delayMicroseconds(50);
    }
  }
}

inline void shift1bit (bool b) {
  // set data:
  if (b) {
    PORTD |= _BV(PD3);
  } else {
    PORTD &= ~_BV(PD3);
  }
  // clock pulse:
  PORTD |=  _BV(PD4);
  PORTD &= ~_BV(PD4);
}

And you can consider:

  • Using HW SPI
  • Using /MR input to clear all registers by one pulse (much faster than shiftOut)
  • Using Johnson counter (4017) for row drivers and save one shift register (also buffer fits into the one uint32_t). With previous you can use Q7S ouput and MSB set to logic 1 to update counter.
KIIV
  • 3,534
  • 2
  • 18
  • 23
  • Are you sure the color is 12-bit not 24-bit? – putu Sep 23 '16 at 17:05
  • @IPutuSusila According to _LED.setR(`constrain(_R / 16, 0, 15)`); yes, I'm pretty sure – KIIV Sep 23 '16 at 17:07
  • I see, didn't notice it ;( – putu Sep 23 '16 at 17:10
  • Thank you for reading my post and giving me a nice Answer ^^ I'll try it as soon as possible. – Tom Stein Sep 23 '16 at 17:48
  • @KIIV The problem with the setup code is that I want to use the FastLED Libary output code so I can use the Software like this one in the video: [link](https://www.youtube.com/watch?v=o6_UYb6I4x4) This software will allways give me: leds[XX] = CRGB(XX, XX, XX); So I made the code above which is a bit slow. But I dont know how I could do it otherwise. One way could be to make a Tool which translates the Code the software gives me to the code you made. But Thanks for your help – Tom Stein Sep 23 '16 at 17:59
  • After modifying the code as suggested by @KIIV, I guess by simply **Replace All** the " = CRGB" with ".setRGB" will do the trick (IDE menu `Edit -> Find`) – putu Sep 23 '16 at 18:42
  • Well, I've added concept for setBitMap but it is not exact code apparently as I don't understand how it should be even working. It might be even better to shift it out dirrectly as desired. – KIIV Sep 23 '16 at 19:34
  • @KIIV if you need it I can draw a scematic. In text: The 5 registers a in a daisy chain. The 1. register controls the first 8 columns of red LEDs. The 2. register controls the last 2 columns of red LEDs + the first 6 columns of green LEDs. The 3. register contorls the last 4 columnsof green leds + the first 4 columns f blue LEDs. The 4. register controls the last 6 blue Leds columns + 2 Row pins (GND Pins). The 5. register controls the last 8 Row pins (GND Pins). The code in setBitMaps isn't finished yet. It also needs to handle the 3&4 register. The 5. + (4) is controlled by myloop. – Tom Stein Sep 23 '16 at 23:15
  • @IPutuSusila I've build a simple program for that in VB.net ^^ [pastebin](http://pastebin.com/FWTSyvbS) – Tom Stein Sep 23 '16 at 23:16
  • @KIIV I've edited the code a bit and added the setBitMaps (I think it's right how I did it). Here the link to pastebin: [pastebin](http://pastebin.com/8c166c55) Ps: would you be able to explain me what you mean by this: // we can change BitMaps directly: byte & result_r1 = BitMapR1[intLayerSel]; because I when I Serial.println(BitMapR1[intLayerSel]) after the for loops it's everytime 0. Same with the "result_r1". – Tom Stein Sep 23 '16 at 23:28
  • I've huge mistake in setRGB method. Fixed. – KIIV Sep 24 '16 at 04:22
  • @TomStein code updated, shifted directly from leds ~90us. And you might be shifting LSB first, not MSB in the original code. Best would be to prepare all buffers directly in LED class by setRGB (needs refactoring and container class) – KIIV Sep 24 '16 at 06:04
  • @KIIV ok first of all Thank you :) Your code works in theory very good(Serial Monitor). But I think there is something wrong with the shiftout. There is nothing happening on the Matrix. I can slove this :/ If you also cant, I will drive tomorrow to my friend. He has a 1GHz Scope. – Tom Stein Sep 24 '16 at 12:37
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/124125/discussion-between-tom-stein-and-kiiv). – Tom Stein Sep 24 '16 at 22:19
  • @KIIV ok somehow I cant look into the discussion anymore. Would you be so kind and send me the code again? – Tom Stein Oct 09 '16 at 23:16
  • @TomStein [PasteBin](http://pastebin.com/XBNh5933) but I'm not sure if I have everything correct, I've tested it on 8x8 RGB display with inverted logic. So I resized it back to 10x10 and switched to positive logic. And I have different pin. You don't have all control pins on the same port, so it would be little bit harder (or you can use pins 3,2,4,6 on micro). – KIIV Oct 10 '16 at 05:49
  • @KIIV ok in your code you used 5 pins right? If I don't think completly wrong I need 4(5) (Data, Latch, Clock, OE, (Clear)). [pic](https://s-media-cache-ak0.pinimg.com/originals/96/34/69/96346944b39d00c36b6300c605c8fecd.jpg) looking to this I would use DPin2-DPin6 for this. So I would change only the lines from 4-11. – Tom Stein Oct 10 '16 at 13:29
  • @TomStein DRV_EN is just for the transistors. In your case you can remove this signal as it isn't on single shift register anyways. – KIIV Oct 10 '16 at 13:33
  • @KIIV I've following: Latch is DPin 2 (PortD2), Data is DPin 3(PortD3), Clock is DPin 4(PortD4), OE is DPin 5 (PortD5), MR (clear) is DPin6 (PortD6). Output is enabled if DPin5 is HIGH. Clear is enabled if DPin6 is LOW. I put OE & MR each on a transistor. The Collector from BJT for OE is connectet to Ground. The Collector from BJT for MR is connectet to VCC. – Tom Stein Oct 10 '16 at 13:39
  • @KIIV look here: https://circuits.io/circuits/2924748 I build a Simulator for my Matrix. There you can test your code. Careful it's a arduino Uno – Tom Stein Oct 14 '16 at 00:53
  • @KIIV I finallay got it working. It's still not perfect (Bitmaps...) but it works with nearly no flicker. I want to say one more time thank you for your help :) If you want to look at my code: [pastebin](http://pastebin.com/7C8iMJ7G) – Tom Stein Nov 09 '16 at 22:07