/*Dwayne Cambridge */ /*Fermi National Accelerator Laboratory*/ /*Completed July 31, 2001*/ /* This program will act as a simple calculator. It will add, subtract, divide and multipy integer numbers only*/ #include /* Used to write to the serial port for the LCD */ #include #include #include #include #include #include float Result, /*Used to compute and store final result*/ NewOperands[50]; /*Array used to store results of *,/ when operator precedence is needed*/ int quit; /*Used to keep program running in an infinite loop*/ int flag, /*Flag used to indicate when operator precedence is needed*/ flag1, /*Flag used to indicate when * or / is seperated by + or -*/ Counter; /*Used as a counter for the NewOperands Array*/ struct termios portset; int contrast = 140; char device[256] = "/dev/lcd"; int speed = B19200; int temp; static int fd; char out[80]; char in[1],zero[1],nothing[1]; char zero_1[1]; ssize_t temp2; int number, /*Used to store numbers into Operands array*/ i, /*Used as an index*/ clear; /*Used as a flag to indicate user wants to clear LCD screen*/ int ind, /*Used as an index*/ indnum, /*Used as an index*/ indchar, /*Used as an index*/ start; /*Used to indicate when the first kew was pressed on the LCD*/ char Oper; /*Used indicate which operator was pressed*/ char TempOperands[10], /*Array used to store Operands as strings*/ *p_array; /*Used to convert strings to int */ float Operands[50], /*Used to store operands*/ TempOperands1[50]; /*Used to read in operands*/ char Operators[50], /*Used to store Operators */ TempOperators[50], /*Used to read in Operators */ All[200]; /*Used to track every key press on LCD by user*/ int Position, /*Used as index*/ row, /*Tracks row to write to on LCD screen*/ column, /*Tracks column to write to on LCD screen*/ digits, /*Used to determine how many digits to write to LCD screen*/ r, /*Tracks row to write to on LCD screen*/ c; /*Tracks column to write to on LCD screen*/ void ReadWriteInt(); void ClearScreen(); void Write_To_LCD(float num); void Initialize(); int InitializePort(); void InitializeLCD(); void OperandsOperators(); main() { /*Function used to initialize flags and values used to compute the final result*/ Initialize(); /*Function used to initialize and open the port for writing*/ temp = InitializePort(); if(temp == -1) { printf("\nPort not open\n"); quit = 0; } /*Function used to Initialize the LCD for writing*/ InitializeLCD(); while (quit == 1) { OperandsOperators(); /* Computing the result */ /*Do the following if only valid operators have been entered by the user*/ i = 0; flag1 = 0; if (quit == 1) { /*Loop through the Operators array until all valid Operators have been processed*/ while(Operators[i] != '=') { /*Check if Operator = /*/ if(Operators[i] == '/') { /*If Result is not equal to 1000000 then there has been a strind of *,/ */ /*Continue computing result using next operand (ex. 5+5*4/10)*/ /*This will detect if operator precedence is needed*/ if(Result != 1000000.0) { Result = Result / Operands[i+1]; /*Store result in NewOperands array, reset result, indicate*/ /*operator precedence is needed*/ if((Operators[i+1] == '+') || (Operators[i+1] == '-')) { NewOperands[Counter] = Result; Counter = Counter + 1; Result = 1000000.0; flag = 1; } /*If this is the last operator and no precedence is needed */ /*then do not change value of result (ex. 1/1/1)*/ if ((Operators[i+1] == '=') && (flag == 0)) { Result = Result; } /*If this is the last operator and precedence is needed then store result*/ else if(Operators[i+1] == '=') { NewOperands[Counter] = Result; Counter = Counter + 1; Result = 1000000.0; } } /*This is the begining of a new computation or this will compute values */ /*for operator precedence of an old computation */ /*(ex. will compute 5*4 first in (5+5*4/10) */ else { Result = Operands[i] / Operands[i+1]; /*If operator precedence exists*/ if (flag1 == 1) { if((Operators[i+1] != '*') && (Operators[i+1] != '/')) { NewOperands[Counter] = Result; Counter = Counter + 1; Result = 1000000.0; flag1 = 0; } } /*Store result of computations for *,/ and indicate operator precedence*/ else if((Operators[i+1] == '+') || (Operators[i+1] == '-')) { NewOperands[Counter] = Result; Counter = Counter + 1; Result = 1000000.0; flag = 1; } /*If this is the last operator and no precedence is needed */ /*then do not change value of result (ex. 1/1/1)*/ if ((Operators[i+1] == '=') && (flag == 0)) { Result = Result; } /*If this is the last operator and precedence is needed then store result*/ else if(Operators[i+1] == '=') { NewOperands[Counter] = Result; Counter = Counter + 1; Result = 1000000.0; } } } /*Check if Operator = * */ /*The following code (logic) operates the same for multiply as it did for divide*/ else if(Operators[i] == '*') { /*Continue computing string of *,/ (ex 5*4/10 in 5+5*4/10) and indicate operator precedence*/ if(Result != 1000000.0) { Result = Result * Operands[i+1]; if((Operators[i+1] == '+') || (Operators[i+1] == '-')) { NewOperands[Counter] = Result; Counter = Counter + 1; Result = 1000000.0; flag = 1; } /*End of valid operators, no precedence is needed*/ if ((Operators[i+1] == '=') && (flag == 0)) { Result = Result; } /*End of string and precedence is needed - store result*/ else if(Operators[i+1] == '=') { NewOperands[Counter] = Result; Counter = Counter + 1; Result = 1000000.0; } } /*Begining of computation or begining of string of *,/ */ else { Result = Operands[i] * Operands[i+1]; /*The computation has the following order: ex. 8*8+7*7+6*6 */ if (flag1 == 1) { if((Operators[i+1] != '*') && (Operators[i+1] != '/')) { NewOperands[Counter] = Result; Counter = Counter + 1; Result = 1000000.0; flag1 = 0; } } /*The next Operator is + or - */ else if((Operators[i+1] == '+') || (Operators[i+1] == '-')) { NewOperands[Counter] = Result; Counter = Counter + 1; Result = 1000000.0; flag = 1; } /*Reached the end of the computation and no precedence is necessary */ if ((Operators[i+1] == '=') && (flag == 0)) { Result = Result; } /*Reached the end of the computation and precedence is necessary */ else if(Operators[i+1] == '=') { NewOperands[Counter] = Result; Counter = Counter + 1; Result = 1000000.0; } } } /* The current operator is not equal to * or / */ /* The following logic will create the NewOperands array as well as set flags */ else { if (i==0) { if((Operators[i+1] == '*') || (Operators[i+1] == '/')) flag = 1; NewOperands[Counter] = Operands[i]; Counter = Counter + 1; if((Operators[i+1] == '+') || (Operators[i+1] == '-')) { if((Operators[i+2] == '*') || (Operators[i+2] == '/')) { NewOperands[Counter] = Operands[i+1]; Counter = Counter + 1; } } } else if((Operators[i-1] == '*') || (Operators[i-1] == '/')) { if((Operators[i+1] == '*') || (Operators[i+1] == '/')) { Result = 1000000.0; flag1 = 1; } else if((Operators[i+1] == '-') || (Operators[i+1] =='+')|| (Operators[i+1] == '=')) { NewOperands[Counter] = Operands[i+1]; Counter = Counter + 1; } } else if((Operators[i-1] == '+') || (Operators[i-1] == '-')) { if((Operators[i+1] == '+') || (Operators[i+1] == '-') || (Operators[i+1] == '=')) { if (i == 1) { NewOperands[Counter] = Operands[i]; Counter = Counter + 1; } else { NewOperands[Counter] = Operands[i+1]; Counter = Counter + 1; } } else if((Operators[i+1] == '*') ||(Operators[i+1] == '/')) { if (flag == 0) { Result = 1000000.0; flag = 1; if(i != 1) { NewOperands[Counter] = Operands[i]; Counter = Counter + 1; } } else { Result = 1000000.0; /*NewOperands[Counter] = Operands[i]; Counter = Counter + 1;*/ flag = 1; } } } else { NewOperands[Counter] = Operands[i+1]; Counter = Counter + 1; } } i = i+1; } /*If there is precedence then reset the result and use the */ /*NewOperands array to compute the result */ if(flag == 1) Result = 1000000.0; Counter = 0; /*Printing for testing purposes for(i=0; i<10; i = i+1) printf("%f ", NewOperands[i]); printf("\n"); for(i=0; i<20;i=i+1) printf("%c ", All[i]); printf("\n"); printf("the flag = %d\n", flag); */ i = 0; /* Loop through Operator array */ while(Operators[i] != '=') { /*If precedence exists compute the result using the NewOperands array*/ if(flag == 1) { if (Operators[i] == '+') { if(Result == 1000000.0) { Result = NewOperands[Counter] + NewOperands[Counter+1]; Counter = 2; } else { Result = Result + NewOperands[Counter]; Counter = Counter + 1; } } else if (Operators[i] == '-') { if(Result == 1000000.0) { Result = NewOperands[Counter] - NewOperands[Counter+1]; Counter = 2; } else { Result = Result - NewOperands[Counter]; Counter = Counter + 1; } } } /*If precedence does not exist then the computation only */ /*is composed of + and -. Use the Operands array to compute the result*/ else { if (Operators[i] == '+') { if(Result == 1000000.0) { Result = Operands[i] + Operands[i+1]; } else { Result = Result + Operands[i+1]; } } if (Operators[i] == '-') { if(Result == 1000000.0) { Result = Operands[i] - Operands[i+1]; } else { Result = Result - Operands[i+1]; } } } i = i+1; } } /*Print the result to the screen*/ /*Write the result to the LCD screen*/ /*Indicate result written in All array*/ if(quit == 1) { printf("> %f\n", Result); Write_To_LCD(Result); All[Position] = '$'; Position = Position + 1; printf("> "); } /*Reset the calculator if port was not opened*/ /*Set into an infinite loop*/ if (quit == 0) quit = 1; } /*Close the Port */ close (fd); } /*Used to initialize flags and values used to compute the result */ void Initialize() { /*Go to Position: Column 1 Row 1 */ sprintf (out, "%cG%c%c", 254, 1, 1); write(fd,out,4); /*Print the Result */ sprintf (out, "%c", "Ready"); write(fd,out,5); /*When quit = 0 Port was not opened*/ quit = 1; number = -1; start = 1; clear = 0; Position = -1; row = 1; column = 1; digits = 0; r = 0; c = 0; /*Indicates a new computation*/ Result = 1000000.0; } /*Used to open the port */ int InitializePort() { /*Open and set port for writing*/ fd = open (device, O_RDWR | O_NOCTTY); if (fd == -1) { fprintf (stderr, "InitializePort: failed (%s)\n", strerror (errno)); printf ("InitializePort: failed (%s)\n", strerror (errno)); return -1; } tcgetattr (fd, &portset); cfsetospeed (&portset, speed); cfsetispeed (&portset, speed); cfmakeraw (&portset); tcsetattr (fd, TCSANOW, &portset); } /*Used to Initialize the LCD for writing */ void InitializeLCD() { /*Go to Position: Column 1 Row 1 */ sprintf (out, "%cG%c%c", 254, column, row); write(fd,out,4); /*Clear Key Buffer*/ sprintf(out, "%cE", 254); write(fd,out,2); /*Turn AutoTransmit Keypresses Off*/ sprintf (out,"%cO", 254); write(fd,out,2); sprintf (nothing,"%c",0); ClearScreen(); } /* Used to read in Operators and Operands from the LCD and store them into appropriate arrays*/ void OperandsOperators() { /*Clear and Initialize all arrays used to compute the result*/ for(i=0; i<50; i++) Operands[i] = -1; for(i=0; i<50; i++) NewOperands[i] = -1; for(i=0; i<50; i++) TempOperands1[i] = -1; for(i=0; i<50; i++) Operators[i] = '$'; for(i=0; i<10; i++) TempOperands[i] = ' '; for(i=0; i<50; i++) TempOperators[i] = '$'; for(i=0; i<200; i++) All[i] = '$'; i = 0; flag = 0; Counter = 0; start = 1; /*Loop until the user enters an = on the LCD */ while (TempOperators[indchar] != '=') { /* Call the function that interfaces with LCD */ ReadWriteInt(); /* If the clear button was pressed on the LCD, then clear and initialize all arrays*/ if(clear == 1) { ClearScreen(); for(i=0; i<50; i++) Operands[i] = -1; for(i=0; i<50; i++) NewOperands[i] = -1; for(i=0; i<50; i++) TempOperands1[i] = -1; for(i=0; i<50; i++) Operators[i] = '$'; for(i=0; i<10; i++) TempOperands[i] = ' '; for(i=0; i<50; i++) TempOperators[i] = '$'; for(i=0; i<200; i++) All[i] = '$'; number = -1; start = 1; Result = 1000000.0; } } /*Place operators in Operators array starting at position 0 if positioning is off*/ /*if positioning is off then the user has computed a result and it continuing with the computation*/ if(TempOperators[0] == '$') { for(i=0;i<50;i++) Operators[i] = TempOperators[i+1]; } else { for(i=0;i<50;i++) Operators[i] = TempOperators[i]; } /*Copy int values of operands into Operands array*/ for(i=0;i<50;i++) Operands[i] = TempOperands1[i]; /*If we are not reading in a negative number */ if(All[0] != '-') { if(Operands[0] == 0) Operands[0] = Result; } /*Printing for testing purposes for(i=0; i -10000000)) digits = 12; else if ((num <= -100000) && (num > -1000000)) digits = 11; else if ((num <= -10000) && (num > -100000)) digits = 10; else if ((num <= -1000) && (num > -10000)) digits = 9; else if ((num <= -100) && (num > -1000)) digits = 8; else if ((num <= -10) && (num > -100)) digits = 7; else if ((num <= -1 ) && (num > -10)) digits = 6; else if ((num < 0 ) && (num > -1)) digits = 5; else if ((num > 0 ) && (num < 1)) digits = 5; else if ((num >= 1 ) && (num < 10)) digits = 5; else if ((num >= 10) && (num < 100)) digits = 6; else if ((num >= 100) && (num < 1000)) digits = 7; else if ((num >= 1000) && (num < 10000)) digits = 8; else if ((num >= 10000) && (num < 100000)) digits = 9; else if ((num >= 100000) && (num < 1000000)) digits = 10; else if ((num >= 1000000) && (num < 10000000)) digits = 11; row = r+1; if(row == 5) { row = 1; ClearScreen(); } /*Go to Position: Column 1 Row 1 */ sprintf (out, "%cG%c%c", 254, column, row); write(fd,out,4); /*Print the Result */ sprintf (out, "%f", num); write(fd,out,digits); r = row; c = digits + 1; }