#include <SD.h>

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

/*#define I2C_ADDR    0x20*/

#define I2C_ADDR    0x27

// initialize the library with the numbers of the interface pins

//LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

#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);

//#define  LED_OFF  0

//#define  LED_ON  1

const int chipSelect = 53;

const uint8_t spiSpeed = SPI_FULL_SPEED;

File myFile;

byte inData[140]; // Allocate some space for the string

int index = 0; // Index into array; where to store the character

byte inbyte = 0;

byte enrich =0;

signed int accelenrich=0;

float accelenrich1=0;

unsigned int gair=0;

unsigned int mat=0;

float mat1=0;

int ase=0;

int running=0;

//int warmup=0;

unsigned int wue=0;

int wue1=0;

int idle=0;

//int n=0;

unsigned int gamma=0;

int accel=0;

int decel=0;

unsigned int clt = 0;

float clt1=0;

unsigned int ve = 0;

float ve1=0;

int waitsd=0;

unsigned int kpa1 =0;

float kpa2 =0;

unsigned int pulsewidth1=0;

float pulsewidth2=0;

unsigned int rpm1=0;

unsigned int xtime1=0;

unsigned int xtime2=0;

unsigned int afrt1=0;

float afrt2=0;

unsigned int egocorrect=0;

signed int afrnew=0;

float afrnewf=0;

unsigned int adv1=0;

float adv2=0;

unsigned int batt1=0;

float batt2=0;

signed int mapdot=0;

int sdstop=0;

unsigned int synccnt=0; //94

unsigned int syncreason=0; //139

void setup()

{

  lcd.begin(20, 4);

  lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);

//  lcd.setBacklight(HIGH);

  lcd.setBacklight(1);

  Serial.begin(9600);

  Serial.println("Rebooted");

  Serial1.begin(115200);

  if (!SD.begin(chipSelect)&&(sdstop==0)) {

    Serial.println("Card failed/!present");

    lcd.setCursor(0,0);

    lcd.print("sd cockup");

    delay(5000);

    sdstop=1;

    // don't do anything more:

    return;

  }

  if (sdstop==0)

  {

      printsdindextab();

  }

  lcd.setCursor(0,0); //begins intro splash screen

  lcd.clear();

  //try print units 1x only

  lcd.setCursor(18,0);//egocorrect

  lcd.print("%");

  lcd.setCursor(3,1);//ve

  lcd.print("%");

  lcd.setCursor(18,1);//battvolt

  lcd.print("v");

  lcd.setCursor(10,1);//pw

  lcd.print("ms");

  lcd.setCursor(18,2);//gair

  lcd.print("%");

  lcd.setCursor(5,2);//rpm

  lcd.print("rpm");

  lcd.setCursor(11,3);//mat

  lcd.print("c");

  lcd.setCursor(18,3);//gamma

  lcd.print("%");

}

void loop()

{

  //setting some parameters to meet for printing into serial for arduino serial monitor or putty to be saved and logged for looking at

  //specific conditions

  if ((rpm1>500)&&/*(hirpm<rpmlessthan)&&*/(kpa2>10)/*&&(kpareal<kpaupperlimit)&&(readingavg<18)*/)

  {

    //    sprint(); //call for serial print

    //     running=1; //simulate test condition

    //    if (running==1)

    if (/*(running==1)&&*/(!SD.begin(chipSelect)&&(sdstop==0))) //call for write data to sd card

    {

  //        waitsd=1;

          filing();

      //end of writing file

    }

    /*else

    {

      waitsd=0;

    }*/

  }

  /*else

  {

    waitsd=0;

//    lcd.setCursor(4,1);

  }*/

  index=0;

  Serial1.write("A"); // calling data from megasquirt. Array of 169 items to be received

  while(Serial1.available()<20)

  {

    //waiting for buffer to fill;

  }

  Serial.println(Serial1.available());

//  delay(8);

  if (Serial1.available() >0)

  {

    delay(15);

    for(index=0;index<140;index++)//trying 70 elements

    {

      inData[index] = Serial1.read(); // Read a character

    //  delay(1); //is delay necessary?

    }

    Serial1.flush();

   

    processserialdata();

    processdisplay();

    serialprint();

/*    if(Serial) //for arduino ide 1.01

    {

    }

    */

   

    inData[index] = '\0'; // Null terminate the strinG

  }

  delay(10);

//  delay(30-(waitsd*sddelay));

}

void  processserialdata()

