#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Adafruit_ADS1015.h>
 
//Adafruit_ADS1015 ads1015;  	// Construct an ads1015 at the default address: 0x48
//Adafruit_ADS1115 ads1115(0x49);	// construct an ads1115 at address 0x49

Adafruit_ADS1115 ads1115;  	// Construct an ads1115 at the default address: 0x48

int16_t adc0, adc1, adc2, adc3;

float voltage;
float Leistung;
float Intensitaet;
float offset;

const int buttonPin = 2;     // the number of the pushbutton pin
int buttonState = 1;         // variable for reading the pushbutton status

LiquidCrystal_I2C lcd(0x3F,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display. ACHTUNG: Adresse kann auch 0x3F sein !!!

// Anschlüsse:
// GND - GND
// VCC - 5V
// SDA - ANALOG Pin 4
// SCL - ANALOG pin 5


// ===========================
// =======   SETUP   =========
// ===========================

void setup()
   {
    offset = 0.0;     // Initialisierung des offsets
     
    Serial.begin(9600);
    
    pinMode(buttonPin, INPUT);
    
    lcd.init();        // initialize the lcd
    lcd.backlight();
    lcd.setCursor(0,0);
    lcd.print("Thermosaeule");
    lcd.setCursor(0,1);
    lcd.print("uV-Meter");
    
    delay(4000);
    
    lcd.setCursor(0,0);
    lcd.print("             ");
    lcd.setCursor(0,1);
    lcd.print("            ");
    
    //ads1015.begin();  // Initialize ads1015
    ads1115.begin();  // Initialize ads1115
    
    // The ADC input range (or gain) can be changed via the following
    // functions, but be careful never to exceed VDD +0.3V max, or to
    // exceed the upper and lower limits if you adjust the input range!
    // Setting these values incorrectly may destroy your ADC!
    //                                                                ADS1015       ADS1115
    //                                                                -------       -------
    // ads1115.setGain(GAIN_TWOTHIRDS);  // 2/3x gain +/- 6.144V  1 bit = 3 mV     0.1875 mV (default)
    // ads1115.setGain(GAIN_ONE);     // 1x gain   +/- 4.096V  1 bit = 2 mV        0.125 mV
    // ads1115.setGain(GAIN_TWO);     // 2x gain   +/- 2.048V  1 bit = 1 mV        0.0625 mV
    // ads1115.setGain(GAIN_FOUR);    // 4x gain   +/- 1.024V  1 bit = 0.5 mV      0.03125 mV 
    // ads1115.setGain(GAIN_EIGHT);   // 8x gain   +/- 0.512V  1 bit = 0.25 mV     0.015625 mV
    // ads1115.setGain(GAIN_SIXTEEN); // 16x gain  +/- 0.256V  1 bit = 0.125 mV    0.0078125 mV
  
    ads1115.setGain(GAIN_TWO);     // 2x gain   +/- 2.048V  1 bit = 0.0625mV
        
   }


// ===========================
// =======    LOOP   =========
// ===========================

void loop()
   {
    buttonState = digitalRead(buttonPin);    // button for new offset
    
    if (buttonState == LOW)
       {        
        offset = ads1115.readADC_SingleEnded(0) * 1.0;   // Einlesen des aktuellen Wertes = offset
        
        offset = offset * 0.0625;
        
        offset = offset / 10.0;    // offset-Spannung in mV vor der Verstärkung
                
        delay(100);
       }
     
    adc0 = ads1115.readADC_SingleEnded(0);
  
    /*
    adc1 = ads1115.readADC_SingleEnded(1);
    adc2 = ads1115.readADC_SingleEnded(2);
    adc3 = ads1115.readADC_SingleEnded(3);
    */

    voltage = adc0 * 0.0625;               // vom ADS1115 eingelesene Spannung in mV nach der Verstärkung
    
    voltage = voltage / 10.0;              // reale Eingangsspannung in mV vor der Verstärkung (gain = 10) 
    
    Leistung = (voltage - offset) * 11.26;            // Auf den Sensor auftreffende Strahlungsleistung in mW. Kalibrierung hat ergeben: 11.26 mW/mV
    
    Intensitaet = (voltage - offset) * 7.0375;        // Strahlungsintensität in W/m². Kalibrierung hat ergeben: 7.0375 W/m²/mV
    
    Serial.print("AIN0: ");
    Serial.println(adc0);
    Serial.print("   U = ");
    Serial.print(voltage*10.0,2);
    Serial.println(" mV");
  
    /*
    Serial.print("AIN1: "); Serial.println(adc1);
    Serial.print("AIN2: "); Serial.println(adc2);
    Serial.print("AIN3: "); Serial.println(adc3);
    */
        
    lcd.setCursor(0,0);
    lcd.print("U = ");
    lcd.print(voltage,2);
    lcd.print(" mV     ");
    
    lcd.setCursor(0,1);
    lcd.print("I = ");
    lcd.print(Intensitaet,2);
    lcd.print(" W/m2     ");
    
    delay(3000);
    
    buttonState = digitalRead(buttonPin);    // button for new offset
    
    if (buttonState == LOW)
       {        
        offset = ads1115.readADC_SingleEnded(0) * 1.0;   // Einlesen des aktuellen Wertes = offset
        
        offset = offset * 0.0625;
        
        offset = offset / 10.0;    // offset-Spannung in mV vor der Verstärkung
        
        delay(100);
       }
    
    adc0 = ads1115.readADC_SingleEnded(0);
        
    voltage = adc0 * 0.0625;          // vom ADS1115 eingelesene Spannung in mV nach der Verstärkung
    
    voltage = voltage / 10.0;         // reale Eingangsspannung in mV vor der Verstärkung (gain = 10) 
    
    Leistung = (voltage - offset) * 11.26;       // Auf den Sensor auftreffende Strahlungsleistung in mW. Kalibrierung hat ergeben: 11.26 mW/mV
    
    Intensitaet = (voltage - offset) * 7.0375;   // Strahlungsintensität in W/m². Kalibrierung hat ergeben: 7.0375 W/m²/mV
     
    lcd.setCursor(0,0);
    lcd.print("P = ");
    lcd.print(Leistung,1);
    lcd.print(" mW      ");
    
    lcd.setCursor(0,1);
    lcd.print("I = ");
    lcd.print(Intensitaet,2);
    lcd.print(" W/m2     ");
    
    delay(3000);
    
   }


