Abfrage mehrerer Eingänge, z.B. mittels Drehschalter

Hallo,
ich bräuchte bitte einen Hinweis, wie mein Vorhaben (besser als ich es mir momentan erschließen konnte) umzusetzen ist:

Ich möchte an einem Arduino Mega ein 16-fach Relais-Shield anschließen, um insgesamt 9 verschiedene Spannungsprüfungen durchzuführen. Je nach Prüfung werden die zwei am Ende liegenden Messbuchsen unterschiedlich belegt und mittels Multimeter abgegriffen - mit Multimeter, weil das geeicht sein muss und ggf. leicht austauschbar sein soll.

Diese 9 unterschiedlichen Prüfungen möchte ich mittels Drehschalter (ähnlich wie dieser hier) einstellen können. Die Nummer der ausgewählten Prüfung soll am LCD angezeigt werden. Nun dachte ich, ich lege +5V am Drehschalter an und deklariere 9 Eingänge, die eingelesen werden. Damit der Controller nicht ständig einliest, habe ich eine Variable “Stellung_Drehknopf” & “Stellung_Drehknopf_alt”, die in einer while-Schleife miteinander verglichen werden, so dass sich nur wenn es dort einen Unterschied gibt, die Eingänge nach und nach eingelesen werden. Am Ende einer Prüfung wird dann “Stellung_Drehknopf_alt” auf einen anderen Wert gesetzt, so dass die Prüfung des Dreschalters wieder stattfinden kann. Hier mal der Sketch:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);                                                   // Adresse 0x3F oder 0x27 (Arduino Uno I2C Pins sind: A4==SDA, A5==SCL; MEGA 20 = SDA, 21 = SCL)

// Pinbelegungen
#define Stellung_1 3                                                                // Wählschalter mit den jeweiligen Pins verbunden
#define Stellung_2 4
#define Stellung_3 5
#define Stellung_4 7
#define Stellung_5 8
#define Stellung_6 9
#define Stellung_7 11
#define Relais_N  22
#define Relais_L  23
#define Relais_1  24
#define Relais_2  25
#define Relais_12 26
#define Relais_3  26
#define Relais_3B 27
#define Relais_4  28
#define Relais_34 29
#define Relais_5  30
#define Relais_5B 31
#define Relais_6  32
#define Relais_7  33

// usw...

byte Stellung_Drehknopf = 0;                                                        // absichtlich Wert = 0, damit die Abfrage des Drehknopfes startet
byte Stellung_Drehknopf_alt = 10;                                                    // absichtlich Wert > 7, damit die Abfrage des Drehknopfes startet

// Variablen
unsigned long startzeit;                                                            // größtmöglicher Wertebereich f. Zeitstempel (ca. 4,29*10^10)
volatile bool status500ms = false;                                                  // Statusvariable, Bedingung f. Prüfungsstart. " volatile", da die Variable durch Interrupt geändert wird
float spannungswert = 0;


void setup() {
  pinMode(2, INPUT_PULLUP);                                                         // interner Pullup-Widerstand aktiviert, hilft gg. Störeinflüsse
  pinMode(A0, INPUT_PULLUP);                                                        // interner Pullup-Widerstand aktiviert, hilft gg. Störeinflüsse
  pinMode(Stellung_1, INPUT_PULLUP);                                                // Zuweisungen siehe oben
  pinMode(Stellung_2, INPUT_PULLUP);
  pinMode(Stellung_3, INPUT_PULLUP);
  pinMode(Stellung_4, INPUT_PULLUP);
  pinMode(Stellung_5, INPUT_PULLUP);
  pinMode(Stellung_6, INPUT_PULLUP);
  pinMode(Stellung_7, INPUT_PULLUP);  
  
  digitalWrite(Stellung_1,LOW);
  digitalWrite(Stellung_2,LOW);
  digitalWrite(Stellung_3,LOW);  
  digitalWrite(Stellung_4,LOW);  
  digitalWrite(Stellung_5,LOW);
  digitalWrite(Stellung_6,LOW);  
  digitalWrite(Stellung_7,LOW);  

  digitalWrite(Relais_N,LOW);
  digitalWrite(Relais_L,LOW);  
  digitalWrite(Relais_1,LOW);
  digitalWrite(Relais_2,LOW);
  digitalWrite(Relais_12,LOW);    
  digitalWrite(Relais_3,LOW);  
  digitalWrite(Relais_3B,LOW);
  digitalWrite(Relais_4,LOW);
  digitalWrite(Relais_34,LOW);
  digitalWrite(Relais_5,LOW);
  digitalWrite(Relais_5B,LOW);
  digitalWrite(Relais_6,LOW);  
  digitalWrite(Relais_7,LOW);  
  attachInterrupt(0, statusinterrupt, LOW);                                         // "Interrupt 0" ist Pin 2! void Statusinterrupt() wird aufgerufen
 
  lcd.init();                                                                       // Initialisierung LCD
  lcd.backlight();                                                                  // Hintergrundbeleuchtung an
  lcd.setCursor (0, 2);            
  lcd.print("Ger\341t anschlie\342en &");
  lcd.setCursor (0, 3);                        
  lcd.print("Pr\365fung w\341hlen");
}

void statusinterrupt() {                                                            // hier wird der Status auf "true" gesetzt
  status500ms = true;
}

void Drehknopf() {                                                                  // Abfrage des Drehknopfes
  while (Stellung_Drehknopf_alt != Stellung_Drehknopf) {
    if (digitalRead(Stellung_1) == HIGH) {
      Stellung_Drehknopf = 1;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
    }
    else if (digitalRead(Stellung_2) == HIGH) {
      Stellung_Drehknopf = 2;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
    }
    else if (digitalRead(Stellung_3) == HIGH) {
      Stellung_Drehknopf = 3;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
    }
    else if (digitalRead(Stellung_4) == HIGH) {
      Stellung_Drehknopf = 4;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
    }
    else if (digitalRead(Stellung_5) == HIGH) {
      Stellung_Drehknopf = 5;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
    }
    else if (digitalRead(Stellung_6) == HIGH) {
      Stellung_Drehknopf = 6;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
    }
    else if (digitalRead(Stellung_7) == HIGH) {
      Stellung_Drehknopf = 7;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
    }
    else Stellung_Drehknopf = 0;

  }
}

void Pruefung_1() {                                                               // 230V, Pin 6 auf +12V, Spannung zwischen Pin 1 & Pin 3 messen:
  //noInterrupts();
  digitalWrite(Relais_N, LOW);                                                    // Relais schaltet Nullleiter 230V AC durch
  digitalWrite(Relais_L, LOW);                                                    // Relais schalter Phase 230V AC durch
  digitalWrite(Relais_1, HIGH);                                                   // Relais schaltet Pin 1 an Pluspol der Bananenbuchse
  digitalWrite(Relais_2, LOW);                                                    // Relais nimmt Pin 2 vom Pluspol der Bananenbuchse
  digitalWrite(Relais_3, HIGH);                                                   // Relais schaltet Pin 3 an Minuspol der Bananenbuchse
  digitalWrite(Relais_3B, LOW);                                                   // Relais nimmt 0,2A Last von Pin 3
  digitalWrite(Relais_4, LOW);                                                    // Relais nimmt Pin 4 vom Minuspol der Bananenbuchse
  digitalWrite(Relais_5, LOW);                                                    // Relais nimmt 0,2A Last von Pin 5  
  digitalWrite(Relais_5B, LOW);                                                   // Relais schaltet Pin 5 an Pluspol der Bananenbuchse
  digitalWrite(Relais_6, LOW);                                                    // Relais schaltet +12V an Pin 6
  digitalWrite(Relais_7, LOW);                                                    // Relais nimmt Pin 7 vom Pluspol der Bananenbuchse
  digitalWrite(Relais_12, LOW);                                                   // Relais nimmt 1,6A Last von Pin 1 & Pin 2  
  digitalWrite(Relais_34, LOW);                                                   // Relais nimmt 1,6A Last von Pin 3 & Pin 4  

  
  lcd.setCursor (0, 0);                                                           // Ausgabe des Ergebnisses ...
  lcd.print("Pr\365fung 1: 1 & 3");                                                        
  lcd.setCursor (0, 2);
  lcd.print("Soll: 37,4V - 42,6V");
 Stellung_Drehknopf_alt = 10;

}


void loop() {
  Drehknopf();
}

Ich habe das Gefühl, der Arduino verschluckt sich beim Prüfen der Eingänge, weil er eine Änderung teilweise erst nach ein paar Sekunden mitbekommt. Das geht mit Sicherheit viel geschmeidiger, aber ich komme da nicht drauf :o

Viele Grüße,
Marcus

PS: Den Code musste ich jetzt kürzen, weil ich ihn sonst nicht hätte posten können

edit:
PPS: Ich sehe gerade, dass ich hier (noch) nur 7 statt 9 Eingänge drin hab - nicht wundern deswegen, es sollen 9 sein …

Dein Sketch ist nicht kompilierbar.

Wozu ist das 'noInterrupts' hier:

void Pruefung_1() {                                                               // 230V, Pin 6 auf +12V, Spannung zwischen Pin 1 & Pin 3 messen:
  noInterrupts();

Sowas ist gefährlich - ich sehe nicht wo Du die Interrupts wieder einschaltest.

Ausserdem solltest Du dich mal dringend mit Arrays ( und evtl. noch mit struct ) befassen.

Und was bezweckst Du mit diesem Konstrukt:

 pinMode(Stellung_1, INPUT_PULLUP);                                                // Zuweisungen siehe oben
  ...
  pinMode(Stellung_7, INPUT_PULLUP);  
  
  digitalWrite(Stellung_1,LOW);
  .....
  digitalWrite(Stellung_7,LOW);

?? Da kannst Du auch gleich

 pinMode(Stellung_1, INPUT);                                                // Zuweisungen siehe oben
  ...

schreiben. Einfacher wäre aber wohl den Drehschalter gegen Gnd schalten zu lassen.

Edit: Und was passiert im loop wirklich? Wo hängt er da gegebenenfalls, und wann wird das drehknopf_alt überall wieder rückgesetzt?
Mit dem Fragment kann man jetzt jedenfalls zum Problem nichts sagen ( ausser, dass es sehr umstäändlich geschrieben ist :wink: )

Hi,
viel von dem COde musste ich wg. der Begrenzung auf 9000 Zeichen kürzen - deswegen der Kompilierungsfehler, sorry - habe ich gerade angepasst.

Ach, wegen pinMode "INPUT_PULLUP" ... das war das Gleiche wie den Auf "HIGH" zu setzen, ne? Stimmt, das hatte ich nicht mehr auf dem Schirm! Danke für den Hinweis.

Drehschalter gegen GND schalten? Hmm, was wäre denn da einfacher/der Vorteil?

Viele Grüße,
Marcus

Dann kannst Du die eingebauten PULLUP benutzen und musst nicht für jeden Eingang einen externen PullDown-Widerstand nach GND anbauen. Die hast Du doch dran oder?

Gruß Tommy

Hallo Marcus,

Faddi:
Drehschalter gegen GND schalten? Hmm, was wäre denn da einfacher/der Vorteil?

Du sparst dir die 9 externen Pull-down Widerstände. (Ok, Tommy war schneller :wink: )

Und so wie der Sketch jetzt aussieht, werden die Drehschalter ja nie mehr eingeschaltet, da drehknopf_alt nicht mehr rückgesetzt wird. Ich vermute dass, das Problem ( mal wieder ) in den Teilen liegt, die nicht gezeigt werden ::slight_smile: .

Hi,

Tommy56:
Dann kannst Du die eingebauten PULLUP benutzen und musst nicht für jeden Eingang einen externen PullDown-Widerstand nach GND anbauen. Die hast Du doch dran oder?

Gruß Tommy

du kennst “deine Pappenheimer” :roll_eyes:
Ich hatte ursprünglich zum Testen mittels eines einzigen Tasters einen Pulldownwiderstand dran, ja - aber um ehrlich zu sein bei den 9 dann heute nicht. Mit den doppelt-gemoppelten Zuweisungen und diesem Fehler hat das an den Eingängen wahrscheinlich gestreut ohne Ende…

Dank Eurer Hilfe wird es langsam so, wie ich mir das eigentlich vorgestellt hatte. Dann schien ja zumindest mein Weg im Prinzip nicht schlecht gewesen zu sein (immerhin etwas) - nur die Umsetzung war bescheiden.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);                                                   // Adresse 0x3F oder 0x27 (Arduino Uno I2C Pins sind: A4==SDA, A5==SCL; MEGA 20 = SDA, 21 = SCL)

// Pinbelegungen
#define Stellung_1 4                                                                // Wählschalter mit den jeweiligen Pins verbunden
#define Stellung_2 5
#define Stellung_3 6
#define Stellung_4 7
#define Stellung_5 8
#define Stellung_6 9
#define Stellung_7 10

// usw...

byte Stellung_Drehknopf = 0;                                                        // absichtlich Wert = 0, damit die Abfrage des Drehknopfes startet
byte Stellung_Drehknopf_alt = 10;                                                    // absichtlich Wert > 7, damit die Abfrage des Drehknopfes startet

// Variablen
unsigned long startzeit;                                                            // größtmöglicher Wertebereich f. Zeitstempel (ca. 4,29*10^10)
volatile bool status500ms = false;                                                  // Statusvariable, Bedingung f. Prüfungsstart. " volatile", da die Variable durch Interrupt geändert wird
float spannungswert = 0;


void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT_PULLUP);                                                         // interner Pullup-Widerstand aktiviert, hilft gg. Störeinflüsse
  pinMode(A0, INPUT_PULLUP);                                                        // interner Pullup-Widerstand aktiviert, hilft gg. Störeinflüsse
  pinMode(Stellung_1, INPUT_PULLUP);                                                // Zuweisungen siehe oben
  pinMode(Stellung_2, INPUT_PULLUP);
  pinMode(Stellung_3, INPUT_PULLUP);
  pinMode(Stellung_4, INPUT_PULLUP);
  pinMode(Stellung_5, INPUT_PULLUP);
  pinMode(Stellung_6, INPUT_PULLUP);
  pinMode(Stellung_7, INPUT_PULLUP);  
  attachInterrupt(0, statusinterrupt, LOW);                                         // "Interrupt 0" ist Pin 2! void Statusinterrupt() wird aufgerufen
 
  lcd.init();                                                                       // Initialisierung LCD
  lcd.backlight();                                                                  // Hintergrundbeleuchtung an
  lcd.setCursor (0, 2);            
  lcd.print("Ger\341t anschlie\342en &");
  lcd.setCursor (0, 3);                        
  lcd.print("Pr\365fung w\341hlen");
}

void statusinterrupt() {                                                            // hier wird der Status auf "true" gesetzt
  status500ms = true;
}

void Drehknopf() {                                                                  // Abfrage des Drehknopfes
  while (Stellung_Drehknopf_alt != Stellung_Drehknopf) {
    if (digitalRead(Stellung_1) == LOW) {
      Stellung_Drehknopf = 1;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      Pruefung_1();
    }
    else if (digitalRead(Stellung_2) == LOW) {
      Stellung_Drehknopf = 2;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      Pruefung_1();
    }
    else if (digitalRead(Stellung_3) == LOW) {
      Stellung_Drehknopf = 3;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      Pruefung_1();
    }
    else if (digitalRead(Stellung_4) == LOW) {
      Stellung_Drehknopf = 4;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      Pruefung_1();
    }
    else if (digitalRead(Stellung_5) == LOW) {
      Stellung_Drehknopf = 5;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      Pruefung_1();
    }
    else if (digitalRead(Stellung_6) == LOW) {
      Stellung_Drehknopf = 6;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      Pruefung_1();
    }
    else if (digitalRead(Stellung_7) == LOW) {
      Stellung_Drehknopf = 7;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      Pruefung_1();
    }
    else Stellung_Drehknopf = 0;
  }
}

void Pruefung_1() {                                                               // 230V, Pin 6 auf +12V, Spannung zwischen Pin 1 & Pin 3 messen:
Serial.print("Stellung: ");
Serial.println(Stellung_Drehknopf);
  delay(2000);
  
 Stellung_Drehknopf_alt = 10;

}


void loop() {
  Drehknopf();
}

Ich habe einen Taster, eine Seite mit GND, andere Seite mit dem jeweiligen Eingang (Stellung_1 … Stellung_7 hier im Code) und der Serial.print spuckt mir nur eine Änderung aus, wenn ich sie auch tätige. Mit diesem Code funktioniert es jetzt erstmal so, wie ich mir das vorgestellt hatte! :wink:
Ist zwar jetzt nur Beispielhaft, z.B. das “delay” fuddel ich mir auch noch weg (wahrscheinlich einfach mittels Zeitstempel oder so, mal schauen…)

Falls Euch noch irgendwas auffällt an der “Prüfauswahl”, bin ich für Anregungen sehr dankbar.
Bis hierhin aber schonmal vielen Dank, es funktioniert ja jetzt schon!!! :slight_smile:

Viele Grüße,
Marcus

MicroBahner:
Hallo Marcus,Du sparst dir die 9 externen Pull-down Widerstände. (Ok, Tommy war schneller :wink: )

Danke f. deine Hilfe.
Ich hätte anfangs direkt gerne den ganzen Code gepostet - aber ich schrieb ja bereits, dass ich auf 9000 Zeichen beschränkt bin. Es ging halt nicht komplett!!

MicroBahner:
Und so wie der Sketch jetzt aussieht, werden die Drehschalter ja nie mehr eingeschaltet, da drehknopf_alt nicht mehr rückgesetzt wird. Ich vermute dass, das Problem ( mal wieder ) in den Teilen liegt, die nicht gezeigt werden ::slight_smile: .

Ja, das stimmt - das ist leider dem Kürzen zum Opfer gefallen. Ich hab das aber mit drin - das war so ziemlich das Einzige, was (im Prinzip) funktioniert hätte :sweat_smile:
Und jetzt musste ich z.B. auch noch 5 Minuten warten, bis ich das hier schreiben konnte ... ist auch ein bissl nervig

Hallo allerseits,
Thema hat sich erledigt, es funktioniert jetzt zu meiner vollsten Zufriedenheit:
Ich speichere noch in einer weiteren Variable “aktuelle_pruefung” die gerade aktive Prüfung und frage diese auch in den if-Schleifen (innerhalb der while-Schleife) ab, so dass nur einmal eine bestimmte Prüfung aufgerufen wird, bis eine andere ausgewählt wird.
Da es vom Prinzip her 9x das gleiche ist, hier nur ein Teilausschnitt:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);                                                   // Adresse 0x3F oder 0x27 (Arduino Uno I2C Pins sind: A4==SDA, A5==SCL; MEGA 20 = SDA, 21 = SCL)

// Pinbelegungen
#define Stellung_1 4                                                                // Wählschalter mit den jeweiligen Pins verbunden
#define Stellung_2 5
#define Stellung_3 6
#define Stellung_4 7
#define Stellung_5 8
#define Stellung_6 9
#define Stellung_7 10
#define Stellung_8 11
#define Stellung_9 12

#define Relais_N   22
#define Relais_L   23
#define Relais_1   24
#define Relais_2   25
#define Relais_1B  26
#define Relais_12B 27
#define Relais_3   27
#define Relais_3B  28
#define Relais_4   29
#define Relais_5   30
#define Relais_6   31
#define Relais_7   32
#define Relais_8   33

byte Stellung_Drehknopf = 0;                                                        // absichtlich Wert = 0, damit die Abfrage des Drehknopfes startet
byte Stellung_Drehknopf_alt = 10;                                                   // absichtlich Wert > 9, damit die Abfrage des Drehknopfes startet
byte aktuelle_pruefung = 10;                                                        // Status zum Vergleich der aktuellen Prüfung mit der Vorherigen

// Variablen
unsigned long startzeit;                                                            // größtmöglicher Wertebereich f. Zeitstempel (ca. 4,29*10^10)
volatile bool status500ms = false;                                                  // Statusvariable, Bedingung f. Prüfungsstart. " volatile", da die Variable durch Interrupt geändert wird
float spannungswert = 0;

void setup() {
  pinMode(2, INPUT_PULLUP);                                                         // interner Pullup-Widerstand aktiviert, hilft gg. Störeinflüsse
  pinMode(A0, INPUT_PULLUP);                                                        // interner Pullup-Widerstand aktiviert, hilft gg. Störeinflüsse
  pinMode(Stellung_1, INPUT_PULLUP);                                                // Zuweisungen siehe oben
  pinMode(Stellung_2, INPUT_PULLUP);
  pinMode(Stellung_3, INPUT_PULLUP);
  pinMode(Stellung_4, INPUT_PULLUP);
  pinMode(Stellung_5, INPUT_PULLUP);
  pinMode(Stellung_6, INPUT_PULLUP);
  pinMode(Stellung_7, INPUT_PULLUP);  
  pinMode(Stellung_8, INPUT_PULLUP);  
  pinMode(Stellung_9, INPUT_PULLUP);  

  digitalWrite(Relais_N,LOW); 
  digitalWrite(Relais_L,LOW);  
  digitalWrite(Relais_1,LOW); 
  digitalWrite(Relais_2,LOW); 
  digitalWrite(Relais_1B,LOW);     
  digitalWrite(Relais_12B,LOW);     
  digitalWrite(Relais_3,LOW);   
  digitalWrite(Relais_3B,LOW); 
  digitalWrite(Relais_4,LOW); 
  digitalWrite(Relais_5,LOW); 
  digitalWrite(Relais_6,LOW);   
  digitalWrite(Relais_7,LOW);   
  digitalWrite(Relais_8,LOW);   
  attachInterrupt(0, statusinterrupt, LOW);                                         // "Interrupt 0" ist Pin 2! void Statusinterrupt() wird aufgerufen

void Drehknopf() {                                                                  // Abfrage des Drehknopfes
  while (Stellung_Drehknopf_alt != Stellung_Drehknopf) {
    if ((digitalRead(Stellung_1) == LOW) && (aktuelle_pruefung != 1)) {
      Stellung_Drehknopf = 1;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      Pruefung_1();
    }
    else if ((digitalRead(Stellung_2) == LOW) && (aktuelle_pruefung != 2)) {
      Stellung_Drehknopf = 2;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      Pruefung_2();
    }
    else if ((digitalRead(Stellung_3) == LOW) && (aktuelle_pruefung != 3)) {
      Stellung_Drehknopf = 3;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      Pruefung_3();
    }
    else if ((digitalRead(Stellung_4) == LOW) && (aktuelle_pruefung != 4)) {
      Stellung_Drehknopf = 4;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      Pruefung_4();
    }
    else if ((digitalRead(Stellung_5) == LOW) && (aktuelle_pruefung != 5)) {
      Stellung_Drehknopf = 5;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      Pruefung_5();
    }
    else if ((digitalRead(Stellung_6) == LOW) && (aktuelle_pruefung != 6)) {
      Stellung_Drehknopf = 6;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      Pruefung_6();
    }
    else if ((digitalRead(Stellung_7) == LOW) && (aktuelle_pruefung != 7)) {
      Stellung_Drehknopf = 7;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      Pruefung_7();
    }
    else if ((digitalRead(Stellung_8) == LOW) && (aktuelle_pruefung != 8)) {
      Stellung_Drehknopf = 8;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      aktuelle_pruefung = 8;
      Pruefung_8();
    }
    else if ((digitalRead(Stellung_9) == LOW) && (aktuelle_pruefung != 9)) {
      Stellung_Drehknopf = 9;
      Stellung_Drehknopf_alt = Stellung_Drehknopf;
      Pruefung_9();
    }
   } 
}

void Pruefung_1() {                                                               // 230V, Pin 6 auf +12V, Spannung zwischen Pin 1 & Pin 3 messen:
  digitalWrite(Relais_N,LOW);                                                     // Relais schaltet Nullleiter 230V AC durch
  digitalWrite(Relais_L,LOW);                                                     // Relais schalter Phase 230V AC durch
  digitalWrite(Relais_1,HIGH);                                                    // Relais schaltet Pin 1 an Pluspol der Messbuchse
  digitalWrite(Relais_2,LOW);                                                     // Relais nimmt Pin 2 vom Pluspol der Messbuchse
  digitalWrite(Relais_1B,LOW);                                                    // Relais nimmt 1,6A Last von Pin 1/2 & Pin 3/4
  digitalWrite(Relais_12B,LOW);                                                   // Relais nimmt Pin 1 & 2 (belastet) vom Pluspol der Messbuchse
  digitalWrite(Relais_3,HIGH);                                                    // Relais schaltet Pin 3 an Minuspol der Messbuchse
  digitalWrite(Relais_3B,LOW);                                                    // Relais nimmt 0,2A Last von Pin 3 / Pin 5
  digitalWrite(Relais_4,LOW);                                                     // Relais nimmt Pin 4 vom Minuspol der Messbuchse
  digitalWrite(Relais_5,LOW);                                                     // Relais nimmt Pin 5 vom Pluspol der Messbuchse
  digitalWrite(Relais_6,LOW);                                                     // Relais schaltet +12V an Pin 6
  digitalWrite(Relais_7,LOW);                                                     // Relais nimmt Pin 7 vom Pluspol der Messbuchse
  digitalWrite(Relais_8,LOW);                                                     // Relais nimmt Spannungsteiler vom Pluspol der Messbuchse      

  lcd.setCursor (0, 0);                                                           // Ausgabe des Ergebnisses ...
  lcd.print("Pr\365fung 1: 1 & 3    ");                                                         
  lcd.setCursor (0, 1);
  lcd.print("                    ");
  lcd.setCursor (0, 2);
  lcd.print("Soll: 37,4V - 42,6V ");
  lcd.setCursor (0, 3);
  lcd.print("                    ");
  Stellung_Drehknopf_alt = 10;
  aktuelle_pruefung = 1;
}
void loop() {
  Drehknopf();
}

Viele Dank für Eure Hilfe und viele Grüße,
Marcus

Ich verstehe nicht wieso Dein Sketch über 9000 Zeichen lang sein sollte. Meinem Empfinden kann man sowas in unter 100 Zeilen schreiben.

Ich würde auch nicht einen Drehschalter verwenden sondern einen Drehencoder. So kannst Du auch mit einer ungefährlichen Startkonfiguration anfangen und nicht zB im 200mA Bereich einschalten und Spannung messen wollen. So kannst Du beim einschalten auch ein AUS-Zustand sicher realisieren.

Grüße Uwe

uwefed:
Ich verstehe nicht wieso Dein Sketch über 9000 Zeichen lang sein sollte. Meinem Empfinden kann man sowas in unter 100 Zeilen schreiben.

Vllt. wegen meiner Kommentare? Ich kann's dir auch nicht sagen. Ich hab gestern mehrmals probiert meinen Beitrag mit Sketch zu posten und es kam jedes mal die 9000 Zeichen - Begrenzung. Der gesamte Code ist auch gefühlt gar nicht so lang: Im Prinzip genau das, was ich zuletzt gepostet hatte, nur noch mit den anderen Prüfungen, wo ja aber nur unterschiedliche Schaltzustände von den Relais drin stehen. Ich mache immer viele Tabs/Leerzeichen hinter dem Code, um die Kommentare in einer Flucht zu haben, vllt. liegt's daran??

uwefed:
Ich würde auch nicht einen Drehschalter verwenden sondern einen Drehencoder. So kannst Du auch mit einer ungefährlichen Startkonfiguration anfangen und nicht zB im 200mA Bereich einschalten und Spannung messen wollen. So kannst Du beim einschalten auch ein AUS-Zustand sicher realisieren.

Ja, sehr guter Einwand! - Da hatte ich zwar auch schon dran gedacht, aber der Arbeitskollege hatte den Drehschalter schon bestellt. Wenn das Probleme gibt, muss ich den doch nochmal austauschen.

Generell hatte ich übrigens auch erst versucht, das Programm mit Arrays aufzubauen, so dass ich nicht alles 9x hinschreiben muss. Ich habe es dann aber aufgegeben, weil ich nicht weiter kam. Ich geb mir ja Mühe, dass ich alles möglichst selbst hinbekomme, denn es ist ja schön, wenn man selber auf "eine" Lösung kommt. Ich versuche mich ja da auch reinzufuchsen und mit den mir verfügbaren Mitteln / know how umzusetzen. Für mich ist das halt auch echt anstrengend! Aber ich geb mir Mühe :wink:

Viele Grüße,
Marcus

z.B.:

const byte pins[] = { 10, 11, 12, 13 };

void setup()
{
   for(auto pin : pins)   //Stichwort: range based loop. In anderen Sprachen als "for each" bekannt
     pinMode(pin, OUTPUT);
}

Wenn die Pins sowieso alle sequentiell sind kann man sich auch das Array sparen:

for (byte i = 20; i <= 33; i++)
   pinMode(i, OUTPUT);

Auch deine Drehknopf() Funktion lässt sich mit einer Schleife erschlagen

Hi,

Serenifly:
Wenn die Pins sowieso alle sequentiell sind kann man sich auch das Array sparen:

for (byte i = 20; i <= 33; i++)

pinMode(i, OUTPUT);





Auch deine Drehknopf() Funktion lässt sich mit einer Schleife erschlagen

Ohja, die for-Schleife bringe ich auch rein, das gefällt mir. Allerdings mache ich das nur bei den Eingangspins vom Drehschalter, denn die Relais möchte ich gerne so benannt haben, dass ich da auch durchblicke, welches was macht.
Ich hatte ursprünglich auch daran gedacht, die Drehknopf() Funktion in eine Schleife zu packen, bin aber daran gescheitert, die dazugehörigen Funktionen aufzurufen - ich sag mal so in der Art hatte ich das vor, bis ich gemerkt hab, dass das NICHT geht (–> Methode als Array):

void Drehknopf() {                                                                  // Abfrage des Drehknopfes
  while ((Stellung_Drehknopf_alt != Stellung_Drehknopf) &&                          // so lange der alte und neue Drehknopfwert ungleich sind ...
         (millis() - schaltzeit >= 2000)) {                                         // und die Schaltzeit zwischden den Stufen > 2 Sekunden (ermöglicht das Durchschalten, ohne dass direkt jede Schaltstellung des Drehschalters aktiv wird) ...
    for (byte i = 0; i < 10; i++) {
      if ((digitalRead(Stellung[i]) == LOW) && (aktuelle_pruefung != i)) {          // ... lese nacheinander die digitalen Eingänge, sofern sie gg. GND geschaltet und nicht bereits ausgewählt sind
        Stellung_Drehknopf = i;
        Stellung_Drehknopf_alt = Stellung_Drehknopf;
        Pruefung[i]();                                                              // starte jeweilige Prüfung
      }
    }
  }
}

Aber wo ich jetzt nochmal drüber nachdenke, könnte ich ja einen Marker als Array setzen, diesen wiederum in der Loop() abfragen und dann die jeweilge Pruefung_0() … Pruefung_9() ausführen … das müsste ja klappen? Die Prüfungen selber wüsste ich jetzt nicht, wie ich die kürzen könnte.

Viele grüße,
Marcus

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);                                                 // Adresse 0x3F oder 0x27 (Arduino Uno I2C Pins sind: A4==SDA, A5==SCL; MEGA 20 = SDA, 21 = SCL)

// Pinbelegungen
const byte Stellung[] = {3, 4, 5, 6, 7, 8, 9, 10 ,11 ,12};                          // Wählschalter mit den jeweiligen Pins verbunden
bool Pruefungsmarker[10];
#define Relais_N   22                                                               // Signalleitungen der Relais mit den jeweiligen Pins verbunden
#define Relais_L   23
#define Relais_1   24
#define Relais_2   25
#define Relais_1B  26
#define Relais_12B 27
#define Relais_3   27
#define Relais_3B  28
#define Relais_4   29
#define Relais_5   30
#define Relais_6   31
#define Relais_7   32
#define Relais_8   33

byte Stellung_Drehknopf = 11;                                                       // absichtlich Wert > 10, damit die Abfrage des Drehknopfes startet
byte Stellung_Drehknopf_alt = 10;                                                   // absichtlich Wert > 9, damit die Abfrage des Drehknopfes startet
byte aktuelle_pruefung = 0;                                                         // Status zum Vergleich der aktuellen Prüfung mit der Vorherigen; absichtlich "0", damit der Startbildschirm stehen bleibt

// Variablen
unsigned long startzeit;                                                            // größtmöglicher Wertebereich f. Zeitstempel (ca. 4,29*10^10)
unsigned long schaltzeit;                                                           // Zeitstempel zur Verzögerung beim Durchschalten des Drehreglers
volatile bool status500ms = false;                                                  // Statusvariable, Bedingung f. Prüfungsstart. " volatile", da die Variable durch Interrupt geändert wird
float spannungswert = 0;

void setup() {
  pinMode(2, INPUT_PULLUP);                                                         // interner Pullup-Widerstand aktiviert, hilft gg. Störeinflüsse
  pinMode(A0, INPUT_PULLUP);                                                        // interner Pullup-Widerstand aktiviert, hilft gg. Störeinflüsse
  for (byte i = 0; i <10; i++) {                                                    // Zuweisungen siehe oben
    pinMode(Stellung[i], INPUT_PULLUP); 
  }
  pinMode(Relais_N, OUTPUT);
  pinMode(Relais_L, OUTPUT);
  pinMode(Relais_1, OUTPUT);
  pinMode(Relais_2, OUTPUT);
  pinMode(Relais_1B, OUTPUT);
  pinMode(Relais_12B, OUTPUT);
  pinMode(Relais_3, OUTPUT);
  pinMode(Relais_3B, OUTPUT);
  pinMode(Relais_4, OUTPUT);
  pinMode(Relais_5, OUTPUT);
  pinMode(Relais_6, OUTPUT);
  pinMode(Relais_7, OUTPUT);
  pinMode(Relais_8, OUTPUT);

  digitalWrite(Relais_N, LOW);
  digitalWrite(Relais_L, LOW);
  digitalWrite(Relais_1, LOW);
  digitalWrite(Relais_2, LOW);
  digitalWrite(Relais_1B, LOW);
  digitalWrite(Relais_12B, LOW);
  digitalWrite(Relais_3, LOW);
  digitalWrite(Relais_3B, LOW);
  digitalWrite(Relais_4, LOW);
  digitalWrite(Relais_5, LOW);
  digitalWrite(Relais_6, LOW);
  digitalWrite(Relais_7, LOW);
  digitalWrite(Relais_8, LOW);
  attachInterrupt(0, statusinterrupt, LOW);                                         // "Interrupt 0" ist Pin 2! void Statusinterrupt() wird aufgerufen

  lcd.init();                                                                       // Initialisierung LCD
  lcd.backlight();                                                                  // Hintergrundbeleuchtung an
  lcd.setCursor (1, 0);
  lcd.print("WM24790 / WM27804");
  lcd.setCursor (0, 2);
  lcd.print("Ger\341t anschlie\342en &");
  lcd.setCursor (0, 3);
  lcd.print("Pr\365fung w\341hlen");
  delay(2000);                                                                      // sicherstellen, dass Startbildschirm wenigstens 2 Sekunden erscheint
}

void statusinterrupt() {                                                            // hier wird der Status auf "true" gesetzt (wenn der Interrupt auslöst)
  status500ms = true;
}

void Drehknopf() {                                                                  // Abfrage des Drehknopfes
  while ((Stellung_Drehknopf_alt != Stellung_Drehknopf) &&                          // so lange der alte und neue Drehknopfwert ungleich sind ...
         (millis() - schaltzeit >= 2000)) {                                         // und die Schaltzeit zwischden den Stufen > 2 Sekunden (ermöglicht das Durchschalten, ohne dass direkt jede Schaltstellung des Drehschalters aktiv wird) ...
    for (byte i = 0; i < 10; i++) {
      if ((digitalRead(Stellung[i]) == LOW) && (aktuelle_pruefung != i)) {          // ... lese nacheinander die digitalen Eingänge, sofern sie gg. GND geschaltet und nicht bereits ausgewählt sind
        Stellung_Drehknopf = i;
        Stellung_Drehknopf_alt = Stellung_Drehknopf;
        Pruefungsmarker[i] = true;                                                   // setze jeweiligen Prüfungsmarker auf true
      }
    }
  }
}

void Pruefung_1() {                                                               // 230V, Pin 6 auf +12V, Spannung zwischen Pin 1 & Pin 3 messen:
  schaltzeit = millis();                                                          // Zeitstempel für Verzögerung beim Durchschalten
  digitalWrite(Relais_N, LOW);                                                    // Relais schaltet Nullleiter 230V AC durch
  digitalWrite(Relais_L, LOW);                                                    // Relais schalter Phase 230V AC durch
  digitalWrite(Relais_1, HIGH);                                                   // Relais schaltet Pin 1 an Pluspol der Messbuchse
  digitalWrite(Relais_2, LOW);                                                    // Relais nimmt Pin 2 vom Pluspol der Messbuchse
  digitalWrite(Relais_1B, LOW);                                                   // Relais nimmt 1,6A Last von Pin 1/2 & Pin 3/4
  digitalWrite(Relais_12B, LOW);                                                  // Relais nimmt Pin 1 & 2 (belastet) vom Pluspol der Messbuchse
  digitalWrite(Relais_3, HIGH);                                                   // Relais schaltet Pin 3 an Minuspol der Messbuchse
  digitalWrite(Relais_3B, LOW);                                                   // Relais nimmt 0,2A Last von Pin 3 / Pin 5
  digitalWrite(Relais_4, LOW);                                                    // Relais nimmt Pin 4 vom Minuspol der Messbuchse
  digitalWrite(Relais_5, LOW);                                                    // Relais nimmt Pin 5 vom Pluspol der Messbuchse
  digitalWrite(Relais_6, LOW);                                                    // Relais schaltet +12V an Pin 6
  digitalWrite(Relais_7, LOW);                                                    // Relais nimmt Pin 7 vom Pluspol der Messbuchse
  digitalWrite(Relais_8, LOW);                                                    // Relais nimmt Spannungsteiler vom Pluspol der Messbuchse

  lcd.setCursor (0, 0);                                                           // Ausgabe des Ergebnisses ...
  lcd.print("Pr\365fung 1: 1 & 3    ");
  lcd.setCursor (0, 1);
  lcd.print("                    ");
  lcd.setCursor (0, 2);
  lcd.print("Soll: 37,4V - 42,6V ");
  lcd.setCursor (0, 3);
  lcd.print("                    ");
  Stellung_Drehknopf_alt = 10;
  aktuelle_pruefung = 1;
  Pruefungsmarker[1] = false;
}
void loop() {
  Drehknopf();
  if (Pruefungsmarker[0] == true) {Pruefung_0();}
  if (Pruefungsmarker[1] == true) {Pruefung_1();}
  if (Pruefungsmarker[2] == true) {Pruefung_2();}
  if (Pruefungsmarker[3] == true) {Pruefung_3();}
  if (Pruefungsmarker[4] == true) {Pruefung_4();}
  if (Pruefungsmarker[5] == true) {Pruefung_5();}
  if (Pruefungsmarker[6] == true) {Pruefung_6();}
  if (Pruefungsmarker[7] == true) {Pruefung_7();}
  if (Pruefungsmarker[8] == true) {Pruefung_8();}
  if (Pruefungsmarker[9] == true) {Pruefung_9();}
}

So läuft´s jetzt (auch) :wink:
Gerade kommt mir noch eine Idee, wie ich evtl. die Prüfungs-Methoden kürzen könnte? Das ist ja auch 10x das Gleiche, nur mit unterschiedlichen Schaltständen der Relais. ich probiere das mal aus …

Statt Pruefung_2(); und Pruefung_3(); vielleicht
Pruefung(2); und Pruefung(3);

Vielleicht merkt man dann, dass man evtl. sogar die 10 if-Konstruktionen weglassen kann?

Allerdings, "wenn's läuft ist es gut" ist auch ein bedenkenswerter Ansatz.
(Auf jeden Fall sollte man die Version aufheben :slight_smile: )

Ich habe gerade einen Lauf: Durch Ausprobieren konnte ich doch den Vorschlag von Serenifly mit den Arrays der Relais umsetzen und konnte die Benennung der Relais trotzdem behalten. Das sieht nun schon (für meine Verhältnisse) echt schick aus:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);                                                 // Adresse 0x3F oder 0x27 (Arduino Uno I2C Pins sind: A4==SDA, A5==SCL; MEGA 20 = SDA, 21 = SCL)

// Pinbelegungen
const byte Stellung[] = {3, 4, 5, 6, 7, 8, 9, 10 ,11 ,12};                          // Wählschalter mit den jeweiligen Pins verbunden
bool Pruefungsmarker[10];
#define Relais_N   22                                                               // Signalleitungen der Relais mit den jeweiligen Pins verbunden
#define Relais_L   23
#define Relais_1   24
#define Relais_2   25
#define Relais_1B  26
#define Relais_12B 27
#define Relais_3   28
#define Relais_3B  29
#define Relais_4   30
#define Relais_5   31
#define Relais_6   32
#define Relais_7   33
#define Relais_8   34

// Variablen
byte Stellung_Drehknopf = 11;                                                       // absichtlich Wert > 10, damit die Abfrage des Drehknopfes startet
byte Stellung_Drehknopf_alt = 10;                                                   // absichtlich Wert > 9, damit die Abfrage des Drehknopfes startet
byte aktuelle_pruefung = 0;                                                         // Status zum Vergleich der aktuellen Prüfung mit der Vorherigen; absichtlich "0", damit der Startbildschirm stehen bleibt
byte Relais[] = {Relais_N, Relais_L, Relais_1, Relais_2, Relais_1B, Relais_12B, Relais_3, Relais_3B, Relais_4, Relais_5, Relais_6, Relais_7, Relais_8};
unsigned long startzeit;                                                            // größtmöglicher Wertebereich f. Zeitstempel (ca. 4,29*10^10)
unsigned long schaltzeit;                                                           // Zeitstempel zur Verzögerung beim Durchschalten des Drehreglers
volatile bool status500ms = false;                                                  // Statusvariable, Bedingung f. Prüfungsstart. " volatile", da die Variable durch Interrupt geändert wird
float spannungswert = 0;

void setup() {
  pinMode(2, INPUT_PULLUP);                                                         // interner Pullup-Widerstand aktiviert, hilft gg. Störeinflüsse
  pinMode(A0, INPUT_PULLUP);                                                        // interner Pullup-Widerstand aktiviert, hilft gg. Störeinflüsse
  for (byte i = 0; i <10; i++) {pinMode(Stellung[i], INPUT_PULLUP);}                         // Zuweisungen siehe oben
  for (byte i = 0; i <13; i++) {pinMode(Relais[i], OUTPUT); digitalWrite(Relais[i], LOW);}   // Zuweisungen siehe oben
  
  attachInterrupt(0, statusinterrupt, LOW);                                         // "Interrupt 0" ist Pin 2! void Statusinterrupt() wird aufgerufen
}

void statusinterrupt() {                                                            // hier wird der Status auf "true" gesetzt (wenn der Interrupt auslöst)
  status500ms = true;
}

void Drehknopf() {                                                                  // Abfrage des Drehknopfes
  while ((Stellung_Drehknopf_alt != Stellung_Drehknopf) &&                          // so lange der alte und neue Drehknopfwert ungleich sind ...
         (millis() - schaltzeit >= 2000)) {                                         // und die Schaltzeit zwischden den Stufen > 2 Sekunden (ermöglicht das Durchschalten, ohne dass direkt jede Schaltstellung des Drehschalters aktiv wird) ...
    for (byte i = 0; i < 10; i++) {
      if ((digitalRead(Stellung[i]) == LOW) && (aktuelle_pruefung != i)) {          // ... lese nacheinander die digitalen Eingänge, sofern sie gg. GND geschaltet und nicht bereits ausgewählt sind
        Stellung_Drehknopf = i;
        Stellung_Drehknopf_alt = Stellung_Drehknopf;
        Pruefungsmarker[i] = true;                                                   // setze jeweiligen Prüfungsmarker auf true
      }
    }
  }
}

void Pruefung_1() {                                                               // 230V, Pin 6 auf +12V, Spannung zwischen Pin 1 & Pin 3 messen:
  schaltzeit = millis();                                                          // Zeitstempel für Verzögerung beim Durchschalten
  digitalWrite(Relais_N, LOW);                                                    // Relais schaltet Nullleiter 230V AC durch
  digitalWrite(Relais_L, LOW);                                                    // Relais schalter Phase 230V AC durch
  digitalWrite(Relais_1, HIGH);                                                   // Relais schaltet Pin 1 an Pluspol der Messbuchse
  digitalWrite(Relais_2, LOW);                                                    // Relais nimmt Pin 2 vom Pluspol der Messbuchse
  digitalWrite(Relais_1B, LOW);                                                   // Relais nimmt 1,6A Last von Pin 1/2 & Pin 3/4
  digitalWrite(Relais_12B, LOW);                                                  // Relais nimmt Pin 1 & 2 (belastet) vom Pluspol der Messbuchse
  digitalWrite(Relais_3, HIGH);                                                   // Relais schaltet Pin 3 an Minuspol der Messbuchse
  digitalWrite(Relais_3B, LOW);                                                   // Relais nimmt 0,2A Last von Pin 3 / Pin 5
  digitalWrite(Relais_4, LOW);                                                    // Relais nimmt Pin 4 vom Minuspol der Messbuchse
  digitalWrite(Relais_5, LOW);                                                    // Relais nimmt Pin 5 vom Pluspol der Messbuchse
  digitalWrite(Relais_6, LOW);                                                    // Relais schaltet +12V an Pin 6
  digitalWrite(Relais_7, LOW);                                                    // Relais nimmt Pin 7 vom Pluspol der Messbuchse
  digitalWrite(Relais_8, LOW);                                                    // Relais nimmt Spannungsteiler vom Pluspol der Messbuchse

  lcd.setCursor (0, 0);                                                           // Ausgabe des Ergebnisses ...
  lcd.print("Pr\365fung 1: 1 & 3    ");
  lcd.setCursor (0, 1);
  lcd.print("                    ");
  lcd.setCursor (0, 2);
  lcd.print("Soll: 37,4V - 42,6V ");
  lcd.setCursor (0, 3);
  lcd.print("                    ");
  Stellung_Drehknopf_alt = 10;
  aktuelle_pruefung = 1;
  Pruefungsmarker[1] = false;
}

void loop() {
  Drehknopf();
  if (Pruefungsmarker[0] == true) {Pruefung_0();}
  if (Pruefungsmarker[1] == true) {Pruefung_1();}
  if (Pruefungsmarker[2] == true) {Pruefung_2();}
  if (Pruefungsmarker[3] == true) {Pruefung_3();}
  if (Pruefungsmarker[4] == true) {Pruefung_4();}
  if (Pruefungsmarker[5] == true) {Pruefung_5();}
  if (Pruefungsmarker[6] == true) {Pruefung_6();}
  if (Pruefungsmarker[7] == true) {Pruefung_7();}
  if (Pruefungsmarker[8] == true) {Pruefung_8();}
  if (Pruefungsmarker[9] == true) {Pruefung_9();}
}

michael_x:
Statt Pruefung_2(); und Pruefung_3(); vielleicht
Pruefung(2); und Pruefung(3);

Vielleicht merkt man dann, dass man evtl. sogar die 10 if-Konstruktionen weglassen kann?

Allerdings, “wenn’s läuft ist es gut” ist auch ein bedenkenswerter Ansatz.
(Auf jeden Fall sollte man die Version aufheben :slight_smile: )

Hihi, die laufenden Versionen speichere ich definitv extra ab :wink:
Wie funktioniert das denn mit “Pruefung(2)” etc?

Wenn ich das im Code schreibe:

void Pruefung(2) {                                                               // 230V, Pin 6 auf +12V, Spannung
...
}

kommt die Fehlermeldung: “exit status 1
variable or field ‘Pruefung’ declared void”.
Wie funktioniert das denn?

Faddi:
Ich hatte ursprünglich auch daran gedacht, die Drehknopf() Funktion in eine Schleife zu packen, bin aber daran gescheitert, die dazugehörigen Funktionen aufzurufen - ich sag mal so in der Art hatte ich das vor, bis ich gemerkt hab, dass das NICHT geht (–> Methode als Array)

Doch das geht. Ich wollte dich nur nicht völlig verwirren. Man kann Zeiger auf Funktionen haben (Methoden gehören zu Klassen). Und man kann dann Arrays aus Funktionszeigern anlegen.

Deine Lösung ist aber nicht schlecht :slight_smile:

Aber wie oben angedeutet ist es generell nicht so gut Funktionen durchnummerieren. Normal übergibt man da eher einen Parameter an die Funktion. Andererseits scheint du ja doch recht unterschiedliche Sachen in den einzelnen Funktionen zu machen. Also würde man dann wahrscheinlich eine sehr lange Funktion haben.

Schlag mal unter Google Funktionen und Funktionsparameter nach. Das sind wirklich absolute Grundlagen die du sowieso lernen musst. Nicht nur für dieses Programm

  for (byte i = 0; i <10; i++) {                                                    // Zuweisungen siehe oben
    pinMode(Stellung[i], INPUT_PULLUP);

Besser:

  for (byte i = 0; i < sizeof(Stellung); i++)

sizeof() liefert die Größe eines Datentyp in Bytes. Mit Datentypen wie byte und bool passt es dann direkt

Serenifly:
Doch das geht. Ich wollte dich nur nicht völlig verwirren. Man kann Zeiger auf Funktionen haben (Methoden gehören zu Klassen). Und man kann dann Arrays aus Funktionszeigern anlegen.

Auweia - da haste recht, das ist zu hoch für mich. Da ich keine Lust auf Copy&Paste habe und den Sketch nachvollziehen möchte, muss ich die Sachen halt manchmal etwas umständlich machen. Ich belasse es dann jetzt dabei.

Serenifly:
Besser:
sizeof() liefert die Größe eines Datentyp in Bytes. Mit Datentypen wie byte und bool passt es dann direkt

Oh, aber das ist cool, das nehme ich noch mit! :slight_smile:

Serenifly:
Deine Lösung ist aber nicht schlecht :slight_smile:

Dankeschön :slight_smile:

Vielen Dank nochmal an alle Beteiligten für Eure Hilfe!
Viele Grüße,
Marcus

Nur zum Spaß:

void funktion_1();
void funktion_2();
void funktion_3();

using FunktionsZeiger = void(*)();   //Zeiger auf eine Funktion die keinen Paramater hat und nichts zurück gibt
const FunktionsZeiger funktionen[] = { funktion_1, funktion_2, funktion_3 };   //Funktionsnamen sind deren Adressen

void setup()
{
  Serial.begin(9600);

  for (auto fkt : funktionen)
  {
    if (fkt) fkt();   //Abfrage dass der Zeiger nicht NULL ist
  }
}

void loop()
{
}

void funktion_1()
{
  Serial.println("Funktion 1");
}

void funktion_2()
{
  Serial.println("Funktion 2");
}
void funktion_3()
{
  Serial.println("Funktion 3");
}

Ist gar nicht sooo kompliziert

Serenifly:
Nur zum Spaß:

using FunktionsZeiger = void(*)();   //Zeiger auf eine Funktion die keinen Paramater hat und nichts zurück gibt

const FunktionsZeiger funktionen = { funktion_1, funktion_2, funktion_3 };   //Funktionsnamen sind deren Adressen

void setup()
{
 Serial.begin(9600);

for (auto fkt : funktionen)
 {
   if (fkt) fkt();   //Abfrage dass der Zeiger nicht NULL ist
 }
}

void loop()
{
}

void funktion_1()
{
 Serial.println("Funktion 1");
}

void funktion_2()
{
 Serial.println("Funktion 2");
}
void funktion_3()
{
 Serial.println("Funktion 3");
}




Ist gar nicht sooo kompliziert

Boah - das ist total nett, aber ich verstehe nichts davon.
Interessehalber hab ich das trotztdem ausprobiert. Denn vllt. hilft´s ja wenn ich sehe, was da passiert und ich da selber dran rumpfuschen kann ... aber es kommt als Fehlermeldung " 'funktion_1' was not declared in this scope"

Mhh, das ist interessant. In VisualMicro geht das. Die Arduino IDE kommt anscheinend wieder mal mit den Funktionsprototypen durcheinander. Normal muss man Funktionen deklarieren bevor man sie verwendet. Die IDE schreibt dann wahrscheinlich das Array vor die Prototypen. Ich dachte das hätte man inzwischen behoben. Und auch VisualMicro verwendet eigentlich die normalen Arduino Tools im Hintergrund.

Einfach das oben hinschreiben:

void funktion_1();
void funktion_2();
void funktion_3();

Ansonsten wenn du etwas nicht verstehst: Google nach den Begriffen. Da gibt es sehr viele Anleitungen.
Deshalb ist es auch sehr wichtig die richtigen Namen für Dinge zu verwenden