Here the updated code. I will appreaciated that you guys look at it and tell me what you think.
/*
size : 2734 bytes
Calculator Version 1.5
Just add a number enter by the keypad and display it.
With 2 function : Add / Equal ===> * button
Clear ==> # button
It will use a MAX7219 for display the data ( for the shiftOut() ).
and a 4021 for the keypad input data with the use of
an NOT gate 74HC14. ( for the shiftin() )
See the keypad example in the tread for details.
The interrupt use a 72LS20 from the row pins, any LOW signal will
produce a HIGH pulse to be use has an interrupt signal.
By Serge J Desjardins
aka techone / tech37
Toronto, Ontario, Canada
Compile and Tested. Still Issues. Maybe it it the Keypad circuit. Not so clean
*/
// Keypad Serial pins
const byte latchkeypin = 10;
const byte datakeypin = 12;
const byte clockkeypin = 11;
// Display Serial pins
const byte datadisplaypin = 9;
const byte clockdisplaypin = 8;
const byte latchdisplaypin = 7;
// Anykey and interrupt pin
const byte anykeypin = 2;
// MAX7419 init data
word initdata[5] = { 0x0C01, 0x0F00, 0x0A0B, 0x0B07, 0x09FF };
// Fill the Display array with a blank code
word display_data[8] = { 0x0100, 0x020F, 0x030F, 0x040F, 0x050F, 0x060F, 0x070F, 0x080F };
// The digit array
byte digit_number[8] = {0,0,0,0,0,0,0,0};
// The second array - The total number
byte add_number[9] = {0,0,0,0,0,0,0,0,0};
// Key press keypad flag
volatile boolean keystate;
// Overflow flag
boolean over_flow;
// add button flag
boolean add_flag;
// Clear button flag
boolean clear_flag;
// The keypad data
byte keydata;
byte keynumber;
// The choice
byte choise;
void setup()
{
//start serial
//Serial.begin(9600);
//define the pins modes
pinMode(latchkeypin, OUTPUT);
pinMode(clockkeypin, OUTPUT);
pinMode(datakeypin, INPUT);
pinMode(datadisplaypin, OUTPUT);
pinMode(clockdisplaypin, OUTPUT);
pinMode(latchdisplaypin, OUTPUT);
pinMode(anykeypin, INPUT);
// setup the interrupt pin
attachInterrupt(0,anykeypress,RISING);
/* Init the MAX7419 : Normal Mode
Normal Operation
Setting the Intensity
Numbers of Digits being display
Set to Decode Mode
*/
for (int i=0;i<5;i++)
{
digitalWrite(latchdisplaypin, LOW);
shiftOut(datadisplaypin, clockdisplaypin, MSBFIRST, highByte(initdata[i]));
shiftOut(datadisplaypin, clockdisplaypin, MSBFIRST, lowByte(initdata[i]) );
digitalWrite(latchdisplaypin, HIGH);
delay(5);
}
// Blank the display
display_the_numbers();
// init the flags and the calculation variable
keystate = 0;
add_flag = 1;
over_flow = 0;
clear_flag = 1;
}
void loop()
{
while ( keystate == 0)
{
// wait for a key press
}
read_keypad();
convert_the_keypad_data();
// The choise 1 = numbers , 2 = add , 3 = clear
switch (choise)
{
case 1 :
entry_of_numbers();
break;
case 2 :
add_section();
break;
case 3 :
clear_section();
break;
}
}
// Choise 1
void entry_of_numbers()
{
// Enter the numbers routine
if ( over_flow == 0 )
{
if ( ( add_flag == 1) && ( clear_flag = 1 ) )
{
for (int i=0;i<8;i++)
{
digit_number[i] = 0;
display_data[i] = word ( ( i+1 ), 0x0F );
}
}
// Enter the key number and move the arrays data.
for (int i=7;i>0;i--)
{
digit_number[i] = digit_number[i-1];
display_data[i]=display_data[i-1];
display_data[i] = word ( (i+1) , lowByte( display_data[i] ) );
}
digit_number[0] = keynumber;
display_data[0] = word ( 1, keynumber );
display_the_numbers();
add_flag = 0;
clear_flag = 0;
keystate = 0;
}
}
// Choise 2 - the add section
void add_section()
{
// Check for the "Add / Equal" button
if ( over_flow == 0 )
{
for (int i=0;i<8;i++)
{
add_number[i] = add_number[i+1] + add_number[i] + digit_number[i];
if ((add_number[i] > 0x09) && (add_number[i] < 0x14) )
{
add_number[i+1] = 1;
display_data[i] = word ( ( i + 1 ), ( add_number[i] - 10 ));
}
else
{
display_data[i] = word ( ( i + 1 ) , add_number[i]);
}
}
// check for over flow
if ( add_number[8] != 0)
{
over_flow = 1;
digit_number[0] = 0;
display_data[0] = 0x010B;
for ( int i=1;i<8;i++)
{
digit_number[i] = 0;
display_data[i] = word( (i+1), 0x0F );
}
keystate = 0;
over_flow = 1;
add_flag = 1;
display_the_numbers();
}
else
{
keystate = 0;
over_flow = 0;
add_flag = 1;
display_the_numbers();
}
}
}
// Choise 3 - The clear section
void clear_section()
{
// Check for the "Clear" button
digit_number[0] = 0;
add_number[0] = 0;
display_data[0] = 0x0100;
for ( int i=1;i<8;i++)
{
digit_number[i] = 0;
add_number[i] = 0;
display_data[i] = word( (i+1), 0x0F );
}
add_number[8] = 0;
keystate = 0;
over_flow = 0;
add_flag = 1;
clear_flag = 1;
display_the_numbers();
}
//For troubleshooting the program using Serial Monitor
/*
Serial.print(keydata, BIN);
Serial.print(" ");
Serial.print(keydata, HEX);
Serial.print(" ");
Serial.print(keynumber, HEX);
Serial.print(" ");
Serial.println(keydata, DEC);
delay(1000);
*/
// Read keypad data via a 74HC14 - Inverter from the 4021
void read_keypad()
{
digitalWrite(latchkeypin,HIGH);
delayMicroseconds(20);
digitalWrite(latchkeypin,LOW);
keydata = shiftIn(datakeypin, clockkeypin,LSBFIRST);
}
// Convert the keypad data into BCD
// And a code for *, 0, # button
void convert_the_keypad_data()
{
byte what_row;
what_row = ( keydata >> 3) & 0x0F;
switch ( what_row)
{
case 1:
keynumber = ( ( keydata >> 1 ) & 0x03 ) + 1;
choise = 1;
break;
case 2:
keynumber = (( keydata >> 1 ) & 0x03 ) + 4;
choise = 1;
break;
case 4:
keynumber = (( keydata >> 1 ) & 0x03 ) + 7;
choise = 1;
break;
case 8:
special_key();
break;
}
}
// the display the data routine to the MAX7219
void display_the_numbers()
{
for (int i=0;i<8;i++)
{
digitalWrite(latchdisplaypin, LOW);
shiftOut(datadisplaypin, clockdisplaypin, MSBFIRST, highByte(display_data[i]) );
shiftOut(datadisplaypin, clockdisplaypin, MSBFIRST, lowByte(display_data[i]) );
digitalWrite(latchdisplaypin, HIGH);
delay(5);
}
}
// A special code for 0, *, # button
void special_key()
{
byte special_case;
special_case = ( ( keydata >> 1) & 0x03 ) + 1;
switch ( special_case )
{
case 1:
keynumber = 0x0E;
choise = 3;
break;
case 2:
keynumber = 0x00;
choise = 1;
break;
case 3:
keynumber = 0x0B;
choise = 2;
break;
}
}
// Interrupt Routibe
void anykeypress()
{
keystate = 1;
}