{

  xtime1  =(inData[0] << 8 ) | (inData[1]);

  //xtime2 = xtime1/256;

  pulsewidth1 =(inData[2] << 8) | (inData[3]);

  pulsewidth2=pulsewidth1*0.000666;

//  pulsewidth2=pulsewidth1/1500;

  rpm1 = (inData[6] << 8) | (inData[7]);

  adv1 = (inData[8] << 8) | (inData[9]);

  adv2 = adv1*0.1;

  //  adv2 = adv1/10;

  enrich=(inData[11]);

  afrt1= (inData[12]);

  afrt2= afrt1*0.1;

//  afrt2= afrt1/10;

  kpa1 = (inData[18] << 8) | (inData[19]);

  kpa2 = kpa1*0.1;

//  kpa2 = kpa1/10;

  mat = (inData[20] << 8) | (inData[21]);

  mat1 = ((mat-320)/18);

//  mat1 = (0.0555*(mat-320));

  clt = (inData[22] << 8) | (inData[23]);

  clt1 = ((clt-320)/18);

//  clt1 = (0.0555*(clt-320));

  batt1 = (inData[26] << 8) | (inData[27]);

  batt2=batt1*0.1;

//  batt2 = batt1/10;

  afrnew = (inData[28] << 8) | (inData[29]);

  afrnewf = afrnew*0.1;

//  afrnewf = afrnew/10;

  egocorrect = (inData[34] << 8) | (inData[35]);

  egocorrect = egocorrect/10;

//  egocorrect = egocorrect*0.1;

  gair = (inData[38] << 8) | (inData[39]);

  wue = (inData[40] <<8) | (inData[41]);

  accelenrich = (inData[42] <<8) | (inData[43]);

  accelenrich1=(accelenrich*0.1);

//  accelenrich1=(accelenrich*0.1);

  gamma = (inData[48] << 8) | (inData[49]);

  ve = ((inData[50] << 8)|(inData[51]));

  ve1=(ve*0.1);

//  ve1=(ve/10);

  mapdot =((inData[60] << 8)|(inData[61]));

  accel=bitRead(enrich,6);

  decel=bitRead(enrich,7);

  ase=bitRead(enrich,2);

  wue1=bitRead(enrich,3);

//  idle=bitRead(enrich,7);

  running=bitRead(enrich,0);      

  synccnt=(inData[94]);

  syncreason=(inData[139]);

}

void  processdisplay()

{

  //begin of line 0

  lcd.setCursor(0,0);

  if (synccnt!=0)

  {

    lcd.print("@");

  }

  else

  {

   // lcd.print(" ");

  }

  lcd.setCursor(1,0);

  if(kpa2>=94)

  {

    if(kpa2>=99)

    {

      lcd.print("ATM   ");

    }

    else

    {

      lcd.print("WOT   ");

    }

  }

  else

  {

    lcd.print(int(kpa2));

    lcd.setCursor(3,0);

    lcd.print(" kpa");      

  }

  lcd.setCursor(8,0);

  lcd.print(adv2,1);

  lcd.setCursor(12,0);    

  lcd.print(char(223));

  lcd.setCursor(15,0);

  if(egocorrect<100)

  {

    lcd.print(" ");

    //lcd.setCursor(16,0);

  }

  lcd.print(egocorrect);

/*  lcd.setCursor(18,0);

  lcd.print("%");*/

  lcd.setCursor(19,0);

  if(accel!=0)

  {

    lcd.print("A");

  }

  else if(decel!=0)

  {

    lcd.print("-");

  }

  else

  {

    lcd.print(" ");

  }

  // end of line 0

  //   start of line 1

  lcd.setCursor(1,1);

  if(ve1>12)

  {

    lcd.print(int(ve1));

  }

  else

  {

    lcd.print("00");

  }

 

/*  lcd.setCursor(3,1);

  lcd.print("%");*/

  lcd.setCursor(7,1);

  if(pulsewidth2==0)

  {

    lcd.print(" OFF  ");

  }

   

  if((pulsewidth2<10)&&(pulsewidth2>0))

  {

    lcd.print(" ");

    //lcd.setCursor(7,1);

  }

 

  if(pulsewidth2!=0)

  {

    lcd.print(pulsewidth2,1);

    lcd.setCursor(11,1);//pw

    lcd.print("ms");

  }

 

  lcd.setCursor(14,1);

  lcd.print(batt2,1);

/*  lcd.setCursor(18,1);

  lcd.print("v");*/

  lcd.setCursor(19,1);    

  if(ase==1)

  {

    lcd.print("A");

  }

  else if(ase==0)

  {

    lcd.print(" ");

  }

  //end of line 1

  //begin of line 2

  lcd.setCursor(1,2);

  if (rpm1<1000)

  {

    lcd.print("0");    

  }

  lcd.print(rpm1);

/*  lcd.setCursor(5,2);

  lcd.print("rpm");*/

  lcd.setCursor(9,2);

  if(clt1>88)

  {

    lcd.print("HOT");

  }

  else

  {

    lcd.print(int(clt1));

    lcd.setCursor(11,2);

    lcd.print("c");

  }

  lcd.setCursor(13,2);

  lcd.print("a");

  lcd.setCursor(15,2);

  if(gair<100)

  {

    lcd.print(" ");

  }

  lcd.print(gair);

/*  lcd.setCursor(18,2);

  lcd.print("%");*/

  lcd.setCursor(19,2);  

  if(wue1!=0)

  {

    lcd.print("W");

  }

  else

  {

    lcd.print(" ");

  }

  //end of line 2

  //begin of line 3

  lcd.setCursor(1,3);

  lcd.print(afrnewf,1);

  lcd.setCursor(5,3);

  if(afrnewf<14.7)

  {

    lcd.print("R");

  }

  else

  {

    lcd.print("L");

  }

  lcd.setCursor(9,3);

  lcd.print(int(mat1));

//  lcd.setCursor(11,3);

//  lcd.print("c  ");

  lcd.setCursor(13,3);

  lcd.print("G");

  lcd.setCursor(15,3);

  if(gamma<100)

  {

    lcd.print(" ");

  }

  lcd.print(gamma);

/*  lcd.setCursor(18,3);

  lcd.print("%");*/

/*  lcd.setCursor(19,3);

  if(idle==1)

  {

    lcd.print("I");

  }

  else if (idle==0)

  {

    lcd.print(" ");

  }*/

  //end of line 3

}

