A/B Umschalter mit Taster

Hallo zusammen,
ich stehe vor folgendem Problem und weiß nicht, wonach ich suchen muss.

Ich möchte gerne mit 2 Tastern 2 Relais (Low switching) schalten.
Beim betätigen von A0 soll Pin 0 Low sein und bleiben und Pin 1 High. Beim betätigen von A1 soll Pin 1 Low sein und bleiben und Pin 1 High.

Also ein A/B Schalter wie z.B. bei einem Umschalter der Eingänge eines Verstärkers.

Könnt ihr mir dazu Hilfestellung leisten?

Hallo
Beschreibe das Projekt mit einfachen Worten und das ganz einfach.

Die Pins 0 und 1 solltest Du nicht benutzen, weil die für die Verbindung zum PC wichtig sind. Welchen Arduino willst Du nutzen?

Gruß Tommy

PS: Eigentlich brauchst Du da nur einen mehrpoligen Schalter ohne Arduino

const byte inPin[] = {A0, A1};
const byte outPin[sizeof(inPin)] = {2, 3};

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  for (byte b=0; b<sizeof(inPin); b++)
  {
    pinMode(inPin[b], INPUT_PULLUP);
    pinMode(outPin[b], OUTPUT);
    digitalWrite(outPin[b], HIGH);
  }
}

void loop()
{
  if (!digitalRead(inPin[0]) && digitalRead(inPin[1]))
  {
    digitalWrite(outPin[1], HIGH);
    digitalWrite(outPin[0], LOW);
  }
  if (!digitalRead(inPin[1]) && digitalRead(inPin[0]))
  {
    digitalWrite(outPin[0], HIGH);
    digitalWrite(outPin[1], LOW);
  }
}

In diesem Aufbau kannst Du nicht beide Taster gleichzeitig drücken :wink:

Hallo zusammen, besten Dank für die schnellen Antworten.

Ich muss wohl doch weiter ausholen. Hatte gehofft das etwas abzukürzen.

8 Taster sollen 8 Relais betätigen. Das Relais des gedrückten Tasters soll so lange anziehen, bis ein anderer Taster gedrückt wird. Dann soll das angezogene Relais Abfallen und das Relais des neuen Tasters anziehen.
Das soll zwar kein Line Umschalter werden, aber die Grundfunktion ist sehr ähnlich.

Dafür nutze ich den Arduino Mega. Das Ganze brauche ich nämlich 2x. :slight_smile:

Hoffe das war verständlicher.

Das wird wohl noch mehr.
Aber ich geb Dir genre die nächste Scheibe der Salami.

const byte inPin[] = {53, 51, 49, 47, 45, 43, 41, 39};
const byte outPin[sizeof(inPin)] = {52, 50, 48, 46, 44, 42, 40, 38};


void setup()
{
  Serial.begin(115200);
  Serial.println(F("Start..."));
  for (byte b = 0; b < sizeof(inPin); b++)
  {
    pinMode(inPin[b], INPUT_PULLUP);
    pinMode(outPin[b], OUTPUT);
    digitalWrite(outPin[b], HIGH);
  }
}

void loop()
{
  for (byte b = 0; b < sizeof(inPin); b++)
  {
    if ((!digitalRead(inPin[b])) != (digitalRead(outPin[b])))
    {
      schaltePin(b);
      continue;
    }
  }
}
void schaltePin(const byte myPin)
{
  for (byte b = 0; b < sizeof(inPin); b++)
  {
    digitalWrite(outPin[b], HIGH);
  }
  digitalWrite(outPin[myPin], LOW);
}

Vielen Dank. Ich werde die Salami heute Abend auf der Couch genießen und hoffen, dass ich da durchsteige.

Du hast gefragt - ne Antwort bekommen, wieder gefragt und wieder ne Antwort bekommen.
Wenn Du Fragen hast, frag.
Wenn ich nicht antworte, findet sich schon einer....
Und Salami am abend... Auf der Couch?
Duck und weg.

Hallo
Ich habe in der Sketchkiste einen Sketch für Radiobuttons gefunden. Zur Zeit arbeitet dieser mit drei Buttons und Relais. Über den struct RADIOBUTTON kannst du die entsprechende Anzahl der Ein- und Ausgabegeräte für dein Projekt anpassen. Einfach mal ausprobieren.

