/* 
Weichenantrieb mit Servo
  Compiler: Board: "Arduino Micro" (ATMEGA32U4)

Funktion:
  an drei Pins (2,3,4) kann Servoposition gestellt werden
  davon ein Testpin (2) für Mittelstellung
  Pulsfolge an Servo wird nach t Impulsen beendet, um
  Durchbrennen des Servos beim Anschlag zu verhindern
  Pulsabstand ist 15 ms
  Prellen wird ignoriert, nur mit anderem Pin wird wieder gestellt
  <servo.h> ist ungeeignet, weil Pulse nicht abgeschaltet werden können

Programm testen mit dem Serial Monitor von Arduino (unter Werkzeuge)
  Serial Monitor einstellen auf: Autoscroll; Kein Zeilenende; 115200 Baud
  #define setdebug  // einschalten, um Infos über USB-VCP "Serial Monitor" zu erhalten 

Pins am Pro Micro:
  Pin 9: Pulse an das Servo
  Pin 2: Test auf Mittelstellung 90°
  Pin 3: vom Taster, Weiche auf  0°
  Pin 4: vom Taster, Weiche auf  180°
  
*/

#define setdebug  // einschalten, um Infos über USB-VCP "Serial Monitor" zu erhalten 

////////////////////////////////////////////////////////////

unsigned int pos, posalt = 90; // Servo Position in Grad (Startwert, ohne Bedeutung)
const unsigned int tk = 25;    // hier die Zeit bis zum Abschalten (in delays) einstellen
unsigned int t = 0;            // ablaufende Zeit

void servoPuls(int posit) { // Ersatz für Library <servo.h>
  unsigned int usec = map(posit, 0, 180, 1000, 2000);
  digitalWrite(9, HIGH);
  delayMicroseconds(usec);  // Gibt nur einen Puls aus
  digitalWrite(9, LOW);
}

void setup() {
  #ifdef setdebug
    #define USB Serial
    USB.begin(115200);  // USB-VCP Kommunikation auf TX0, RX0 115200, 8n1n
  #endif
  pinMode(9, OUTPUT);        // zum Servo
  pinMode(2, INPUT_PULLUP);  // Test auf Mittelstellung
  pinMode(3, INPUT_PULLUP);  // vom Taster, Weiche auf gerade
  pinMode(4, INPUT_PULLUP);  // vom Taster, Weiche auf abbiegen
  #ifdef setdebug
    delay(5000);             // sonst wird folgendes ignoriert
    USB.println(F("\r\n Servo-Endlagenabschalter\r\n www.gheinz.de"));
    USB.println(F(" USB-VCP Kommunikation auf TX0, RX0 mit 115200 Baud, 8n1n\r\n"));
  #endif
}

void loop() {
  if ( (digitalRead(2) == LOW) ) {    // weiche = 'm';
    pos = 90;    // in Grad
    t = tk;
  }
  if ( (digitalRead(3) == LOW) ) {    // weiche = 'g';
    pos = 0;      // in Grad
    t = tk;
  }
  if ( (digitalRead(4) == LOW) ) {    // weiche = 'a';
    pos = 180;   // in Grad
    t = tk;
  }
  
  if (pos != posalt) { // Verhindern, daß dasselbe Pin mehrfach nacheinander auslöst
    while (t > 0) {    // Servo pulsen, bis t abgelaufen ist
    servoPuls(pos);
    t--;
    if ( t == 0 ) posalt = pos;
    delay(15);    // Servo Pausenzeit
    #ifdef setdebug
      USB.print(F("posalt = ")); USB.print(posalt, DEC);
      USB.print(F("; posneu = ")); USB.print(pos, DEC);
      USB.print(F("; t = ")); USB.println(t, DEC);
      if ( t == 0 ) USB.println(F(" fertig\r\n"));
    #endif
    }
  }
}
