#include <SPI.h>
#include <LiquidCrystal.h>    //LCD
#include <SFE_BMP180.h>       //Tlakovy senzor
#include <Wire.h>             // I2C
LiquidCrystal lcd(4, 3, 5, 6, 7, 8); // LiquidCrystal(rs, enable, d4, d5, d6, d7) 

int x = 0;               // pocitanie cyklov programu


int CS=10;               //pin 10 Slave select
int RDY=9;               //pin 9 RDY
float nasobok=1E16;           //nasobic
word DATA16 =  0;
word ADCvalue = 0;       //aktualna hodnota napatia
byte data=0;
byte data1=0;
float A=0.0039083;
float B=-0.0000005755;
float U1,U2;
float k=0.0;
double D,T1,T2,RT1,RT2,CN;
float R=0.25;
double P=101325.00;
SFE_BMP180 pressure;
// BMP180 premenna
 
void setup()
{
  Serial.begin(115200); //inicializacia FTDI-RS232

  
  pinMode(CS,OUTPUT);   //nastavenie pinu CS ako vystupny
  
  lcd.begin(16, 2);
  
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);  //nastavenie SPI komunikacie
  SPI.setDataMode(SPI_MODE0);
  
  pressure.begin();          //nastavenie tlakoveho senzoru
    
  digitalWrite(CS, LOW);     // nizka uroven na pin CS (slave select)
    //----------------------nastavenie prevodnika---------------------------//
      
    SPI.transfer(0b00000111);  // dalsia operacia bude write do I/O Current registru 
    DATA16=0b0000001100000000; // hodnota nastavenia (tieto data sa zapisu do registru)  zapni Iout1 a Iout2
      data = highByte(DATA16);
    SPI.transfer(data);
      data = lowByte(DATA16);
    SPI.transfer(data);
    SPI.transfer(0b00000100); // dalsia operacia bude write do Filter registru
    SPI.transfer(0b00001101); // hodnota nastavenia (tieto data sa zapisu do registru )   
    SPI.transfer(0b00000001); // dalsia oepracia bude write do MODE register
    SPI.transfer(0b00000011); // hodnota nastavenia (tieto data sa zapisu do registru)   
    SPI.transfer(0b00000010); // dalsia oepracia bude write do ADC KONTROL registru
    SPI.transfer(0b10011100); // hodnota nastavenia (tieto data sa zapisu do registru )
    SPI.transfer(0b00000011); // dalsia oepracia bude write do AUX registru
    SPI.transfer(0b00000000); // hodnota nastavenia (tieto data sa zapisu do registru )
    
    //-----------------------nastavenie prevodnika-------------------------//
}


void loop()
{   
    teplota1();
    teplota2();
    tlak();
    CNparameter();

//---komunikacia---//    
 Serial.println(T1,3);
 Serial.println(T2,3);
 Serial.println(CN,10);
 Serial.println(P,3);
//---komunikacia---// 

    vypis();   
    x++; 


}


int vypis()
{
  if (x>3)                 //rychlost vypisu na display (kazde 3 cykly)
  {
  x=0;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(T1,2);
  lcd.setCursor(5, 0);
  lcd.print((char)223);    //znak Celzia
  lcd.setCursor(6, 0);
  lcd.print("C");
  
  lcd.setCursor(0, 1);
  lcd.print(T2,2);
  lcd.setCursor(5, 1);
  lcd.print((char)223);
  lcd.setCursor(6, 1);
  lcd.print("C");
 
  lcd.setCursor(8, 0);
  lcd.print(P,1);  
  lcd.setCursor(13, 0);
  lcd.print("hPa");
  
  //-----------------format CN----------------------------------//
  CN=CN/nasobok;
  lcd.setCursor(8, 1);
  
  if(CN>=1e-18 && CN<1e-17) {
      CN=CN*1e18;
      lcd.print(CN,1);
      lcd.print("E-18");
  }
  
 else   if(CN>=1e-17 && CN<1e-16) {
      CN=CN*1e17;
      lcd.print(CN,1);
      lcd.print("E-17");
  }
 else   if(CN>=1e-16 && CN<1e-15) {
      CN=CN*1e16;
      lcd.print(CN,1);
      lcd.print("E-16");
  }
 else   if(CN>=1e-15 && CN<1e-14) {
      CN=CN*1e15;
      lcd.print(CN,1);
      lcd.print("E-15");
  }

 else   if(CN>=1e-14 && CN<1e-13) {
      CN=CN*1e14;
      lcd.print(CN,1);
      lcd.print("E-14");
  }  
  
else   if(CN>=1e-13 && CN<1e-12) {
      CN=CN*1e13;
      lcd.print(CN,1);
      lcd.print("E-13");
  }
  
else    if(CN>=1e-12 && CN<1e-11) {
      CN=CN*1e12;
      lcd.print(CN,1);
      lcd.print("E-12");
  }
   
else    if(CN>=1e-11 && CN<1e-10) {
      CN=CN*1e11;
      lcd.print(CN,1);
      lcd.print("E-11");
  }
  
else   if(CN>=10e-10) {

      lcd.print("Overload");
  }
      
else  {
       lcd.print("Cn2-->0");  
      }
 

 
   //-----------------format CN----------------------------------//  
 }  
} 

