Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 21 of 21

Thread: cheap 32x32 RGB panel with 24bit color and 30fps live streaming

  1. #1
    Junior Member
    Join Date
    Feb 2014
    Posts
    7

    cheap 32x32 RGB panel with 24bit color and 30fps live streaming

    Teensy is just so awesome!
    Click image for larger version. 

Name:	teensy.jpg 
Views:	1827 
Size:	157.9 KB 
ID:	1503

    In contrast to the intelligent LED-strips, the cheap 32x32 RGB panels natively only support 1bit per color. If you want more, you have to switch the LEDs rapidly. The Adafruit Matrix library for Arduino only supported this for up to 4bits per color, in total 4096 colors.

    Using the incredibly powerfull Teensy I was able to increase this to 8bit per color, 24bit in total, thats 16.7 million colors, with 30fps! I believe this is a first. To achieve this, I prepare the interleaved, gamma-corrected buffer on the PC in a Java app and stream it live. This is possible due to the fast USB of the Teensy. You can stream any part of your screen. I don't use DMA yet, this could reduce CPU even more.

    Especially on dark scenes there are still some artifacts on the bottom side, must either be a bug or timing issue.

    Videos: NEW http://youtu.be/SDrxM1TDR18 http://youtu.be/x0Wcpol7cO4, http://youtu.be/dmCp1OEAtMU

    Here's the Teensy 3.1 sketch:
    Code:
        /* Modified by Markus Lipp adding interleaved buffers, streaming, 32x32 & 24bit support
        * Based on "_16x32_Matrix R3.0" by Creater Alex Medeiros, http://PenguinTech.tk
        * Use code freely and distort its contents as much as you want, just remeber to thank the
        * original creaters of the code by leaving their information in the header. :)
        */
    
        //modified by markus lipp for 32x32 panel
    
    
        //PortC[0:11] = {15, 22, 23, 9, 10, 13, 11, 12, 28, 27, 29, 30}
        //PortD[0:7] = {2, 14, 7, 8, 6, 20, 21, 5}
        //Define pins
        const uint8_t
        //PortC
        APIN      = 15, BPIN      = 22, CPIN      = 23, DPIN = 9,
        CLOCKPIN  = 10, LATCHPIN  = 13, OEPIN     = 11,
        //PortD
        R1PIN     = 2, R2PIN     = 8,
        G1PIN     = 14, G2PIN     = 6,
        B1PIN     = 7, B2PIN     = 20;
    
        uint8_t pinTable[13] = {
          R1PIN,R2PIN,G1PIN,G2PIN,B1PIN,B2PIN,
          APIN,BPIN,CPIN,DPIN,CLOCKPIN,LATCHPIN,OEPIN};
    
        //Addresses 1/8 rows Through a decoder
        uint16_t const A = 1, B = 2,C = 4, D=8;
        //Acts like a 16 bit shift register
        uint16_t const SCLK   = 16;
        uint16_t const LATCH  = 32;
        uint16_t const OE     = 64;
    
        uint16_t const abcVar[16] = { //Decoder counter var
          0,A,B,A+B,C,C+A,C+B,A+B+C,
          0+D,A+D,B+D,A+B+D,C+D,C+A+D,C+B+D,A+B+C+D};
    
        //Data Lines for row 1 red and row 9 red, ect.
        uint16_t const RED1   = 1, RED2   = 8;
        uint16_t const GREEN1 = 2, GREEN2 = 16;
        uint16_t const BLUE1  = 4, BLUE2  = 32;
    
        const uint8_t SIZEX = 32;
        const uint8_t SIZEY = 32;
    
        //Here is where the data is all read
        uint8_t interleavedBuffer[SIZEX*SIZEY*4];
    
        //BAM and interrupt variables
        boolean actDisplay = false;
        uint8_t rowN = 0;
        uint16_t BAM;
        uint8_t BAMMAX = 7; //now 24bit color! (0-7)
    
        void setup() {
          for(uint8_t i = 0; i < 13; i++){
                pinMode(pinTable[i], OUTPUT);
            }
          timerInit();
          Serial.begin(250000);
        }
    
        uint8_t r,g, prevVal,val;
        int dataPos=0;
    
        void loop() {       
           if (Serial.available())
           {     
              prevVal = val;
              val = Serial.read();     
           
              if ( (prevVal==0x21 && val==0x8) || dataPos>=4096)
              {
                 dataPos=0;
              }
              else
              {
                interleavedBuffer[dataPos++] = val;
              }
           } 
        }
    
        IntervalTimer timer1;
        #define BAMDUR 2
        void timerInit() {
            timer1.begin(timerCallBack,BAMDUR);
            BAM = 0;
        }
    
    
        //Where the PIT calls
        void timerCallBack() {
            attackMatrix(); // Updated the display
            if(BAM > BAMMAX) { //Checks the BAM cycle for next time.
                BAM = 0;
                timer1.begin(timerCallBack,BAMDUR);
                actDisplay = false;
            } else {
                BAM ++;
                actDisplay = true;
            }
        }
    
        //The updating matrix stuff happens here
        //each pair of rows is taken through its BAM cycle
        //then the rowNumber is increased and id done again
        void attackMatrix() {
            uint16_t portData;
    
            //sets up which BAM the matrix is on
            if(BAM == 0) { timer1.begin(timerCallBack,BAMDUR); }
            if(BAM == 1) { timer1.begin(timerCallBack,BAMDUR*2); }
            if(BAM == 2) { timer1.begin(timerCallBack,BAMDUR*4); }
            if(BAM == 3) { timer1.begin(timerCallBack,BAMDUR*8); }
            if(BAM == 4) { timer1.begin(timerCallBack,BAMDUR*16); }
            if(BAM == 5) { timer1.begin(timerCallBack,BAMDUR*32); }
            if(BAM == 6) { timer1.begin(timerCallBack,BAMDUR*64); }
            if(BAM == 7) { timer1.begin(timerCallBack,BAMDUR*128); }
    
            portData = 0; // Clear data to enter
            portData |= (abcVar[rowN])|OE; // abc, OE
            portData &=~ LATCH;        //LATCH LOW
            GPIOC_PDOR = portData;  // Write to Port
           
            uint8_t *start = &interleavedBuffer[rowN*SIZEX*8+((7-BAMMAX)+BAM)*32];
           
            for(uint8_t _x = 0; _x < 32; _x++){
    
                  GPIOD_PDOR = start[_x]; // Transfer data
                  GPIOC_PDOR |=  SCLK;// Clock HIGH
                  GPIOC_PDOR &=~ SCLK;// Clock LOW
            }
    
            GPIOC_PDOR |= LATCH;// Latch HIGH
            GPIOC_PDOR &=~ OE;// OE LOW, Displays line   
    
            if(BAM == BAMMAX){
               if(rowN == 15){
                    rowN = 0;
                } else {
                    rowN ++;
                }
            }
        }
    And here is the Java live streaming app for your PC. Just start the jar in the bin directory. Move&Scale the small window to define what to stream. Select Interleaved RGB8 for Teensy as output mode. Click "enable output" to start streaming.
    https://dl.dropboxusercontent.com/u/...reenStream.rar

    Click image for larger version. 

