/* =====================================
TEMPORISATION POUR RELAIS PAR TINY85
version 20260209
====================================
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! LICENCE D'UTILISATION – Philippe Guenet !
! !
! Ce code est librement téléchargeable pour un usage personnel et non commercial. !
! !
! Toute utilisation commerciale, professionnelle ou rémunérée est interdite. !
! !
! La redistribution, la copie publique ou l’intégration dans un autre projet !
! sont interdites. !
! !
! Aucune modification ou adaptation n’est autorisée sans l’accord écrit préalable !
! de l’auteur. !
! !
! L’auteur conserve tous les droits de propriété intellectuelle sur ce code. !
! !
! L’auteur ne saurait être tenu responsable d’aucun dommage résultant de !
! l’utilisation de ce code. !
! !
! L’utilisation du code vaut acceptation de ces conditions. !
! !
! © Philippe Guenet – Tous droits réservés - [email protected] - https://wgnt-train.fr !
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
RESET / PB5 * * VCC
PB3 * * PB2/ADC1/INT0/SCL
PB4 * * PB1/ADC1
GND * * PB0/ADC2/SDA
La sortie commandera un relais via un 2N2222
*/
// ------------------------
// CONFIGURATION DES PINS
// ------------------------
const int pinDetection = PB2; // PB2 = pin 7 = INT0
const int pinSortie = PB1; // PB1 = pin 6
const int pinLed = PB0; // PB0 = pin 5
const int pinPot = A2; // PB4 = pin 3 (ADC3)
// ------------------------
// VARIABLES INTERRUPTION
// ------------------------
volatile bool detectionFlag = false;
volatile unsigned long lastInterruptTime = 0;
const unsigned long debounceDelay = 10; // 10 ms comme Bounce2
// ------------------------
// VARIABLES TEMPO
// ------------------------
unsigned long tempoStart = 0;
unsigned long tempoDuree = 0;
unsigned long tempoMini = 6000UL; // divisée par 10 pour les tests
unsigned long tempoMaxi = 60000UL; // divisée par 10 pour les tests
bool tempoEnCours = false;
// ------------------------
// MACHINE A ETATS
// ------------------------
enum etat {
ATTENTE,
TEMPO
};
etat etatDetection = ATTENTE;
// ------------------------
// ROUTINE D'INTERRUPTION
// Déclenchée sur front descendant
// (équivalent de detection.fell())
// ------------------------
void ISR_detection() {
unsigned long now = millis();
// Anti-rebond logiciel
if (now - lastInterruptTime > debounceDelay) {
detectionFlag = true;
lastInterruptTime = now;
}
}
void setup() {
pinMode(pinSortie, OUTPUT);
pinMode(pinLed, OUTPUT);
digitalWrite(pinSortie, LOW);
// Entrée détecteur avec pullup interne
pinMode(pinDetection, INPUT_PULLUP);
// ------------------------
// Attachement interruption INT0
// Front descendant
// ------------------------
attachInterrupt(0, ISR_detection, FALLING);
} // Fin de setup()
void loop() {
switch (etatDetection) {
case ATTENTE:
digitalWrite(pinSortie, LOW);
digitalWrite(pinLed, LOW);
tempoEnCours = false;
// Si un front descendant a été détecté
if (detectionFlag) {
detectionFlag = false; // acquittement
// Lecture du potentiomètre : 1 à 10 minutes (déclenchement à l'appui)
int potValue = analogRead(pinPot);
tempoDuree = map(potValue, 0, 1023, tempoMini, tempoMaxi);
tempoStart = millis();
tempoEnCours = true;
digitalWrite(pinLed, HIGH); // LED ON = tempo active
digitalWrite(pinSortie, HIGH);
etatDetection = TEMPO; // changement d'état
}
break;
case TEMPO:
// Lorsque le temps est écoulé
if (millis() - tempoStart >= tempoDuree) {
digitalWrite(pinSortie, LOW); // LED OFF = tempo terminée
digitalWrite(pinLed, LOW);
tempoEnCours = false;
etatDetection = ATTENTE; // retour à l'état d'attente
}
break;
} // Fin de switch()
} // Fin de loop()