2 Taster 4 Led 2 Servo

Hallo Community,

ich versuche mir einem Arduino Mega über Servo´s Weicen anzusteuern. Dabe soll mit jeden Tastendruck die Weiche gestellt werden, gleichzeitig sollen 2 LED´s die Fahrtrichtung auf dem Stellpult anzeigen. Bisher hat das mit einem Taster, 2 LED und einem Servo funktioniert. Jetzt versuch ich mit einen 2. Taster einen 2. Servo und 2 ander Led´s zusteuern. Das klappt nur nicht. Egal welchen Taster ich drücke werden alle 4 LED und die beiden Servos gesteuert.

Hier ist der Sketch

#include <Servo.h> // zugriff auf Servo Bibliothek

const int BUTTONw1 = 22; // Pushbutton Pin auf dem Board (22)
const int BUTTONw2 = 23; // Pushbutton Pin auf dem Board (23)
int LEDw1lks = 6;
int LEDw2lks = 7;
int LEDw2re = 4;
int LEDw1re = 5;
int val_1 = 0; // speichert den Zustand des Tasters
int old_val_1 = 0; // speichert den vorherigen wert von val
int val_2 = 0; // speichert den Zustand des Tasters
int old_val_2 = 0; // speichert den vorherigen wert von val
int state = 0; // 0 = Servo Position eins 1 = Servo Position zwei
Servo servow1; // deklariert den Namen des ersten Servos
Servo servow2;
void setup() {
  pinMode(BUTTONw1, INPUT_PULLUP); // Gibt an dass Buttom ein Input ist - DAS IST GEÄNDERT
  pinMode(BUTTONw2, INPUT_PULLUP);
  servow1.attach(9); // gibt an auf welchem Pin der Servo mit dem steuerkabel anliegt
  servow1.write(36); // gibt die Grundstellung des Servo beim start an
  servow2.attach(10); // gibt an auf welchem Pin der Servo mit dem steuerkabel anliegt
  servow2.write(36); // gibt die Grundstellung des Servo beim start an
  pinMode(LEDw1lks, OUTPUT);
  pinMode(LEDw2lks, OUTPUT);
  pinMode(LEDw2re, OUTPUT);
  pinMode(LEDw1re, OUTPUT);
  
}

void loop()
{ val_1 = digitalRead(BUTTONw1); // liest den Input aus und cheked ob er gedrückt ist.
   if ((val_1 == LOW) && (old_val_1 == HIGH)) {   // HIER IST DIE ABFRAGE GEÄNDERT
     state = 1 - state;
     delay(500);
   }
 
  old_val_1 = val_1; // aktueller val wird zu val alt
 
  if (state == 1) {
    servow1.write(85); // Stelle servo auf 100 grad
    digitalWrite(LEDw1lks, HIGH);
    digitalWrite(LEDw1re, LOW);
    delay(20);
    
  }
  else {
    servow1.write(36); // stelle servo auf startposition
    digitalWrite(LEDw1lks, LOW);
    digitalWrite(LEDw1re, HIGH);
  }

   val_2 = digitalRead(BUTTONw2); // liest den Input aus und cheked ob er gedrückt ist.
   if ((val_2 == LOW) && (old_val_2 == HIGH)) {   // HIER IST DIE ABFRAGE GEÄNDERT
     state = 1 - state;
     delay(500);
   }
 
  old_val_2 = val_2; // aktueller val wird zu val alt
 
  if (state == 1) {
    servow2.write(85); // Stelle servo auf 100 grad
    digitalWrite(LEDw2lks, HIGH);
    digitalWrite(LEDw2re, LOW);
    delay(20);
    
  }
  else {
    servow2.write(36); // stelle servo auf startposition
    digitalWrite(LEDw2lks, LOW);
    digitalWrite(LEDw2re, HIGH);
  }

}

Kann mir jemand helfen und mir erklären was ich falsch mache? ICh bin absolut neu in der Materie.

Danke Wiliam_t_riker

step 1:

