/*
 Author: Obrtac Tomas  
 Mail: obrtac.tomas@gmail.com
 2017
 */


#include <xc.h>
#include "SHT75.h"

uint16_t SHT_Read_Humidity(void)
{
    uint16_t humidity,i;
    Send_StartBit_SHT75(); // Communication starting with specific start bit
    s_Write_ByteSHT(0b00000101); // Command for reading humidity
    RELEASE_DATA;
    if (DATA == 1){
        __delay_ms(30); // Waiting for conversion
        while (DATA == 1);
    }
        if (DATA == 0){
            humidity = s_Read_ByteSHT(1); // MSB
            humidity = humidity << 8; // Shift left
            humidity += s_Read_ByteSHT(0); // LSB
        }
        CAPTURE_DATA;
        return humidity;
}

uint16_t SHT_Read_Temperature(void)
{
    uint16_t temperature,i;
    Send_StartBit_SHT75(); // Communication starting with specific start bit
    s_Write_ByteSHT(0b00000011); // Command for reading temperature
    RELEASE_DATA;
    if (DATA == 1){
        __delay_ms(30); // Waiting for conversion
        while (DATA == 1);
    }
        if (DATA == 0){
            temperature = s_Read_ByteSHT(1); // MSB
            temperature = temperature << 8; // Shifting left
            temperature += s_Read_ByteSHT(0); //LSB
        }
        return temperature;
}

float SHT75_Humidity(void)
{
    float humidity;
    uint16_t unconverted_value = SHT_Read_Humidity();
    while (unconverted_value == 0 ) unconverted_value = SHT_Read_Humidity(); // Read until we get a non-zero value
    humidity = -2.0468 + 0.0367 * (float)unconverted_value - 0.0000015 * pow (unconverted_value,2); // Formula for value conversion
    return humidity;
}

float SHT75_Temperature(void)
{
    float temperature;
    uint16_t unconverted_value = SHT_Read_Temperature(); 
    while (unconverted_value == 0 ) unconverted_value = SHT_Read_Temperature(); // Read until we get a non-zero value
    temperature = 0.01 * unconverted_value - 39.7; // Formula for value conversion
    return temperature; 
}

float SHT_Humidity_With_Compensation(float temperature)
{
    char uart[62];
    float true_humidity,humidity;
    humidity = SHT75_Humidity();
    uint16_t humidity_u = SHT_Read_Humidity();
    while (humidity_u == 0) humidity_u = SHT_Read_Humidity(); // Read until we get a non-zero value
    SCK_UP;
    RELEASE_DATA; // Setting the port as input to reduce power consumption
    return ((temperature -  (float)25)*( 0.01 + 0.00008 *humidity_u) + humidity); // Formula for value conversion
}

unsigned char s_Write_ByteSHT(unsigned char value)
{ 
    unsigned char i,error=0;  
    for (i=0x80;i>0;i/=2)             // Shift bit for masking
    { 
        if (i & value) RELEASE_DATA;          // Masking value with i , write to SENSI-BUS
    else {
            LOW_DATA; 
            CAPTURE_DATA;
    }                        
    SCK=1;                          // Clk for SENSI-BUS
    __delay_us(5);        // Pulsewidth approx. 5 us  	
    SCK=0;
    }
    RELEASE_DATA;                           //release DATA-line
    SCK=1;                            // Clk pulse #9 for ack
    __delay_us(2);	 
    error=DATA;                       // Check ack (DATA will be pulled down by SHT11)
    SCK=0; 
     __delay_us(2);  
     return error;//error=1 in case of no acknowledge
}

unsigned char s_Read_ByteSHT(unsigned char ack)
{ 
    unsigned char i,val=0;
    RELEASE_DATA;                           // Release DATA-line
    for (i=0x80;i>0;i/=2)             // Shift bit for masking
    { 
        SCK=1; 
        __delay_us(2);                         // Clk for SENSI-BUS
        if (DATA) val=(val | i);        // Read bit  
        SCK=0; 
        //DelayUs(5); 					 
    }
    if(ack) 
    {
        LOW_DATA; 
        CAPTURE_DATA;
    } 
    else RELEASE_DATA;                        // If "ack==1" pull down DATA-Line
    SCK=1;                                      // Clk pulse #9 for ack
    __delay_us(5);                              // Pulsewidth approx. 5 us 
    SCK=0;						    
    RELEASE_DATA; 
	//DelayUs(2);                          // Release DATA-line
    return val;
}

void Send_StartBit_SHT75(void)
{ 
    // Specific start bit
    CAPTURE_DATA;
    LOW_SCK;
    //RD1 = SDA
    // RB4  = CLK
    DATA_LAT = 1;
    SCK = 1;
    DATA_LAT = 0;
    SCK = 0;
    SCK = 1;
    DATA_LAT = 1;
    SCK = 0; 
    DATA_LAT = 0;
}