#include <LiquidCrystal_I2C.h>
#include<lcd.h>
#include <EEPROM.h>
#define I2C_ADDR 0x3F
#define BACKLIGHT_PIN 3
#define En_pin 2
#define Rw_pin 1
#define Rs_pin 0
#define D4_pin 4
#define D5_pin 5
#define D6_pin 6
#define D7_pin 7
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
//declaring variables
int hallpin=1;
int hallstate=0;
int hallcounter=0;
long odometer=0;
int tripmeter=0;
int servicemeter=0;
int rotationcounter=0;
int vspeed=0;
int dvspeed=0;
int tyrec=1935;
long deltat=0;
long timea=0;
long timec=0;
int b1pin=6;
int b1prevstate=HIGH;
int b1state=HIGH;
long b1timepressed=0;
long b1timereleased=0;
long b1holdtime=0;
int b1waspressed=0;
int speedrr=500;
const int speedarraysize=5;
int speedarray[speedarraysize];
int arrayposition=0;
int odoaddress=1;
int tripaddress=odoaddress+8;
int serviceaddress=odoaddress+15;
byte bar1[8] =
{
B11100,
B11110,
B11110,
B11110,
B11110,
B11110,
B11110,
B11100
};
byte bar2[8] =
{
B00111,
B01111,
B01111,
B01111,
B01111,
B01111,
B01111,
B00111
};
byte bar3[8] =
{
B11111,
B11111,
B00000,
B00000,
B00000,
B00000,
B11111,
B11111
};
byte bar4[8] =
{
B11110,
B11100,
B00000,
B00000,
B00000,
B00000,
B11000,
B11100
};
byte bar5[8] =
{
B01111,
B00111,
B00000,
B00000,
B00000,
B00000,
B00011,
B00111
};
byte bar6[8] =
{
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B11111,
B11111
};
byte bar7[8] =
{
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B00111,
B01111
};
byte bar8[8] =
{
B11111,
B11111,
B00000,
B00000,
B00000,
B00000,
B00000,
B00000
};
void setup() {
//declare LCD size
lcd.begin(16, 2);
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
attachInterrupt(hallpin, hallfunction, RISING);
pinMode(b1pin, INPUT_PULLUP);
addressselector();
lcd.createChar(1,bar1);
lcd.createChar(2,bar2);
lcd.createChar(3,bar3);
lcd.createChar(4,bar4);
lcd.createChar(5,bar5);
lcd.createChar(6,bar6);
lcd.createChar(7,bar7);
lcd.createChar(8,bar8);
/////////end of bigfont stuff
}
void loop() {
//check the speed
speedcheck();
//check if something is going on with the button
buttoncheck();
lcd.setCursor(10,0);
lcd.print(odometer);
lcd.setCursor(10,1);
lcd.print(tripmeter);
printlargespeed();
}
void hallfunction(){
vspeed=tyrec*3.6/(millis()-deltat);
timea=millis();
deltat=millis();
rotationcounter=rotationcounter+1;
}
void speedcheck(){
if (millis()-timea > 1000){
vspeed=0;
timea=millis();
}
if (millis()-timec >= speedrr/speedarraysize){
speedarray[arrayposition]=vspeed;
arrayposition=arrayposition+1;
if (arrayposition == speedarraysize){
arrayposition=0;
dvspeed=0;
for (int x=0; x<speedarraysize; x++)
{
dvspeed=dvspeed+speedarray[x];
}
/*
* The following line calculates the speed in km/h.
* If you want the speed in MPH change it into this:
* dvspeed=(dvspeed/speedarraysize)*0.621371192;
*/
dvspeed=dvspeed/speedarraysize;
}
timec=millis();
}
//actions after driving 1km
if (rotationcounter >= 1000000/tyrec){
odometer=odometer+1;
memorywrite(odoaddress, odometer);
tripmeter=tripmeter+1;
if (tripmeter > 999){
tripmeter=0;
}
memorywrite(tripaddress, tripmeter);
//call the wearleveller to reduce EEPROM wear
wearleveller();
rotationcounter=0;
}
}
void buttoncheck(){
b1state=digitalRead(b1pin);
if (b1state != b1prevstate){
if (b1state == LOW){
b1timepressed=millis();
b1waspressed=1;
}
if (b1state == HIGH){
b1timereleased=millis();
b1waspressed=0;
b1holdtime=b1timereleased-b1timepressed;
lcd.clear();
}
}
b1prevstate=b1state;
if (b1waspressed==1){
if (millis()-b1timepressed > 3000){
tripmeter=0;
memorywrite(tripaddress, tripmeter);
b1waspressed=0;
}
}
}
void addressselector(){
odometer=memoryread(odoaddress);
tripmeter=memoryread(odoaddress+8);
servicemeter=memoryread(odoaddress+15);
for (int pos=1; pos<252; pos=pos+25){
if (memoryread(pos)> odometer){
odoaddress=pos;
odometer=memoryread(pos);
tripaddress=pos+8;
tripmeter=memoryread(tripaddress);
serviceaddress=pos+15;
servicemeter=memoryread(serviceaddress);
}
}
}
void wearleveller(){
odoaddress=odoaddress+25;
tripaddress=tripaddress+25;
serviceaddress=serviceaddress+25;
if (odoaddress >= 250){
odoaddress=1;
tripaddress=odoaddress+8;
serviceaddress=odoaddress+15;
}
}
void memorywrite(int address, long value){
long val1=value/100000;
value=value-val1*100000;
long val2=value/10000;
value=value-val2*10000;
int val3=value/1000;
value=value-val3*1000;
int val4=value/100;
value=value-val4*100;
int val5=value/10;
int val6=value-val5*10;
EEPROM.write(address, val1);
EEPROM.write(address+1, val2);
EEPROM.write(address+2, val3);
EEPROM.write(address+3, val4);
EEPROM.write(address+4, val5);
EEPROM.write(address+5, val6);
}
long memoryread(int address){
long val1=EEPROM.read(address);
long val2=EEPROM.read(address+1);
int val3=EEPROM.read(address+2);
int val4=EEPROM.read(address+3);
int val5=EEPROM.read(address+4);
int val6=EEPROM.read(address+5);
long result=val1*100000+val2*10000+val3*1000+val4*100+val5*10+val6;
return result;
}
void printlargespeed(){
int c, d, u, number;
number = dvspeed;
if (number > 99) {
c = (number - (number % 100)) / 100;
number = number % 100;
} else {
c = 0;
}
if (number > 9) {
d = (number - (number % 10)) / 10;
number = number % 10;
} else {
d = 0;
}
u = number;
if (dvspeed <10){
lcd.setCursor(0,0);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(" ");
printNumber(u, 6);
}
if (dvspeed >= 10 && dvspeed < 100){
lcd.setCursor(0,0);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(" ");
printNumber(d, 3);
printNumber(u, 6);
}
if (dvspeed >= 100){
lcd.setCursor(0,0);
printNumber(c, 0);
printNumber(d, 3);
printNumber(u, 6);
}
}