/*attiny servo cde aiguillage V2
  07/03/2025
   Commande de servo-moteur pour aiguillage avec ATtiny85
   liens: https://forum.locoduino.org/index.php?topic=1437.0
          https://wokwi.com/projects/424785839108251649
         
         Brochage ATtiny85
         
            =|1  U  8|= VCC
  Led1 <--3 =|2     7|= 2--> PinServo 
  Led2 <--4 =|3     6|= 1<-- BP2
        GND =|4     5|= 0<-- BP1
*/

const byte BP1 = 0; // Commande le servo en position travail
const byte BP2 = 1; // Commande le servo en position repos
const byte PinServo = 2; // Signal de commande du servo
const byte Led1 = 3; // Allumée si servo en position repos
const byte Led2 = 4; // Allumée si servo en position travail
const byte PAS = 5; // Agit sur la vitesse de rotation du servo
const int PERIODE = 20000; // Période entre chaque début d'impulsion en microsecondes
const int PO = 1550; // Durée impulsion en microsecondes pour la position repos
const int PF = 1250; // Durée impulsion en microsecondes pour la position travail

int t1 = PO;
int t2 = PF;
bool aiguillageRepos = true;

void setup() {
  pinMode(BP1, INPUT_PULLUP); // Broche en entrée avec pullup
  pinMode(BP2, INPUT_PULLUP); // Broche en entrée avec pullup
  pinMode(Led1, OUTPUT); // Broche en sortie
  pinMode(Led2, OUTPUT); // Broche en sortie
  pinMode(PinServo, OUTPUT); // Signal en sortie

  digitalWrite(Led1, LOW); // Led1 éteinte
  digitalWrite(Led2, LOW); // Led2 éteinte
  digitalWrite(PinServo, LOW); // Initialise à l'état bas

  // Initialise en aiguillage repos
  envoyerImpulsion(t2);
  digitalWrite(Led1, HIGH); // Led1 allumée
}

void loop() {
  bool etatBP1 = digitalRead(BP1);
  bool etatBP2 = digitalRead(BP2);

  // Commande aiguillage position travail par BP1
  if (etatBP1 == LOW && aiguillageRepos) {
    changerPosition(PF, PO, Led2, Led1);
    aiguillageRepos = false;
  }

  // Commande aiguillage position repos par BP2
  if (etatBP2 == LOW && !aiguillageRepos) {
    changerPosition(PO, PF, Led1, Led2);
    aiguillageRepos = true;
  }
}

void changerPosition(int positionInitiale, int positionFinale, byte ledAllumee, byte ledEteinte) {
  int positionActuelle = positionInitiale;
  while (positionActuelle != positionFinale) {
    positionActuelle += (positionActuelle < positionFinale) ? PAS : -PAS;
    envoyerImpulsion(positionActuelle);
  }
  digitalWrite(ledAllumee, HIGH);
  digitalWrite(ledEteinte, LOW);
}

void envoyerImpulsion(int duree) {
  digitalWrite(PinServo, HIGH); // Envoie l'impulsion
  delayMicroseconds(duree); // Pendant la bonne durée
  digitalWrite(PinServo, LOW); // Stoppe l'impulsion
  delayMicroseconds(PERIODE - duree); // Attend le temps restant pour atteindre la période
}
ATTINY8520PU
tiny:PB5
tiny:PB3
tiny:PB4
tiny:GND
tiny:PB0
tiny:PB1
tiny:PB2
tiny:VCC
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
led1:A
led1:C
led2:A
led2:C
servo1:GND
servo1:V+
servo1:PWM