/* Servo_PN_ATtiny.ino
* --------------------------------------------------------------------------------
* Servomoteur avec un ATtiny pour barrieres PN
* http://www.locoduino.org/spip.php?article194
* Fabrique sur la sortie ServoPin un signal de servomoteur avec une
* impulsion réglable de pulseMin à pulseMax (soit 1 à 2 ms) et
* avec une période de 15000 µS (soit 15 ms) qui est fixe.
* 1,0 ms ==> servo a -90°
* 1,5 ms ==> servo centré
* 2,0 ms ==> servo a +90°
* En fait, depend du modele de servo
* --------------------------------------------------------------------------------
* ILS non déclenché ==> barrieres fixes (ouvertes ou fermées)
* ILS déclenché ==> provoque mouvement des barrieres
* --------------------------------------------------------------------------------
* Introduit le clignotement des feux rouges de PN sur sortie ledPin
*/
// constantes :
const int bpPin = 4; // ILS
const int ServoPin = 3; // Servo
const int ledPin = 0; // LED de feux rouges
const int nbre_cligno_avant = 3; // clignotement des DEL avant fermeture barrières
const int duree_cligno = 500; // demi période de clignotement des LED en ms
const long period = 15000; // période (en microsecondes; comprise entre 10 et 20 ms)
const long pulseMin = 1000; // logiquement >= 1000
const long pulseMax = 2000; // logiquement <= 2000
// Ces deux valeurs permettent un débattement de 90° du servo S3001 Futaba
// variables :
unsigned long debut_boucle = 0; // mémorise le début du signal Servo
unsigned long duree_signal = 2000; // signal limité en durée pour éviter frétillement
unsigned long previousMicros = 0; // mémorise l instant du front montant
unsigned long previousMillis = 0; // mémorise changement d état de la LED
unsigned long currentMicros;
unsigned long currentMillis;
long pulse = 1000; // Impulsion en microsecondes du signal, de pulseMin à pulseMax
void setup() {
pinMode(bpPin, INPUT_PULLUP);
pinMode(ServoPin, OUTPUT);
pinMode(ledPin, OUTPUT);
}
void loop() {
debut_boucle = millis();
while(digitalRead(bpPin)==HIGH){
// ILS non déclenché
pulse = pulseMin;
currentMicros = micros();
if(currentMicros - previousMicros >= pulse) {
digitalWrite(ServoPin, LOW);
}
if (currentMicros - previousMicros >= (period - pulse)) {
digitalWrite(ServoPin, HIGH);
previousMicros = currentMicros;
}
if(millis() - debut_boucle >= duree_signal){
break; // on arrête le signal après 2 secondes
}
}
while(digitalRead(bpPin)==HIGH) {
// attendre
}
// Ici, ILS déclenché : clignotement des LED
for(int i = 1; i <= nbre_cligno_avant; i++) {
digitalWrite(ledPin, HIGH);
delay(duree_cligno);
digitalWrite(ledPin, LOW);
delay(duree_cligno);
}
debut_boucle = millis();
while(digitalRead(bpPin) == HIGH) {
currentMillis = millis();
pulse = pulseMax;
currentMicros = micros();
if(currentMicros - previousMicros >= pulse) {
digitalWrite(ServoPin, LOW);
}
if (currentMicros - previousMicros >= (period - pulse)) {
digitalWrite(ServoPin, HIGH);
previousMicros = currentMicros;
}
// Clignotement des LED rouges
if (currentMillis - previousMillis >= duree_cligno) {
digitalWrite(ledPin, !digitalRead(ledPin));
previousMillis = currentMillis;
}
if(millis() - debut_boucle >= duree_signal) {
break; // on arrête le signal après 2 secondes
}
}
while(digitalRead(bpPin)==HIGH) {
// les LED continuent à clignoter
currentMillis = millis();
if(currentMillis - previousMillis >= duree_cligno) {
digitalWrite(ledPin, !digitalRead(ledPin));
previousMillis = currentMillis;
}
}
// Déclenchement ILS
delay(500); // anti-rebond
digitalWrite(ledPin, LOW); // Extinction des LED rouges
// ouverture des barrières se fera en début de fonction loop
}