void  printsdindextab()

{

  myFile = SD.open("ms2.txt", O_WRITE | O_CREAT);

  if(myFile)

  {

    myFile.print("Time,");

    myFile.print("MAP,");

    myFile.print("RPM,");

    myFile.print("VE,");

    myFile.print("PW,");

    myFile.print("ADV,");

    myFile.print("Accel,");

    myFile.print("Decel,");

    myFile.print("Mapdot,");

    myFile.print("AccelEnrich,");

    myFile.print("IAT,");

    myFile.print("CLT,");    

    myFile.print("WUE,");

    myFile.print("Volt,");

    myFile.print("GAIR,");

    myFile.print("GAMMA,");

    myFile.print("EGOCORRECT,");

    myFile.print("AFR_TGT,");

    myFile.print("AFR_ACT,");

    myFile.println();

    myFile.flush();

    myFile.close();

 //   delay(50);

  }

  else

  {

    Serial.println("error opening ms2.txt for tab index printing");

    lcd.setCursor(0,0);

    lcd.print("iSD File missing");

    delay(5000);

  }

 

}

void  filing()

{

  myFile = SD.open("ms2.txt", O_WRITE | O_CREAT);

  if(myFile)

  {

//    myFile.print(xtime2);

    myFile.print(xtime1);

    myFile.print(",");

    myFile.print((kpa2));

    myFile.print(",");

    myFile.print(rpm1);

    myFile.print(",");

    myFile.print((ve1));

    myFile.print(",");

    myFile.print(pulsewidth2);

    myFile.print(",");

    myFile.print(adv2);

    myFile.print(",");

    myFile.print(accel);

    myFile.print(",");

    myFile.print(decel);

    myFile.print(",");

    myFile.print(mapdot);

    myFile.print(",");

    myFile.print(accelenrich1);    

    myFile.print(",");

    myFile.print(mat1);

    myFile.print(",");

    myFile.print(clt1);

    myFile.print(",");

    myFile.print(wue);

    myFile.print(",");

    myFile.print(batt2);

    myFile.print(",");

    myFile.print(gair);

    myFile.print(",");

    myFile.print(gamma);

    myFile.print(",");

    myFile.print((egocorrect));

    myFile.print(",");

    myFile.print(afrt2);

    myFile.print(",");

    myFile.print(afrnewf);

    myFile.println();

    myFile.flush();

    myFile.close();

//    delay(30);

   

   

    lcd.setCursor(4,1);

    lcd.print("%");

   

  }

  else

  {

    Serial.println("error opening ms2.txt for tab index printing");

    lcd.setCursor(0,0);

    lcd.print("SD File missing");

    delay(5000);

  }

}

void  serialprint()

{

  Serial.print("Time:");

  Serial.print(xtime1);

  Serial.print("s ");

  Serial.print("MAP:");

  Serial.print((kpa2));

  Serial.print(" kpa ");

  Serial.print("VE:");

  Serial.print((ve1));

  Serial.print("% ");

  Serial.print("Pulsewidth:");

  Serial.print(pulsewidth2);

  Serial.print("ms ");    

  Serial.print("RPM:");

  Serial.print(rpm1);  

  Serial.print(" rpm ");

  Serial.print("adv:");

  Serial.print(adv2);

  Serial.print(" deg ");

  Serial.print("Accel:");

  if(accel==1)

  {

    Serial.print("A ");

  }

  else if(decel==1)

  {

    Serial.print("D ");

  }

  else

  {

    Serial.print("  ");

  }

 

  Serial.print("IAT:");

  Serial.print(mat1);    

  Serial.print(" degC ");

  Serial.print("CLT:");

  Serial.print(clt1);

  Serial.print(" degC ");

  Serial.print("WUE:");

  Serial.print(wue);

  Serial.print("% ");

  Serial.print("Voltage:");

  Serial.print(batt2);

  Serial.print(" V ");

  Serial.print("GAIR:");

  Serial.print(gair);

  Serial.print("% ");

  Serial.print("GAMMA:");

  Serial.print(gamma);

  Serial.print("EGOCorrect:");

  Serial.print(egocorrect);

  Serial.print("% ");

  Serial.print(" AFR Tgt:");

  Serial.print(afrt2);

  Serial.print(" ");

  Serial.print("AFR Actual:");

  Serial.print(afrnewf);

  Serial.println();

}