views:

330

answers:

3

I'm making a driver for an 8x8 LED matrix that I'm driving from a computer's parallel port. It's meant to be a clock, inspired by a design I saw on Tokyoflash.

Part of the driver is an array of 3*5 number "sprites" that are drawn to the matrix. A coordinate of the matrix is assigned to a coordinate of the sprite and so forth, until the entire sprite is drawn on it. This process is repeated for the other digit with an offset. I have verified I have drawn the sprites correctly, and that the matrix is blank when it is written to. However, when I draw a number on the matrix I get errant 1s at Numpad6 for the left digit, Numpad1 for the right (Example with the left digit not drawn.)

I have a week of experience in C and this is baffling me.

Here is the driver in full if you want to compile it yourself. It is nowhere near finished.

//8x8 LED MATRIX DRIVER VER 0.1 APR062009
//CLOCK 
// 
//  01234567
// 0    BXXXXXXH  B: Binary Mode Indicator 
// 1    DXXXXXXM  D: Decimal Mode Indicator
// 2    NNNNNNNN  H: Hour Centric Display
// 3    LLLNNRRR  M: Minute Centric Display
// 4    LNLNNRNR  X: Secondary Information 
// 5    LLLNNRRR  L: Left Digit
// 6    LNLNNRNR  R: Right digit
// 7    LLLNNRRR  N: Not Used

#include <stdio.h>
#include <unistd.h>
//#include <math.h>
#include <time.h>
#include </usr/include/sys/io.h>

#define BASEPORT 0x378

int main()
{
//Increasing array parameters to seems to reduce glitching [best 10 5 3]
int Dig[10][5][3] = {0};  //ALPHANUMERIC ARRAY [NUMBER (0..9)][Y(0..4)][X(0..2)]
int Mat[7][7] = {0};     //[ROW][COL], Top L corner = [0][0]
int Aux1[7] = {0};   //Topmost Row
int Aux2[7] = {0};     //Second to Topmost Row
int Clk; //Clock
int Wait; //Delay; meant to eventually replace clock in its current state
int C1;  //Counters
int C2;
int C3;
int L;   //Left Digit
int R;  //Right Digit
//break string left undefined atm

//ioperm (BASEPORT, 3, 1);
//outb(0, BASEPORT);
printf("Now running.\n");

//Set Variables

//3D DIGIT ARRAY [Num][Row][Col] (INITIALIZED BY INSTRUCTIONS)
 //Dig array is meant to be read only once initialized
 //3D arrays are unintuitive to declare so the numbers are 
 //"drawn" instead. 

//Horizontals
 //Some entries in the loop may have the variable in the middle
 //coordinate instead of the 3rd and/or with a +2. This is to 
 //incorporate the incomplete columns some numbers have (eg "2") and 
 //saves coding additional loops. 

for(C1=0; C1<=2; C1++){
Dig[0][0][C1]=1; Dig[0][4][C1]=1;
Dig[2][0][C1]=1; Dig[2][2][C1]=1; Dig[2][4][C1]=1; Dig[2][C1][2]=1; Dig[2][C1+2][0]=1;
Dig[3][0][C1]=1; Dig[3][2][C1]=1; Dig[3][4][C1]=1;
Dig[4][2][C1]=1; Dig[4][C1][0]=1; 
Dig[5][0][C1]=1; Dig[5][2][C1]=1; Dig[5][4][C1]=1; Dig[5][C1][0]=1; Dig[5][C1+2][2]=1;
Dig[6][0][C1]=1; Dig[6][2][C1]=1; Dig[6][4][C1]=1; Dig[6][C1+2][2]=1;
Dig[7][0][C1]=1;
Dig[8][0][C1]=1; Dig[8][2][C1]=1; Dig[8][4][C1]=1;
Dig[9][0][C1]=1; Dig[9][2][C1]=1; Dig[9][4][C1]=1; Dig[9][C1][0]=1;
}

//Verticals 

for(C1=0; C1<=4; C1++){
Dig[0][C1][0]=1; Dig[0][C1][2]=1;
Dig[1][C1][2]=1;
Dig[3][C1][2]=1;
Dig[4][C1][2]=1;
Dig[6][C1][0]=1;
Dig[7][C1][2]=1;
Dig[8][C1][0]=1; Dig[8][C1][2]=1;
Dig[9][C1][2]=1;
    }

Clk=10000;

L=2; //Think about incorporating overflow protection for L,R
R=4;

//Print Left Digit to Matrix @ (3, 0)

for(C1=0; C1<=4; C1++){    //For some reason produces column of 1s at numpad 6
 for(C2=0; C2<=2; C2++){  
 Mat[C1+3][C2]=Dig[L][C1][C2]; 
 printf("%d", Dig[L][C1][C2]);   //Debug
 }
printf(" %d %d %d\n", L, C1, C2); //Debug
}

//Print Right Digit to Matrix @ (3, 5)

for(C1=0; C1<=4; C1++){    //For some reason produces column of 1s at numpad 1
 for(C2=0; C2<=2; C2++){
 Mat[C1+3][C2+5]=Dig[R][C1][C2];
 }
}

//X Test Pattern

//for(C1=0; C1<=7; C1++){
// Mat[C1][C1]=5;  
// Mat[7-C1][C1]=5;
//}

usleep(Clk);

    //while(1){

//Breakfree [NOT FUNCTIONAL]

//Break_String=getch(); (Getch is not ANSI, need ncurses)

//if(Break_String != -1){
// if(Break_String = 27){
// break;
// }
//}  

//Terminal Display 

//for(C3=0; C3<=9; C3++){   //Debug Digit array [Successful, numbers draw correctly]
// for(C2=0; C2<=4; C2++){
//  for(C1=0; C1<=2; C1++){
//   printf("%d", Dig[C3][C2][C1]);
//  }
// printf("\n");
// }
//printf("\n");
//usleep(1000000); //Debug
//}

usleep(3000000); //Debug

for(C1=0; C1<=7; C1++){    //Prints to terminal every second, when looping 
 for(C2=0; C2<=7; C2++){
 printf("%d", Mat[C1][C2]);
 }
printf("\n");
}

printf("\n"); 

//Hardware Display

for(C1=0; C1<=29; C1++){    //30 Hz
 for(C3=0; C3<=7; C3++){    //COLUMN
  //printf("%d %d \n", C3, C1);  //Loop Debug
  usleep(1000);
  //CLOCK GROUND TO GO HERE, OUT STATUS
  //for(C2=0; C2<=7; C2++){  //PX
   //outb(Mat[C3][C2], BASEPORT);
  //}
 }
usleep(4*Clk);
}

//} 

//ioperm(BASEPORT, 3, 0);
exit(0);
}

