#include <Arduino.h>
// ------------------ Pins ------------------
const int trig = PA9;
const int echo = PA10;
#define LED_GREEN PA5
#define LED_ORANGE PB7
#define LED_RED PB0
#define BUZZER PA12
#define SWITCH_PIN PB6
// 74HC595 (Interface Mikro-Bus)
#define DS PA6
#define SH_CP PA7
#define ST_CP PA4
// ------------------ Variables ------------------
long duration;
float distance;
// ------------------ Table ANODE COMMUNE ------------------
const byte SEG[10] = {
0b11000000, // 0
0b11111001, // 1
0b10100100, // 2
0b10110000, // 3
0b10011001, // 4
0b10010010, // 5
0b10000010, // 6
0b11111000, // 7
0b10000000, // 8
0b10010000 // 9
};
void setup() {
pinMode(trig, OUTPUT);
pinMode(echo, INPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_ORANGE, OUTPUT);
pinMode(LED_RED, OUTPUT);
pinMode(BUZZER, OUTPUT);
pinMode(SWITCH_PIN, INPUT_PULLUP);
pinMode(DS, OUTPUT);
pinMode(SH_CP, OUTPUT);
pinMode(ST_CP, OUTPUT);
Serial.begin(115200);
}
void displayTwoDigits(int meters, int decimeters) {
// Point décimal activé sur le premier digit (Mètres)
byte metersData = SEG[meters] & 0b01111111;
byte decimetersData = SEG[decimeters];
digitalWrite(ST_CP, LOW);
shiftOut(DS, SH_CP, MSBFIRST, decimetersData);
shiftOut(DS, SH_CP, MSBFIRST, metersData);
digitalWrite(ST_CP, HIGH);
}
void loop() {
// Le système ne s'active que si l'interrupteur est actionné (appui = LOW)
if (digitalRead(SWITCH_PIN) == HIGH) {
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_ORANGE, LOW);
digitalWrite(LED_RED, LOW);
noTone(BUZZER);
// On peut laisser les afficheurs éteints ou à 0.0
return;
}
// --- Mesure distance ---
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
duration = pulseIn(echo, HIGH, 30000);
distance = (duration * 0.0343) / 2; // cm
// --- Préparation Affichage (ex: 70cm -> 0.7) ---
float distMetres = distance / 100.0;
if (distMetres > 9.9) distMetres = 9.9;
if (distMetres < 0) distMetres = 0;
int metersPart = (int)distMetres;
int deciPart = (int)(distMetres * 10) % 10;
displayTwoDigits(metersPart, deciPart);
// --- Terminal PC (Phase 1) ---
Serial.print("Distance: ");
Serial.print(distMetres, 1);
Serial.println(" m");
// --- Logique Alertes (Cahier des charges) ---
if (distance > 120) {
// Diode Verte uniquement
digitalWrite(LED_GREEN, HIGH);
digitalWrite(LED_ORANGE, LOW);
digitalWrite(LED_RED, LOW);
noTone(BUZZER);
}
else if (distance >= 30) {
// Diode Orangée + Bips variables
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_ORANGE, HIGH);
digitalWrite(LED_RED, LOW);
// Intervalle linéaire : 1s (1000ms) à 1.2m, 0s à 30cm
int interval = map(distance, 30, 120, 0, 1000);
tone(BUZZER, 440, 50);
delay(interval + 50); // Ajustement pour la fluidité
}
else {
// Diode Rouge + Bip continu
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_ORANGE, LOW);
digitalWrite(LED_RED, HIGH);
tone(BUZZER, 440);
}
delay(50);
}Loading
st-nucleo-l031k6
st-nucleo-l031k6