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.
nonsense! modding is always good idea! looks like conversion error, try casting: intA = (int)floatA;
have never tried it on a pointer though, (int) is the cast

array will be sized for full screen so 8*32 = array[256]
to move down a line newPOS=oldPOS +32;
my heat array is similar in that it is 16x4, the math to convert array to xy position is: pixel = (y*16) + x; so if i want pixel 56, that is y=3, x= 8.

I still fear c++ and all its semicolons. so this is just shot in dark.
Also, got schematic/ wire diagram of daisys and registers?
 
I meant that perhaps smaller would'been easier to tackle, but then again code-wise is same are there 1 or 100 matrises/registers chained, once principle is known.
I got those conversion errors out but as i said, nothing worthwhile comes on screen, but at least something; and it's only during startup, not same phase as ISR. I'll try to dig that code i had ''working''
 
oh, schematic that i do have: (sorry about inversed ground symbols.....they look like mushrooms)
8x_32_controller.jpg
 
Truth be told, I never knew there would be this much behind those matrises I see time to time and even bigger couple questions:
array will be sized for full screen so 8*32 = array[256]
is this array single or two-dimesnional? i suppose one is enough, but why i can't be
C:
array [32] =
{0,2,3,4,5,6,7,8,9,.........31};
^that are taken from other array (8-bits)
to move down a line newPOS=oldPOS +32;
so is whole screen refreshed without scrolling at all?
my heat array is similar in that it is 16x4, the math to convert array to xy position is: pixel = (y*16) + x; so if i want pixel 56, that is y=3, x= 8.
hmm, never worked with pixels, i did see mention of pixels in Ians code though
 
Last edited:
made a mistake there, since your pixel data is only 1 bit , on or off ,you can fit 8 pixel to a byte so you only need 32 array blocks, so your array actually only needs to be 32 byte, and each row is 8 byte long which would change new=old + 8 for scrolling; my last example is set up for a 256 bit color per pixel(multi-color),
so when you want to scroll, all you are doing is taking the info from each point x in the array and moving it over a few blocks so it rolls to next line.

some compilers/language can do 2d array, which looks similar to like this: array[4][8]; but i think we dont here cause its easier to code and more efficient when just rolling across the buffer, my example is more just to illustrate what its doing in there,.

with ians code , you are first inputting your strings and chars, the code takes that and rolls it out to the appropriate buffer pixel, with the timer interrupt, then taking the info from the buffer and writing to shift register.

pixel is just what I called MY variable in my example i used pixel as a variable in array[pixel] defining a point in the buffer and as example of how to decode a buffer to position,
in Ians code he is using the word pixel as a subroutine to write 1/0 to location x,y which is why it is written void pixel(signed char x,signed char y,int cond)
in reality it is best defined as a dot on a screen whether it be tvs, projectors or leds. in my led cube matrix (5x5x5x256), i used rgb leds which is why i have larger buffer.



My suspicion is that your and Ians hardware doesnt match, we would need him to confirm how he wired registers as well, my feeling is the shift registers are not aligned the same, try to modify code in void setup, change while(1) to:

unsigned char xxx; // add these two lines at the beginning of subroutine
unsigned char yyy;

while(1){ // this is what to replace while 1 with
clr();
for(yyy = 1;yyy<8; yyy++){
for(xxx = 1;xxx<32; xxx++){
pixel(xxx,yyy,1);
Delay10KTCYx(10);
}}}

this instruction should be able to light up each dot in order to see if the buffer matches, should write a dot one after other in row, per column, if they still light up randomly we may need to make few code tweaks.
 
Argh, had nice string of text here but firefox crashed....
But, as for that code, changed one bit as it gave error saying delay-thingy wasn't declared. Changed it to delay(10); and it now lights all leds, was intended so yes?
I'm not sure did i understood subroutine right, but at least it didn't gave errors.....
Funny, arduino and pic both use c-language but still different....
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 uint8_t* 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
   {
    unsigned char xxx; // add these two lines at the beginning of subroutine
unsigned char yyy;
    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){ // this is what to replace while 1 with
clr();
for(yyy = 1;yyy<8; yyy++){
for(xxx = 1;xxx<32; xxx++){
pixel(xxx,yyy,1);
delay(10);    //was Delay10KTCYx(10);
}}}
   }   // End main

   void loop() //just sitting here
   {}
 
Last edited:
This is what it looks like, one column is dead because there is bad slodering somewhere....
IMG_1132.jpg
 
yup good! but turn the delay wayy up, add a couple if you need,

