//----------KNIHOVNY----------
#include <U8glib.h>
#include <Wire.h>
#include <DS1307.h>
#include <SD.h>
#include <EEPROM.h>

//----------NASTAVEN PIN DISPLEJE----------
U8GLIB_ST7920_128X64_1X u8g(2, 1, 0); //nastaven ovldacch pin displeje (CLK,MOSI,CS)

//---------NASTAVEN VELIKOSTI VODNHO LOGA----------
#define u8g_logo_width 128 //ka
#define u8g_logo_height 64 //vka

//----------VODN LOGO FAKULTY----------
static unsigned char u8g_logo_bits[] U8G_PROGMEM = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff,
  0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0xfc, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff,
  0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x03,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff,
  0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xf9, 0xff, 0xff, 0xff, 0x7f,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x7f, 0xf8,
  0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xfe, 0xff, 0x1f, 0xfc, 0x7f, 0xf8, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x0f, 0xfc, 0x3f, 0xe0, 0xff, 0x7f,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x07, 0xfe,
  0x3f, 0xc0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xfe, 0xff, 0x03, 0xfe, 0x1f, 0xc0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x01, 0xff, 0x0f, 0x80, 0xff, 0x7f,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x00, 0xff,
  0x07, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xfc, 0x7f, 0x00, 0xff, 0x07, 0x00, 0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0xff, 0x03, 0x00, 0xfc, 0x7f,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7f, 0x80, 0xff,
  0x01, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xfc, 0x3f, 0x80, 0xff, 0x01, 0x10, 0xfc, 0x3f, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f, 0x80, 0xff, 0x00, 0x1f, 0xf8, 0x3f,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0xff,
  0xc0, 0x1f, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xf8, 0x1f, 0x80, 0x7f, 0xf0, 0x0f, 0xf8, 0x3f, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0x7f, 0xfe, 0x0f, 0xf8, 0x1f,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0xbf,
  0xff, 0x0f, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xf0, 0x1f, 0xc0, 0xff, 0xff, 0x07, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0xc0, 0xff, 0xff, 0x07, 0xf0, 0x1f,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1f, 0xc0, 0xff,
  0xff, 0x03, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xe0, 0x1f, 0xc0, 0xff, 0xff, 0x03, 0xf0, 0x0f, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0xc0, 0xff, 0xff, 0x01, 0xf0, 0x0f,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0xc0, 0x7f,
  0xfe, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0xe0, 0x1f, 0xc0, 0x1f, 0xfe, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0xc0, 0x07, 0x7f, 0x00, 0xf8, 0x07,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x3f, 0xc0, 0x00,
  0x7f, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x80, 0x7f, 0x00, 0x00, 0x3f, 0x00, 0xfc, 0x03, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0x00, 0x00, 0x1f, 0x00, 0xfc, 0x01,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00,
  0x1f, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0xff, 0x00, 0xf8, 0xff, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x01, 0xf8, 0xff, 0x01, 0xff, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x03, 0xf8,
  0x7f, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0xfc, 0x07, 0xf0, 0x3f, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xf0, 0x1f, 0xe0, 0x3f, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0xf0,
  0x0f, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0xf0, 0x7f, 0xe0, 0x03, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xe0, 0x01, 0xff, 0x0f, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff, 0xc7,
  0xe0, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff,
  0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x7f, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff,
  0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0xf8, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x0f, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xff,
  0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0xc0, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0x01, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe,
  0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
  0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00 };

void logo(void) {
  u8g.drawXBMP( 0, 0, u8g_logo_width, u8g_logo_height, u8g_logo_bits);
}

//----------PROMNN----------
unsigned long timeold; //as prletu
unsigned long vzdalenost; //stav tachometru
int rozdil; //asov rozdl
int rychlost; //vypoten rychlost
int rychlostold = 0; //rychlost pechozho otoen
char jedna[2]; //znak jednotek
char deset[1]; //znak destek
int rtc[7]; //pole sel pro ukldn asu
const int hall = 3; //pipojen hallovy sondy na pin 3
const int chipSelect = 4; //CS pro SD kartu
int nulovani = HIGH; //detekce pli dlouh doby bez prletu
char st[3]; //znak 100m
char je[4]; //znak 1km
char dv[5]; //znak 10km
char tr[6]; //znak 100km
char ct[7]; //znak 1000km
char pe[8]; //znak 10000km