starte die Serial Ausgabe mit Serial.begin(115200) und schreibe in all deine IF's ein Serial.print(F("ich bin jetz hier bzw. da")) - dann siehst du was dein Code zur Laufzeit macht und warum er vieleicht was anderes tut als du geplant hast.

Edit:
Step 2:
Dein Problem könnte evtl. das sein:

int state = 0; // 0 = Servo Position eins 1 = Servo Position zwei

jo - ich denke das verwendest auch beim zweiten ... na kein Wunder dass sich das dann gegenseitig beeinflusst.
da wirst zwei separate brauchen.
Reine Annahme, habe ja deine Hardware nicht.

Dein Problem könnte evtl. das sein:

int state = 0; // 0 = Servo Position eins 1 = Servo Position zwei

jo - ich denke das verwendest auch beim zweiten ... na kein Wunder dass sich das dann gegenseitig beeinflusst.

Ich hilf mir mal was muss ich tun steh grad auf dem Schlauch.
Irgendwie hab ich mich gedanklich verrannt.

Hi

In Richtung Modellbahn gibt's hier im Forum eine Lib vom MicroBahner, Die ist quasi für so Zeug gedacht.
MoBa-Tools auf GitHub.
Mit dieser Lib 'spiele' ich gerade mit einem Mini-Stepper herum.
Da der MicroBahner einen Fehler ausgebessert hatte, muß Das doch wer Probelaufen lassen :wink:

Verzeih, daß ich mir Deinen Sketch jetzt nicht mehr ansehe - bin eh schon zu spät.

MfG

wiliam_t_riker:
Ich hilf mir mal was muss ich tun steh grad auf dem Schlauch.

du hast alle anderen Codeteile ja auch nur "umbenannt, kopiert und verdoppelt" ... aber für diese Variable

int state = 0; // 0 = Servo Position eins 1 = Servo Position zwei

hast nur eine (ohne Nummer), also gehe ich davon aus dass du davon auch zwei brauchst.

Dass Du für jeden Servo eine eigene Statusvariable brauchst, hat dir noiasca ja schon geschrieben.
Wenn Du das auf noch mehr Weichen ausbauen willst, solltest Du über arrays nachdenken.

Wenn Du für die Servosteuerung die MobaTools verwendest, kannst Du das Umlaufen der Weichenzumgen schön langsam machen. Die Lib lässt sich auch über den Bibliotheksverwalter installieren.

@ noiasca
das war das Problem danke dir.

@MicroBahner
ich schaue mir das morgen mal an. Klingt verlockend.

Vielen Dank

übrigens, so könnte man es mit Arrays verkürzen:

#include <Servo.h> // zugriff auf Servo Bibliothek

const byte weichen = 2;
const int buttonPin[] =    {22, 23};
const int ledLinksPin[] =  {6, 7};
const int ledRechtsPin[] = {5, 4};
const int servoPin[] =     {9, 10};

bool tasterAlt[weichen];
bool tasterAktuell[weichen];

bool position[weichen];

const byte servoGrundstellung = 36;
const byte servoAbbiegen = 85;

Servo servo[weichen];

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println(F("Gleisschaltplan"));
  for (byte i = 0; i < weichen; i++)
  {
    pinMode(buttonPin[i], INPUT_PULLUP);
    servo[i].attach(servoPin[i]);
    servo[i].write(servoGrundstellung);
    pinMode(ledLinksPin[i], OUTPUT);
    pinMode(ledRechtsPin[i], OUTPUT);
  }
}