delay(100);delay(100);delay(100);delay(100);delay(100);delay(100);delay(100);delay(100);delay(100);

ru sure about bad solder? it could be cause my code starts at xxx=1, not 0, or something similar somewhere else. since the code is protected from overflow, try this one:

while(1){
for(yyy = 0;yyy<9; yyy++){
for(xxx = 0;xxx<33; xxx++){
pixel(xxx,yyy,1);
delay(100);delay(100);delay(100);delay(100);delay(100);delay(100);delay(100);delay(100);delay(100);
}}}

the results of test will be in the order they light up.
 
I found one bad solder earlier and it was just hair-size, literally, found it by accident and long time of searching, I'm sure it's bad solder as that column is dead in all other skecthes too, like when I scroll text in all matrises same time.
Hmm, I tested that code and it is same result as earlier, still nothing moves in screen? not even flicker.
Same code, only that part is new, even tested with delay(1000); but nothing
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 uint8_t* 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
   {
    unsigned char xxx; // add these two lines at the beginning of subroutine
unsigned char yyy;
    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){
// clr(); tested with and without
for(yyy = 0;yyy<9; yyy++){
for(xxx = 0;xxx<33; xxx++){
pixel(xxx,yyy,1);   //placed delay(1000); too
delay(100);delay(100);delay(100);delay(100);delay(100);delay(100);delay(100);delay(100);delay(100);
}}}
   }   // End main

   void loop() //just sitting here
   {}
 
Last edited:
After a while running with that code, screen looks like this so something is happening (probadly overflow, but I don't see what overflows....):
IMG_1133.jpg
 
is that the full run? also were the pixles lighting up one after another, in a horizontal row one beside the other? did you stop it early? really at the end both codes should produce the same result.

also you can speed everything up by deleting some of those delays if you like,

as you can see i am just using that sub to hit each pixel individually for test, but wait , did you say screen is displaying text ok, or just random dots? or is the random dots you get while scrolling? is it just the scroll function that is not working? I seen the video, but wasn't that with the old code?
 
Nothing is slowly moving, lit or blinked, at first all are on and then after few minutes that other picture. I tested with other code to make sure micro and other stuff in controller is working so problem is in code
This i tested as scrolling all matrises same time: different code but this was just for test for controller circuit
In repeat, nothing moving is happening in your code, no matter what speed I set, or which of those while(1) variations i place
C:
//scrolls text with variable speed, or with set speed
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 timer;   
int timerPrev;
int shift;
int length = 100;
//int val; //used for speed select with potentiometer
//int section; //used for if/else instead of ?
uint8_t  text [] =  //text is 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
};

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

void loop()
{
  //int val = analogRead(A0);     //if set speed, comment this out
  timer = millis ();            //get time from current millis value
  if (timer - timerPrev > 200)    //chech if it is time
  {
    shift++;             //increment
    if (shift == length) //if enought shifts has happened
    {
    shift = 0;  //reset shift counter
    }
    timerPrev = timer;   //take timerprew from current time
  }
  for (int columns = 0; columns < 8; columns++)  //count columns for scanning
  {
    PORTD = B00000000;                                  //turn latch low
    shiftOut(dataPin, clockPin, MSBFIRST, 1 << columns);          //Send the data #2        (what columns to power)
    shiftOut(dataPin, clockPin, MSBFIRST, 1 << columns);          //Send the data #2        (what columns to power)
    shiftOut(dataPin, clockPin, MSBFIRST, 1 << columns);          //Send the data #2        (what columns to power)
    shiftOut(dataPin, clockPin, MSBFIRST, 1 << columns);          //Send the data #2        (what columns to power)
                                          //if bigger > smaller    true               false, smaller way for if/else
    shiftOut(dataPin, clockPin, LSBFIRST, text[columns + shift > length - 1 ? columns + shift - length : columns + shift]); //Send the data #1       ( what data to draw)
    /*
if (columns+ shift > length -1)
{
section=columns+shift-len;    //equilavent way for ?
}
else
{
section=columns+shift;
}
*/
    PORTD = B00001000;                                  //turn latch on->show screen
  }

}
 
Last edited:
oops again, i just noticed that ian put a clever little condition switch in there, we were using 1, he set msk to be the value in the array , using AND means we were doing a comparison type,

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
}



OK! use second code i gave you , might as well throw first one out, but change this line here, and use condition 3 instead:

pixel(xxx,yyy,3);


Ian: very cool trick there to incorporate overlay!
 