byte stovky;
byte stovkyold;
byte jednicky;
byte jednickyold;
byte dvojky;
byte dvojkyold;
byte trojky;
byte trojkyold;
byte ctverky;
byte ctverkyold;
byte petky;
byte petkyold;

//----------NASTAVEN VSTUPNCH HODNOT----------
void setup() {  
  jedna[0] = 48; //zobrazen nuly
  rychlost = 0; //po sepnup nulov rychlost
  pinMode(hall, INPUT); //nastaven pinu hallovy sondy jako vstup
  pinMode(10, OUTPUT); //nco k SD kart
  nacteni_tacho(); //nacteni stavu tachometru z EEPROM do promnn vzdalenost
  tachometr(vzdalenost); //rozlo vzdalenost na jednotliv znaky  
  attachInterrupt(1, pricteni, FALLING); //nastaven peruen pro piten vzdlenosti
  //---------ZAHJEN KOMUNIKACE S SD---------
  if (!SD.begin(chipSelect)) {
    return;
  }
  //----------VYKRESLEN VODNHO LOGA----------
  u8g.firstPage();
  do {
    logo();
  } 
  while( u8g.nextPage() );

  delay(3000);
  
  //----------VYKRESLEN INFORMAC NA DISPLEJ----------
  u8g.firstPage();
  do {
    displej();
  } 

  while( u8g.nextPage() );
}

//----------NASTAVEN SMYKY---------
void loop(){

  //----------DETEKCE PRLETU MAGNETU
  if (digitalRead(hall) == LOW) {
    timeold = millis(); //zaznamenn asu prvnho prletu
    delay(53);    //zpodn, aby to sondu nechytlo dvakrt
    while(millis() - timeold <= 5168 && digitalRead(hall) == HIGH){  //ekn na hallovu sondu
    }
    rozdil = (millis() - timeold); //rozdl mezi prlety sondy
    rychlost = (5168/rozdil); //vpoet rychlosti ((v[mm]*3,6)/t[ms])
    tachometr(vzdalenost); //rozlo vzdalenost na jednotliv znaky
    jedna[0] = ((rychlost%10)+48); //jednotky rychlosti - zbytek po dlen 10 + 48 do znakov sady
    
    if(rychlost >= 95){ //pokud se sonda zastavila na hallov sond
      jedna[0] = 48; //zobraz nulu
      deset[0] = 32; //skryje prvn znak
      rychlost = 0; //nastav rychlost na nulu
      vzdalenost -= 144;  //odete vzdlenost co se naetla peruenm
    }
    else if(rychlost < 95 && rychlost >= 10){   //pokud bude men ne maximln avak stle dvoucifern
      deset[0] = ((rychlost/10)+48); //destky rychlosti - dlen 10 + 48 do znakov sady
    }
    else{ //pokud nebude rychlost dvoucifern
      deset[0] = 32; //skryje prvn znak
    }
    //----------ZAPSN NA SD KARTU JEN KDY SE ZMN RYCHLOST---------
    if(rychlost != rychlostold){ //vyhodnocen zmny rychlosti
      rychlostold = rychlost; //zape souasnou rychlost do pamti
      zapisSD(rychlost); //zpis na SD kartu
    }

    //----------VPIS RYCHLOSTI NA DISPLEJ---------
    u8g.firstPage();
    do {
      displej();
    } 
    while( u8g.nextPage() );

    rozdil = 0; //vynulovn asovho rozdlu
    timeold = millis(); //vynulovn starho asu aby bylo mon detekovat dlouhou dobu bez prletu
    nulovani = LOW; //zapne monost nulovn pi neinnosti
  }
  //----------DETEKCE PLI DLOUH DOBY BEZ PRLETU MAGNETU---------
  if(millis()- timeold >= 5168 && nulovani == LOW){
    //  Serial.println("Dlouho bez magnetu -> reset");
    rychlost = 0;
    jedna[0] = 48;
    deset[0] = 32;
    zapisSD(rychlost);
    nulovani = HIGH;
  //----------VPIS RYCHLOSTI NA DISPLEJ---------
    u8g.firstPage();
    do {
      displej();
    } 
    while( u8g.nextPage() );
  }

}
//----------FUNKCE PRO VYKRESLEN DISLEJE----------
void displej(void) {
  //rychlost
  u8g.setFont(u8g_font_courR18r);
  u8g.setColorIndex(1);
  u8g.drawStr( 55, 36, "km/h"); //npis km/h
  u8g.setColorIndex(0);
  u8g.drawBox(27,20,10,20);
  u8g.setColorIndex(1);
  u8g.drawStr( 25, 36, deset); //slo vlevo
  u8g.setColorIndex(0);
  u8g.drawBox(42,20,10,20);
  u8g.setColorIndex(1);
  u8g.drawStr( 40, 36, jedna); //slo vpravo
  //stav tacho
  u8g.setFont(u8g_font_courR12r);
  u8g.drawStr( 103, 62, je); //1
  u8g.drawStr( 93, 62, dv); //10
  u8g.drawStr( 83, 62, tr); //100
  u8g.drawStr( 68, 62, ct); //1000
  u8g.drawStr( 58, 62, pe); //10000
  //100m
  u8g.drawBox(115,49,10,20); 
  u8g.setColorIndex(0); 
  u8g.drawStr( 115, 62, st); 
}

