/*
Programed by Peter Bell
Written for fun.
Calculates the calibration switch settings (Dil switch) for a Veeder Root 8400
or Keinzle 1318 tachograph.
*/
#include <LiquidCrystal.h> // get the lcd include file so we can use the lcd
#include <Keypad.h> // get the keypad include file so we can use the keypad
long K; // variable to store the tachograph K factor
float decimal; // Decimal value to be converted to binary switches
bool cflag; // comma flag (0 before first dil is printed, 1 after first printed value)
float power; // 2 to the power of the dil switch number being processed
const long product=4192000; // K times the binary value of the switch setting (in decimal)
// keybard parameters and definitions
const uint8_t ROWS = 4; // number of rows in the keyboard
const uint8_t COLS = 4; // number of collumns in the keypad
char keys[ROWS][COLS] = { // the keypad charater matrix (there are 4 nul keys)
{ 1, 2, 3, ' ' }, // top row numbers 1 to 3 and a null
{ 4, 5, 6, ' ' }, // 2nd row numbers 4 to 6 and a null
{ 7, 8, 9, ' ' }, // 3rd row numbers 7 to 9 and a null
{ '0', ' ', 'D', 'C' } // 4th row number 0, a null D for delete and C for clear
};
// note that American Standard Code for Information Interchange (ASCII)
// is used for zero, as zero would be interpreted as no key pressed
uint8_t colPins[COLS] = { A3, A2, A1, A0 }; // Pins connected to collumns 1 to 4
uint8_t rowPins[ROWS] = { 5, 4, 3, 2 }; // Pins connected to rows 1 to 4
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// make the keyboard map used by keyboard.h from the above information
LiquidCrystal lcd(12, 11, 10, 9, 8, 7); // define the pind used by the display to LiquidCrystal.h
void setup() // initial setup procedure
{
lcd.begin(20, 4); // set up the LCD as 4 rows of 20 collumns
lcd.print("K factor switch "); // display te first line of the startup message
lcd.setCursor(0,1); // position the cursor at the start of the second line of the display
lcd.print("settings calculator"); // display the second line of the startup message
delay(2000); // conrtinue displaying the startup message for 2 seconds
lcd.clear(); // then clear the display
lcd.setCursor(0,0); // and set the cursor to the start of the display (probably not neccessary)
lcd.print("Enter K factor"); // ask the user to enter the K factor
}
void loop() // the main program loop, runs and repeats continuously
{
lcd.setCursor(17,1); // position the cursor at tposition 17 of the second line of the display
lcd.blink(); // blink the cursor to show ready for data
char key = keypad.getKey(); // get the value of any pressed key from keyboard.h
if (key != NO_KEY) // test to see if it is non zero (i.e. has a key been pressed)
{
lcd.setCursor(0,1); // yes, so a key has been pressed
lcd.print(" ");// so blank the second line of the display
switch (key) // test the value of the key
{
case 'D': // is it D?
{
K=K/10; // yes so delete the last number entered by dividing K by 10
} // discarding rthe remainder from the division (integer division)
break; // end of section for D
case 'C': // is it C?
{
K=0; // yes, so clear the value of K to zero
}
break; // end of section for C
case ' ': // is it a null?
{ // yes so ignore it
}
break; // end of section for null
default: // come here if not C D or null character (it must therefore be a number)
{
if (key=='0' ) // test if it is ascii code for 0 (0 would be interpreted as no key pressed)
{
key=0; // yes it is "0" so change it to 0
}
if (K>=99999) // test if K exceeds the maximum alowable value
{ // yes so ignore the number that has been pressed
}
else // K does not exceed the maximum allowable value
{
K=K*10+key; // so multiply the stored value of K by 10 and add the new key value
} // i.e. if K was 54 anf key was 7 the new value would be 547
}
break; // end of number processing section
}
lcd.setCursor(0,1); // position the cursor at the start of the second line of the display
lcd.print ("K factor is "); // and display "K factor is"
lcd.print(K); // and display the present value of K
if (K>=2401) // test if K is greater or equal to 2401
{ // valid K factor so
decimal=int(((float)product/K) +.5); // calculate the decimal value of dil switch setting
// integer value of 4192000 divided by K +.5 to give correct roundoff
lcd.setCursor(0,3); // position the cursor at thestart of the bottom line of the display
lcd.print(" "); // clear the bottom line of the display by writing 20 spaces to it
lcd.setCursor(0,2); // set the cursor to the start of the 3rd line of the display
lcd.print("Dil setting is "); // and print "Dil setting is "
if (K>=99999) // test if K is greater than max allowed value
{
lcd.setCursor(0,2); // if yes then display K factor too big message on bottom
lcd.print("K factor too large"); // two lines of the display
lcd.setCursor(0,3);
lcd.print("for practical use");
}
else // K value is good
{
convert(); // so convert it to switch numbers and sisplay them on the display bottom line
}
}
else // K is too low
{
lcd.setCursor(0,2); // so blank the bottom 2 lines of the display
lcd.print("K too low ");
lcd.setCursor(0,3);
lcd.print("for Tachograph ");
}
}
}
/*
Convert decimal number (decimal) no to tachograph dil switch setting
dil 10 maps to 1024 (2^10)
dil 9 maps tp 512 (2^9)
|
| (and so on)
| (until)
dil 1 maps to 2 (2^1)
*/
void convert()
{
lcd.setCursor(0,3); // set the cursor to the start od the bottom line of the display
cflag=false; // clear the comma flag
// a for loop that starts with I being made to 10
// then decreasing by 1 each time round the loop untill it reaches 0
// at which point the loop terminates
for (int I=10; I>0; I-- ) // for I is assigned the initial value of 10 decrease by 1 each time round
// until I has become 0
{
power=pow(2,I); // power is assigned 2 to the power I (i.e. if I=10 power becomes 1024)
if (decimal>power) // if the decimal value of the switch setting is greater than power
// then switch I has to be set and power is subtracted from the decimal value
{
if (cflag==true) // test the state of the comma flag (false if no switch numbers have been
// displayed so far)
{
lcd.print(","); // comma flag is true so display a comma (1 or more switches already displayed)
}
cflag=true; // we are about to display a switch number so set comma flag true
lcd.print(I); // display the current switch number (I)
decimal-=power; // decimal is made equal to decimal - power (remove the binary value of I from decimal)
} // completed procecinng current value of I
} // go back to the begining of the for loop after subtracting 1 from I
} // all done so return to main loop