1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

(Solved)Again problem with matrix, this time 8x32

Discussion in 'Arduino' started by fezder, Jan 4, 2016.

  1. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Yup, I now made bigger matrix from 8x8's. circuit is 5 daisy chained 74595's, again shift registers. First one handles anodes (rows) and rest columns (cathodes), so matrises are row anode-column cathode. I've succeeded to display simple test code showing 5x8 font scrolling, but thing is they are displayed at all 4 matrises same time (just like intended in code)
    What I actually am trying to accomplish is to use whole area effectively as large screen for say scrolling text. Have code also that allows to create stationary characters without scrolling but there is flicker seen (probably because I made it by displaying one matrix at a time)
    Any hints ,links, tips? Should Imake 2d-array where to store data, or what would be best approach? Preferably without libraries because this far has been well without them.
    I read that some examples mention bit mask, but I'll gladly hear suggestions and such while trying to get this work....

    current code as follows: (sorry, some of font is HEX and some in binary, haven't cleaned it yet....)
    Code (c):
    int dataPin = 2;        //IC 14       //Define which pins will be used for the Shift Register control
    int latchPin = 3;       //IC 12
    int clockPin = 4;       //IC 11
    //OE-GND
    //MR-VCC
    int delaytime = 1, timer, timerPrev = 0;
    int shift = 0;
    int len = 400;
    static uint8_t  x [400] =
    {
      0xff, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xff, // square
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // block
      0x00, 0x7c, 0xa2, 0x92, 0x8a, 0x7c, 0x00, 0x00, // 0
      0x00, 0x42, 0xfe, 0x02, 0x00, 0x00, 0x00, 0x00, // 1
      0x00, 0x42, 0x86, 0x8a, 0x92, 0x62, 0x00, 0x00, // 2
      0x00, 0x84, 0x82, 0xa2, 0xd2, 0x8c, 0x00, 0x00, // 3
      0x00, 0x18, 0x28, 0x48, 0xfe, 0x08, 0x00, 0x00, // 4
      0x00, 0xe4, 0xa2, 0xa2, 0xa2, 0x9c, 0x00, 0x00, // 5
      0x00, 0x3c, 0x52, 0x92, 0x92, 0x0c, 0x00, 0x00, // 6
      0x00, 0x80, 0x8e, 0x90, 0xa0, 0xc0, 0x00, 0x00, // 7
      0x00, 0x6c, 0x92, 0x92, 0x92, 0x6c, 0x00, 0x00, // 8
      0x00, 0x60, 0x92, 0x92, 0x94, 0x78, 0x00, 0x00, // 9
      0x00, 0x7e, 0x90, 0x90, 0x90, 0x7e, 0x00, 0x00, //A
      0x00, 0x7e, 0x92, 0x92, 0x6c, 0x00, 0x00, 0x00, //B
      B00000000, B01111100, B10000010, B10000010, B10000010, B01000100, B00000000, B00000000, //C
      B00000000, B11111110, B10000010, B10000010, B10000010, B01111100, B00000000, B00000000, //D
      B00000000, B11111110, B10010010, B10010010, B10010010, B10000010, B00000000, B00000000, //E
      B00000000, B11111110, B10010000, B10010000, B10010000, B10000000, B00000000, B00000000, //F
      B00000000, B01111100, B10000010, B10001010, B10001010, B01001100, B00000000, B00000000, //G
      B00000000, B11111110, B00010000, B00010000, B00010000, B11111110, B00000000, B00000000, //H
      B00000000, B00000000, B10000010, B11111110, B10000010, B00000000, B00000000, B00000000, //I
      B00000000, B00001100, B00000010, B00000010, B00000010, B11111100, B00000000, B00000000, //J
      B00000000, B11111110, B00010000, B00101000, B01000100, B10000010, B00000000, B00000000, //K
      B00000000, B11111110, B00000010, B00000010, B00000010, B00000010, B00000000, B00000000, //L
      B00000000, B11111110, B01000000, B00100000, B01000000, B11111110, B00000000, B00000000, //M
      B00000000, B11111110, B00100000, B00010000, B00001000, B11111110, B00000000, B00000000, //N
      B00000000, B01111100, B10000010, B10000010, B10000010, B01111100, B00000000, B00000000, //O
      B00000000, B11111110, B10010000, B10010000, B10010000, B01100000, B00000000, B00000000, //P
      B00000000, B01111100, B10000010, B10001010, B10000110, B01111110, B00000000, B00000000, //Q
      B00000000, B01111110, B10010000, B10011000, B10010100, B01100010, B00000000, B00000000, //R
      B00000000, B01100100, B10010010, B10010010, B10010010, B01001100, B00000000, B00000000, //S
      B00000000, B10000000, B10000000, B11111110, B10000000, B10000000, B00000000, B00000000, //T
      B00000000, B11111100, B00000010, B00000010, B00000010, B11111100, B00000000, B00000000, //U
      B00000000, B11111000, B00000100, B00000010, B00000100, B11111000, B00000000, B00000000, //V
      B00000000, B11111110, B00000100, B00001000, B00000100, B11111110, B00000000, B00000000, //W
      B00000000, B11000110, B00101000, B00010000, B00101000, B11000110, B00000000, B00000000, //X
      B00000000, B11000000, B00100000, B00011110, B00100000, B11000000, B00000000, B00000000, //Y
      B00000000, B10000110, B10001010, B10010010, B10100010, B11000010, B00000000, B00000000, //Z
      B00000000, B01000000, B10000000, B10001010, B10010000, B01100000, B00000000, B00000000, //?
      B00000000, B00000000, B00000000, B11111010, B00000000, B00000000, B00000000, B00000000, //!
      B00000000, B00010000, B00010000, B01111100, B00010000, B00010000, B00000000, B00000000, //+
      B00000000, B00010000, B00010000, B00010000, B00010000, B00010000, B00000000, B00000000, //-
      B00000000, B00101000, B00101000, B00101000, B00101000, B00101000, B00000000, B00000000, //=
      B00000000, B00000000, B00000000, B01111100, B10000010, B00000000, B00000000, B00000000, //(
      B00000000, B00000000, B10000010, B01111100, B00000000, B00000000, B00000000, B00000000, //)

    };




    void setup()
    {
      DDRD = DDRD | B00011100;                                  //set pins as output

    }

    void loop()
    {
      timer = millis ();
      if (timer - timerPrev > 100)
      {
        shift++;
        if (shift == len)shift = 0;
        timerPrev = timer;
      }
      for (int i = 0; i < 8; i++)
      {
        PORTD = B00000000;                                  //turn latch low
        shiftOut(dataPin, clockPin, MSBFIRST, 1 << i);          //Send the data #2        (what columns to power)  all columns work at same time here
        shiftOut(dataPin, clockPin, MSBFIRST, 1 << i);          //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, MSBFIRST, 1 << i);          //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, MSBFIRST, 1 << i);          //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, LSBFIRST, x[i + shift > len - 1 ? i + shift - len : i + shift]); //Send the data #1       ( what data to draw)
        PORTD = B00001000;                                  //turn latch on->show screen
       //delayMicroseconds (1000);  //seems not needed
      }


    }


     
     
    Last edited: Feb 15, 2016
  2. KeepItSimpleStupid

    KeepItSimpleStupid Well-Known Member Most Helpful Member

    Joined:
    Oct 30, 2010
    Messages:
    9,970
    Likes:
    1,099
    Stationary characters require inter-digit blanking. What does that mean?
    If you took a simple 7 segment multiplexed display. You need to turn all of the digits completely off for a short time while loading the next digit. If you don't there is a "blurr" which is perceived as a flicker. e.g. 80. The - in the 8 segment will be of much lower intensity without blanking.
     
    • Informative Informative x 1
  3. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    KISS, it's not that sort of blur i meant, I mean whole display flickers. This code I used for drawing stationary (3210) pattern:
    There isn't any delay() used so that isn't cause, but I think it's because each time number is drawed at matrix, 3 others are disabled (wrote B00000000 to those what aren't in use, so there is blanking, at least in my understanding even if whole screen is not blanked)
    Code (c):
    int dataPin = 2;        //IC 14       //Define which pins will be used for the Shift Register control
    int latchPin = 3;       //IC 12
    int clockPin = 4;       //IC 11
    //OE-GND
    //MR-VCC
    int delaytime = 1, timer, timerPrev = 0;
    int shift = 0;
    int len = 400;
    static uint8_t  x [400] =
    {
      0xff, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xff, // square
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // block
      0x00, 0x7c, 0xa2, 0x92, 0x8a, 0x7c, 0x00, 0x00, // 0
      0x00, 0x42, 0xfe, 0x02, 0x00, 0x00, 0x00, 0x00, // 1
      0x00, 0x42, 0x86, 0x8a, 0x92, 0x62, 0x00, 0x00, // 2
      0x00, 0x84, 0x82, 0xa2, 0xd2, 0x8c, 0x00, 0x00, // 3
      0x00, 0x18, 0x28, 0x48, 0xfe, 0x08, 0x00, 0x00, // 4
      0x00, 0xe4, 0xa2, 0xa2, 0xa2, 0x9c, 0x00, 0x00, // 5
      0x00, 0x3c, 0x52, 0x92, 0x92, 0x0c, 0x00, 0x00, // 6
      0x00, 0x80, 0x8e, 0x90, 0xa0, 0xc0, 0x00, 0x00, // 7
      0x00, 0x6c, 0x92, 0x92, 0x92, 0x6c, 0x00, 0x00, // 8
      0x00, 0x60, 0x92, 0x92, 0x94, 0x78, 0x00, 0x00, // 9
      0x00, 0x7e, 0x90, 0x90, 0x90, 0x7e, 0x00, 0x00, //A
      0x00, 0x7e, 0x92, 0x92, 0x6c, 0x00, 0x00, 0x00, //B
      B00000000, B01111100, B10000010, B10000010, B10000010, B01000100, B00000000, B00000000, //C
      B00000000, B11111110, B10000010, B10000010, B10000010, B01111100, B00000000, B00000000, //D
      B00000000, B11111110, B10010010, B10010010, B10010010, B10000010, B00000000, B00000000, //E
      B00000000, B11111110, B10010000, B10010000, B10010000, B10000000, B00000000, B00000000, //F
      B00000000, B01111100, B10000010, B10001010, B10001010, B01001100, B00000000, B00000000, //G
      B00000000, B11111110, B00010000, B00010000, B00010000, B11111110, B00000000, B00000000, //H
      B00000000, B00000000, B10000010, B11111110, B10000010, B00000000, B00000000, B00000000, //I
      B00000000, B00001100, B00000010, B00000010, B00000010, B11111100, B00000000, B00000000, //J
      B00000000, B11111110, B00010000, B00101000, B01000100, B10000010, B00000000, B00000000, //K
      B00000000, B11111110, B00000010, B00000010, B00000010, B00000010, B00000000, B00000000, //L
      B00000000, B11111110, B01000000, B00100000, B01000000, B11111110, B00000000, B00000000, //M
      B00000000, B11111110, B00100000, B00010000, B00001000, B11111110, B00000000, B00000000, //N
      B00000000, B01111100, B10000010, B10000010, B10000010, B01111100, B00000000, B00000000, //O
      B00000000, B11111110, B10010000, B10010000, B10010000, B01100000, B00000000, B00000000, //P
      B00000000, B01111100, B10000010, B10001010, B10000110, B01111110, B00000000, B00000000, //Q
      B00000000, B01111110, B10010000, B10011000, B10010100, B01100010, B00000000, B00000000, //R
      B00000000, B01100100, B10010010, B10010010, B10010010, B01001100, B00000000, B00000000, //S
      B00000000, B10000000, B10000000, B11111110, B10000000, B10000000, B00000000, B00000000, //T
      B00000000, B11111100, B00000010, B00000010, B00000010, B11111100, B00000000, B00000000, //U
      B00000000, B11111000, B00000100, B00000010, B00000100, B11111000, B00000000, B00000000, //V
      B00000000, B11111110, B00000100, B00001000, B00000100, B11111110, B00000000, B00000000, //W
      B00000000, B11000110, B00101000, B00010000, B00101000, B11000110, B00000000, B00000000, //X
      B00000000, B11000000, B00100000, B00011110, B00100000, B11000000, B00000000, B00000000, //Y
      B00000000, B10000110, B10001010, B10010010, B10100010, B11000010, B00000000, B00000000, //Z
      B00000000, B01000000, B10000000, B10001010, B10010000, B01100000, B00000000, B00000000, //?
      B00000000, B00000000, B00000000, B11111010, B00000000, B00000000, B00000000, B00000000, //!
      B00000000, B00010000, B00010000, B01111100, B00010000, B00010000, B00000000, B00000000, //+
      B00000000, B00010000, B00010000, B00010000, B00010000, B00010000, B00000000, B00000000, //-
      B00000000, B00101000, B00101000, B00101000, B00101000, B00101000, B00000000, B00000000, //=
      B00000000, B00000000, B00000000, B01111100, B10000010, B00000000, B00000000, B00000000, //(
      B00000000, B00000000, B10000010, B01111100, B00000000, B00000000, B00000000, B00000000, //)

    };




    void setup()
    {
      DDRD = DDRD | B00011100;                                  //set pins as output

    }

    void loop()
    {

      for (int i = 0; i < 8; i++)
      {
        PORTD = B00000000;                                  //turn latch low
        shiftOut(dataPin, clockPin, MSBFIRST, 1 << i);          //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, MSBFIRST, B00000000);          //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, MSBFIRST, B00000000);          //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, MSBFIRST, B00000000);          //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, LSBFIRST, x[i + 16]); //Send the data #1       ( what data to draw)
        PORTD = B00001000;                                  //turn latch on->show screen
        PORTD = B00000000;                                  //turn latch low
        shiftOut(dataPin, clockPin, MSBFIRST, B00000000);          //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, MSBFIRST, 1 << i);          //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, MSBFIRST, B00000000);          //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, MSBFIRST, B00000000);          //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, LSBFIRST, x[i + 24]); //Send the data #1       ( what data to draw)
        PORTD = B00001000;                                  //turn latch on->show screen
        PORTD = B00000000;                                  //turn latch low
        shiftOut(dataPin, clockPin, MSBFIRST, B00000000);         //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, MSBFIRST, B00000000);         //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, MSBFIRST, 1 << i);          //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, MSBFIRST, B00000000);         //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, LSBFIRST, x[i + 32]); //Send the data #1       ( what data to draw)
        PORTD = B00001000;                                  //turn latch on->show screen
        PORTD = B00000000;                                  //turn latch low
        shiftOut(dataPin, clockPin, MSBFIRST, B00000000);          //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, MSBFIRST, B00000000);         //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, MSBFIRST, B00000000);          //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, MSBFIRST, 1 << i);          //Send the data #2        (what columns to power)
        shiftOut(dataPin, clockPin, LSBFIRST, x[i + 40]); //Send the data #1       ( what data to draw)
        PORTD = B00001000;                                  //turn latch on->show screen

      }


    }


     
     
    Last edited: Feb 15, 2016
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland

    Screen doesn't flicker TOO much but if looked closely enough, flicker is seen. So, in fact there is two issues; that flicker as well as using whole matrix effectively, when thinked about it.
     
  6. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    NVM about that flicker issue, I had delay lurking there....was very small but that made it, forgot to upload code after editing
     
    Last edited: Feb 15, 2016
  7. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    If you need flicker free, then use interrupts... You need to keep the led's alive by keeping the current flowing.... If you are now using 8 matrices there is a lot of OFF time ( as you pointed out )

    I'm back at work now but the flooding was a tad harder to mop up as I thought... I may be able to get something up and running soon!!
     
    • Informative Informative x 1
  8. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Ian, I have 4 matrises, I was planning to do 8 matrises combo but didn't have 8 that would been same in appearance.
    By interrupt, do you mean timer interrupt with register-manipulation? didn't thought about that
    I suppose there's quite a mess there at your job site? at least I imagine so
     
  9. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    The water was only a foot high but there is quite a bit of a mess!!

    I have 8x8 matrices somewhere so I'll did them out... And yes! You really need to set up a duty cycle...Updating every LED periodically is the best way to do this... with 4 8x8 matrices you can setup a 1:32 duty cycle so every LED will be lit evenly.... Then just use a 32 byte array as your drawing surface, a 32 byte array as your blit surface and use a "blit" function to swap the LED data when you are ready to update...

    I have all the functions ready to go..
     
    • Informative Informative x 1
  10. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Good thing there wasn't too much water in there
    Got bit sidetracked, tested whether there is ghosting and seems there isn't, good (9999 counter as test)


    But, does any of your tutorial files include that ''blit'' function as an part of code?
    And, do i have separate array for columns and rows? bit confused
     
  11. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    Here is the code for my 4 8x8 matrices..
    The animation and the font are separate files..

    All done on a pic16f877a....
    Code (c):

    #include<pic.h>
    #define _XTAL_FREQ 20000000L       // 20 meg crsytal
    __CONFIG(0x3F52);             // HS on,  WDT off, BOR on, PWRTon..

    char displayPointer=0;           // for interrupt use...
    extern const char  fnt[];         // Font in external C file
    extern const char  anim[];
    unsigned char buffer[32];          // buffer for screen
    unsigned char backbuffer[32];       // Spare screen for drawing on
    char pow[8]={128,64,32,16,8,4,2,1};

    void interrupt ISR()           // This just swaps the buffer to the display
       {
       if(TMR2IF)               // Make sure its the timer interrupt.
         {
         PORTB = 0;             // Clear old data first
         if(displayPointer == 0 )      // 1st frame..
           RC4 = 1;           // Data = 1 on the first clock only
         RC3 = 1;
         __delay_us(20);           // Clock the shift registers
         RC3 = 0;
         RC4 = 0;             // Make sure data stays low for the rest of the cycles
         PORTB = buffer[displayPointer];   // Move buffer row by row( 4 row sections per row )    
         if(++displayPointer==32)      // 32 LED row sections in total
           displayPointer = 0;       // Back to first row..
         }
       TMR2IF = 0;               // Clear timer 2 interrupt flag
       }

    void pixel(signed char x,signed char y,int cond)
       {
       int tmp;
       char pix,msk;
       if(x<0 || y<0) return;       // outside drawing limits negative
       if(x>31 || y>7) return;       // outside drawing limits positive
       tmp = (y << 2) + (x>>3);     // Linear position
       pix = x%8;             // pixel required
       pix = pow[ pix];
       msk = backbuffer[tmp];       // get exsisting data
       if(cond == 2)
         pix ^= msk;           // XOR data to screen
       if (cond == 1)
         {
         pix = ~pix;
         pix &= msk;           // AND data to screen
         }
       if(cond == 0)
         pix |= msk;           // OR data to screen
       backbuffer[tmp] = pix;       // apply changes
       }

    void charput(char ch, signed char x,signed char y)
       {
       signed char x1, y1;        
       const char* addr2;         // pointer to character
       char disp;
       ch -= 0x20;             // characters starts a 0 not 0x20
       addr2 = &fnt[0];         // start of font array
       addr2 = addr2 + ((int)ch * 8);   // start place in font array
       for( y1=0;y1<8;y1++)       // eight rows
         {
         disp = *addr2;
         for (x1 = 0; x1<8; x1++)   // eight pixels
           {      
           if(disp & pow[x1])
             pixel(x+x1,y+y1,0); // OR the pixel to the display buffer
           }
         addr2++;
         }  
       }

    void strput(const char* ch, signed char x,signed char y)
       {
       int addr;
     
       while (*ch )
         {
         charput(*ch++,x,y);       // write a string to the display buffer
         x+=7;
         }    
       }

    void clr()
       {
       int addr;
       for(addr=0;addr<32;addr++)         // Empty display buffer
         backbuffer[addr]= 0;
       }

    void Blit()
       {
       int addr=0;
       GIE = 0;
       for(addr=0;addr < 32;addr ++)
         {
         buffer[addr] = backbuffer[addr];   // put all data from display buffer
         }                   // to screen buffer
       GIE = 1;
       }

    void animation(void)
       {
       char x,y;
       const char* frame;             // pointer to frames
       for(x=0;x<14;x++)             // 14 frames in animation
         {
         clr();                 // clears the display buffer
         frame = &anim[0];           // start of frames
         frame += x*32;              // each frame is 32 bytes long
         for(y=0;y<32;y++)
           backbuffer[y] = *frame++;     // Cycle through the animation
         Blit();                 // pass to screen buffer
         __delay_ms(150);           // time to view
         }
       }

    void displaystring(void)         // this routine prints through the screen buffer
       {                   // moving one pixel at a time
       signed char x=32,y=0;         // I made these signed so I could print
       for(y = 0;y  < 96 ;y++)         // to nowhere so I could produce the scrolling effect
         {
         clr();               // Clear the display buffer
         strput("HELLO WORLD!!",x--,0);   // adjust the scrolling string
         Blit();               // pass to screen buffer
         __delay_ms(80);           // time to view
         }
       }

    void main(void)
       {
       int sx,sy;
       int xdir=1, ydir=1;
       ADCON1 = 0x6;             // ALL digital
       T2CON = 0x1e;             // T2 on, 16:1 pre scale
       PR2 = 49;               // timer preload value ( equates to 1.4mS with 20mhz crystal)
       TMR2IE = 1;               // enable timer 2 interrupt
       PEIE = 1;               // enable peripheral interrupt
       GIE = 1;               // enableglobal interrupt
       TRISB = 0;               // Port B as output...
       TRISC = 0;               // Port C as ouput...
       animation();
       displaystring();
       while(1)
         {
         clr();
         sx += xdir; sy += ydir;    
      strput("]",sx,sy);      // this is a ball character for bouncing routine

         if(sx>27) xdir = -1;      /// Wall limits
         if(sy>4) ydir = -1;
         if(sx<0) xdir = 1;
         if(sy<0) ydir = 1;
         __delay_ms(80);
         Blit();
         }
       }   // End main

     
     
    Last edited: Jan 4, 2016
    • Thanks Thanks x 1
  12. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Cool, I'll try to understand important bits , never even touched PIC's but at least that looks somewhat familiar.
     
  13. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Ah, this was the ''blit'' function you meant?
    That GIE part, is it for disabling and enabling interrupts so it doesn't fool during blit?
    And, where is timer set for interrupt? EDIT: found it seems so, at main void PR2 = 49; (prescaler i presume)
    Code (c):
    void Blit()
       {
       int addr=0;
       GIE = 0;
       for(addr=0;addr < 32;addr ++)
         {
         buffer[addr] = backbuffer[addr];   // put all data from display buffer
         }                   // to screen buffer
       GIE = 1;
       }
     
    Last edited: Feb 15, 2016
  14. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    I tried to remark on the important bits... It works very well... I have a working 8 8x8matrix 16x32 leds, but the LED's are a lot dimmer.... I need to change the row driver to be able to supply more current!! But as it was for demonstration I didn't carry it on..
     
    • Like Like x 1
  15. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Ian, progress so far, takes a while as never touched pic....noticed that at least setup and loop can be combined in a way, but loop() is still needed....
    what is confusing is that how should daisy-chained shift registers be implemented in code? Please tell if you see any alarming in code, placed comments here and there (took animation part entirely out since didn't have it, and I presume it's not needed)
    only three erros, conversion things:
    Code (c):
    Arduino: 1.6.5 (Windows 7), Board: "Arduino Pro or Pro Mini, ATmega328 (5V, 16 MHz)"

    Ian_s_Sketch.ino: In function 'void charput(char, signed char, signed char)':
    Ian_s_Sketch:64: error: invalid conversion from 'uint8_t* {aka unsigned char*}' to 'const char*' [-fpermissive]
    invalid conversion from 'uint8_t* {aka unsigned char*}' to 'const char*' [-fpermissive]

      This report would have more information with
      "Show verbose output during compilation"
      enabled in File > Preferences.
     
    Code (c):
    int dataPin = 2;        //  ic: 14, ser_in Define which pins will be used for the Shift Register control
    int latchPin = 3;      //   ic:12         silkscreen numbers!
    int clockPin = 4;

    char displayPointer=0;           // for interrupt use...
    static uint8_t  font [80] =    //numbers stored here
    {
      0x00, 0x7c, 0xa2, 0x92, 0x8a, 0x7c, 0x00, 0x00, // 0
      0x00, 0x42, 0xfe, 0x02, 0x00, 0x00, 0x00, 0x00, // 1
      0x00, 0x42, 0x86, 0x8a, 0x92, 0x62, 0x00, 0x00, // 2
      0x00, 0x84, 0x82, 0xa2, 0xd2, 0x8c, 0x00, 0x00, // 3
      0x00, 0x18, 0x28, 0x48, 0xfe, 0x08, 0x00, 0x00, // 4
      0x00, 0xe4, 0xa2, 0xa2, 0xa2, 0x9c, 0x00, 0x00, // 5
      0x00, 0x3c, 0x52, 0x92, 0x92, 0x0c, 0x00, 0x00, // 6
      0x00, 0x80, 0x8e, 0x90, 0xa0, 0xc0, 0x00, 0x00, // 7
      0x00, 0x6c, 0x92, 0x92, 0x92, 0x6c, 0x00, 0x00, // 8
      0x00, 0x60, 0x92, 0x92, 0x94, 0x78, 0x00, 0x00, // 9
    };
    unsigned char buffer[32];          // buffer for screen
    unsigned char backbuffer[32];       // Spare screen for drawing on
    char power[8]={128,64,32,16,8,4,2,1};

    ISR(TIMER1_COMPA_vect)          // timer compare interrupt service routine
       {
     
       
       
         if(displayPointer == 0 )      // 1st frame..
         PORTB = buffer[displayPointer];   // Move buffer row by row( 4 row sections per row )  
         if(++displayPointer==32)      // 32 LED row sections in total
           displayPointer = 0;       // Back to first row..
       

       }

    void pixel(signed char x,signed char y,int cond)
       {
       int tmp;
       char pix,msk;
       if(x<0 || y<0) return;       // outside drawing limits negative
       if(x>31 || y>7) return;       // outside drawing limits positive
       tmp = (y << 2) + (x>>3);     // Linear position
       pix = x%8;             // pixel required
       pix = power[pix];
       msk = backbuffer[tmp];       // get exsisting data
       if(cond == 2)
         pix ^= msk;           // XOR data to screen
       if (cond == 1)
         {
         pix = ~pix;
         pix &= msk;           // AND data to screen
         }
       if(cond == 0)
         pix |= msk;           // OR data to screen
       backbuffer[tmp] = pix;       // apply changes
       }

    void charput(char ch, signed char x,signed char y)
       {
       signed char x1, y1;      
       const char* addr2;         // pointer to character
       char disp;
       ch -= 0x20;             // characters starts a 0 not 0x20
       addr2 = &font[0];         // start of font array
       addr2 = addr2 + ((int)ch * 8);   // start place in font array
       for( y1=0;y1<8;y1++)       // eight rows
         {
         disp = *addr2;
         for (x1 = 0; x1<8; x1++)   // eight pixels
           {    
           if(disp & power[x1])
             pixel(x+x1,y+y1,0); // OR the pixel to the display buffer
           }
         addr2++;
         }
       }

    void strput(const char* ch, signed char x,signed char y)
       {
       int addr;
       while (*ch )
         {
         charput(*ch++,x,y);       // write a string to the display buffer
         x+=7;
         }  
       }

    void clr()                   //clear
       {
       int addr;
       for(addr=0;addr<32;addr++)         // Empty display buffer
         backbuffer[addr]= 0;
       }

    void Blit()              //transfers data between display buffer to screen buffer
       {
       int addr=0;
       noInterrupts();           // disable all interrupts during setup
       for(addr=0;addr < 32;addr ++)
         {
         buffer[addr] = backbuffer[addr];   // put all data from display buffer
         }                   // to screen buffer
       interrupts();             // enable all interrupts
       }



    void displaystring(void)         // this routine prints through the screen buffer
       {                   // moving one pixel at a time
       signed char x=32,y=0;         // I made these signed so I could print
       for(y = 0;y  < 96 ;y++)         // to nowhere so I could produce the scrolling effect
         {
         clr();               // Clear the display buffer
         strput("HELLO WORLD!!",x--,0);   // adjust the scrolling string
         Blit();               // pass to screen buffer
         delay(80);           // time to view
         }
       }

    void setup()          //setup runs once
       {
        noInterrupts();           // disable all interrupts during setup
        DDRD = DDRD | B11111100;  //port registers used to set pin directions
       //int sx,sy;   //these two necessary? couldn't see them anywhere else than ball-thingy
       //int xdir=1, ydir=1;
      TCCR1A = 0;
      TCCR1B = 0;
      TCNT1  = 0;
      OCR1A = 31250;            // compare match register 16MHz/256/2Hz
      TCCR1B |= (1 << WGM12);   // CTC mode, free-running, clear on match
      TCCR1B |= (1 << CS12);    // 256 prescaler
      TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
      interrupts();             // enable all interrupts
       displaystring();  //prints just hello world at startup

       while(1)         //essentially loop()? but loop is still needed...
         {
         clr();    //clear buffer first
         /*sx += xdir; sy += ydir;     no balls needed so can be omitted
      strput("]",sx,sy);      // this is a ball character for bouncing routine

         if(sx>27) xdir = -1;      /// Wall limits
         if(sy>4) ydir = -1;
         if(sx<0) xdir = 1;
         if(sy<0) ydir = 1;*/

         delay(80);    //delay, but won't effect ISR
         Blit();       //swap buffers
         }
       }   // End main

       void loop() //just sitting here
       {}
     
     
    Last edited: Feb 15, 2016
  16. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    You may have to wait for my conversion.... Arduino is more C++ than C...
     
    • Informative Informative x 1
  17. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Bah, I confuse C and C++ between eachother. When I started this hobby, I was told that arduino would be easiest route so didn't really compare between PIC and arduino stuff
     
    Last edited: Feb 15, 2016
  18. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Ian, there are couple things what confuses, I mean what these mean:
    Code (c):
    frame += x*32;     //that +=
    const char* frame; // char*
    while (*ch )  //where it checks condition of *ch?
    (^those were in that code you gave earlier)
    shiftOut(dataPin, clockPin, LSBFIRST, x[i + shift > len - 1 ? i + shift - len : i + shift]); //Send the data #1       ( what data to draw) // this was in earlier problem but that ''?-symbol'' caught my eye, couldn't find it's meaning either...
    //edit: that ? symbol i at least found, smaller way for if/else:
      shiftOut(dataPin, clockPin, LSBFIRST, x[m]); //Send the data #1  ( what data to draw)
    if (i+ shift > len -1)
    {
    m=i+shift-len;
    }
    else
    {
    m=i+shift;
    }
     
     
    Last edited: Feb 15, 2016
  19. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    found this, but that pointer (*) is only thing now that i don't get even with ''simple'' examples
    Code (c):
    frame += x*32;     //that += is: frame = frame + x*32
     
    Last edited: Feb 15, 2016
  20. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    1) frame is 32 bytes long so "x*32" tells me where the frame x is so ...

    frame += x*32; really means frame = frame+ x*32...
    2) const char* frame; pointer to a constant char.... or a rom character
    3) while(*ch) this means while ch is pointing to something.... When ch points to '0' it will stop!

    I don't recognize the other bits..
     
    • Thanks Thanks x 1
  21. fezder

    fezder Well-Known Member

    Joined:
    Dec 11, 2011
    Messages:
    1,665
    Likes:
    100
    Location:
    Mikkeli, Finland
    Ugh, this is tedious problem....perhaps it wasn't wise to chain all together, all I've gotten is some random leds lit, nothing that would make sense
     
    Last edited: Feb 15, 2016

Share This Page