Also, I had to make my Sprite array bounds each one bigger than they should have been to make it work. I figure this is all some some memory snafu but I'm nowhere near that proficient in C to know what to do.

I would greatly appreciate any help.

+8  A: 

I need to look through it more but one problem off the bat is that you're driving an 8x8 LED matrix but using a 7x7 matrix to hold the data. Declare your matrix as:

int Mat[8][8];
Devrin
I thought declaring it as [7][7] was okay since all array indices in C start at 0 and not 1?
Arrays in C are _indexed_ from 0, but declared using absolute sizes. Therefore to get at the last element of an array you declared as `array[8]` you'd say `x = array[7]`.
Devrin
What! Mat[7][7] is a 7x7 matrix ranging from Mat[0 .. 6][0 .. 6]
sharth
I agree with @sharth. When declaring a matrix you use absolute sizes.
Devrin
Consider the usual "int a[5]; for (i = 0; i < 5; ++i)" This works because it references a[0], a[1], a[2], a[3], and a[4], but not a[5]. Devrin and sharth are correct.
David Thornley
See http://gd.tuwien.ac.at/languages/c/programming-bbrown/c_034.htm for clarification.
Devrin
It was early, pre coffee.
Charlie Martin
+2  A: 

Bryan, I don't see the problem offhand, but what you're describing sounds like you are having an array indexing issue. (Rule of thumb, any time you think that there's something wrong with the computer causing your errors, you're mistaken.)

Two places new C programmers run into trouble with this is getting confused by 0 based indices -- an array of size 7 has indices from 0..6 -- and by not realizing that arrays are just laid out on top of one blob of memory, so an array that's [10][5][2] is really just one 100-cell piece of memory. If you make an indexing mistake, you can put things in what appear to be random places.

I'd go through the code and check what's where in smaller steps; what happens after one initialization, that sort of thing.

Charlie Martin
+3  A: 

Bryan, I think you are just missing the fundamental understanding of how array indices work in C.

When you declare

int array[N]

you access the elements in a range of

array[0] ... array[N-1]

which gives you a total of N elements.

For example:

int array[4]

gives you

array[0]
array[1]
array[2]
array[3]

for a total of 4 elements.

When looping over this array, this is the convention that's almost always used:

for(i = 0; i < 4; i++)

I think that this issue is causing multiple problems in your code and if you go back over your arrays after understanding this you'll be able to fix the problems.

17 of 26