Hallo und guten Tag!
Als Neuling im Thema Arduino habe ich mir wohl ein etwas zu schweres Projekt vorgenommen. Aber immerhin so etwa Dreiviertel funktioniert es schon!
Zum Verständnis hier die Idee, um die es geht:
Im Endausbau soll diese "Superkreuzung" mit einem Taster bedient werden. Dabei werden die 8 Weichen mittels Servo gestellt und eine LED für die entsprechende Stellung 1, 2 oder 3 eingeschaltet.
Das funktioniert auch soweit ganz gut. Es hat mich sehr gefreut, dass ich das hinbekommen habe!
Für mein Testprogramm habe ich erstmal nur 3 Servos ohne Last angeschlossen. Die externe Stromversorgung fehlt auch noch.
Also wenn ich den Arduino (kein Original, ein ELEGOO MEGA-R3) einschalte, soll die letzte Stellung der Servos gelesen werden und die entsprechende LED angehen.
Hier mein bisheriger Code:
//Programmcode ANFANG
//Licht AN/AUS mit Taster
//Idee von @hubertoberleithner4101
//Taster als an-aus-Schalter und Klicks zaehlen
//Kombiniert, um mit einem Taster 3 verschiedene Ereignisse (hier: Servos) zu steuern
#include <Servo.h>
Servo servo1;
Servo servo2;
Servo servo3;
byte LED_PIN1 = A0; // Variablentypen immer so klein wie möglich wählen, damit der Arbeits-
byte LED_PIN2 = A1;
byte LED_PIN3 = A2;
byte BUTTON_PIN = 12; // speicher nicht so voll wird.
bool buttonstatus = 0; // Da buttonstatus und letzterStatus nur die Zustände 0 und 1 annehmen
bool letzterStatus = 0; // können, sollte der Variablentyp bool genutzt werdern. Das spart
// Arbeitsspeicher und kann bei Berechnungen gut genutzt werden.
byte zaehlen; //zaehlt die Klicks
void setup() {
Serial.begin(9600);
pinMode(LED_PIN1, OUTPUT);
pinMode(LED_PIN2, OUTPUT);
pinMode(LED_PIN3, OUTPUT);
pinMode(BUTTON_PIN, INPUT);
servo1.attach(2);
servo2.attach(3);
servo3.attach(4);
if (servo1.read() <= 79) { //Wenn Servo1 den vorgegebenen Winkel 10 hat, dann
zaehlen = 0; //setze zaehlen auf 0 (entspricht Stellung 1) und
digitalWrite(LED_PIN1, HIGH); //schalte LED_PIN1 an und (warum ist das "verkehrt" herum?)
digitalWrite(LED_PIN2, LOW); //schalte LED_PIN2 aus und
digitalWrite(LED_PIN3, LOW); //schalte LED_PIN3 aus
}
if (servo1.read() >= 80 && servo1.read() <= 100) { //Wenn Servo1 den vorgegebenen Winkel zwischen 80 und 100 (also 90) hat, dann
zaehlen = 1; //setze zaehlen auf 1 (entspricht Stellung 2) und
digitalWrite(LED_PIN1, LOW); //schalte LED_PIN1 aus und
digitalWrite(LED_PIN2, HIGH); //schalte LED_PIN2 an und
digitalWrite(LED_PIN3, LOW); //schalte LED_PIN3 aus
}
if (servo1.read() >= 101) { //Wenn Servo1 den vorgegebenen Winkel 170 hat, dann
zaehlen = 2; //setze zaehlen auf 2 (entspricht Stellung 3) und
digitalWrite(LED_PIN1, LOW); //schalte LED_PIN1 aus und
digitalWrite(LED_PIN2, LOW); //schalte LED_PIN2 aus und
digitalWrite(LED_PIN3, HIGH); //schalte LED_PIN3 an
}
}
void loop() {
buttonstatus = digitalRead(BUTTON_PIN);
if (buttonstatus != letzterStatus) { //Wenn Buttonstatus ungleich letzterStatus ist dann
letzterStatus = !letzterStatus; //setze letzterStatus auf nicht letzterStatus und
zaehlen = zaehlen + buttonstatus; //erhöhe zaehlen um buttonstatus (also 1 oder 0)
}
switch (zaehlen) {
case 0: //Stellung 1
servo1.write(10); //drehe den Servo1 auf xx Grad und
//hier soll eine Pause hin, damit die Servos nicht gleichzeitig arbeiten
servo2.write(90); //drehe den Servo2 auf xx Grad und
//hier soll eine Pause hin, damit die Servos nicht gleichzeitig arbeiten
servo3.write(170); //drehe den Servo3 auf xx Grad und
digitalWrite(LED_PIN1, HIGH); //schalte LED_PIN1 an und
digitalWrite(LED_PIN2, LOW); //schalte LED_PIN2 aus und
digitalWrite(LED_PIN3, LOW); //schalte LED_PIN3 aus
break;
case 1: //Stellung 2
servo1.write(90); //drehe den Servo1 auf xx Grad und
servo2.write(170); //drehe den Servo2 auf xx Grad und
servo3.write(10); //drehe den Servo3 auf xx Grad und
digitalWrite(LED_PIN1, LOW); //schalte LED_PIN1 aus und
digitalWrite(LED_PIN2, HIGH); //schalte LED_PIN2 an und
digitalWrite(LED_PIN3, LOW); //schalte LED_PIN3 aus
break;
case 2: //Stellung 3
servo1.write(170); //drehe den Servo1 auf xx Grad und
servo2.write(10); //drehe den Servo2 auf xx Grad und
servo3.write(90); //drehe den Servo3 auf xx Grad und
digitalWrite(LED_PIN1, LOW); //schalte LED_PIN1 aus und
digitalWrite(LED_PIN2, LOW); //schalte LED_PIN2 aus und
digitalWrite(LED_PIN3, HIGH); //schalte LED_PIN3 an
break;
case 3: //Wenn 3 erreicht ist,
zaehlen = 0; //wieder auf 0 setzen
}
Serial.print("zaehlen = ");
Serial.print(zaehlen);
Serial.print("; Buttonstatus = ");
Serial.print(buttonstatus);
Serial.print("; letzterStatus = ");
Serial.print(letzterStatus);
Serial.print(" Servo1: ");
Serial.println(servo1.read());
delay(10); //Pause 10 ms
}
//Programmcode ENDE
In dieser Version landet "zaehler" beim einschalten oder Reset immer bei 1 und entsprechend bewegen sich die Servos zu den dort definierten Winkeln. Im seriellen Monitor wird auch der dazu gehörende Winkel 90 angezeigt.
Wenn ich die ganzen If-Schleifen im Setup entferne, dann ist zaehler = 0 und die Servos gehen in Stellung 1. Das erscheint mir auch richtig so.
Demnach ist meine Idee mit dem Servo lesen im Setup wohl nicht richtig.
Ich hatte die Schleifen auch schon im loop mit einer Hilfsvariablen für nur einmaligen Durchlauf ausprobiert, funktionierte aber auch nicht.
Wo liegt hier mein Denkfehler?
Danke schon mal vorab für Hilfe und Denkanstöße!
Gruß
Martin