float getADCvalue()
{               
    navrat:
    if (digitalRead(RDY)== LOW )
    {
     //-------------------------------------------------//
    SPI.transfer(0b01000101);       
    data=SPI.transfer(0);
    data1=SPI.transfer(0);
    //-------------------------------------------------//
 
    ADCvalue= data << 8;
    ADCvalue= ADCvalue | data1;
    return ADCvalue;   
    }
  else    
  goto navrat;
}


float teplota1()
{  
    k=0;
    //-------------------------------------------------//
    SPI.transfer(0b00000010); // dalsia oepracia bude write do ADC KONTROL registru
    SPI.transfer(0b11001100); // hodnota nastavenia (tieto data sa zapisu do registru ) Nastavnie MAIN ADC na pin AIN1 a AIN2
    //-------------------------------------------------//    
    delay(20);
    
    for(int i = 0; i < 5; i++)     // priemerovanie z 5 hodnôt
    {       
    k=k + getADCvalue();
    }
    
    U1=(k/5)*(0.32/65535);   //U=(k/10)*(0.64/65535);  
    RT1=(U1/0.0002246);                  // Prud IEX1 namerane 224.6uA pred kalib.
    D=(A*A)-(4*B*(1-(RT1/1000)));
    T1=(-A+sqrt(D))/(2*B);  
    return T1;
}


float teplota2()
{
    k=0;
    //-------------------------------------------------//
    SPI.transfer(0b00000010);          // dalsia oepracia bude write do ADC KONTROL registru
    SPI.transfer(0b11011100);          // hodnota nastavenia (tieto data sa zapisu do registru ) Nastavnie MAIN ADC na pin AIN3 a AIN4
    //-------------------------------------------------//
    delay(20);
    
    for(int i = 0; i < 5; i++)     // priemerovanie z 5 hodnot
    {       
    k=k + getADCvalue();
    }
    
    U2=(k/5)*(0.32/65535);
    RT2=(U2/0.00022827);                  // Prud IEX2 namerane 228.2uA (pred kalib.)
    D=(A*A)-(4*B*(1-(RT2/1000)));
    T2=(-A+sqrt(D))/(2*B);  
    return T2;             
}


float CNparameter ()
{
    float CT,Tavg,TA,TB;
    TA=273.15+T1;                                // Prevod na C na K
    TB=273.15+T2;
    Tavg=(TA+TB)/2;
    CT=((TA-TB)*(TA-TB))/(pow(R, (2/3)));   
    CN=pow(((0.000079*P)/(Tavg*Tavg)),2)*CT;     // tlak P je v hPa
    CN=CN*nasobok;                   //CN*1E+16
    return CN;
}


void tlak() 
{
  P = getPressure();  
}

double getPressure()
{
  char status;
  double T,P,p0,a;

  status = pressure.startTemperature();
  if (status != 0)
  {
    delay(status);
    status = pressure.getTemperature(T);
    if (status != 0)
    {
      status = pressure.startPressure(3);
      if (status != 0)
      {
        delay(status);
        status = pressure.getPressure(P,T);
        if (status != 0)
        {
          return(P);
        }
        else Serial.println("error retrieving pressure measurement\n");
      }
      else Serial.println("error starting pressure measurement\n");
    }
    else Serial.println("error retrieving temperature measurement\n");
  }
  else Serial.println("error starting temperature measurement\n");
}