Hmm, it still does the same thing, but now i recalled one change i made in original code which Ian supplied, perhaps relevant now that searched:
C:
char power[8] = {128, 64, 32, 16, 8, 4, 2, 1};
power was pow, but if i change it back to pow(all powers to pow), i get error:
Code:
Arduino: 1.6.5 (Windows 7), Board: "Arduino Pro or Pro Mini, ATmega328 (5V, 16 MHz)"

sketch_jan07a:21: error: 'char pow [8]' redeclared as different kind of symbol
In file included from C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino/Arduino.h:26:0,
                 from sketch_jan07a.ino:1:
c:\program files (x86)\arduino\hardware\tools\avr\avr\include\math.h:316:15: error: previous declaration of 'double pow(double, double)'
extern double pow(double __x, double __y) __ATTR_CONST__;
               ^
sketch_jan07a.ino: In function 'void pixel(signed char, signed char, int)':
sketch_jan07a:43: error: invalid conversion from 'double (*)(double, double)' to 'char' [-fpermissive]
sketch_jan07a.ino: In function 'void charput(char, signed char, signed char)':
sketch_jan07a:70: error: invalid operands of types 'char' and 'double(double, double)' to binary 'operator&'
'char pow [8]' redeclared as different kind of symbol

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.
and here's code when that error comes, i was fool to change coloured stuff, but, mistakes happen:
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 pow[8] = {128, 64, 32, 16, 8, 4, 2, 1};   //here pow

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 = 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 uint8_t* 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 & pow[x1])  //here pow
        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
{
  unsigned char xxx; // add these two lines at the beginning of subroutine
  unsigned char yyy;
  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){
for(yyy = 0;yyy<9; yyy++){
for(xxx = 0;xxx<33; xxx++){
pixel(xxx,yyy,3);
delay(1000);delay(1000);delay(1000);delay(1000);delay(1000);delay(1000);delay(1000);delay(100);delay(100);
}}}
}   // End main

void loop() //just sitting here
{}
and again code, original what Ian posted, there are just couple mine own markings but they are comments:
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 either is true
   if(x<0 || y<0) return;       // outside drawing limits negative
   //if either is true
   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 = pix ^ msk
     pix ^= msk;           // XOR data to screen
   if (cond == 1)
     {
        //swaps 1's and 0's
     pix = ~pix;
     //pix = pix & msk
     pix &= msk;           // AND data to screen
     }
   if(cond == 0)
   //pix = pix | msk
     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 = ch - 0x20
   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 = frame + x*32
     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 = sx + xdir ; sy = sy +ydir
     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
and when i compile this, errors come as: (some are obvious like __delay__ms(80); not declared and those libraries/files missing, but figured to tell at least that pow-thingy, maybe it is inportant
C:
Arduino: 1.6.5 (Windows 7), Board: "Arduino Pro or Pro Mini, ATmega328 (5V, 16 MHz)"

Ian_s_Sketch.ino:1:16: fatal error: pic.h: No such file or directory
compilation terminated.
Error compiling.

  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.
 
Last edited:
try this, its the code in post 14, I fixed the cast issue(maybe!) , also its ok that you changed pow to power, because you did it everywhere, it is not the same as POW() in math.h:


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 char 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
{}
 
Hmm, still same output? strange that nothing changes, even you do lot of work to help out! Thanks :) I did change delays bigger but not even flicker
 
//sorry for wasting time, i seem to be off the ball today, reading upside down, and lots of dumb mistakes, odds are it is lang conversion issue, , , but here is one more shot!:


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}; //here pow

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] = 1; // apply changes
}

void charput(char ch, signed char x, signed char y)
{
signed char x1, y1;
const uint8_t* 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]) //here pow
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
{
unsigned char xxx; // add these two lines at the beginning of subroutine
unsigned char yyy;
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){
for(yyy = 0;yyy<9; yyy++){
for(xxx = 0;xxx<33; xxx++){
pixel(xxx,yyy,0);
delay(500);
}}}


} // End main

void loop() //just sitting here
{}
 
Helping isn't waste of time, but sadly that didn't help :/. personally I have no idea where to look lol...
 
i think i found it, as suspected there is hardware differences, looking closer at code. Ian was using portB on part of matrix, but you use additional shift register,which is different, right here:
ISR(TIMER1_COMPA_vect) // timer compare interrupt service routine, also i seen you cut out rc4 and rc3, which is how i think he was using shift register, but i have other question there too.

we will need to rewrite this sub to match your hardware config,,,brb!
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top