/* BLOCK COMMENT
  ATTENTION: This Sketch contains elements of C++.
  https://www.learncpp.com/cpp-tutorial/
  https://forum.arduino.cc/t/a-b-umschalter-mit-taster/934347
*/
#define ProjectName "A/B Umschalter mit Taster"
// YOU MAY NEED TO CHANGE THESE CONSTANTS TO YOUR HARDWARE AND NEEDS
enum {On, Off};             // low active relay type
// CONSTANT DEFINITION
enum {One, Two, Three};     // button names
// VARIABLE DECLARATION AND DEFINITION
unsigned long currentTime;
struct RADIOBUTTON {
  byte name_;               // button name
  byte buttonPin;           // portPin o---|button|---GND
  int statusQuo;            // current pin state
  byte relayPin;            // portPin o---|relay shield|---GND
  unsigned long stamp;      // time information for debouncing
  unsigned long duration;   // time information for debouncing
} radioButtons [] {
  {One, A0, false, 3, 0, 20},
  {Two, A1, false, 5, 0, 20},
  {Three, A2, false, 6, 0, 20},
};
// -------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  Serial.println(F("."));
  Serial.print(F("File   : ")), Serial.println(__FILE__);
  Serial.print(F("Date   : ")), Serial.println(__DATE__);
  Serial.print(F("Project: ")), Serial.println(ProjectName);
  pinMode (LED_BUILTIN, OUTPUT);  // used as heartbeat indicator
  for (auto &radioButton : radioButtons) {
    pinMode(radioButton.buttonPin, INPUT_PULLUP);
    digitalWrite(radioButton.relayPin, Off);
    pinMode(radioButton.relayPin, OUTPUT);
  }
  digitalWrite(radioButtons[One].relayPin, On);
}
void loop () {
  currentTime = millis();
  digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
  for (auto &radioButton : radioButtons) {
    if (currentTime - radioButton.stamp - radioButton.duration) {
      radioButton.stamp = currentTime;
      int stateNew = !digitalRead(radioButton.buttonPin);
      if (radioButton.statusQuo != stateNew) {
        radioButton.statusQuo = stateNew;
        if (radioButton.statusQuo) {
          for (auto &radioButton : radioButtons) digitalWrite(radioButton.relayPin, Off);
          digitalWrite(radioButtons[radioButton.name_].relayPin, On);
        }
      }
    }
  }
}

Ich wünsche einen geschmeidigen Abend und viel Spass beim Programmieren in C++.

Vielen Dank, echt klasse. Der Skatch von paulpaulson funktioniert prima mit 8 I/O's.
Jetzt würde ich gerne eine weitere Lane mit 8 I/O's haben und dachte, ich komme mit Kopieren und einigen Anpassungen von Variablen ans Ziel. Leider falsch gedacht.
Könnt Ihr mir sagen, was ich falsch gemacht habe?

`
enum {On, Off};             // low active relay type
// CONSTANT DEFINITION
enum {One, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Eleven, Twelve, Thirteen, Fourteen, Fiveteen, Sixteen};     // button names
// VARIABLE DECLARATION AND DEFINITION
unsigned long currentTime;
struct RADIOBUTTON {
  byte name_;               // button name
  byte buttonPin;           // portPin o---|button|---GND
  int statusQuo;            // current pin state
  byte relayPin;            // portPin o---|relay shield|---GND
  unsigned long stamp;      // time information for debouncing
  unsigned long duration;   // time information for debouncing
}radioButtons [] {
  {One, A8, false, 22, 0, 20},
  {Two, A9, false, 23, 0, 20},
  {Three, A10, false, 24, 0, 20},
  {Four, A11, false, 25, 0, 20},
  {Five, A12, false, 26, 0, 20},
  {Six, A13, false, 27, 0, 20},
  {Seven, A14, false, 28, 0, 20},
  {Eight, A15, false, 29, 0, 20},
};

struct RADIOBUTTON1 {
  byte name_1;               // button name
  byte buttonPin1;           // portPin o---|button|---GND
  int statusQuo1;            // current pin state
  byte relayPin1;            // portPin o---|relay shield|---GND
  unsigned long stamp1;      // time information for debouncing
  unsigned long duration1;   // time information for debouncing
} radioButtons1 [] {
  {Nine, A0, false, 30, 0, 20},
  {Ten, A1, false, 31, 0, 20},
  {Eleven, A2, false, 32, 0, 20},
  {Twelve, A3, false, 33, 0, 20},
  {Thirteen, A4, false, 34, 0, 20},
  {Fourteen, A5, false, 35, 0, 20},
  {Fiveteen, A6, false, 36, 0, 20},
  {Sixteen, A7, false, 37, 0, 20},
};
// -------------------------------------------------------------------
void setup() {

  for (auto &radioButton : radioButtons) {
    pinMode(radioButton.buttonPin, INPUT_PULLUP);
    digitalWrite(radioButton.relayPin, Off);
    pinMode(radioButton.relayPin, OUTPUT);
  }
  digitalWrite(radioButtons[One].relayPin, On);

  for (auto &radioButton1 : radioButtons1) {
    pinMode(radioButton1.buttonPin1, INPUT_PULLUP);
    digitalWrite(radioButton1.relayPin1, Off);
    pinMode(radioButton1.relayPin1, OUTPUT);
  }
  digitalWrite(radioButtons1[Nine].relayPin1, On);
}
void loop () {
  currentTime = millis();
  digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
  for (auto &radioButton : radioButtons) {
    if (currentTime - radioButton.stamp - radioButton.duration) {
      radioButton.stamp = currentTime;
      int stateNew = !digitalRead(radioButton.buttonPin);
      if (radioButton.statusQuo != stateNew) {
        radioButton.statusQuo = stateNew;
        if (radioButton.statusQuo) {
          for (auto &radioButton : radioButtons) digitalWrite(radioButton.relayPin, Off);
          digitalWrite(radioButtons[radioButton.name_].relayPin, On);
        }
      }
    }
  }
  for (auto &radioButton1 : radioButtons1) {
    if (currentTime - radioButton1.stamp1 - radioButton1.duration1) {
      radioButton1.stamp1 = currentTime;
      int stateNew1 = !digitalRead(radioButton1.buttonPin1);
      if (radioButton1.statusQuo1 != stateNew1) {
        radioButton1.statusQuo1 = stateNew1;
        if (radioButton1.statusQuo1) {
          for (auto &radioButton1 : radioButtons1) digitalWrite(radioButton1.relayPin1, Off);
          digitalWrite(radioButtons1[radioButton1.name_1].relayPin1, On);
        }
      }
    }
  }
}`

eigentlich hättest das struct von paul für deine zweite Gruppe wiederverwenden können.

Aber die Kernfrage ist:

Was macht dein Sketch aktuell was dir nicht gefällt?
Was soll er statt dessen machen?

kurz gesagt: FEHLER beschreiben und Sollzustand beschreiben.

(wenn du den Fehler selber finden willst, lies nach was eine c++ enumeration ist, wie ein Array funktioniert, dass das erste Feld immer 0 ist und dann ist klar, warum das nicht passt: dein Nine wird eben nicht zu 0 ... rest sollte klar sein)

Hallo, was macht der Skatch gerade:

Eingänge A8-A15 und Ausgänge 22-29 funktionieren wie sie sollen. Durch Tasterdruck des jeweiligen Eingangs zieht das entsprechende Relais an und alle anderen fallen ab.
Beim betätigen des Eingangs A0 zieht das Relais 22 an. Bei A1 zieht das Relais 23 an. Dabei geht allerdings 22 nicht aus. D.h. mit A0-A7 kann ich nacheinander alle Relais 22-29 einschalten. Mit drücken von z.B. A8 gehen dann alle wieder aus, nur 22 bleibt an.
Ich möchte aber mit A0-A7 die Ausgänge 30-37 genauso schalten wie bei A8-A15.

Ich hoffe das war verständlich. :wink:

ja und hast du mittlerweile rausgefunden was in deiner enumeration für Nine drinnen steht?

gib es dir auf der Seriellen Schnittstelle aus.
Serial.println(Nine).

Und jetzt überleg mal was aus dieser Anweisung wird:

digitalWrite(radioButtons1[radioButton1.name_1].relayPin1, On);

na?
verstehst du deinen Fehler jetzt?

edit:
quick und dirty könntest du das enum teilen, dann beginnt Nine wieder mit 0 und es passt zu den Array Index.

// https://forum.arduino.cc/t/a-b-umschalter-mit-taster/934347/
enum {On, Off};             // low active relay type
// CONSTANT DEFINITION
enum {One, Two, Three, Four, Five, Six, Seven, Eight};     // button names
enum {Nine, Ten, Eleven, Twelve, Thirteen, Fourteen, Fiveteen, Sixteen};     // button names

// VARIABLE DECLARATION AND DEFINITION
unsigned long currentTime;
struct RADIOBUTTON {
  byte name_;               // button name
  byte buttonPin;           // portPin o---|button|---GND
  int statusQuo;            // current pin state
  byte relayPin;            // portPin o---|relay shield|---GND
  unsigned long stamp;      // time information for debouncing
  unsigned long duration;   // time information for debouncing
} radioButtons [] {
  {One, A8, false, 22, 0, 20},
  {Two, A9, false, 23, 0, 20},
  {Three, A10, false, 24, 0, 20},
  {Four, A11, false, 25, 0, 20},
  {Five, A12, false, 26, 0, 20},
  {Six, A13, false, 27, 0, 20},
  {Seven, A14, false, 28, 0, 20},
  {Eight, A15, false, 29, 0, 20},
};

RADIOBUTTON radioButtons1 [] {
  {Nine, A0, false, 30, 0, 20},
  {Ten, A1, false, 31, 0, 20},
  {Eleven, A2, false, 32, 0, 20},
  {Twelve, A3, false, 33, 0, 20},
  {Thirteen, A4, false, 34, 0, 20},
  {Fourteen, A5, false, 35, 0, 20},
  {Fiveteen, A6, false, 36, 0, 20},
  {Sixteen, A7, false, 37, 0, 20},
};

// -------------------------------------------------------------------
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);  // hat meines erachtens im Ausgangssketch gefehlt
  for (auto &radioButton : radioButtons) {
    pinMode(radioButton.buttonPin, INPUT_PULLUP);
    digitalWrite(radioButton.relayPin, Off);
    pinMode(radioButton.relayPin, OUTPUT);
  }
  digitalWrite(radioButtons[One].relayPin, On);

  for (auto &radioButton1 : radioButtons1) {
    pinMode(radioButton1.buttonPin, INPUT_PULLUP);
    digitalWrite(radioButton1.relayPin, Off);
    pinMode(radioButton1.relayPin, OUTPUT);
  }
  digitalWrite(radioButtons1[Nine].relayPin, On);
}
void loop () {
  currentTime = millis();
  digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
  for (auto &radioButton : radioButtons) {
    if (currentTime - radioButton.stamp - radioButton.duration) {
      radioButton.stamp = currentTime;
      int stateNew = !digitalRead(radioButton.buttonPin);
      if (radioButton.statusQuo != stateNew) {
        radioButton.statusQuo = stateNew;
        if (radioButton.statusQuo) {
          for (auto &radioButton : radioButtons) digitalWrite(radioButton.relayPin, Off);
          digitalWrite(radioButtons[radioButton.name_].relayPin, On);
        }
      }
    }
  }
  // dirty duplicate code now...
  for (auto &radioButton : radioButtons1) {
    if (currentTime - radioButton.stamp - radioButton.duration) {
      radioButton.stamp = currentTime;
      int stateNew = !digitalRead(radioButton.buttonPin);
      if (radioButton.statusQuo != stateNew) {
        radioButton.statusQuo = stateNew;
        if (radioButton.statusQuo) {
          for (auto &radioButton : radioButtons) digitalWrite(radioButton.relayPin, Off);
          digitalWrite(radioButtons[radioButton.name_].relayPin, On);
        }
      }
    }
  }
}

ungetestet, 2282Flash/221SRAM am Mega.

Du siehst, es gibt nur EINE Struktur. Jetzt mit zwei Instanzen. Daher brauchen die Mmember Variablen kein Anhängsel 1.

Die Lösung ist aber nicht besonders schön, weils noch immer duplizierten Code gibt.

Alternativ:
Wenn du nun die Anweisungen im Loop zu einer Member function machst, wäre es nur mehr einmal im Sketch.
Wir machen also aus der Struktur eine Klasse.
Weiter gedacht.
die 8 Buttons/Relays bilden eine logische Einheit - sie entriegeln jeweils die anderen Ausgänge
Das heißt wir Modellieren jetzt eine Klasse die 8 Relais und 8 Buttons als Einheit verwaltet.
16 pins an ein Objekt übergeben schaut zwar graußig aus, aber das ist dem Controller egal.

"Entprellen" brauchst meines erachtens Taster nicht, wenn sie nur etwas aktivieren sollen.

Als "Goodie" legen wir dann nicht zwei separate Instanzen (objekte) mit radioButton und radioButton1 an, sondern wir machen uns ein ARRAY von radiobutton.
Wir haben jetzt also zwei Objekte: radioButton[0] und radioButton[1]. Das können wir jeweils in Forschleifen schön durchackern.
für jede weitere 8er Einheit braucht es eine einzige Zeile - nämlich die Übergabe der 16 Pins. Bzw. wenn man individuelle "Buttonnamen" in einem enum haben will halt auch noch ein Enum.

// https://forum.arduino.cc/t/a-b-umschalter-mit-taster/934347/
// CONSTANT DEFINITION
enum {One, Two, Three, Four, Five, Six, Seven, Eight};                       // button names
enum {Nine, Ten, Eleven, Twelve, Thirteen, Fourteen, Fiveteen, Sixteen};     // button names
constexpr byte ON = LOW;    // low active button
constexpr byte OFF = HIGH;

constexpr byte noOfButtons = 8;   // buttons/relays per group

unsigned long currentTime;
class Radiobutton {
  public:
    byte currentState = 0;              // current active output
    const byte buttonPin[noOfButtons];  // portPin o---|button|---GND
    const byte relayPin[noOfButtons];   // portPin o---|relay shield|---GND

    Radiobutton (byte buttonPin0, byte buttonPin1, byte buttonPin2, byte buttonPin3, byte buttonPin4, byte buttonPin5, byte buttonPin6, byte buttonPin7,
                 byte relayPin0, byte relayPin1, byte relayPin2, byte relayPin3, byte relayPin4, byte relayPin5, byte relayPin6, byte relayPin7 ) :
      buttonPin{buttonPin0, buttonPin1, buttonPin2, buttonPin3, buttonPin4, buttonPin5, buttonPin6, buttonPin7, },
      relayPin {relayPin0, relayPin1, relayPin2, relayPin3, relayPin4, relayPin5, relayPin6, relayPin7,}
    {}

    void begin()
    {
      for (byte i = 0; i < noOfButtons; i++)
      {
        if (buttonPin[i] != 255) {
          pinMode(buttonPin[i], INPUT_PULLUP);
          digitalWrite(buttonPin[i], OFF);
          pinMode(relayPin[i], OUTPUT);
        }
      }
      //set(0); // optional init with an active pin
    }

    void set(byte newState)
    {
      currentState = newState;
      for (byte i = 0; i < noOfButtons; i++)
      {
        if (currentState == i) digitalWrite(relayPin[i], HIGH); else digitalWrite(relayPin[i], LOW);  // evtl. LOW/HIGH tauschen falls man low active Relais hat (ich habe aber high active LEDs
      }
    }

    void update()
    {
      for (byte i = 0; i < noOfButtons; i++)
      {
        if (digitalRead(buttonPin[i]) == ON && currentState != i)  // only on change
        {
          set(i);
        }
      }
    }
};


Radiobutton radioButton[] {
  // 8 input pins                        8 output pins
  {A8, A9, A10, A11, A12, A13, A14, A15, 22, 23, 24, 25, 26, 27, 28, 29},
  {A0, A1, A2, A3, A4, A5, A6, A7, 30, 31, 32, 33, 34, 35, 36, 37}
};

/*
  // mein Test
  Radiobutton radioButton[] {
  // 8 input pins                        8 output pins
  {A0, A1, 255, 255, 255, 255, 255, 255, 2, 3, 255, 255, 255, 255, 255, 255, },
  {A2, A3, 255, 255, 255, 255, 255, 255, 4, 5, 255, 255, 255, 255, 255, 255, }
  };
*/
// -------------------------------------------------------------------
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);  // hat meines erachtens im Ausgangssketch gefehlt
  for (auto &i : radioButton) i.begin();
  radioButton[0].set(One);   // optional activate one
  radioButton[1].set(Nine);
}

void loop () {
  digitalWrite(LED_BUILTIN, (millis()/ 500) % 2);
  for (auto &i : radioButton) i.update();
}

getestet, 1954 Flash/43 byte SRAM am Mega.
300 byte weniger Flash, nur ein fünftel SRAM
Und der loop nur mehr ein Zweizeiler :wink:

Hallo
Ich habe meinen Sketch ein bißl klassenlos aufgebohrt und ein zweidimensionales Array programmmiert und die Methode dafür entsprechend angepasst. Du kannst dieses Array für dein Projekt anpassen.

/* BLOCK COMMENT
  ATTENTION: This Sketch contains elements of C++.
  https://www.learncpp.com/cpp-tutorial/
  https://forum.arduino.cc/t/a-b-umschalter-mit-taster/934347
*/
#define ProjectName "A/B Umschalter mit Taster mit zwei Bänken"
// YOU MAY NEED TO CHANGE THESE CONSTANTS TO YOUR HARDWARE AND NEEDS
enum {On, Off};             // low active relay type
// CONSTANT DEFINITION
enum {Bank1,Bank2};         // names of switch banks
enum {One, Two};            // button name first bank
enum {Three, Four};         // button name second bank
// VARIABLE DECLARATION AND DEFINITION
unsigned long currentTime;
constexpr int NumberOfSwitches {2};
struct RADIOBUTTON {
  byte name_;               // button name
  byte buttonPin;           // portPin o---|button|---GND
  int statusQuo;            // current pin state
  byte relayPin;            // portPin o---|relay shield|---GND
  unsigned long stamp;      // time information for debouncing
  unsigned long duration;   // time information for debouncing
} radioButtons [][NumberOfSwitches] {
  {
    {One, A0, false, 3, 0, 20},
    {Two, A1, false, 5, 0, 20},
  },
  {
    {Three, A2, false, 6, 0, 20},
    {Four, A3, false, 7, 0, 20},
  },
};
// -------------------------------------------------------------------
void setup() {
  Serial.begin(9600);
  Serial.println(F("."));
  Serial.print(F("File   : ")), Serial.println(__FILE__);
  Serial.print(F("Date   : ")), Serial.println(__DATE__);
  Serial.print(F("Project: ")), Serial.println(ProjectName);
  pinMode (LED_BUILTIN, OUTPUT);  // used as heartbeat indicator

  for (auto &radioButton_ : radioButtons) {
    for (auto &radioButton : radioButton_) {
      pinMode(radioButton.buttonPin, INPUT_PULLUP);
      digitalWrite(radioButton.relayPin, Off);
      pinMode(radioButton.relayPin, OUTPUT);
    }
  }
  digitalWrite(radioButtons[Bank1][One].relayPin, On);
  digitalWrite(radioButtons[Bank2][Three].relayPin, On);
}
void loop () {
  currentTime = millis();
  digitalWrite(LED_BUILTIN, (currentTime / 500) % 2);
  for (auto &radioButton_ : radioButtons) {
    for (auto &radioButton : radioButton_) {
      if (currentTime - radioButton.stamp - radioButton.duration) {
        radioButton.stamp = currentTime;
        int stateNew = !digitalRead(radioButton.buttonPin);
        if (radioButton.statusQuo != stateNew) {
          radioButton.statusQuo = stateNew;
          if (radioButton.statusQuo) {
            for (auto &radioButton : radioButton_) digitalWrite(radioButton.relayPin, Off);
            digitalWrite(radioButton_[radioButton.name_].relayPin, On);
          }
        }
      }
    }
  }
}

Ich wünsche einen geschmeidigen Tag und viel Spass beim Programmieren in C++.
p.s.
An die Zahlen von noiasca komme ich nicht ran.
Sketch uses 2802 bytes (8%) of program storage space. Maximum is 32256 bytes.
Global variables use 474 bytes (23%) of dynamic memory, leaving 1574 bytes for local variables. Maximum is 2048 bytes.

Hm, dann will ich auch mal:

Der Sketch verwendet 1802 Bytes (0%) des Programmspeicherplatzes. Das Maximum sind 253952 Bytes.
Globale Variablen verwenden 41 Bytes (0%) des dynamischen Speichers, 8151 Bytes für lokale Variablen verbleiben. Das Maximum sind 8192 Bytes.

Gleicher Ansatz wie gestern.
Wenn ich was übersehen habe, kurz Bescheid geben.

// *INDENT-OFF*
const byte ebenen = 2;
const byte inPin[ebenen][8] = {{53, 51, 49, 47, 45, 43, 41, 39},
                               {37, 36, 35, 34, 33, 32, 31, 30}};
const byte outPin[ebenen][8] = {{52, 50, 48, 46, 44, 42, 40, 38},
                                {29, 28, 27, 26, 25, 24, 23, 22}};

// *INDENT-ON*
void setup()
{
  //Serial.begin(115200);
  // Serial.println(F("Start..."));
  for (byte c = 0; c < ebenen; c++)
    for (byte b = 0; b < sizeof(inPin) / ebenen; b++)
    {
      pinMode(inPin[c][b], INPUT_PULLUP);
      pinMode(outPin[c][b], OUTPUT);
      digitalWrite(outPin[c][b], HIGH);
    }
}

void loop()
{
  for (byte c = 0; c < ebenen; c++)
    for (byte b = 0; b < sizeof(inPin) / ebenen; b++)
    {
      if ((!digitalRead(inPin[c][b])))
      {
        schaltePin(c, b);
        continue;
      }
    }
}
void schaltePin(const byte ebene, const byte myPin)
{
  for (byte c = 0; c < ebenen; c++)
    for (byte b = 0; b < sizeof(inPin) / ebenen; b++)
    {
      digitalWrite(outPin[c][b], HIGH);
    }
  digitalWrite(outPin[ebene][myPin], LOW);
}

:slight_smile:
[edit]
kürzt man schaltePin ab, sinds nur noch 1774/41 bytes.

void schaltePin(const byte ebene, const byte myPin)
{
  for (byte c = 0; c < ebenen; c++)
    for (byte b = 0; b < sizeof(inPin) / ebenen; b++)
    {
      if (c != ebene || b != myPin)
        digitalWrite(outPin[c][b], HIGH);
      else
        digitalWrite(outPin[c][b], LOW);
    }
}

Hallo
Man bekommt den Code nochn bißl schlanker, wenn man das nicht benötigte Debouncing und die Texte rausschmeißt.

irgenwas ist ja immer :nerd_face:

Aufm Mega - die Variante 2 darf nicht && sondern || heissen.
Ich taste von PIN 53 bis 39 gegen GND, dann geht der Gegenüber in Stellung.
Bei den nächsten 8 sind die 4 und deren Gegenüber mit den nächsten 8 je 4 gegenüber.
Ich habs mit dem SerMon gemacht:

void schaltePin(const byte ebene, const byte myPin)
{
  /*
    for (byte c = 0; c < ebenen; c++)
    for (byte b = 0; b < sizeof(inPin) / ebenen; b++)
    {
      digitalWrite(outPin[c][b], HIGH);
    }
    digitalWrite(outPin[ebene][myPin], LOW);
  */
  for (byte c = 0; c < ebenen; c++)
    for (byte b = 0; b < sizeof(inPin) / ebenen; b++)
    {
      if ((c != ebene) || (b != myPin))
        digitalWrite(outPin[c][b], HIGH);
      else
        digitalWrite(outPin[c][b], LOW);
    }
    // AUSGABE Welche PIN jetzt LOW ist:
  for (byte c = 0; c < ebenen; c++)
    for (byte b = 0; b < sizeof(inPin) / ebenen; b++)
    {
      if (!digitalRead(outPin[c][b]))
        Serial.print(outPin[c][b]);
      Serial.print(" ");
    }
  Serial.println();
}

Vielen lieben Dank an euch alle. Jetzt habe ich verschiedene Herangehensweisen kennengelernt.
Ich nutze erstmal das Update von paulpaulson. Das hat sofort mit 2x8 I/O's funktioniert.
Alle anderen Lösungen muss ich noch lesen und verstehen lernen.
Dafür brauche ich bestimmt ein paar Tage. Habe ja erst am Mittwoch mit C++ angefangen. :wink:

Super Forum hier. Das ich gleich einen quasi schlüsselfertigen Sketch präsentiert bekomme, hätte ich nicht gedacht.

Jetzt geht's vom Breadboard zum Lötkolben. Dann werde ich schon vor Weihnachten mit dem Projekt fertig. Dank(e) euch! :+1:

und vergessen das fertige Projekt zu präsentieren.