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

How to make snake on LEd display....

Discussion in 'Microcontrollers' started by koolguy, Apr 2, 2013.

  1. misterT

    misterT Well-Known Member Most Helpful Member

    Joined:
    Apr 19, 2010
    Messages:
    2,697
    Likes:
    368
    Location:
    Finland
    When did snake change to a bouncing ball? Are you referring to some other thread with this?
     
  2. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    Sorry misterT..... If you are following the two threads on this forum AND the other three on AAC... You'll see there is MUCH more to this than snake...

    The main issue is animation on a 32x8 led matrix.... ( This in itself is a bit small for snake ) but I think it's the coding he wants....

    Here is the whole code just so you can see what he's up to..

    Code (text):

    #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 = 109;                          // 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);

            if(sx>27) xdir = -1;
            if(sy>4) ydir = -1;
            if(sx<0) xdir = 1;
            if(sy<0) ydir = 1;
            __delay_ms(80);
            Blit();
            }
        }   // End main
     
    I wrote it for him a while since.... The character "]" has been redefined as a "°"
     
  3. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Hi,

    I am doing this for better understanding the basing because code goes over my head!!
     
  4. dave

    Dave New Member

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


     
  5. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9

    Hi again,

    Please don't mind i think I should go in steps to learn first i should concentrate with basic program after that to huge program.....
    then my brain will work faster and efficient!
     
  6. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    OMG!! You think that's a huge program..... You want to see the code for my displays... Hundreds of functions...
     
  7. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Yes show....

    For me yes, because i have started uc few months back!!
    so, please tell ball bouncing in steps!
     
  8. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK

    No chance.... Its my professional stuff.... I was being facetious...
     
  9. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
     
  10. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    I'm trying to figure out what "steps" you are on about!!

    You draw a small circle..
    You display the small circle...
    You draw the small circle slightly moved..
    You display the small circle...

    If the small circle is touching the edge ( width or height ) ..
    make it go the other way....
    The circle will appear to bounce off the sides
     
  11. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    For this i have to shift the buffer, right?
     
  12. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    You are completely missing the point!!!!!

    Once you have your on screen buffer, which is exactly the same size as your screen, you can draw to the screen with any shape, line, text, etc...

    Imagine you have a blank square of paper.. You draw an image on the paper... You clear the paper quickly and redraw the image... Animation!!

    You don't have to worry about shifting the buffers... The buffers are just memory locations..

    There two are functions in my code... One is clr() and the other is blit() ... clr() clears the buffer and blit() puts the buffer onto the led..

    Lets assume I give you a routine to draw a circle ANYWHERE on the LED screen and any size ( even if its too big for the screen )..


    start a loop

    Code (text):
    for(x=1;x<16;x++)
       {
       clr(); // clear the buffer.
       circle(16,4,x,0);  // circle at 16, 4 with an 'x' radius..
       blit(); // redraw the LED screen.
       __delay_ms(100) // time to view.
       }
    what will appear on the LED display will be a dot right in the middle ( x=1).
    then it will draw the circle bigger and bigger clearing the LED's each loop so it looks like the circle grows until it cant be seen..

    circles.gif
     
  13. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Hi again,

    In this function how to make it i mean the four variable are used.......so, how to draw it?
     
  14. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    Try and write a circle routine yourself...

    Its quite easy to do...
     
  15. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    I have written the equation for circle:-
    X1= X-N AND X+1
    Y1=Y-N AND Y+N
    WHERE N=1,2,3,4........
    but how to fill the in memory buffer???
    as we do for char was simple but in this i am not getting how to do, pls help..
     
  16. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    The pixel routine writes to the correct memory location... Each routine.. Box, Line, Circle etc plots the positions then they call the pixel routine

    Once you have finished drawing onto the buffer, the bit function places the drawing onto the LED array.... I can't see why you don't get it!!
     
  17. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Here is the pixel routine now tell me how to do....
    once i will able to understand it i can do then myself...!
     
  18. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    You don't need to know what pixel does..... Pixel() puts a LED on or off at position x,y... the last parameter is condition... Or , Xor and AND..


    If you want the LED at co-ordinates 16, 4 ( centre), on the display to be lit... then you call...

    Code (text):
    pixel(16,4,0); // centre

    If you need a line from 0,0 to 7,7 then

    Code (text):
    pixel(0,0,0); // first
    pixel(1,1,0); // second
    pixel(2,2,0); // third
    pixel(3,3,0); // forth
    pixel(4,4,0); // fifth
    pixel(5,5,0); // sixth
    pixel(6,6,0); // seventh
    pixel(7,7,0); // eighth
    A diagonal line from 0,0 to 7,7 at 45°
     
  19. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    Now some darkness is removing from my brain but still need more info....
    Code (text):

    pix = pow[ pix];
    msk = backbuffer[tmp]; // get exsisting data
    why are you using pow array (1 2 4 8....) here???
    and what existing data are you talking about??
     
  20. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,164
    Likes:
    910
    Location:
    Rochdale UK
    Lets think about it....

    lets assume we are drawing a box from 0,0 to 15,7 creating a border right round the LED's...

    Now we print the letter 'A' at 1,1 ... You will destroy a portion of the box you have just made

    LED's off blank.png .. LED border boxed.png ..

    Drawing an 'A' preserving the data

    A masked.png

    Drawing an 'A' not preserving the data

    A unmasked.png

    If there is already data on the LED's You may want to preserve it.... so my routine takes a condition so you can make the relevant drawing..
     
    • Like Like x 1
  21. koolguy

    koolguy Active Member

    Joined:
    Aug 24, 2010
    Messages:
    2,196
    Likes:
    9
    ok then what is the use of pow. array here?
     

Share This Page