//----------FUNKCE PRO ZPIS NA SD KARTU----------
void zapisSD(int rychlost){
  RTC.get(rtc,true);
  char cas[9];
  sprintf(cas, "%02d:%02d:%02d", rtc[2],rtc[1],rtc[0]);
  String dataString = ""; // inicializuje promnou pro data
  dataString = cas; // as do promn data
  dataString = dataString + ";"; // vhodn oddlova
  dataString = dataString + String(rychlost);
  File dataFile = SD.open("data.csv", FILE_WRITE);
  if (dataFile) {
    // samotn zpis - zape a sko na nov dek
    dataFile.println(dataString);
    dataFile.close();
  }  
}

//----------FUNKCE PRO ROZLOEN UJET VZDLENOSTI NA JEDNOTLIV ZNAKY + ULOEN DO PAMTI EEPROM
void tachometr(unsigned long vzdalenost){

  st[0] = ((vzdalenost/10000)%10+48);  
  stovky = ((vzdalenost/10000)%10);
  if(stovky != stovkyold){
    stovkyold = stovky;
    EEPROM.write(1, stovky);
  }

  je[0] = ((vzdalenost/100000)%10+48);
  jednicky = ((vzdalenost/100000)%10);
  if(jednicky != jednickyold){
    jednickyold = jednicky;
    EEPROM.write(2, jednicky);
  }

  dv[0] = ((vzdalenost/1000000)%10+48); 
  dvojky = ((vzdalenost/1000000)%10);
  if(dvojky != dvojkyold){
    dvojkyold = dvojky;
    EEPROM.write(3, dvojky);
  }  

  tr[0] = ((vzdalenost/10000000)%10+48);  
  trojky = ((vzdalenost/10000000)%10);
  if(trojky != trojkyold){
    trojkyold = trojky;
    EEPROM.write(4, trojky);
  }   

  ct[0] = ((vzdalenost/100000000)%10+48);
  ctverky = ((vzdalenost/100000000)%10);
  if(ctverky != ctverkyold){
    ctverkyold = ctverky;
    EEPROM.write(5, ctverky);
  } 

  pe[0] = ((vzdalenost/1000000000)%10+48);
  petky = ((vzdalenost/1000000000)%10);
  if(petky != petkyold){
    petkyold = petky;
    EEPROM.write(6, petky);
  }

}
//----------FUNKCE PRO NATEN TACHOMETRU Z PAMTI EEPROM
void nacteni_tacho(void){

  unsigned long sto = EEPROM.read(1);
  stovkyold = byte(sto);
  unsigned long jed = EEPROM.read(2);
  jednickyold = byte(jed);
  unsigned long dva = EEPROM.read(3);
  dvojkyold = byte(dva);
  unsigned long tri = EEPROM.read(4);
  trojkyold = byte(tri);
  unsigned long cty = EEPROM.read(5);
  ctverkyold = byte(cty);
  unsigned long pet = EEPROM.read(6);
  petkyold = byte(pet);
  vzdalenost = sto*10000+jed*100000+dva*1000000+tri*10000000+cty*100000000+pet*1000000000;
}

void pricteni()
{
  vzdalenost += 144;
}






