#define echoPin A0
#define trigPin A1
#define greenLED A4
#define orangeLED A3
#define redLED A2
#define switchPin D1
#define buzzerPin D2
#define SHCP D5
#define STCP D4
#define DS D3

long duration, distance;

// Séquences de chiffres pour chaque condition d'affichage
byte segments[] = {
  B01111111, // 0 avec virgule décimale
  B00001010, // 1 sans virgule décimale
  B10110110, // 2 sans virgule décimale
  B10011110, // 3 sans virgule décimale
  B11001010, // 4 sans virgule décimale
  B11011100, // 5 sans virgule décimale
  B11111100, // 6 sans virgule décimale
  B00001110, // 7 sans virgule décimale
  B11111110, // 8 sans virgule décimale
  B11011110, // 9 sans virgule décimale
};

void setup() {
  Serial.begin(9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(greenLED, OUTPUT);
  pinMode(orangeLED, OUTPUT);
  pinMode(redLED, OUTPUT);
  pinMode(switchPin, INPUT_PULLUP);
  pinMode(SHCP, OUTPUT);
  pinMode(STCP, OUTPUT);
  pinMode(DS, OUTPUT);
}

void loop() {
  int switchState = digitalRead(switchPin); // Lire l'état de l'interrupteur
  
  if (switchState == HIGH) { // Si l'interrupteur est activé (appuyé)
    digitalWrite(trigPin, LOW);
    delayMicroseconds(2);
    digitalWrite(trigPin, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigPin, LOW);
      
    duration = pulseIn(echoPin, HIGH);
    distance = (duration * 0.034 / 2) / 10;

    Serial.println(distance);
    
    // Contrôle des LED en fonction de la distance
    if (distance > 12.0) { // Distance > 1.2 m (120 cm)
      digitalWrite(greenLED, HIGH);
      digitalWrite(orangeLED, LOW);
      digitalWrite(redLED, LOW);
    } 
    else if (distance >= 7.5 && distance <= 12.0) { // 0.75 m - 1.2 m (75 cm - 120 cm)
      digitalWrite(greenLED, LOW);
      digitalWrite(orangeLED, HIGH);
      digitalWrite(redLED, LOW);
      tone(buzzerPin, 440);
      delay(200);
      noTone(buzzerPin);
      digitalWrite(buzzerPin, LOW);
      Serial.print("Temps d'arrêt: ");
      Serial.print(map(distance, 5, 50, 500, 1000)); // Correspondance de la distance avec le temps d'arrêt
      Serial.println(" ms");
      delay(map(distance, 5, 50, 500, 1000));
    } 
    else if (distance > 3.0 && distance <= 7.5) { // < 75 cm
      digitalWrite(greenLED, LOW);
      digitalWrite(orangeLED, HIGH);
      digitalWrite(redLED, LOW);
      tone(buzzerPin, 440);
      delay(200);
      noTone(buzzerPin);
      digitalWrite(buzzerPin, LOW);
      Serial.print("Temps d'arrêt: ");
      Serial.print(map(distance, -30, 5, 0, 500)); // Correspondance de la distance avec le temps d'arrêt
      Serial.println(" ms");
      delay(map(distance, -30, 5, 0, 500));
    } 
    else { // Distance <= 3.0
      digitalWrite(greenLED, LOW);
      digitalWrite(orangeLED, LOW);
      digitalWrite(redLED, HIGH);
      tone(buzzerPin, 440);
      delay(200);
      noTone(buzzerPin);
    }
  }
  else { // Si l'interrupteur est désactivé
    digitalWrite(LED_BUILTIN, LOW);
    digitalWrite(orangeLED, LOW);
    digitalWrite(redLED, LOW);
    noTone(buzzerPin);
    digitalWrite(buzzerPin, LOW);
  }

  // Affichage des chiffres en fonction de la condition
  int digit1 = distance / 10;
  int digit2 = distance % 10;

  // Détermination de la séquence de chiffres à afficher en fonction de A
  byte* segmentSequence;
  if (A == 0) {
    segmentSequence = segments; // Séquence de chiffres pour A = 0
  } else if (A == 1) {
    segmentSequence = segments + 1; // Séquence de chiffres pour A = 1
  } else if (A == 2) {
    segmentSequence = segments + 2; // Séquence de chiffres pour A = 2
  } else if (A == 3) {
    segmentSequence = segments + 3; // Séquence de chiffres pour A = 3
  }

  // Affichage des chiffres sur les afficheurs à décalage
  digitalWrite(STCP, LOW);
  shiftOut(DS, SHCP, MSBFIRST, segmentSequence[digit2]);
  shiftOut(DS, SHCP, MSBFIRST, segmentSequence[digit1]);
  digitalWrite(STCP, HIGH);

  delay(50);
}
74HC595
74HC595