// ================================================================
//  THERMOMÈTRE À CTN — Arduino Nano + OLED SSD1306 0,96"
// ================================================================
//  Schéma électrique :
//    +5V ──── CTN ──── TEMP_A0 (A0) ──── R1 (10 kΩ) ──── GND
//
//  Principe :  pont diviseur de tension entre CTN (variable)
//              et R1 (fixe). La tension en A0 dépend du rapport
//              des deux résistances, donc de la température.
//
//  Bibliothèques nécessaires (Library Manager) :
//    - Adafruit SSD1306
//    - Adafruit GFX Library
// ================================================================

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <math.h>   // pour log()

// ---------------------------------------------------------------
//  PARAMÈTRES — ÉCRAN OLED
// ---------------------------------------------------------------
#define LARGEUR_OLED  128
#define HAUTEUR_OLED   64
#define OLED_RESET     -1      // pas de broche RESET dédiée
#define OLED_ADRESSE 0x3C      // adresse I2C (0x3C ou 0x3D)
Adafruit_SSD1306 oled(LARGEUR_OLED, HAUTEUR_OLED, &Wire, OLED_RESET);

// ---------------------------------------------------------------
//  PARAMÈTRES — CAPTEUR CTN
// ---------------------------------------------------------------
#define BROCHE_CTN   A0        // broche de lecture analogique

#define R_SERIE    10000.0     // résistance série R1 (Ω) — 10 kΩ
#define R0         10000.0     // résistance CTN à T0 = 25 °C (Ω)
#define T0_KELVIN   298.15     // T0 en Kelvin (25 + 273,15)
#define COEFF_B    3950.0      // coefficient B de la CTN (K)
                               // ⚠ vérifier sur la fiche technique !

// ---------------------------------------------------------------
//  PARAMÈTRES — ACQUISITION
// ---------------------------------------------------------------
#define NB_MESURES   10        // nb de lectures pour la moyenne

// ================================================================
//  SETUP
// ================================================================
void setup() {
  Serial.begin(9600);

  // --- Initialisation OLED ---
  if (!oled.begin(SSD1306_SWITCHCAPVCC, OLED_ADRESSE)) {
    Serial.println(F("ERREUR : ecran OLED non detecte !"));
    while (true);  // arrêt si OLED absent
  }

  // --- Écran de démarrage ---
  oled.clearDisplay();
  oled.setTextColor(SSD1306_WHITE);
  oled.setTextSize(1);
  oled.setCursor(10, 15);
  oled.println(F("  Thermometre CTN"));
  oled.setCursor(20, 30);
  oled.println(F("  1ere STL"));
  oled.setCursor(15, 45);
  oled.println(F("Initialisation..."));
  oled.display();
  delay(2000);
}

// ================================================================
//  LECTURE ET CALCUL DE LA TEMPÉRATURE
// ================================================================
float lireTemperature() {

  // 1) Moyenne de NB_MESURES lectures ADC (réduction du bruit)
  long somme = 0;
  for (int i = 0; i < NB_MESURES; i++) {
    somme += analogRead(BROCHE_CTN);
    delay(5);
  }
  float adc = (float)somme / NB_MESURES;  // valeur ADC moyenne (0–1023)

  // 2) Calcul de la résistance CTN
  //    V_A0 = R1 / (R_CTN + R1) × 5V
  //    => R_CTN = R1 × (1023 - ADC) / ADC
  float r_ctn = R_SERIE * (1023.0 - adc) / adc;

  // 3) Calcul de la température — loi de Steinhart-Hart simplifiée
  //    Paramètre B :  1/T = 1/T0 + (1/B) × ln(R_CTN / R0)
  float inv_T = (1.0 / T0_KELVIN) + (1.0 / COEFF_B) * log(r_ctn / R0);
  float T_celsius = (1.0 / inv_T) - 273.15;

  // 4) Affichage debug sur le port série (Moniteur série : 9600 bps)
  Serial.print(F("ADC = "));    Serial.print(adc, 0);
  Serial.print(F("  R_CTN = ")); Serial.print(r_ctn, 0);
  Serial.print(F(" ohms  T = ")); Serial.print(T_celsius, 1);
  Serial.println(F(" C"));

  return T_celsius;
}

// ================================================================
//  AFFICHAGE SUR L'ÉCRAN OLED
// ================================================================
void afficherTemperature(float temp) {

  oled.clearDisplay();

  // --- Titre ---
  oled.setTextSize(1);
  oled.setCursor(18, 0);
  oled.print(F("Thermometre CTN"));

  // --- Ligne de séparation ---
  oled.drawLine(0, 10, 127, 10, SSD1306_WHITE);

  // --- Valeur de température (grande taille) ---
  char buf[7];
  dtostrf(temp, 5, 1, buf);   // "XXX.X"

  oled.setTextSize(3);
  // Centrage horizontal de la valeur
  int16_t x1, y1;
  uint16_t larg, haut;
  oled.getTextBounds(buf, 0, 0, &x1, &y1, &larg, &haut);
  oled.setCursor((LARGEUR_OLED - larg) / 2 - 10, 16);
  oled.print(buf);

  // --- Unité °C ---
  oled.setTextSize(2);
  oled.setCursor(100, 20);
  oled.print(F("\xF7""C"));   // \xF7 = ° dans la fonte Adafruit

  // --- Barre de progression (0 °C → 100 °C) ---
  int barre = constrain((int)map((long)(temp * 10), 0, 1000, 0, 114), 0, 114);
  oled.drawRect(7, 55, 114, 7, SSD1306_WHITE);
  oled.fillRect(7, 55, barre, 7, SSD1306_WHITE);

  oled.setTextSize(1);
  oled.setCursor(0,  55); oled.print(F("0"));
  oled.setCursor(112, 55); oled.print(F("100"));

  oled.display();
}

// ================================================================
//  BOUCLE PRINCIPALE
// ================================================================
void loop() {
  float temperature = lireTemperature();
  afficherTemperature(temperature);
  delay(500);  // rafraîchissement toutes les 500 ms
}