void loop() {
  // put your main code here, to run repeatedly:

  for (byte i = 0; i < weichen; i++)
  {
    tasterAktuell[i] = digitalRead(buttonPin[i]);
    if (!tasterAktuell[i] && tasterAlt[i])
    {
      Serial.print(F("Tastendruck ")); Serial.print (i); Serial.print(F(" Pin ")); Serial.println(buttonPin[i]);
      position[i] = !position[i];
      delay(500);

      // ich würde änderungen nur nach Tastendruck machen,
      // nicht bei jedem Loop durchlauf
      // daher habe ich den folgenden Abschnitt in das If des erkannten Tastendrucks genommen
      if (position[i])
      {
        //Serial.print(F("Weiche ")); Serial.print (i); Serial.print(F(" abbiegen"));
        servo[i].write(servoAbbiegen);
        digitalWrite(ledLinksPin[i], HIGH);
        digitalWrite(ledRechtsPin[i], LOW);
        delay(20);
      }
      else
      {
        Serial.print(F("Weiche ")); Serial.print (i); Serial.print(F(" gerade"));
        servo[i].write(servoGrundstellung);
        digitalWrite(ledLinksPin[i], LOW);
        digitalWrite(ledRechtsPin[i], HIGH);
      }
    }
    tasterAlt[i] = tasterAktuell[i];
  }
}

Obs klappt sieht man nur mit Hardware.

Lässt man die Debug.Ausgaben weg braucht es weniger RAM und weniger Flash!

Der Sketch verwendet 2658 Bytes (8%) des Programmspeicherplatzes. Das Maximum sind 32256 Bytes.
Globale Variablen verwenden 71 Bytes (3%) des dynamischen Speichers, 1977 Bytes für lokale Variablen verbleiben. Das Maximum sind 2048 Bytes.

kann man natürlich weiter optimieren, weniger globale Variabeln etc.

Aber ich denke so wird das hinzufügen von weiteren Weichen wesentlich einfacher.

Wenn du das auf 10 Weichen erweiterst hast, bist du Fit für die Mobatools :wink:

delay(500);

Vom globalen Aspekt aus betrachtet, hat sowas, also eine Blockade des µCs, im Zusammenhang mit Tastendrücken keine Berechtigung. Verwende stattdessen millis(), dann werden die Vorgänge quasi prallel ablaufen.

const int ledLinksPin[] =  {6, 7};
const int ledRechtsPin[] = {5, 4};
...
const byte servoGrundstellung = 36;
const byte servoAbbiegen = 85;

Als Hobby-Eisenbahner kenne ich bei einfachen Weichen nur Geradeaus und Abzweig, links und rechts eher nicht. Weichen links-geradeaus-rechts dürften die Ausnahme sein.

noiasca:
Wenn du das auf 10 Weichen erweiterst hast, bist du Fit für die Mobatools :wink:

Oder für OOP, also Klassen und Strukturen. Aber ich traue mich nicht, weil es ja anfängerunfreundlich ist ::slight_smile:

agmue:
Oder für OOP, also Klassen und Strukturen. Aber ich traue mich nicht, weil es ja anfängerunfreundlich ist ::slight_smile:

Sobald er eine Lib verwendet, arbeitet er eh mit Klassen, er weis es nur noch nicht :wink: .

Wenn er das mit den Arrays umgesetzt hat, ist es dann nur noch ein kleiner Schritt, alle Variable für eine Weiche in einer Struktur zusammenzufassen. Aber immer eins nach dem anderen.... wir wollen ihn ja nicht verschrecken :slight_smile:

agmue:

delay(500);

Vom globalen Aspekt aus betrachtet, hat sowas, also eine Blockade des µCs, im Zusammenhang mit Tastendrücken keine Berechtigung. Verwende stattdessen millis(), dann werden die Vorgänge quasi prallel ablaufen.

Wenn er die MobaTools verwendet, kann er für Zeitsteuerungen auch die 'Eieruhr' (EggTimer) verwenden. Meine Erfahrung aus dem Stummiforum ist, dass Anfänger damit leichter zurechtkommen, als direkt mit millis zu hantieren (Ich mach's auch nur noch so - ist m.M.n. im Code auch übersichtlicher). Wobei die Frage ist, ob er da im Moment überhaupt schon eine Zeitsteuerung braucht. Zum Entprellen reicht erstmal ein ganz kleines delay() im loop.
Immer nach dem KISS-Prinzip ( Keep It Simple and Stupid ) 8)

@Agmue - ich wollte in erster Linie seine verstümmelten Variablen-Bezeichnungen zumindest in der Nomenklatur verbessern, nicht noch inhaltliche Verbesserungen anbringen.

