/* CCs

The following code is based on the work of the following people.

MeshTastic:
https://meshtastic.org/docs/getting-started/

SGP30:
AdaFruit example code - https://learn.adafruit.com/adafruit-sgp30-gas-tvoc-eco2-mox-sensor/arduino-code

SCD30:
AdaFruit example code from Arduino IDE

OLED Screen:
Rui Santos : https://randomnerdtutorials.com/esp32-ssd1306-oled-display-arduino-ide/

LED:
FastLED example code from Arduino IDE

VMA320
Code from here : https://learn.adafruit.com/thermistor/using-a-thermistor

Some debugging was done with ChatGPT

Code arrangement by me: Patrick Dezséri

*/

/*

//Basic Library
#include <arduino.h>

#define RX_PIN 44 //RX Pin of your controller that will send the data to the MeshTastic Node
#define TX_PIN 43 //TX Pin of your controller that will send the data to the MeshTastic Node

// Math library
#include <math.h>

// I2C Communication
#include <Wire.h>

// SCD30 - CO2 Sensor
#include <Adafruit_SCD30.h>
Adafruit_SCD30  SCD30;
void SCD30_STAR(bool); //function to initialize the CO2 Sensor - SCD30
void SCD30_Sensor(); //CO2 Sensor - SCD30
float SCD30_T;
float SCD30_Humidity;
float SCD30_CO2;

// I2C Scanner -----------
void I2C_Scan(); //I2C Scanner, no Pin required, To check I2C devices connected to the board

// For the OLED Display
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#include <Fonts/FreeSerif12pt7b.h>

void OLED_STAR(bool initialize); //function to initialize the OLED Display
void OLED_DISPLAY(); //function to display the data on the OLED Display

//LED
void BlinkLED(int time);

// ---------- Setup ----------
void setup() {
    Serial.begin(115200);     // USB for debug
    Serial1.begin(921600, SERIAL_8N1, RX_PIN, TX_PIN);    // UART for Meshtastic node

    Wire.begin(); // Initialize I2C communication

    pinMode(LED_BUILTIN, OUTPUT); // Set the built-in LED as output

    // Initialize the CO2 Sensor - SCD30
    SCD30_STAR(true);

    // Initialize the OLED Display
    OLED_STAR(true);
}



// ---------- Loop ----------
void loop() {
    //I2C_Scan(); // Uncomment to scan I2C devices
  
    //Sensors
    SCD30_Sensor();

    //OLED Screen
    OLED_DISPLAY();

    // UART to Node (Meshtastic)

    Serial1.println("");

    Serial1.print("T: ");
    Serial1.print(SCD30_T);
    Serial1.println(" °C");

    Serial1.print("Humidity: ");
    Serial1.print(SCD30_Humidity);
    Serial1.println(" %");

    Serial1.print("Co2: ");
    Serial1.print(SCD30_CO2);
    Serial1.println(" ppm");

    

    BlinkLED(1500);
    delay(5000);
}



// ---------- Function definitions ----------

// ---------- CO2, T and Humidity Sensor - Sensirion SCD30
void SCD30_STAR(bool initialize){
    Serial.println("Adafruit SCD30 test!");

    // Try to initialize!
    if (!SCD30.begin()) {
        Serial.println("Failed to find SCD30 chip");
        while (1) { delay(10); }
    }
    Serial.println("SCD30 Found!");


    // if (!SCD30.setMeasurementInterval(10)){
    //   Serial.println("Failed to set measurement interval");
    //   while(1){ delay(10);}
    // }
    Serial.print("Measurement Interval: "); 
    Serial.print(SCD30.getMeasurementInterval()); 
    Serial.println(" seconds");
}
  
void SCD30_Sensor(){
    if (SCD30.dataReady()){
        Serial.println("Data available!");

        if (!SCD30.read()){ 
        Serial.println("Error reading sensor data");
        SCD30_CO2 =-1;
        SCD30_Humidity=-1;
        SCD30_T=-1;; 
        }

        //Serial.print("Temperature: ");
        //float T = SCD30.temperature;
        SCD30_T = SCD30.temperature;
        SCD30_T = round(SCD30_T * 10.0) / 10.0;
        //Serial.print(SCD30_T);
        //Serial.println(" degrees C");
        
        //Serial.print("Relative Humidity: ");
        //float Humidity = SCD30.relative_humidity;
        SCD30_Humidity = SCD30.relative_humidity;
        SCD30_Humidity = round(SCD30_Humidity * 10.0) / 10.0;
        //Serial.print(SCD30_Humidity);
        //Serial.println(" %");
        
        //Serial.print("CO2: ");
        //float CO2 = SCD30.CO2;
        SCD30_CO2 = SCD30.CO2;
        SCD30_CO2 = round(SCD30_CO2 * 10.0) / 10.0;
        //Serial.print(SCD30_CO2);
        //Serial.println(" ppm");
        //Serial.println("");
    } 
    else {
        //Serial.println("No data");
        //SCD30_CO2 =-1;
        //SCD30_Humidity=-1;
        //SCD30_T=-1;
    }
    delay(100);
}

// ---------- Integrated LED Blinking
void BlinkLED(int time) {
    digitalWrite(LED_BUILTIN, HIGH);
    Serial.println("ON");
    delay(time);
    digitalWrite(LED_BUILTIN, LOW);
    delay(time);
    Serial.println("OFF");
}
    
// ---------- I2C Scanner
void I2C_Scan() {
    byte error, address;
    int nDevices;
    Serial.println("Scanning...");
    nDevices = 0;
    for(address = 1; address < 127; address++ ) {
        Wire.beginTransmission(address);
        error = Wire.endTransmission();
        if (error == 0) {
        Serial.print("I2C device found at address 0x");
        if (address<16) {
            Serial.print("0");
        }
        Serial.println(address,HEX);
        nDevices++;
        }
        else if (error==4) {
        Serial.print("Unknown error at address 0x");
        if (address<16) {
            Serial.print("0");
        }
        Serial.println(address,HEX);
        }    
    }
    if (nDevices == 0) {
        Serial.println("No I2C devices found\n");
    }
    else {
        Serial.println("done\n");
    }
    delay(5000);          
}
  
// ---------- OLED Display
void OLED_STAR(bool initialize){
    // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
    if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
        Serial.println(F("SSD1306 allocation failed"));
        for(;;); // Don't proceed, loop forever
    }
    // Show initial display buffer contents on the screen --
    // the library initializes this with an Adafruit splash screen.
    display.display();
    delay(2000); // Pause for 2 seconds
    
    // Clear the buffer
    display.clearDisplay();
}

  
void OLED_DISPLAY(){
    // Clear the display buffer
    display.clearDisplay();
    
    // Text Settings
    display.setTextSize(1); // Normal 1:1 pixel scale
    display.setFont(); // Choose a font
    display.setTextColor(WHITE); // Draw white text
    display.setCursor(0, 0); // Start at top-left corner
    display.setRotation(0); // Rotate the display 0 to 3 times 90 degrees
        
    // Display the values
    display.print("Temp: ");
    display.print(SCD30_T);
    display.println(" C");
  
    display.print("CO2: ");
    display.print(SCD30_CO2);
    display.println(" ppm");
  
    display.print("Humidity: ");
    display.print(SCD30_Humidity);
    display.println(" %");
  
    // Display the buffer contents on the screen
    display.display();
}

//*/