Name:	streamingApp.png 
Views:	503 
Size:	368.7 KB 
ID:	1500

    Here's a link to the Arduino version I posted earlier. It's just 4bit and 12fps. http://forums.adafruit.com/viewtopic.php?f=47&t=50115
    Last edited by MarkusL; 02-23-2014 at 10:32 PM.

  2. #2
    Junior Member
    Join Date
    Feb 2014
    Posts
    7
    Found the bug causing some artifacts at the bottom. It was an index out of range because of a wrong timer.

    Edit: After hours of searching and writing unit tests i fixed another rare bug, caused by a collision of the framesync with specific colors. Java-app and sketch is updated.

    Edit2: Removed another nasty bug. Didn't realize IntervallTimer is periodic, ouch. Also tweaked timing for smoother gradients.

    Ps: if you want to try it, it's quite easy: Attach your 32x32 panel inputs (e.g. https://www.sparkfun.com/products/12584) to the pins shown in the beginning of the code. Add 5V power to the panel (NOT to the Teensy, only connect the grounds). Attach the Teensy to USB, start the Java app and stream your screen.

    Updated code:

    Code:
    /*
    * Modified by Markus Lipp adding interleaved buffers, streaming, 32x32 & 24bit support
    * Based on "_16x32_Matrix R3.0" by Creater Alex Medeiros, http://PenguinTech.tk
    * Use code freely and distort its contents as much as you want, just remeber to thank the 
    * original creaters of the code by leaving their information in the header. :)
    */
    
    //PortC[0:11] = {15, 22, 23, 9, 10, 13, 11, 12, 28, 27, 29, 30}
    //PortD[0:7] = {2, 14, 7, 8, 6, 20, 21, 5}
    //Define pins
    const uint8_t
    //PortC
    APIN      = 15, BPIN      = 22, CPIN      = 23, DPIN = 9,
    CLOCKPIN  = 10, LATCHPIN  = 13, OEPIN     = 11,
    //PortD
    R1PIN     = 2, R2PIN     = 8,
    G1PIN     = 14, G2PIN     = 6,
    B1PIN     = 7, B2PIN     = 20;
    
    uint8_t pinTable[13] = {
      R1PIN,R2PIN,G1PIN,G2PIN,B1PIN,B2PIN,
      APIN,BPIN,CPIN,DPIN,CLOCKPIN,LATCHPIN,OEPIN};
    
    //Addresses 1/8 rows Through a decoder
    uint16_t const A = 1, B = 2,C = 4, D=8;
    //Acts like a 16 bit shift register
    uint16_t const SCLK   = 16;
    uint16_t const LATCH  = 32;
    uint16_t const OE     = 64;
    
    uint16_t const abcVar[16] = { //Decoder counter var
      0,A,B,A+B,C,C+A,C+B,A+B+C,
      0+D,A+D,B+D,A+B+D,C+D,C+A+D,C+B+D,A+B+C+D};
    
    //Data Lines for row 1 red and row 9 red, ect.
    uint16_t const RED1   = 1, RED2   = 8;
    uint16_t const GREEN1 = 2, GREEN2 = 16;
    uint16_t const BLUE1  = 4, BLUE2  = 32;
    
    const uint8_t SIZEX = 32;
    const uint8_t SIZEY = 32;
    
    //Here is where the data is all read
    uint8_t interleavedBuffer[SIZEX*SIZEY*4];
    
    //BAM and interrupt variables
    uint8_t rowN = 0;
    uint16_t BAM;
    uint8_t BAMMAX = 7; //now 24bit color! (0-7)
    
    
    void setup() {
      for(uint8_t i = 0; i < 13; i++){
            pinMode(pinTable[i], OUTPUT);
        }
      timerInit();
      Serial.begin(250000); 
    }
    
    uint8_t r,g, prevVal,val;
    int dataPos=0;
    
    void loop() {       
       if (Serial.available())
       {     
          prevVal = val;
          val = Serial.read();     
       
          if ( (prevVal==192 && val==192) || dataPos>=4096)
          {
            dataPos=0;
          }
          else
          {
            interleavedBuffer[dataPos++] = val;
          }
       }  
    }
    
    IntervalTimer timer1;
    
    void timerInit() {
        BAM = 0;
        attackMatrix();
    }
    
    
    //The updating matrix stuff happens here
    //each pair of rows is taken through its BAM cycle
    //then the rowNumber is increased and id done again
    void attackMatrix() {
        timer1.end();    
        
        uint16_t portData;
        portData = 0; // Clear data to enter
        portData |= (abcVar[rowN])|OE; // abc, OE
        portData &=~ LATCH;        //LATCH LOW
        GPIOC_PDOR = portData;  // Write to Port
        
        uint8_t *start = &interleavedBuffer[rowN*SIZEX*8+((7-BAMMAX)+BAM)*32];    
        for(uint8_t _x = 0; _x < 32; _x++){
              GPIOD_PDOR = start[_x]; // Transfer data
              GPIOC_PDOR |=  SCLK;// Clock HIGH
              GPIOC_PDOR &=~ SCLK;// Clock LOW
        }
    
        GPIOC_PDOR |= LATCH;// Latch HIGH
        GPIOC_PDOR &=~ OE;// OE LOW, Displays line
    
        #define LOOPTIME 2 //trial&error to get both smooth gradients & little flicker
        #define CALLOVERHEAD 2
        timer1.begin(attackMatrix,((LOOPTIME+CALLOVERHEAD)<<BAM)-CALLOVERHEAD);
      
        if(BAM >= BAMMAX) { //Checks the BAM cycle for next time.    
            if(rowN == 15){
                rowN = 0;
            } else {
                rowN ++;
            }        
            BAM = 0;
          } else {
            BAM ++;
        }
    }
    Last edited by MarkusL; 02-23-2014 at 09:57 PM.

  3. #3
    Thanks Markus for sharing your efforts,

    I am trying to understand and adapt your code to my needs but no success so far. I cannot run your Java code on my Mac, some problem with jssc, but from its code I feel that you feed a Matrix of argb values to the Teensy. How about for starter to just display a matrix of 1024 colors (simplest case I can think)? What would be the code in this case? Or to draw a pixel for example.

    I cannot understand where you make in your code the switch for the rows 16 to 32.
    Finally you say your sketch is for Teensy 3.1, does it work also for Teensy 3.0?

    My naive attempt was posted here, it worked but flickered a lot.

  4. #4
    Junior Member
    Join Date
    Feb 2014
    Posts
    7
    I cannot run your Java code on my Mac
    What exactly happes, does it crash or fail to open the COM port? I haven't tested on Mac, maybe I can test tomorrow on a Macbook Air.

    but from its code I feel that you feed a Matrix of argb values to the Teensy.
    I feed RGB888 values. The argb value is just an intermediate value returned by a Java function.

    How about for starter to just display a matrix of 1024 colors (simplest case I can think)? Or to draw a pixel for example.
    Right now you always have to stream all pixels from Java. There you can for example change individual pixels in the update() function. You can't change pixels directly on Teensy (yet). This would require implementing drawPixel888() on the Teensy.


    I cannot understand where you make in your code the switch for the rows 16 to 32.
    There are always two rows pushed to the panel simultaneously, and they are 16 rows apart. So the pairs are [1,16], [2,17] ... [15,32] . This interleaving of lines happens in drawPixel888().

    Finally you say your sketch is for Teensy 3.1, does it work also for Teensy 3.0?
    It should also work, although I can't test that.

  5. #5
    Junior Member
    Join Date
    Feb 2014
    Posts
    7
    OK, i quickly created a debug sketch. It displays a gradient with lots of colors, and does not require any PC connection. It should just work when powering up the Teensy.

    Code:
    /*
    * Modified by Markus Lipp adding interleaved buffers, streaming, 32x32 & 24bit support
    * Based on "_16x32_Matrix R3.0" by Creater Alex Medeiros, http://PenguinTech.tk
    * Use code freely and distort its contents as much as you want, just remeber to thank the 
    * original creaters of the code by leaving their information in the header. :)
    */
    
    
    //PortC[0:11] = {15, 22, 23, 9, 10, 13, 11, 12, 28, 27, 29, 30}
    //PortD[0:7] = {2, 14, 7, 8, 6, 20, 21, 5}
    //Define pins
    const uint8_t
    //PortC
    APIN      = 15, BPIN      = 22, CPIN      = 23, DPIN = 9,
    CLOCKPIN  = 10, LATCHPIN  = 13, OEPIN     = 11,
    //PortD
    R1PIN     = 2, R2PIN     = 8,
    G1PIN     = 14, G2PIN     = 6,
    B1PIN     = 7, B2PIN     = 20;
    
    uint8_t pinTable[13] = {
      R1PIN,R2PIN,G1PIN,G2PIN,B1PIN,B2PIN,
      APIN,BPIN,CPIN,DPIN,CLOCKPIN,LATCHPIN,OEPIN};
    
    //Addresses 1/8 rows Through a decoder
    uint16_t const A = 1, B = 2,C = 4, D=8;
    //Acts like a 16 bit shift register
    uint16_t const SCLK   = 16;
    uint16_t const LATCH  = 32;
    uint16_t const OE     = 64;
    
    uint16_t const abcVar[16] = { //Decoder counter var
      0,A,B,A+B,C,C+A,C+B,A+B+C,
      0+D,A+D,B+D,A+B+D,C+D,C+A+D,C+B+D,A+B+C+D};
    
    //Data Lines for row 1 red and row 9 red, ect.
    uint16_t const RED1   = 1, RED2   = 8;
    uint16_t const GREEN1 = 2, GREEN2 = 16;
    uint16_t const BLUE1  = 4, BLUE2  = 32;
    
    const uint8_t SIZEX = 32;
    const uint8_t SIZEY = 32;
    
    
    
    //BAM and interrupt variables
    uint8_t rowN = 0;
    uint16_t BAM;
    uint8_t BAMMAX = 7; //now 24bit color! (0-7)
    
    
    void setup() {
      for(uint8_t i = 0; i < 13; i++){
            pinMode(pinTable[i], OUTPUT);
        }
      timerInit();
      Serial.begin(250000); 
    }
    
    uint8_t r,g, prevVal,val;
    int dataPos=0;
    
    byte interleavedBuffer[] = {
    0,0,48,63,63,63,63,56,56,56,48,63,63,59,57,61,53,57,29,24,8,63,47,31,63,8,47,47,15,15,63,63,0,0,16,16,16,31,24,24,23,31,31,31,31,23,29,52,52,45,44,31,8,31,8,8,8,40,15,40,63,24,63,7,0,0,48,48,56,48,55,56,56,63,48,55,48,53,63,53,21,43,27,31,40,56,15,24,31,40,63,63,24,8,0,0,0,0,16,16,16,24,16,31,31,31,16,24,23,17,27,61,61,45,29,63,47,8,15,31,24,8,47,31,15,15,7,7,0,0,16,16,16,16,24,24,16,24,31,23,23,19,29,60,61,45,24,24,15,40,24,63,8,47,31,8,15,8,7,56,0,0,48,48,48,48,48,48,56,56,48,56,48,56,61,21,29,60,62,8,40,31,15,63,56,24,8,15,15,8,56,63,0,0,48,48,48,48,48,48,48,
    48,56,56,48,52,52,60,60,29,13,15,47,63,63,15,8,8,8,8,8,15,63,63,0,0,48,48,48,48,48,48,48,48,48,48,56,56,60,60,60,60,56,56,24,8,8,8,15,15,15,15,15,15,63,63,0,0,48,63,56,63,55,56,48,48,56,61,61,53,52,30,62,46,60,45,61,30,63,63,63,40,31,15,15,31,63,63,0,0,48,48,55,31,24,24,23,55,61,53,52,21,28,29,53,45,12,44,28,30,24,24,56,8,31,56,63,15,56,7,0,0,16,16,24,48,55,56,56,63,56,61,61,29,21,21,61,60,44,61,45,31,63,40,63,40,47,47,8,24,7,0,0,0,16,16,16,24,16,31,31,31,28,20,29,60,52,60,52,45,12,44,13,8,63,63,40,24,63,15,31,15,7,7,0,0,16,16,16,16,24,24,16,24,23,20,28,29,28,61,52,
    29,61,60,29,58,56,15,56,47,31,24,15,8,7,56,0,0,16,16,16,16,16,16,24,24,20,28,28,20,29,61,60,60,13,60,44,25,47,47,24,24,8,15,15,8,56,63,0,0,48,48,48,48,48,48,48,48,56,60,60,52,52,20,29,29,29,44,44,60,31,31,8,8,8,8,8,15,63,63,0,0,48,48,48,48,48,48,48,48,48,52,52,60,60,60,60,60,60,29,29,13,8,8,15,15,15,15,15,15,63,63,0,0,48,31,16,23,31,16,23,20,28,23,21,31,63,55,62,23,62,60,15,45,13,43,15,24,31,47,47,31,63,63,0,0,16,16,23,31,16,16,19,20,21,52,62,54,54,23,62,31,31,47,28,28,12,31,8,63,56,15,24,15,56,7,0,0,16,48,24,16,23,24,20,20,20,60,52,29,61,53,60,28,44,60,61,12,12,9,63,
    8,8,47,31,8,7,0,0,0,16,16,48,56,48,63,63,60,60,29,20,21,29,53,52,52,13,44,45,61,45,63,40,8,40,31,31,31,7,7,0,0,16,16,16,16,24,24,16,28,20,28,29,21,52,61,61,60,13,13,44,12,60,31,40,63,8,24,15,8,7,56,0,0,48,48,48,48,48,48,56,60,52,52,60,52,21,29,20,29,29,44,29,12,61,45,8,24,31,15,15,8,56,63,0,0,16,16,16,16,16,16,16,20,28,28,28,20,20,20,29,29,29,60,44,45,29,24,24,8,8,8,8,15,63,63,0,0,48,48,48,48,48,48,48,52,52,52,52,60,60,60,60,60,60,29,29,29,13,13,15,15,15,15,15,15,63,63,0,0,16,55,56,55,63,59,52,63,20,53,63,62,28,55,30,30,45,29,13,47,28,13,61,8,31,31,63,15,63,63,0,
    0,16,16,31,23,24,19,22,52,54,21,52,30,60,61,21,20,61,15,12,15,62,9,9,31,8,15,24,15,56,7,0,0,48,48,48,48,63,50,60,20,61,62,31,55,29,21,28,28,29,47,31,13,28,45,13,24,24,47,31,8,7,0,0,0,0,48,48,56,56,56,52,52,52,53,52,60,62,22,55,22,14,29,13,28,29,25,41,24,56,15,15,15,7,7,0,0,0,16,16,16,16,28,20,28,20,28,21,52,61,20,21,21,60,29,61,29,61,9,57,63,8,8,31,24,7,56,0,0,0,16,16,16,16,16,28,28,20,20,28,61,61,28,20,29,60,44,29,12,61,61,9,24,31,31,15,8,56,63,0,0,0,16,16,16,16,20,20,20,28,28,28,60,60,21,29,29,60,60,44,45,29,29,29,8,8,8,8,15,63,63,0,0,0,48,48,48,48,48,52,
    52,52,52,52,20,20,60,60,60,29,29,29,29,13,13,13,15,15,15,15,15,63,63,0,0,0,55,48,63,63,62,29,53,29,52,21,20,60,31,22,62,53,29,31,31,63,45,57,61,31,31,31,15,63,7,0,0,0,16,31,31,19,52,52,55,28,29,31,29,22,22,22,31,31,28,45,47,11,59,9,25,56,47,24,31,0,7,0,0,0,48,48,56,59,28,28,30,31,61,60,22,63,62,23,30,30,63,44,46,25,61,57,45,56,15,15,8,63,56,0,0,0,16,16,16,28,22,30,28,20,55,31,31,23,54,30,55,22,15,31,29,57,41,29,61,8,31,31,15,7,7,0,0,0,48,48,48,50,60,60,52,60,20,21,28,29,29,60,29,29,44,12,44,13,61,61,13,24,8,31,24,7,56,0,0,0,48,48,48,52,52,52,60,60,52,52,53,61,52,61,
    53,60,29,12,61,45,25,13,9,31,31,15,8,56,63,0,0,0,48,48,48,48,52,52,52,52,60,60,60,60,53,53,61,60,60,61,13,13,29,25,25,8,8,8,15,63,63,0,0,0,16,16,16,20,20,20,20,20,20,20,20,20,28,28,28,29,29,29,29,29,13,13,13,15,15,15,15,63,63,0,0,0,55,24,62,30,63,63,21,62,63,54,28,22,54,62,30,28,47,63,44,45,47,25,29,29,63,15,63,63,7,0,0,0,16,23,20,20,22,21,23,61,20,61,61,54,52,52,53,63,46,28,13,9,29,15,57,29,31,8,63,0,0,0,0,0,48,16,56,54,52,52,63,30,30,29,31,31,52,20,60,62,61,28,46,25,11,13,29,41,15,31,0,63,63,0,0,0,48,16,49,60,52,60,54,63,22,61,61,28,31,62,23,52,29,45,63,27,41,25,
    45,9,15,15,7,7,7,0,0,0,48,16,49,54,62,62,52,52,61,31,22,54,55,55,54,22,31,63,29,25,41,41,25,13,24,15,56,7,56,0,0,0,16,48,20,20,20,20,28,28,28,28,21,28,20,29,20,29,29,44,61,45,9,29,9,13,31,31,0,56,63,0,0,0,48,48,54,52,52,52,52,52,52,52,60,61,53,53,60,60,60,29,13,13,13,25,25,29,8,8,63,63,63,0,0,0,16,16,20,20,20,20,20,20,20,20,20,20,28,28,29,29,29,29,29,29,29,13,13,9,15,15,63,63,63,0,0,0,63,16,30,63,28,29,55,62,28,29,31,55,31,22,23,28,55,29,63,63,11,57,59,57,63,15,63,63,7,0,0,0,16,55,62,30,22,61,53,22,21,62,53,20,54,31,30,52,53,60,25,45,57,61,61,41,10,24,56,7,0,0,
    0,0,32,16,22,30,31,55,28,54,23,53,31,21,61,20,61,60,62,60,41,27,9,27,41,25,29,31,7,63,63,0,0,0,48,48,54,54,62,22,31,52,60,22,54,21,28,61,20,52,23,47,25,59,15,45,9,29,29,31,7,7,7,0,0,0,32,16,22,22,22,30,30,55,55,62,55,20,28,29,29,61,62,14,15,45,61,29,9,9,29,15,56,7,56,0,0,0,48,16,20,20,20,20,20,60,60,61,53,30,31,23,30,55,60,61,45,25,13,25,25,13,30,31,0,56,63,0,0,0,0,48,52,52,52,52,52,20,20,20,28,61,61,53,52,28,29,29,29,13,9,25,25,29,13,8,63,63,63,0,0,0,16,16,20,20,20,20,20,20,20,20,20,20,20,28,29,29,29,29,29,29,29,13,13,9,9,15,63,63,63,0,0,0,63,22,29,55,61,30,
    55,60,61,61,60,29,54,55,22,63,29,47,29,13,59,25,31,45,29,63,63,63,7,0,0,0,0,20,20,55,55,60,60,63,61,52,23,62,21,61,21,60,61,47,15,9,13,31,15,29,9,7,56,7,0,0,0,0,0,20,20,62,55,63,52,31,63,54,61,31,52,61,52,63,20,15,45,43,63,11,57,25,25,63,7,63,63,0,0,0,0,52,52,22,30,31,54,52,29,29,63,22,20,28,28,55,55,31,63,25,59,45,25,13,13,7,7,7,7,0,0,0,0,54,54,52,52,52,29,29,29,20,29,61,63,54,54,21,21,31,63,59,25,9,13,29,9,7,56,7,56,0,0,0,0,54,54,54,54,54,54,54,54,63,63,54,63,54,63,55,62,61,9,25,13,9,29,9,9,7,0,56,63,0,0,0,0,20,20,20,20,20,20,20,20,20,20,29,29,20,
    20,28,29,29,29,13,9,9,29,29,29,56,63,63,63,0,0,0,0,20,20,20,20,20,20,20,20,20,20,20,20,29,29,29,29,29,29,29,29,29,9,9,9,63,63,63,63,0,0,0,63,4,54,21,30,53,61,22,52,20,54,30,28,29,30,23,61,55,61,27,41,47,11,29,13,62,63,63,7,0,0,0,0,62,55,62,53,20,30,54,60,23,63,28,63,30,63,63,55,23,57,47,9,25,57,27,9,4,56,7,56,0,0,0,0,36,54,55,62,22,52,22,62,63,63,62,60,29,62,20,54,29,11,61,9,45,11,9,25,61,7,63,63,0,0,0,0,4,22,22,23,30,63,52,21,55,52,30,21,60,22,23,53,55,25,59,45,15,29,9,9,1,7,7,7,0,0,0,0,60,22,22,22,23,55,62,62,52,62,22,21,29,31,30,62,57,45,15,31,29,
    25,13,25,5,56,7,56,0,0,0,0,36,54,54,54,54,22,23,23,31,30,55,61,60,55,62,23,31,27,13,25,13,29,25,9,5,0,56,63,0,0,0,0,6,20,20,20,20,20,20,20,20,21,29,31,30,20,21,29,29,29,25,9,13,29,29,29,57,63,63,63,0,0,0,0,20,20,20,20,20,20,20,20,20,20,20,20,21,29,29,29,29,29,29,29,25,9,9,9,57,63,63,63,0,0,0,60,61,52,61,20,62,31,54,52,53,29,52,52,60,31,53,62,63,47,31,57,13,15,13,7,61,63,63,7,0,0,0,6,62,22,23,63,61,28,63,60,55,62,22,60,29,53,55,21,21,9,27,27,63,13,29,61,5,0,63,56,0,0,0,4,6,23,21,53,21,28,54,53,23,63,30,22,54,28,53,54,17,59,11,59,15,9,15,61,61,63,63,63,0,
    0,0,6,4,52,52,21,20,20,63,54,21,29,55,61,52,60,31,21,19,59,59,29,15,31,9,1,1,7,7,7,0,0,0,6,6,54,54,54,55,54,20,29,53,52,52,62,62,54,53,53,51,25,27,27,9,13,25,61,1,56,7,56,0,0,0,4,4,20,20,20,20,21,21,21,29,28,21,20,29,20,28,21,31,27,13,25,29,9,25,61,5,0,56,63,0,0,0,6,6,22,22,22,22,22,22,22,22,23,31,30,30,23,23,31,29,29,25,9,13,13,29,1,57,63,63,63,0,0,0,4,4,20,20,20,20,20,20,20,20,20,20,21,21,29,29,29,29,29,29,29,25,25,9,57,57,63,63,63,0,0,0,62,62,60,52,53,61,30,22,55,63,52,30,55,22,63,53,53,31,25,63,25,27,9,41,5,61,59,63,7,0,0,0,4,61,5,20,52,21,
    28,60,30,52,22,31,28,53,23,52,27,57,27,29,57,27,9,51,3,61,4,63,63,0,0,0,6,6,63,55,23,20,22,63,28,23,52,21,21,20,31,61,57,23,25,43,31,29,11,55,5,61,58,63,63,0,0,0,6,6,6,55,54,55,53,20,60,63,63,28,22,30,29,61,49,53,57,25,31,25,27,45,61,5,6,7,7,0,0,0,4,4,4,20,21,21,20,21,20,30,23,61,61,53,60,28,31,25,23,13,15,11,29,37,57,5,61,7,56,0,0,0,6,6,6,22,22,22,23,23,22,20,28,31,22,31,30,23,29,17,31,27,13,29,9,29,61,1,3,56,63,0,0,0,6,6,6,22,22,22,22,22,23,23,23,23,30,30,31,23,23,31,25,25,29,13,13,1,1,57,61,63,63,0,0,0,4,4,4,20,20,20,20,20,20,20,20,20,21,21,
    21,29,29,29,29,29,25,25,25,57,57,57,57,63,63,0,0,1,60,61,60,62,23,54,29,20,21,29,54,62,60,21,63,29,55,63,63,45,29,31,59,63,3,61,57,63,7,0,0,4,6,63,6,63,23,55,55,52,21,52,60,31,29,52,29,29,49,31,51,11,27,15,43,3,3,61,5,56,63,0,0,6,4,4,60,61,53,20,21,29,61,63,55,22,29,28,23,21,59,57,25,31,29,31,55,3,5,61,61,56,63,0,0,0,4,4,5,5,20,20,21,21,29,23,21,52,52,60,55,61,17,31,27,27,29,25,27,57,57,1,5,0,7,0,0,0,4,4,4,4,21,20,20,21,20,31,22,30,20,28,31,23,17,29,27,25,25,31,17,5,57,5,57,0,56,0,0,0,4,4,4,4,20,21,21,21,20,22,31,30,21,20,30,23,31,29,23,27,15,25,
    41,61,61,1,1,63,63,0,0,0,4,4,4,4,20,20,20,20,21,23,23,22,28,29,31,23,23,19,25,25,29,13,37,1,1,57,57,63,63,0,0,0,6,6,6,6,22,22,22,22,22,20,20,21,23,23,21,29,29,29,29,29,25,25,25,57,57,57,57,63,63,0,0,2,60,61,61,60,4,20,21,22,53,31,62,31,23,53,31,31,55,55,57,29,25,3,7,59,1,63,57,63,7,0,0,4,6,63,6,60,63,23,21,28,21,55,53,23,31,21,31,29,55,21,19,31,25,63,57,1,1,57,5,56,63,0,0,5,4,4,60,60,4,21,23,22,21,22,30,60,63,60,61,63,21,31,19,31,9,57,1,1,7,57,57,56,63,0,0,3,6,6,7,6,63,22,22,23,30,21,29,31,29,22,21,29,31,21,17,25,27,63,61,63,61,1,5,0,7,0,
    0,4,6,6,6,7,7,22,23,22,23,30,31,20,30,31,22,25,25,27,29,23,9,3,63,1,61,5,57,0,56,0,0,6,4,4,4,4,4,21,21,20,20,21,21,28,29,20,29,29,19,29,17,31,31,1,5,61,57,1,1,63,63,0,0,4,4,4,4,4,4,20,20,21,21,21,21,20,20,29,29,29,23,19,27,29,29,5,1,1,1,57,57,63,63,0,0,6,6,6,6,6,6,22,22,22,22,22,22,23,23,23,23,23,29,29,29,25,25,57,57,57,57,57,57,63,63,0,0,6,63,62,61,60,4,61,61,28,28,23,28,60,53,61,51,53,19,19,31,31,7,7,5,63,5,61,57,63,7,0,0,4,6,62,7,63,61,7,7,23,22,22,29,21,31,22,21,25,29,31,31,43,57,59,57,7,3,63,5,56,7,0,0,6,4,5,60,60,5,60,
    4,21,29,29,28,31,31,20,27,17,17,25,31,13,3,63,7,5,7,57,61,56,7,0,0,6,6,6,7,6,63,63,7,23,22,31,22,20,21,30,31,21,31,21,31,43,3,63,61,63,57,5,1,0,63,0,0,6,6,6,6,7,7,6,63,22,22,23,31,22,31,22,29,31,23,21,29,59,5,7,59,5,61,1,57,0,56,0,0,6,6,6,6,6,6,7,7,22,23,23,22,31,31,23,23,25,23,27,29,23,3,5,5,57,57,1,1,63,63,0,0,4,4,4,4,4,4,4,4,21,21,21,20,20,20,29,29,29,19,19,23,29,5,1,1,1,1,57,57,63,63,0,0,6,6,6,6,6,6,6,6,22,22,22,23,23,23,23,23,23,29,29,25,25,57,57,57,57,57,57,57,63,63,0,0,6,63,63,62,63,7,63,62,63,55,30,23,30,31,30,
    23,31,19,3,61,3,7,1,3,57,5,57,57,63,7,0,0,6,6,62,6,63,63,6,7,6,30,30,20,31,20,23,19,27,23,33,57,63,63,57,61,5,3,63,61,0,7,0,0,6,6,7,63,62,7,63,7,62,22,22,29,30,30,23,25,31,29,41,7,63,3,57,3,7,7,61,57,0,7,0,0,4,4,4,5,4,61,61,5,4,61,28,23,29,28,20,23,19,25,23,61,3,3,57,57,59,61,1,1,56,63,0,0,6,6,6,6,7,7,6,63,63,62,22,31,31,23,23,27,19,25,33,3,63,1,5,59,5,57,1,57,0,56,0,0,4,4,4,4,4,4,5,5,4,5,20,20,21,28,21,23,25,29,27,61,59,3,7,5,57,57,1,1,63,63,0,0,6,6,6,6,6,6,6,6,7,7,22,22,22,23,31,29,29,25,59,63,61,5,1,
    1,1,1,57,57,63,63,0,0,6,6,6,6,6,6,6,6,6,6,23,23,23,23,23,23,23,23,5,1,1,57,57,57,57,57,57,57,63,63,0,0,4,61,60,61,60,5,61,60,60,61,61,60,5,5,59,7,61,3,7,59,7,1,5,7,63,7,57,57,63,7,0,0,6,6,62,7,61,61,4,5,5,61,60,5,5,5,59,1,5,59,7,63,59,59,63,7,1,63,7,57,7,0,0,0,4,4,5,60,60,5,61,5,60,4,61,60,4,60,3,57,61,57,3,3,61,5,57,63,7,7,1,57,0,0,0,0,6,6,6,7,6,63,63,7,6,63,62,6,6,7,63,3,63,3,3,61,1,1,57,57,63,57,57,1,56,56,0,0,6,6,6,6,7,7,6,63,63,62,62,6,6,62,61,5,1,61,5,7,57,7,1,63,1,57,1,57,0,63,0,
    0,6,6,6,6,6,6,7,7,6,7,6,63,6,63,63,1,7,1,63,57,57,7,7,1,57,57,1,1,63,63,0,0,6,6,6,6,6,6,6,6,7,7,6,6,7,7,7,63,57,57,63,63,63,1,1,1,1,1,57,57,63,63,0,0,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,1,1,1,57,57,57,57,57,57,57,63,63};
    
    
    void loop() {       
    }
    
    IntervalTimer timer1;
    
    void timerInit() {
        BAM = 0;
        attackMatrix();
    }
    
    
    //The updating matrix stuff happens here
    //each pair of rows is taken through its BAM cycle
    //then the rowNumber is increased and id done again
    void attackMatrix() {
        timer1.end();    
        
        uint16_t portData;
        portData = 0; // Clear data to enter
        portData |= (abcVar[rowN]);//|OE; // abc, OE
        portData &=~ LATCH;        //LATCH LOW
        GPIOC_PDOR = portData;  // Write to Port
        
        uint8_t *start = &interleavedBuffer[rowN*SIZEX*8+((7-BAMMAX)+BAM)*32];    
        for(uint8_t _x = 0; _x < 32; _x++){
              GPIOD_PDOR = start[_x]; // Transfer data
              GPIOC_PDOR |=  SCLK;// Clock HIGH
              GPIOC_PDOR &=~ SCLK;// Clock LOW
        }
    
        GPIOC_PDOR |= LATCH;// Latch HIGH
        GPIOC_PDOR &=~ OE;// OE LOW, Displays line
    
        #define LOOPTIME 2 //trial&error to get both smooth gradients & little flicker
        #define CALLOVERHEAD 2
        timer1.begin(attackMatrix,((LOOPTIME+CALLOVERHEAD)<<BAM)-CALLOVERHEAD);
      
        if(BAM >= BAMMAX) { //Checks the BAM cycle for next time.    
            if(rowN == 15){
                rowN = 0;
            } else {
                rowN ++;
            }        
            BAM = 0;
          } else {
            BAM ++;
        }
    }

  6. #6
    Senior Member xxxajk's Avatar
    Join Date
    Nov 2013
    Location
    Buffalo, NY USA
    Posts
    453
    Very cool!

  7. #7
    Thanks a lot,
    I could easily display the gradient with Teensy 3.0, this is very helpful. Now I am trying to understand the format of your matrix. I can see 4096 numbers, but the pixel value and position is puzzling me!

    Regarding your java code, I cannot compile it; I do not develop with Java so I probably don't have the right environment. I just downloaded and added the jssc.jar file in the java library directory and run javac. I got a few error message like:
    StreamGUI.java:37: package jssc does not exist
    import jssc.SerialPort;

    Then I gave-up (very easily I admit) since my interest at the moment, is first to output an image to the matrix.

  8. #8
    Junior Member
    Join Date
    Feb 2014
    Posts
    7
    Good to hear the gradient is working.

    Actually there is a precompiled version of the Java prog in the /bin directory. It should work without recompiling.

    Regarding the matrix layout: It's interleaved to allow fast output to the display, in the order the panel expects. The first byte contains the first rgb bits of row 1 and 16. 2 bits are wasted this way. Second byte: second rgb bits of first element in row 1 and 16, and so on.

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,406
    Awesome

  10. #10
    Hello,
    I found the .jar program in bin directory; I can confirm that it works with the LED panel. The program displays the top left portion of my screen.
    Thanks for your efforts and sharing.

    Now I have work to do to understand how the Teensy sketch works

  11. #11
    I changed parts of Markus sketch for my purpose (display a 32x32 image and interactive painting), it works well except for a global color change from row 16 with BAMMAX = 7. If I reduce the number of colors (BAMMAX = 5) the bottom part looks good (white background and colors) but the top part colors are shifted!

    Click image for larger version. 

