Continue to Site

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.

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

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

Status
Not open for further replies.

fezder

Well-Known Member
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....)
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:
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.
 
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)
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:
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.
 
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:
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!!
 
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
 
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..
 
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
 
Here is the code for my 4 8x8 matrices..
The animation and the font are separate files..

All done on a pic16f877a....
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:
Cool, I'll try to understand important bits , never even touched PIC's but at least that looks somewhat familiar.
 
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)
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:
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..
 
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:
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.
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:
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:
Ian, there are couple things what confuses, I mean what these mean:
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:
found this, but that pointer (*) is only thing now that i don't get even with ''simple'' examples
C:
frame += x*32;     //that += is: frame = frame + x*32
 
Last edited:
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..
 
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:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top