LEDw2lks

ging für mich halt gar nicht.

MicroBahner:
Wenn er die MobaTools verwendet, kann er für Zeitsteuerungen auch die 'Eieruhr' (EggTimer) verwenden.

Eieruhr und Eisenbahn, das bringe ich in meinem Kopf nicht zusammen, aber ja, möglicherweise ist das ein einfacherer Einstieg.

noiasca:
@Agmue - ich wollte in erster Linie seine verstümmelten Variablen-Bezeichnungen zumindest in der Nomenklatur verbessern, ...

Eine Verbesserung ist Dir auf jeden Fall geglückt. Jeder stolpert halt so über andere Sachen.

MicroBahner:
... wir wollen ihn ja nicht verschrecken :slight_smile:

Auf gar keine Fall!

agmue:
Als Hobby-Eisenbahner kenne ich bei einfachen Weichen nur Geradeaus und Abzweig, links und rechts eher nicht.

Was machst Du bei einer Y-Weiche? :smiley:

So hab da mal ne weiter Frage bzw ein Problem.
Ich habe den Sketch jetzt um weitere Weichen erweitert.
Aber wenn den Sketch kompilieren will kommt immer die Fehlermeldung: expected } at end of input

Das hab ich aber drinne oder überseh ich hier was?

#include <Servo.h> // zugriff auf Servo Bibliothek

const int BUTTONw1 = 22; // Pushbutton Pin auf dem Board (22)
const int BUTTONw2 = 23; // Pushbutton Pin auf dem Board (23)
const int BUTTONw3 = 24;
const int BUTTONw4 = 25;
const int BUTTONw5 = 26;
const int BUTTONw6 = 27;
int LEDw1lks = 6;
int LEDw2lks = 7;
int LEDw2re = 4;
int LEDw1re = 5;
int LEDw3lks = 28;
int LEDw3re = 29;
int LEDw4lks = 30;
int LEDw4re = 31;
int LEDw5lks = 32;
int LEDw5re = 33;
int LEDw6lks = 34;
int LEDw6re = 35;
int val_1 = 0; // speichert den Zustand des Tasters
int old_val_1 = 0; // speichert den vorherigen wert von val
int val_2 = 0; // speichert den Zustand des Tasters
int old_val_2 = 0; // speichert den vorherigen wert von val
int val_3 = 0;
int old_val_3 = 0;
int val_4 = 0;
int old_val_4 = 0;
int val_5 = 0;
int old_val_5 = 0;
int val_6 = 0;
int old_val_6 = 0;
int statew1 = 0; // 0 = Servo Position eins 1 = Servo Position zwei
int statew2 = 0; // 0 = Servo Position eins 1 = Servo Position zwei
int statew3 = 0;
int statew4 = 0;
int statew5 = 0;
int statew6 = 0;
Servo servow1; // deklariert den Namen des ersten Servos
Servo servow2;
Servo servow3;
Servo servow4;
Servo servow5;
Servo servow6;
void setup() {
  pinMode(BUTTONw1, INPUT_PULLUP); // Gibt an dass Buttom ein Input ist - DAS IST GEÄNDERT
  pinMode(BUTTONw2, INPUT_PULLUP);
  pinMode(BUTTONw3, INPUT_PULLUP);
  pinMode(BUTTONw4, INPUT_PULLUP);
  pinMode(BUTTONw5, INPUT_PULLUP);
  pinMode(BUTTONw6, INPUT_PULLUP);
  servow1.attach(9); // gibt an auf welchem Pin der Servo mit dem steuerkabel anliegt
  servow1.write(36); // gibt die Grundstellung des Servo beim start an
  servow2.attach(10); // gibt an auf welchem Pin der Servo mit dem steuerkabel anliegt
  servow2.write(36); // gibt die Grundstellung des Servo beim start an
  servow3.attach(11); // gibt an auf welchem Pin der Servo mit dem steuerkabel anliegt
  servow3.write(36); // gibt die Grundstellung des Servo beim start an
  servow4.attach(12); // gibt an auf welchem Pin der Servo mit dem steuerkabel anliegt
  servow4.write(36); // gibt die Grundstellung des Servo beim start an
  servow5.attach(13); // gibt an auf welchem Pin der Servo mit dem steuerkabel anliegt
  servow5.write(36); // gibt die Grundstellung des Servo beim start an
  servow6.attach(14); // gibt an auf welchem Pin der Servo mit dem steuerkabel anliegt
  servow6.write(36); // gibt die Grundstellung des Servo beim start an
  pinMode(LEDw1lks, OUTPUT);
  pinMode(LEDw2lks, OUTPUT);
  pinMode(LEDw2re, OUTPUT);
  pinMode(LEDw1re, OUTPUT);
  pinMode(LEDw3lks, OUTPUT);
  pinMode(LEDw3re, OUTPUT);
  pinMode(LEDw4lks, OUTPUT);
  pinMode(LEDw4re, OUTPUT);
  pinMode(LEDw5lks, OUTPUT);
  pinMode(LEDw5re, OUTPUT);
  pinMode(LEDw6lks, OUTPUT);
  pinMode(LEDw6re, OUTPUT);

}

void loop()
{  val_1 = digitalRead(BUTTONw1); // liest den Input aus und cheked ob er gedrückt ist.
   if ((val_1 == LOW) && (old_val_1 == HIGH)) {   // HIER IST DIE ABFRAGE GEÄNDERT
     statew1 = 1 - statew1;
     delay(500);
   }
 
  old_val_1 = val_1; // aktueller val wird zu val alt
 
  if (statew1 == 1) {
    servow1.write(85); // Stelle servo auf 100 grad
    digitalWrite(LEDw1lks, HIGH);
    digitalWrite(LEDw1re, LOW);
    delay(20);
    
  }
  else {
    servow1.write(36); // stelle servo auf startposition
    digitalWrite(LEDw1lks, LOW);
    digitalWrite(LEDw1re, HIGH);
  }
//WEICHE 2
   val_2 = digitalRead(BUTTONw2); // liest den Input aus und cheked ob er gedrückt ist.
   if ((val_2 == LOW) && (old_val_2 == HIGH)) {   // HIER IST DIE ABFRAGE GEÄNDERT
     statew2 = 1 - statew2;
     delay(500);
   }
 
  old_val_2 = val_2; // aktueller val wird zu val alt
 
  if (statew2 == 1) {
    servow2.write(85); // Stelle servo auf 100 grad
    digitalWrite(LEDw2lks, HIGH);
    digitalWrite(LEDw2re, LOW);
    delay(20);
    
  }
  else {
    servow2.write(36); // stelle servo auf startposition
    digitalWrite(LEDw2lks, LOW);
    digitalWrite(LEDw2re, HIGH);
  }
//WEICHE3
  val_3 = digitalRead(BUTTONw3); // liest den Input aus und cheked ob er gedrückt ist.
   if ((val_3 == LOW) && (old_val_3 == HIGH)) {   // HIER IST DIE ABFRAGE GEÄNDERT
     statew3 = 1 - statew3;
     delay(500);
   }
 
  old_val_3 = val_3; // aktueller val wird zu val alt
 
  if (statew3 == 1) {
    servow3.write(85); // Stelle servo auf 100 grad
    digitalWrite(LEDw3lks, HIGH);
    digitalWrite(LEDw3re, LOW);
    delay(20);
    
  }
  else {
    servow3.write(36); // stelle servo auf startposition
    digitalWrite(LEDw3lks, LOW);
    digitalWrite(LEDw3re, HIGH);
   //WEICHE 4 
    val_4 = digitalRead(BUTTONw4); // liest den Input aus und cheked ob er gedrückt ist.
   if ((val_4 == LOW) && (old_val_4 == HIGH)) {   // HIER IST DIE ABFRAGE GEÄNDERT
     statew4 = 1 - statew4;
     delay(500);
   }
 
  old_val_4 = val_4; // aktueller val wird zu val alt
 
  if (statew4 == 1) {
    servow4.write(85); // Stelle servo auf 100 grad
    digitalWrite(LEDw4lks, HIGH);
    digitalWrite(LEDw4re, LOW);
    delay(20);
    
  }
  else {
    servow4.write(36); // stelle servo auf startposition
    digitalWrite(LEDw4lks, LOW);
    digitalWrite(LEDw4re, HIGH);
   //WEICHE 5 
    val_5 = digitalRead(BUTTONw5); // liest den Input aus und cheked ob er gedrückt ist.
   if ((val_5 == LOW) && (old_val_5 == HIGH)) {   // HIER IST DIE ABFRAGE GEÄNDERT
     statew5 = 1 - statew5;
     delay(500);
   }
 
  old_val_5 = val_5; // aktueller val wird zu val alt
 
  if (statew5 == 1) {
    servow5.write(85); // Stelle servo auf 100 grad
    digitalWrite(LEDw5lks, HIGH);
    digitalWrite(LEDw5re, LOW);
    delay(20);
    
  }
  else {
    servow5.write(36); // stelle servo auf startposition
    digitalWrite(LEDw5lks, LOW);
    digitalWrite(LEDw5re, HIGH);
  //WEICHE 6  
    val_6 = digitalRead(BUTTONw6); // liest den Input aus und cheked ob er gedrückt ist.
   if ((val_6 == LOW) && (old_val_6 == HIGH)) {   // HIER IST DIE ABFRAGE GEÄNDERT
     statew6 = 1 - statew6;
     delay(500);
   }
 
  old_val_6 = val_6; // aktueller val wird zu val alt
 
  if (statew6 == 1) {
    servow6.write(85); // Stelle servo auf 100 grad
    digitalWrite(LEDw6lks, HIGH);
    digitalWrite(LEDw6re, LOW);
    delay(20);
    
  }
  else {
    servow6.write(36); // stelle servo auf startposition
    digitalWrite(LEDw6lks, LOW);
    digitalWrite(LEDw6re, HIGH);
  } 


}

Zeile 141 fehlt }
Zeile 162 fehlt }
Zeile 183 fehlt }

Mit Strg+t kann man das leicht sehen.

Da fehlt mehr als eine Klammer. Mache mal +T in der IDE. Dann siehst Du evtl. die Fehler

Gruß Tommy

Ja, Du übersiehst was. Wie der Compiler sagt, fehlt eine } ( der hat da eigentlich immer Recht :wink: )

2 Tips zum Suchen für solche Fehler:

1- Drücke ctrl-T zum Formatieren. Dann rückt die IDE entsprechend der {} ein - und zwar so wie sie tatsächlich gesetzt sind ( und nicht wie Du meinst das sie gesetzt sein müssten )

  1. Setz den Cursor vor ( oder direkt hinter ) ein geschweifte Klammer. Dann markiert dir die IDE die zugehörige andere Klammer ( die bekommt ein Kästchen drumrum ). Dann kannst Du gleich sehen, ob das auch die ist, die Du erwartest.

Und noch ein Tip bevor Du weitere Weichen hinzufügst und dich 'tottippst' und 'totkopierst': Schau dir das Beispiel von noiasca an und befasse dich mit arrays. Dein Sketch schreit geradezu danach, das mit arrays zu realisieren.

Super jetzt hab ich es.

Danke für die Tips

Hi

Danke für's Feedback und schön, daß Es jetzt klappt.
Leider ist im ersten Teil Ironie enthalten - oder Du hast den Sinn eines Forum noch nicht verstanden: Nehmen UND Geben.
Wenn wir (also hier wohl 'die Anderen') Dich zu einer Lösung bringen konnten, gebietet Es alleine schon die genossene Erziehung, die Lösung des Problem auch zu zeigen.

MfG

Ich kann dir jetzt zwar nicht ganz folgen (wahrscheinlich schon zu spät). Aber das Problem wurde gelöst durch setzen der fehlenden Klammern so wie es in den vorherigen Post´s beschrieben.