Name:	IMG_0046.jpg 
Views:	281 
Size:	110.8 KB 
ID:	1529
    Any idea, thanks for your help.

    Code:
    /*
    * Modified by Markus Lipp adding interleaved buffers, streaming, 32x32 & 24bit support
     * Based on "_16x32_Matrix R3.0" by Creater Alex Medeiros, http://PenguinTech.tk
     * Use code freely and distort its contents as much as you want, just remeber to thank the 
     * original creaters of the code by leaving their information in the header. :)
     */
    
    //PortC[0:11] = {15, 22, 23, 9, 10, 13, 11, 12, 28, 27, 29, 30}
    //PortD[0:7] = {2, 14, 7, 8, 6, 20, 21, 5}
    //Define pins
    const uint8_t
    //PortC
    APIN      = 15, BPIN      = 22, CPIN      = 23, DPIN = 9,
    CLOCKPIN  = 10, LATCHPIN  = 13, OEPIN     = 11,
    //PortD
    R1PIN     = 2, R2PIN     = 8,
    G1PIN     = 14, G2PIN     = 6,
    B1PIN     = 7, B2PIN     = 20;
    
    uint8_t pinTable[13] = {
        R1PIN,R2PIN,G1PIN,G2PIN,B1PIN,B2PIN,
        APIN,BPIN,CPIN,DPIN,CLOCKPIN,LATCHPIN,OEPIN};
    
    //Addresses 1/8 rows Through a decoder
    uint16_t const A = 1, B = 2,C = 4, D=8;
    //Acts like a 16 bit shift register
    uint16_t const SCLK   = 16;
    uint16_t const LATCH  = 32;
    uint16_t const OE     = 64;
    
    uint16_t const abcVar[16] = { //Decoder counter var
     //   0,A,B,A+B,C,C+A,C+B,A+B+C,
     //   0+D,A+D,B+D,A+B+D,C+D,C+A+D,C+B+D,A+B+C+D};
    0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15}; // need to change a few rows to avoid switching !!
    //Data Lines for row 1 red and row 9 red, ect.
    uint16_t const RED1   = 1, RED2   = 8;
    uint16_t const GREEN1 = 2, GREEN2 = 16;
    uint16_t const BLUE1  = 4, BLUE2  = 32;
    
    const uint8_t SIZEX = 32;
    const uint8_t SIZEY = 32;
    
    //BAM and interrupt variables
    uint8_t rowN = 0;
    uint16_t BAM;
    uint8_t BAMMAX = 7; //now 24bit color! (0-7)
    IntervalTimer timer1;
    
    //Test image 32x32
    int mario[1024] { 
    0xFF0000,0x00FF00,0x0000FF,0xF0C30B,0xCA0BF0,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0x181818,0x181818,0xFFFFFF,0x181818,0xF8F8F8,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0x181818,0xF82038,0xF82038,0xF82038,0xF82038,0x181818,0xF0C830,0xF8F8F8,0xF8F8F8,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0xC80018,0xC80018,0xC80018,0xE08030,0xF0C830,0xF0C830,0x181818,0xF0C830,0xF8F8F8,0xF0C830,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0xC80018,0xC80018,0xC80018,0x181818,0x181818,0x181818,0x181818,0x181818,0x181818,0xF0C830,0xF0C830,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0xA00000,0xA00000,0x181818,0x181818,0x181818,0x181818,0x181818,0x181818,0x181818,0x181818,0xF0C830,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0xA00000,0x181818,0x181818,0xE06058,0xF8F8F8,0xF8F8F8,0xE06058,0xF8F8F8,0xE06058,0x181818,0x181818,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0x181818,0x181818,0xE06058,0xE06058,0xF8F8F8,0x181818,0xF8A870,0x181818,0xF8A870,0x181818,0x4058B8,0x303888,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xF8A870,0x181818,0x181818,0xE06058,0xE06058,0xF8F8F8,0x181818,0xF8A870,0x181818,0x181818,0x181818,0x4058B8,0x303888,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xF8A870,0xF8A870,0x181818,0x181818,0x181818,0xE06058,0xF8A870,0xF8A870,0xF8A870,0xF8A870,0xF8A870,0xF8A870,0x181818,0x303888,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xE06058,0xF8A870,0xE06058,0x181818,0xE06058,0xF8A870,0x181818,0xE06058,0xE06058,0xF8A870,0xF8A870,0xF8A870,0x181818,0x303888,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xE06058,0xE06058,0xE06058,0xF8A870,0x181818,0x181818,0x181818,0x181818,0xE06058,0xE06058,0x181818,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0xE06058,0xE06058,0xF8A870,0xF8A870,0x181818,0x181818,0x181818,0x181818,0x181818,0x303888,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0x181818,0xE06058,0xE06058,0xE06058,0xE06058,0xE06058,0x181818,0x4058B8,0x303888,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x4058B8,0x4058B8,0x4058B8,0x181818,0x181818,0x181818,0x181818,0x181818,0x181818,0x303888,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0x0000FF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x303888,0x4058B8,0x7088E8,0x7088E8,0x4058B8,0x181818,0x181818,0x4058B8,0x7088E8,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x303888,0x4058B8,0x7088E8,0x181818,0x181818,0x181818,0xC80018,0x181818,0x303888,0x4058B8,0x7088E8,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x303888,0x303888,0x181818,0xF8F8F8,0xF8F8F8,0xF8F8F8,0x181818,0xC80018,0x181818,0x303888,0x4058B8,0x4058B8,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x303888,0x181818,0xF0C830,0xF8F8F8,0xF8F8F8,0xF8F8F8,0xF8F8F8,0x181818,0xF82038,0x181818,0x181818,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0xF0C830,0xF0C830,0xF8F8F8,0xF8F8F8,0xF8F8F8,0x181818,0xF8F8F8,0xF8F8F8,0xF82038,0xC80018,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0xF0C830,0xF0C830,0xF0C830,0x181818,0xC80018,0xF8F8F8,0xF8F8F8,0xF82038,0xC80018,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0x181818,0x181818,0x181818,0xC80018,0xF82038,0xF82038,0xF82038,0xF82038,0xC80018,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0xA00000,0xC80018,0xC80018,0xC80018,0xC80018,0xF82038,0xF82038,0xC80018,0x181818,0xE08030,0xE08030,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0xC80018,0xC80018,0xC80018,0xC80018,0xA00000,0xC80018,0xC80018,0x181818,0xE08030,0xE08030,0xA85000,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0xA00000,0xC80018,0xC80018,0xC80018,0xA00000,0xA00000,0xA00000,0xA00000,0x181818,0xE08030,0xA85000,0xA85000,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA85000,0x181818,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0x181818,0x181818,0x181818,0x181818,0xE08030,0xA85000,0xA85000,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA85000,0xE08030,0x181818,0xA00000,0x181818,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xE08030,0xA85000,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA85000,0xE08030,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA85000,0xF0C830,0xF0C830,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    };
    
    uint8_t gImage[1024][3];
    uint8_t gr, gg, gb;
    
    void setup() {
        for(uint8_t i = 0; i < 13; i++){
            pinMode(pinTable[i], OUTPUT);
        }
        
        for (int i = 0; i < 1024; i++) {
            gammaCorrect(mario[i]);
            gImage[i][0] = gr;
            gImage[i][1] = gg;
            gImage[i][2] = gb;
        }
        timerInit();
    }
    
    void loop() {       
    }
    
    void timerInit() {
        BAM = 0;
        attackMatrix();
    }
    
    
    //The updating matrix stuff happens here
    //each pair of rows is taken through its BAM cycle
    //then the rowNumber is increased and id done again
    void attackMatrix() {
        timer1.end();    
    
        uint16_t portData;
        portData = 0; // Clear data to enter
        portData |= (abcVar[rowN])|OE; // abc, OE
        portData &=~ LATCH;        //LATCH LOW
        GPIOC_PDOR = portData;  // Write to Port
    
        for(uint8_t i = 0; i < 32; i++){
             uint16_t tempC[6] = { //Prepare data in correct place
                 (gImage[rowN*32+i][0])   , ((gImage[(rowN+16)*32+i][0])<<1),
                ((gImage[rowN*32+i][1])<<2), ((gImage[(rowN+16)*32+i][1])<<3),
                (gImage[rowN*32+i][2])<<4, (gImage[(rowN+16)*32+i][2])<<5  };           
              uint16_t allC =//Put OUTPUT data into temp variable
              ((tempC[0]>>BAM)&RED1)|((tempC[1]>>BAM)&RED2)|
                ((tempC[2]>>BAM)&GREEN1)|((tempC[3]>>BAM)&GREEN2)|
                ((tempC[4]>>BAM)&BLUE1)|((tempC[5]>>BAM)&BLUE2);
            GPIOD_PDOR = (allC); // Transfer data    
            GPIOC_PDOR |=  SCLK;// Clock HIGH
            GPIOC_PDOR &=~ SCLK;// Clock LOW
        }
    
        GPIOC_PDOR |= LATCH;// Latch HIGH
        GPIOC_PDOR &=~ OE;// OE LOW, Displays line
    
    #define LOOPTIME 1 //trial&error to get both smooth gradients & little flicker
    #define CALLOVERHEAD 1
        timer1.begin(attackMatrix,((LOOPTIME+CALLOVERHEAD)<<BAM)-CALLOVERHEAD);
    
        if(BAM >= BAMMAX) { //Checks the BAM cycle for next time.    
            if(rowN == 15){
                rowN = 0;
            } 
            else {
                rowN ++;
            }        
            BAM = 0;
        } 
        else {
            BAM ++;
        }
    }
    
    void gammaCorrect(int pixel)
    {
        float gammaCorrect = 1.0 /0.45;
        gr = uint8_t(255.0 * (pow(((pixel  >> 16) & 0xFF) / 255.0, gammaCorrect)));
        gg = uint8_t(255.0 * (pow(((pixel  >> 8) & 0xFF) / 255.0, gammaCorrect)));
        gb = uint8_t(255.0 * (pow((pixel  & 0xFF) / 255.0, gammaCorrect)));
    }
    Last edited by freto; 03-01-2014 at 12:53 AM.

  12. #12
    Junior Member
    Join Date
    Feb 2014
    Posts
    7
    By piecing together bits you are doing much more work in the inner loop. Probably you need to increase the delays to get a stable result.

  13. #13
    Junior Member
    Join Date
    Mar 2014
    Posts
    3
    Hi! I made an adaptation of your work in order to send the data with processing: https://benjamin-poilv.squarespace.c...3232-led-panel
    Amazing job by the way!
    Hope you'll enjoy

  14. #14
    Junior Member
    Join Date
    Jun 2014
    Posts
    1

    Code modified for use with multiple panels

    Hi,
    here is Benjamin Poilvé's modified code if want to use multiple panels daisy chained

    Here is the working code for multiple panels. I added a variable for the number of panels on both teensy code and processing code.
    Must set the number of panels variable in both teensy and processing code.

    Teensy Code :
    Code:
    /*
    * Modified by Markus Lipp adding interleaved buffers, streaming, 32×32 & 24bit support
    * Based on “_16x32_Matrix R3.0″ by Creater Alex Medeiros, http://PenguinTech.tk
    * Use code freely and distort its contents as much as you want, just remeber to thank the
    * original creaters of the code by leaving their information in the header. :)
    **
    * 11 June 2014 – modified by Robotpapier: adding multiple panels support to Alex Medeiros who gave me a strating point to tweak the code.
    */
    
    //PortC[0:11] = {15, 22, 23, 9, 10, 13, 11, 12, 28, 27, 29, 30}
    //PortD[0:7] = {2, 14, 7, 8, 6, 20, 21, 5}
    //Define pins
    const uint8_t
    //PortC
    APIN = 15, BPIN = 22, CPIN = 23, DPIN = 9,
    CLOCKPIN = 10, LATCHPIN = 13, OEPIN = 11,
    //PortD
    R1PIN = 2, R2PIN = 8,
    G1PIN = 14, G2PIN = 6,
    B1PIN = 7, B2PIN = 20;
    
    uint8_t pinTable[13] = {
    R1PIN,R2PIN,G1PIN,G2PIN,B1PIN,B2PIN,
    APIN,BPIN,CPIN,DPIN,CLOCKPIN,LATCHPIN,OEPIN};
    
    //Addresses 1/8 rows Through a decoder
    uint16_t const A = 1, B = 2,C = 4, D=8;
    //Acts like a 16 bit shift register
    uint16_t const SCLK = 16;
    uint16_t const LATCH = 32;
    uint16_t const OE = 64;
    
    uint16_t const abcVar[16] = { //Decoder counter var
    0,A,B,A+B,C,C+A,C+B,A+B+C,
    0+D,A+D,B+D,A+B+D,C+D,C+A+D,C+B+D,A+B+C+D};
    
    //Data Lines for row 1 red and row 9 red, ect.
    uint16_t const RED1 = 1, RED2 = 8;
    uint16_t const GREEN1 = 2, GREEN2 = 16;
    uint16_t const BLUE1 = 4, BLUE2 = 32;
    
    const uint8_t NBPANEL = 2;
    const uint8_t SIZEX = 32*NBPANEL;
    const uint8_t SIZEY = 32;
    
    //Here is where the data is all read
    uint8_t interleavedBuffer[SIZEX*SIZEY*4];
    
    //BAM and interrupt variables
    uint8_t rowN = 0;
    uint16_t BAM;
    uint8_t BAMMAX = 4; //now 24bit color! (0-7) // I supposed the more panels we add the less color depth we must use in order to avoid flickering
    
    void setup() {
    for(uint8_t i = 0; i =4096*NBPANEL)
    {
    dataPos=0;
    }
    else
    {
    interleavedBuffer[dataPos++] = val;
    }
    }
    }
    
    IntervalTimer timer1;
    
    void timerInit() {
    BAM = 0;
    attackMatrix();
    }
    
    //The updating matrix stuff happens here
    //each pair of rows is taken through its BAM cycle
    //then the rowNumber is increased and id done again
    void attackMatrix() {
    timer1.end();
    
    uint16_t portData;
    portData = 0; // Clear data to enter
    portData |= (abcVar[rowN])|OE; // abc, OE
    portData &=~ LATCH; //LATCH LOW
    GPIOC_PDOR = portData; // Write to Port
    
    uint8_t *start = &interleavedBuffer[rowN*SIZEX*8+((7-BAMMAX)+BAM)*32*NBPANEL];
    for(uint8_t _x = 0; _x < 32*NBPANEL; _x++){
    GPIOD_PDOR = start[_x]; // Transfer data
    GPIOC_PDOR |= SCLK;// Clock HIGH
    GPIOC_PDOR &=~ SCLK;// Clock LOW
    }
    
    GPIOC_PDOR |= LATCH;// Latch HIGH
    GPIOC_PDOR &=~ OE;// OE LOW, Displays line
    
    #define LOOPTIME 2 //trial&error to get both smooth gradients & little flicker
    #define CALLOVERHEAD 2
    timer1.begin(attackMatrix,((LOOPTIME+CALLOVERHEAD)<= BAMMAX) { //Checks the BAM cycle for next time.
    if(rowN == 15){
    rowN = 0;
    } else {
    rowN ++;
    }
    BAM = 0;
    } else {
    BAM ++;
    }
    }
    Processing code:

    Code:
    /*processing version of 32*32 led panel with teensy 3.0 or 3.1
    Made by benjamin Poilvé http://www.theelectrisquid.fr based on the work of Markus Lipp based on the work by Alex Medeiros!
    Enjoy!*/
    
    /* 11 June 2014 – modified by Robotpapier: adding multiple panels support. Thanks to Alex Medeiros who gave me a strating point to tweak the code. Based on Benjamin Poilvé’s code
    */
    
    import processing.serial.*;
    int nbPanel = 2; // set number of panel here
    
    //import processing.video.*;
    
    //Capture cam;
    Serial serialPort;
    PImage img;
    byte[] matrixbuff = new byte[4096*nbPanel];
    
    void setup(){
    
    frameRate(100);
    size(32*nbPanel, 32);
    
    println(Serial.list());
    
    // Open the port you are using at the rate you want:
    serialPort = new Serial(this, Serial.list()[1], 250000);
    //String[] cameras = Capture.list();
    
    /* if (cameras.length == 0) {
    println(“There are no cameras available for capture.”);
    exit();
    } else {
    println(“Available cameras:”);
    for (int i = 0; i < cameras.length; i++) {
    println(cameras[i]);
    }
    
    // The camera can be initialized directly using an
    // element from the array returned by list():
    cam = new Capture(this, cameras[12]);
    cam.start();
    }*/
    }
    
    void draw(){
    /*if (cam.available() == true) {
    cam.read();
    }
    img=cam.get(0,0,45,45);
    */
    
    background(0);
    img = loadImage("test_color.png"); // must be a png the size of all the panels chained
    img.resize(32*nbPanel,32);
    image(img,0,0);
    
    noSmooth();
    stroke(255,255,255);
    point(mouseX, mouseY);
    
    //background(127,0,0);
    update();
    
    }
    
    void update(){
    if (serialPort != null ) {
    
    serialPort.write((byte)(192)); //00001000
    serialPort.write((byte)(192)); //00100001
    
    int pIdx = 0;
    for (int y = 0; y < 32; y++) {
    for (int x = 0; x < 32*nbPanel; x++) {
    
    float ga = 4f;
    
    color c = get(x, y); //img.get(x,y);
    
    int r = int(red(c));
    int g = int(green(c));
    int b = int(blue(c));
    
    r = (byte)(Math.pow(((float)r)/255.0,ga)*255.0);
    g = (byte)(Math.pow(((float)g)/255.0,ga)*255.0);
    b = (byte)(Math.pow(((float)b)/255.0,ga)*255.0);
    
    matrixbuff=drawPixel888(x,y,(byte)r,(byte)g,(byte)b,matrixbuff);
    
    pIdx++;
    }}
    
    serialPort.write(matrixbuff);
    //println(matrixbuff);
    }
    
    }
    
    byte[] drawPixel888(int x, int y, byte r, byte g, byte b, byte target[]) {
    
    int rowLength = 32*nbPanel*8;
    
    int targetRow =getTargetRow(y);
    boolean targetHigh = getTargetHigh(y);
    
    int baseAddr = targetRow*rowLength;
    for (int i=0; i<8; i++)
    {
    int baseAddrCol = baseAddr+getTargetCol(x,i);
    int bit = 1<=16;
    }

  15. #15
    Junior Member
    Join Date
    Jun 2014
    Posts
    5
    Heyho!
    Great project, it worked immediately after connecting everything.
    Unfortunately you are using a different pin configuration for connecting the panel than the SmartMatrix Lib uses. But I'd like to use their breakout board and maybe even the Lib itself to stream data to the panel. Now your PC software has the option "Full RGB8 (Teensy MatrixLib)", but was it ment for the SmartMatrix Lib? And how does the Sketch look like?

    I've tried and so far failed to understand your concept of the interleaved buffer, but I think, its quite easy to transform it to the Smartmatrix BackBuffer, which consists of three individual buffers, for every color one.

    An example for showing a bitmap:
    Code:
     rgb24 *buffer;
    
        buffer = matrix.backBuffer();
    
        for (i = 0; i < 32 * matrix.getScreenHeight(); i++) {
            buffer[i].red = bitmap.pixel_data[i * 3 + 0];
            buffer[i].green = bitmap.pixel_data[i * 3 + 1];
            buffer[i].blue = bitmap.pixel_data[i * 3 + 2];
        }
    It would be great if you could give me a push!

    Edit: I've tried to set the interleavedBuffer to a size of 32*32*3 (1024*3 Bytes)
    and my loop() looks like:

    Code:
    void loop() {
      int i;
      rgb24 *buffer;
      buffer = matrix.backBuffer();
    
      if (Serial.available())
      {     
        prevVal = val;
        val = Serial.read();     
    
        if ( (prevVal==192 && val==192) || dataPos>=2048+1024)
        {
    
          for (i = 0; i < 32 * matrix.getScreenHeight(); i++) {
            buffer[i].red = interleavedBuffer[i * 3 + 0];
            buffer[i].green = interleavedBuffer[i * 3 + 1];
            buffer[i].blue = interleavedBuffer[i * 3 + 2];
          }
    
          matrix.swapBuffers(true);
          dataPos=0;
        }
        else
        {
          interleavedBuffer[dataPos++] = val;
        }
    
      }  
    }
    And setting the ScreenStream to Full RGB8 it works.. almost.. Some colors are shifted or some positions are incorrect, but it's close from being the real thing!
    Just something isn't right yet.
    Last edited by SebiR; 06-12-2014 at 07:36 PM.

  16. #16
    Junior Member
    Join Date
    Jun 2014
    Posts
    5
    It's me again. Searching on the right place brought me to this:
    http://www.pixelmatix.com/forum/#!/s...test-streaming
    So, everyone who wants to use his SmartMatrix configuration to work with this great project just needs this code.
    Thanks Markus for thinking in every direction. But you should've mentioned the snippet for the Library here
    Last edited by SebiR; 06-13-2014 at 10:27 PM.

  17. #17
    Junior Member
    Join Date
    Mar 2014
    Posts
    3
    You did it robotpapier! Sorry I couldn't be of any help on that, but I'm very impressed..
    We are starting to have some pretty good piece of code for those panels! Anyone up to turning it into a library?
    Still great work everybody!
    On a somehow related topic, we are currently working on making it work on the WebIO card, (http://www.we-io.net/index.html) my teacher/friend Uros creation!

  18. #18
    Member tcottle's Avatar
    Join Date
    Dec 2014
    Location
    Longmont, CO
    Posts
    29
    Hi Freto

    Markus' youtube video lead me to this thread and your code with the Mario test image motivated me to pick up a Teensy 3.1 and a 32x32 panel to experiment with driving RGB LEDs using BAM modulation. Found a couple of bugs that prevented the image from being displayed correctly. Interesting problem - the picture kinda displays correctly even if you pick the color values wrong.

    So it looks like you were playing with the row decoder but left the rows out of order. I removed this and just used nRow as an index

    Code:
     //Addresses 1/8 rows Through a decoder
    uint16_t const A = 1, B = 2,C = 4, D=8;
    
    ...
    
    uint16_t const abcVar[16] = { //Decoder counter var
     //   0,A,B,A+B,C,C+A,C+B,A+B+C,
     //   0+D,A+D,B+D,A+B+D,C+D,C+A+D,C+B+D,A+B+C+D};
    0,1,4,5,2,3,6,7,8,9,12,13,10,11,14,15}; // need to change a few rows to avoid switching !!
    The reason why the lower half of the image was light blue rather than white was because the code has a logic error in it and not because of ISR overhead. I removed a few intermediate variables and repeated calculations in to minimize ISR execution time. The code runs fine with LOOPTIME and CALLOVERHEAD = 1. Here is the updated code and thanks for an interesting project!!!

    Code:
    /*
    * Modified by Markus Lipp adding interleaved buffers, streaming, 32x32 & 24bit support
     * Based on "_16x32_Matrix R3.0" by Creater Alex Medeiros, http://PenguinTech.tk
     * Use code freely and distort its contents as much as you want, just remeber to thank the 
     * original creaters of the code by leaving their information in the header. :)
     */
    
    //PortC[0:11] = {15, 22, 23, 9, 10, 13, 11, 12, 28, 27, 29, 30}
    //PortD[0:7] = {2, 14, 7, 8, 6, 20, 21, 5}
    //Define pins
    const uint8_t
    //PortC
    APIN      = 15, BPIN      = 22, CPIN      = 23, DPIN = 9,
    CLOCKPIN  = 10, LATCHPIN  = 13, OEPIN     = 11,
    //PortD
    R1PIN     = 2, R2PIN     = 8,
    G1PIN     = 14, G2PIN     = 6,
    B1PIN     = 7, B2PIN     = 20;
    
    #define RED 0
    #define GRN 1
    #define BLU 2
    
    uint8_t pinTable[13] = {
        R1PIN,R2PIN,G1PIN,G2PIN,B1PIN,B2PIN,
        APIN,BPIN,CPIN,DPIN,CLOCKPIN,LATCHPIN,OEPIN};
    
    // bit masks
    uint16_t const SCLK   = 16, LATCH  = 32, OE = 64;
    uint16_t const RED1   = 1,  RED2   = 8;
    uint16_t const GREEN1 = 2,  GREEN2 = 16;
    uint16_t const BLUE1  = 4,  BLUE2  = 32;
    
    const uint8_t SIZEX = 32;
    const uint8_t SIZEY = 32;
    
    //BAM and interrupt variables
    uint8_t rowN = 0;
    uint16_t BAM;
    uint8_t BAMMAX = 7; //now 24bit color! (0-7)
    IntervalTimer timer1;
    
    //Test image 32x32
    int mario[1024] { 
    0xFF0000,0x00FF00,0x0000FF,0xF0C30B,0xCA0BF0,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0x181818,0x181818,0xFFFFFF,0x181818,0xF8F8F8,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0x181818,0xF82038,0xF82038,0xF82038,0xF82038,0x181818,0xF0C830,0xF8F8F8,0xF8F8F8,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0xC80018,0xC80018,0xC80018,0xE08030,0xF0C830,0xF0C830,0x181818,0xF0C830,0xF8F8F8,0xF0C830,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0xC80018,0xC80018,0xC80018,0x181818,0x181818,0x181818,0x181818,0x181818,0x181818,0xF0C830,0xF0C830,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0xA00000,0xA00000,0x181818,0x181818,0x181818,0x181818,0x181818,0x181818,0x181818,0x181818,0xF0C830,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0xA00000,0x181818,0x181818,0xE06058,0xF8F8F8,0xF8F8F8,0xE06058,0xF8F8F8,0xE06058,0x181818,0x181818,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0x181818,0x181818,0xE06058,0xE06058,0xF8F8F8,0x181818,0xF8A870,0x181818,0xF8A870,0x181818,0x4058B8,0x303888,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xF8A870,0x181818,0x181818,0xE06058,0xE06058,0xF8F8F8,0x181818,0xF8A870,0x181818,0x181818,0x181818,0x4058B8,0x303888,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xF8A870,0xF8A870,0x181818,0x181818,0x181818,0xE06058,0xF8A870,0xF8A870,0xF8A870,0xF8A870,0xF8A870,0xF8A870,0x181818,0x303888,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xE06058,0xF8A870,0xE06058,0x181818,0xE06058,0xF8A870,0x181818,0xE06058,0xE06058,0xF8A870,0xF8A870,0xF8A870,0x181818,0x303888,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xE06058,0xE06058,0xE06058,0xF8A870,0x181818,0x181818,0x181818,0x181818,0xE06058,0xE06058,0x181818,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0xE06058,0xE06058,0xF8A870,0xF8A870,0x181818,0x181818,0x181818,0x181818,0x181818,0x303888,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0x181818,0xE06058,0xE06058,0xE06058,0xE06058,0xE06058,0x181818,0x4058B8,0x303888,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x4058B8,0x4058B8,0x4058B8,0x181818,0x181818,0x181818,0x181818,0x181818,0x181818,0x303888,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0x0000FF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x303888,0x4058B8,0x7088E8,0x7088E8,0x4058B8,0x181818,0x181818,0x4058B8,0x7088E8,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x303888,0x4058B8,0x7088E8,0x181818,0x181818,0x181818,0xC80018,0x181818,0x303888,0x4058B8,0x7088E8,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x303888,0x303888,0x181818,0xF8F8F8,0xF8F8F8,0xF8F8F8,0x181818,0xC80018,0x181818,0x303888,0x4058B8,0x4058B8,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x303888,0x181818,0xF0C830,0xF8F8F8,0xF8F8F8,0xF8F8F8,0xF8F8F8,0x181818,0xF82038,0x181818,0x181818,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0xF0C830,0xF0C830,0xF8F8F8,0xF8F8F8,0xF8F8F8,0x181818,0xF8F8F8,0xF8F8F8,0xF82038,0xC80018,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0xF0C830,0xF0C830,0xF0C830,0x181818,0xC80018,0xF8F8F8,0xF8F8F8,0xF82038,0xC80018,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0x181818,0x181818,0x181818,0xC80018,0xF82038,0xF82038,0xF82038,0xF82038,0xC80018,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0xA00000,0xC80018,0xC80018,0xC80018,0xC80018,0xF82038,0xF82038,0xC80018,0x181818,0xE08030,0xE08030,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0xC80018,0xC80018,0xC80018,0xC80018,0xA00000,0xC80018,0xC80018,0x181818,0xE08030,0xE08030,0xA85000,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA00000,0xA00000,0xC80018,0xC80018,0xC80018,0xA00000,0xA00000,0xA00000,0xA00000,0x181818,0xE08030,0xA85000,0xA85000,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA85000,0x181818,0xA00000,0xA00000,0xA00000,0xA00000,0xA00000,0x181818,0x181818,0x181818,0x181818,0xE08030,0xA85000,0xA85000,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA85000,0xE08030,0x181818,0xA00000,0x181818,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xE08030,0xA85000,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA85000,0xE08030,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0xA85000,0xF0C830,0xF0C830,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0x181818,0x181818,0x181818,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,0xFFFFFF,
    };
    
    uint8_t gImage[1024][3];
    uint8_t gr, gg, gb;
    
    void setup() {
        for(uint8_t i = 0; i < 13; i++){
            pinMode(pinTable[i], OUTPUT);
        }
        
        for (int i = 0; i < 1024; i++) {
            gammaCorrect(mario[i]);
            gImage[i][0] = gr;
            gImage[i][1] = gg;
            gImage[i][2] = gb;
        }
        timerInit();
    }
    
    void loop() {       
    }
    
    void timerInit() {
        BAM = 0;
        attackMatrix();
    }
    
    //The updating matrix stuff happens here
    //each pair of rows is taken through its BAM cycle
    //then the rowNumber is increased and id done again
    void attackMatrix() {
        timer1.end();    
    
        uint16_t portData;
        GPIOC_PDOR = (rowN & 0x0F)|OE; // row select abcd, OE
        GPIOC_PDOR &=~ LATCH;          // LATCH LOW
    
        for(uint8_t i = 0; i < 32; i++){
              int const pix = rowN*32 + i;
              int const pix1 =(rowN+16)*32+i;
              /* using the BAM counter, isolate bit of interest in the color byte then shift the bit
                 into the correct position in port D.  Do for all 6 LEDs                         */
              GPIOD_PDOR =  
              
              (((gImage[pix][RED]) >> BAM) & RED1) | (((gImage[pix1][RED]) >> BAM) << 3 & RED2) |
              ((gImage[pix][GRN] >> BAM) << 1 & GREEN1) | ((gImage[pix1][GRN] >> BAM) << 4 & GREEN2) |
              ((gImage[pix][BLU]>>BAM) << 2 & BLUE1) | ((gImage[pix1][BLU] >> BAM) << 5 & BLUE2);
              GPIOC_PDOR |=  SCLK; // Clock HIGH
              GPIOC_PDOR &= ~SCLK; // Clock LOW
        }
    
        GPIOC_PDOR |= LATCH;// Latch HIGH
        GPIOC_PDOR &= ~OE;  // OE LOW, Displays line
    
    #define LOOPTIME 1 //trial&error to get both smooth gradients & little flicker
    #define CALLOVERHEAD 1
    
        timer1.begin(attackMatrix,((LOOPTIME+CALLOVERHEAD)<<BAM)-CALLOVERHEAD);  // 1uS ticks
    
        if(BAM >= BAMMAX) { //Checks the BAM cycle for next time.    
            if(rowN == 15) rowN = 0;  // Hold row constant for a complete BAM cycle
            else rowN ++;        
            BAM = 0;
        } 
        else BAM ++;
    }
    
    void gammaCorrect(int pixel)
    {
        float gammaCorrect = 1.0 /0.45;
        
        gr = uint8_t(255.0 * (pow(((pixel  >> 16) & 0xFF) / 255.0, gammaCorrect)));
        gg = uint8_t(255.0 * (pow(((pixel  >> 8) & 0xFF) / 255.0, gammaCorrect)));
        gb = uint8_t(255.0 * (pow((pixel  & 0xFF) / 255.0, gammaCorrect)));
    }
    Click image for larger version. 

Name:	FullSizeRender (1).jpg 
Views:	197 
Size:	103.9 KB 
ID:	3188

  19. #19
    Junior Member
    Join Date
    Aug 2016
    Posts
    1

    movie streaming

    Does anyone know how to stream a movie on to a 32x32 panel using an arduino and processing?

  20. #20
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    15,406
    A few years ago I used a Beaglebone to read a webcam and send the pixels to a pair of Teensy boards at 30 frames/sec. It used the v4l2 library to get the camera data in RGB format.

    Maybe it's also possible from Processing? I don't know.

  21. #21
    Junior Member
    Join Date
    Mar 2017
    Posts
    1

    Teensy 3.2 USB with 32x32 LED Matrix

    Hello all,

    I need help. I’m trying to put a LED matrix on my graduation cap. I have completed the circuit build, but I cannot Arduino software for animate gif’s to run without errors. I downloaded it from the library yet the animate gif software is bad. I have no idea how to troubleshoot the software because I don’t have programming skills. Since I cannot get the software to run correctly I cannot upload it to the Teensy. Can anyone help me with this?

    Teensy 3.2 USB + Header

    32x32 RGB LED Matrix -6mm (MI-T352P6RGB3232-16S-AI-75) PN1484

    Smartmatrix SD shield V3 – for Teensy 3.2

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •