Mit 3 Taster 3 Servos (beliebig erweiterbar) gleichzeitig ansteuern

Schönen guten Tag die Damen und Herren,

ich stehe vor einem Problem bei meinem derzeitigen Projekt (kaum Arduino-Kenntnisse, aber bereit zu lernen).

Ich habe 3 Servos (S1,S2,S3) und 3 Taster (T1,T2,T3).

//Bei auslösen von jeweils EINEM Taster:

Zustand 1: wenn T1 == 1, dann S1(90°), S2(45°),
Zustand 2: wenn T2 == 1, dann S1(45°), S2(90°), S3(45°),
Zustand 3: wenn T3 == 1, dann           , S2(45°), S3(90°),
ansonsten S1(0°),S2(0°),S3(0°)
usw.

//bei auslösen zb. von 2 GLEICHZEITIG,

wenn T1 == 1 & T2 == 1, dann "Zustand 1" + "Zustand 2", ALLERDINGS darf S2 nicht 45° + 90° sein, sondern nur 90°

Erledige ich das über einfache If-Abfragen, hab ich das Problem,
dass S2 auf 45° bleibt und nicht auf 90° geht.
Das da oben soll erstmal Proof of Concept sein...am Ende habe ich 12 Taster und 12 Servos (können auch mehr werden). Ich hatte gelesen, dass man erst den Status der Tasten einließt und danach, je nachdem welche Kombination der Tasten gedrückt wurde, wird das Programm ausgeführt. Bei 12 Tasten also 2^12 Kombinationsmöglichkeiten, was etwas viel ist. Und unter "Taster gleichzeitig Arduino" lese ich nur über das "debouncen" von den Tastern (wie ich verstanden habe, um zu verhindern, dass der Input vom Taster mehrfach eingelesen wird).

Schön wäre es, wenn ich so gestalten könnte:

Zustand 1 - x definieren und im Loop wird dann einfach je nachdem welche TX == 1 sind, die entsprechenden "Zustände X" zeitgleich ausgeführt.

Nur weiß ich nicht, nach was ich da genau googlen soll um das zu bewerkstelligen...irgendwie stehe ich da auf dem Schlauch :confused:

Ich hab da auch was von ShiftIn gelesen oder über Keypad library. Sind das die richtigen Ansätze? Welche Möglichkeiten gäbe es noch? Ich bin da für alles offen, auch zusätzliche Hardware würde ich ordern. Es muss nicht auf den Arduino beschränkt sein, rein mechanische Ansätze wären auch gut. Solange ich es beliebig erweitern kann.

Vielen Dank fürs durchlesen, Gedanken machen und helfen!

Mit freundlichen Grüßen
UnterStrom

P.s.: Im Anhang findet Ihr eine Zeichnung, wie ich es meine :slight_smile:

ja dann mache es doch so. zähl den Ausschlag jeweils zusammen und wenn >90 dann ausschlag=90

Servos sind träge, da ist prellen zweitrangig

nimm einen Mega2560, der hat genug Pins für den Anfang

P.S. Willkommen im Forum noch!

Ich glaube du mußt alle 8 Möglichkeiten der Tasterzustände (oder die meisten) berücksichtigen.

if (S1==1 && S2 == 0 && S3 == 0) mach was.

ecc.

Grüße Uwe

Wenn ich die Logik richtig verstehe, beeinflußt Tastern immer den Servon auf 90°, sowie Servon-1 und Servon+1 mit 45°, wobei 90° Vorrang vor 45° hat. Richtig?

ElEspanol:
zähl den Ausschlag jeweils zusammen und wenn >90 dann ausschlag=90

Genau so würde ich dann auch machen mit n als Feldindex. Muß man nur an den Rändern aufpassen.

Erstmal vielen dank an alle für die schnellen Antworten!

@ElEspanol
Das mit den Auschlägen addieren ist ein guter Tipp, das habe ich irgendwie nicht auf dem Schirm gehabt. Jetzt muss ich schauen, ob ich das dem arduino auch so mitteilen kann :smiley:

@uwefed
Das mit den if-abfragen wollte ich erst auch so machen, aber bei 12 Tastern, wären das zu viele verschiedene if-abfragen, oder?

@agmue
Japp genauso. Das mit dem Feld hab ich verstanden, da könnte ich an den Rändern einfach “virtuell' erweitern und was dann da passiert wäre ja egal, da es keine physischen Elemente zum auslösen gäbe? Aber wie programmiert man das mit dem Feld und n als Feldindex? (Google ich später mal wenn ich etwas Zeit habe. Falls du auf Anhieb einen Link dazu hast, wäre ich sehr dankbar dafür)

Nochmal vielen dank für die Hilfen

MfG
UnterStrom

UnterStrom:
... da könnte ich an den Rändern einfach “virtuell' erweitern und was dann da passiert wäre ja egal, da es keine physischen Elemente zum auslösen gäbe?

Ungewöhnlich aber möglich, zumindest für den ersten Versuch.

UnterStrom:
Falls du auf Anhieb einen Link dazu hast, wäre ich sehr dankbar dafür

Sorry, aber da bin ich alte Schule und krame erstmal im eigenen Gehirn. Das spuckt dann diesen "Link" aus:

const int tasterPins[] = {2, 2, 3, 4, 5, 6, 6};  // das erste und letzte Element sollen nicht benutzt werden
const byte elemente = sizeof(tasterPins) / sizeof(tasterPins[0]);
byte pos[elemente];

void setup() {
  Serial.begin(9600);        // nur zum Debuggen
  Serial.println("Anfang");  // nur zum Debuggen
  for (byte j = 0; j < elemente; j++) {
    pinMode(tasterPins[j], INPUT_PULLUP);
  }
}

void loop() {
  for (byte j = 0; j < elemente; j++) {
    pos[j] = 0;
  }
  for (byte j = 1; j < (elemente - 1); j++) {
    Serial.print(" ");
    if (!digitalRead(tasterPins[j])) { // gedrückt = LOW
      pos[j - 1] += 45;
      pos[j] += 90;
      pos[j + 1] += 45;
      Serial.print("I "); // gedrückt; nur zum Debuggen
    } else {
      Serial.print("O "); // losgelassen; nur zum Debuggen
    }
  }
  Serial.println();        // nur zum Debuggen

  // Überprüfung
  for (byte j = 1; j < (elemente - 1); j++) {
    if (pos[j] > 90) pos[j] = 90;
    if (pos[j] < 10) Serial.print(" ");
    Serial.print(pos[j]);
    Serial.print(" ");
  }
  Serial.println();
  Serial.println();
  delay(2000);  // nur zum Debuggen
}

Kommt da was Sinnvolles raus?

 O  O  O  O  O 
 0  0  0  0  0 

 O  O  I  I  O 
 0 45 90 90 45 

 O  O  I  O  O 
 0 45 90 45  0 

 I  I  I  I  I 
90 90 90 90 90

Genau so muss das aussehen! :smiley: Danke agmue, ich arbeite mich mal durch den code durch und versuche die servos mit einzubinden.

mfg

UnterStrom

Edit:
Nachdem man den code verstanden hat, war das einbinden gar nicht so schwer :smiley:

#include <Servo.h>
Servo servoArray[7];

const int tasterPins[] = {2, 2, 3, 4, 5, 6, 6};  // das erste und letzte Element sollen nicht benutzt werden
const byte elemente = sizeof(tasterPins) / sizeof(tasterPins[0]);
byte pos[elemente];

void setup() {
for(int j=0; j<7; j++)
{
  servoArray[j].attach(j+7);
}
  
  Serial.begin(9600);        // nur zum Debuggen
  Serial.println("Anfang");  // nur zum Debuggen
  for (byte j = 0; j < elemente; j++) {
    pinMode(tasterPins[j], INPUT_PULLUP);
  }
}

void loop() {
  for (byte j = 0; j < elemente; j++) {
    pos[j] = 0;
  }
  for (byte j = 1; j < (elemente - 1); j++) {
    Serial.print(" ");
    if (!digitalRead(tasterPins[j])) { // gedrückt = LOW
      pos[j - 1] += 45;
      pos[j] += 90;
      pos[j + 1] += 45;
      servoArray[j-1].write(pos[j-1]);
      servoArray[j].write(pos[j]);
      servoArray[j+1].write(pos[j+1]);
      Serial.print("I "); // gedrückt; nur zum Debuggen
    } else {
      Serial.print("O "); // losgelassen; nur zum Debuggen
    }
  }
  Serial.println();        // nur zum Debuggen

  // Überprüfung
  for (byte j = 1; j < (elemente - 1); j++) {
    if (pos[j] > 90) pos[j] = 90;
    if (pos[j] < 10) Serial.print(" ");
    servoArray[j].write(pos[j]);
    Serial.print(pos[j]);
    Serial.print(" ");
  }
  Serial.println();
  Serial.println();
  delay(20);  // nur zum Debuggen
}