Mehrere Initialiserungs- bzw. Deklarierungsfragen

Das kopierst du jetzt 50 mal und verschreibst dich dann mindestens 20 mal beim Ändern der Nummern :slight_smile:
Sowas kann man bei einer handvoll Variablen machen (und selbst dann baut man da leicht Fehler ein), aber nicht bei 50+

Geht ganz einfach so:

const int arraySize = 54;

for(int i=0; i < arraySize; i++)
{
      if (!digitalRead(leitung[i]) && zaehlerVariableLeitung[i]==false)
      {
        zaehlerVariableLeitung[i] = true;
        zaehler ++;
        lcd.print (i); lcd.print(bezeichnungLeitung[i]); lcd.print(farbcodeLeitung[i]); lcd.print(zaehler);
      }
}

Und das wäre der ganze Code? Das wäre ja krass.
Arbeitet der Arduino denn in so einem Tempo? Wenn jetzt sagen wir mal i erst bei 3 ist, ich aber gerade Leitung 40 messe, kriegt er die Änderung denn so schnell mit?
Ihr müsst mein erstaunen entschuldigen, aber ich habe halt noch keine zeitliche Relation in dieser Thematik.

Ja. Allgemein liegt der Taktzyklus mit 16MHz bei etwa 62ns. Das langsamste in der loop() ist digitalRead() und selbst das dauert nur ca. 60-70 Zyklen also ca. 4µs. Das ist bei manchen Anwendung zu lahm, aber 50 mal lesen würde dann etwa 200µs dauern. Plus die restlichen Sachen die jedesmal gemacht werden.

Das mit der LCD Anzeige geht so natürlich nicht gut :slight_smile:
Aber man kann das auch verzögern, wenn du nur alle x ms einen Schritt machen willst.

Dann müsste dementsprechend das Programm so aussehen (Beispielhaft)

// Zur Benennung der Variablen wurde die Camel-Case-Konvention verwendet

// Anzahl der Kabel für die Schleifen
const byte kabelMenge = 50;

// Leitungs-Array mit Pin-Werten
byte leitung[kabelMenge] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49};

// Zählervariablen deklarieren zwecks einmaligem hochzählen pro Leitung
boolean zaehlerVariableLeitung[kabelMenge];

// Deklaration des Zählers für das LCD
byte zaehler ;

// Farbcodes von Leitung 1 bis 50 (von oben nach unten)
char farbcodeLeitung[][6] =
  {
    "blau",
    "gruen",
    "rot"
  };
  
// Leitungsbezeichnung von 1 bis 50 (von oben nach unten)
char bezeichnungLeitung[][4] =
  {
    "kd1",
    "gr2",
    "7d3"
  };
  
  
void setup()
{
  // Alle Pins des Arrays als Eingang und mit Pullup-Widerstand auf HIGH gesetzt
  for(byte i = 0; i < kabelMenge; i++)
  pinMode(leitung[i], INPUT_PULLUP);   
}  


void loop()
{
  for(int i=0; i < kabelMenge; i++)
     {
       if (!digitalRead(leitung[i]) && zaehlerVariableLeitung[i]==false)
          {
             zaehlerVariableLeitung[i] = true;
             zaehler ++;
             lcd.print (i); lcd.print(bezeichnungLeitung[i]); lcd.print(farbcodeLeitung[i]); lcd.print(zaehler);
          }
     }
}

Wird die Anzeige denn flackern, oder wie wird sich das bemerkbar machen?

Die Anzeige wird sich so schnell ändern dass du es gar nicht bekommst. Das ist auch etwas problematisch weil LCDs träge sind und eigentlich ein paar ms brauchen um umzuschalten.

Ist das nur zum Test? Dafür solltest du vielleicht auf Serial.print() umsteigen (und es mit dem SerialMonitor anschauen). Dann siehst du jede Zeile. Da musst du aber auch aufpassen dass du nicht zu schnell schreibst.

P.S.:
Wenn du nicht gleich alles definierst solltest du das so machen:
char farbcodeLeitung[kabelMenge][6]

Sonst liest er Unsinn wenn du mit [40] auf Speicher zugreifst der nicht zu diesem Array gehört. Der Rest ist dann halt leer: ""

P.P.S.:
Pin 0 kannst du nicht verwenden. Das ist RX und mit dem USB Port verbunden. Pin 1 kannst du auch nicht verwenden wenn du mit Serial sendest. Man kann zwar die serielle Schnittstelle abschalten, aber die ist halt praktisch zum Debuggen. Du hast eigentlich genug Pins damit du die freihalten kannst. Du kannst auch die Analog-Pins als digitale Eingänge nehmen. digitalRead(A0) z.B.

Naja Ziel ist es ein Kabel damit zu prüfen. Wenn ich eine Leitung gegen Masse lege, dann sollen für diesen Zeitraum die Bezeichnungen angezeigt werden.
Wenn keine Leitung auf Masse liegt, dann soll nur der Zähler angezeigt werden.
Ich hab leider das LCD nicht hier um es zu testen. Was meinst du mit zu schnell? Ich werde das flackern nicht bemerken, oder ich werde die Anzeige nicht sehen?
Das ganze soll nachher wirklcih angewendet werden können.
Der SerialMonitor wird mir dann nichts nutzen, außer zum debuggen, wenn man die Funktion einbauen will.
Primär soll sich alles auf dem LCD abspielen.

Wie gesagt, die loop läuft sehr schnell. Wenn sich da was alle paar hundert µs ändert kannst du da nichts unterscheiden.

Willst du jetzt die Anzeige solange Masse anliegt? Und dann weiter wenn es wieder High wird? Oder gleich mit der nächsten Leitungen weitermachen? Für ersteres fehlt noch eine Schleife die ständig den Pin abfragt wenn er das erste mal Low war.

EDIT:
Gerade einen Denkfehler gehabt :frowning: :frowning:

Die Anzeige ändern sich ja nur wenn der nächste Pin Low ist. Wenn der Pin High ist bleibt der alte Wert auf dem Display. Da ist dann die Frage wie schnell sich da die Signale ändern. Wenn das langsam genug ist, sieht man den alten Wert noch.

Kurz und knapp
Masse an Leitung 1
-> Anzeige der Bezeichnungen auf dem Display für Leitung 1
Leitung 1 von Masse trennen
-> Es soll nur der Zählerstand angezeigt werden, der Rest wird nicht mehr angezeigt

Das Spiel geht solange weiter mit Leitung 2, 3, 4 usw
Geschwindigkeit der Umschaltung spielt keine Rolle.
Eine Person macht das manuell.
Er hält die Masse an die Leitung und guckt, ob die Leitungsbezeichnungen stimmen.
Das ganze wird über eine Art IDE-Stecker an den Arduino angeschlossen.
So kann man das Kabel mit seinen Leitungen durchprüfen und gucken, ob es richtig am Stecker belegt ist.

An Automatisierung wird noch nicht gedacht.
Danke für deine Zeit und Mühe mit mir. Ich weiß das zu schätzen.

Edit:
Hab den Code mal leicht abgeändert, damit die Bezeichnungen zwar angezeigt werden, jedoch aber nicht nochmal der Zähler hochzählt, wenn die Leitung bereits geprüft wurde.

// Zur Benennung der Variablen wurde die Camel-Case-Konvention verwendet

// Anzahl der Kabel für die Schleifen
const byte leitungsAnzahl = 50;

// Leitungs-Array mit Pin-Werten
byte leitung[leitungsAnzahl] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49};

// Zählervariablen deklarieren zwecks einmaligem hochzählen pro Leitung
boolean zaehlerVariableLeitung[leitungsAnzahl];

// Deklaration des Zählers für das LCD
byte zaehler ;

// Farbcodes von Leitung 1 bis 50 (von oben nach unten)
char farbcodeLeitung[][6] =
  {
    "blau",
    "gruen",
    "rot",
    "usw"
  };
  
// Leitungsbezeichnung von 1 bis 50 (von oben nach unten)
char bezeichnungLeitung[][4] =
  {
    "kd1",
    "gr2",
    "7d3",
    "usw"
  };
  
  
void setup()
{
  // Alle Pins des Arrays als Eingang und mit Pullup-Widerstand auf HIGH gesetzt
  for(byte i = 0; i < leitungsAnzahl; i++)
  pinMode(leitung[i], INPUT_PULLUP);   
}  


void loop()
{
  for(int i=0; i < leitungsAnzahl; i++)
     {
       if (!digitalRead(leitung[i]))
          {
             lcd.print (i); lcd.print(bezeichnungLeitung[i]); lcd.print(farbcodeLeitung[i]); lcd.print(zaehler);
               if (zaehlerVariableLeitung[i]==false)
                 {
                   zaehlerVariableLeitung[i] = true;
                   zaehler ++;
                 }
          }
     }
}

Ok. Ich hatte da auch noch einen Denkfehler drin. Der alte Wert bleibt ja auf dem Display wenn der Pin High ist. Duh! Das ist also schon brauchbar. D.h. wie oben sollte immer der letzte Wert der Messung auf dem Display sein.

Aber da du die Umschaltung von Bezeichnung auf Zähler willst, muss man das noch etwas aufbohren. Das primitivste wäre wie gesagt eine while-Schleife

  for(int i=0; i < kabelMenge; i++)
     {
          if (!digitalRead(leitung[i]) && zaehlerVariableLeitung[i]==false)
          {
             zaehlerVariableLeitung[i] = true;
             zaehler ++;
             lcd.print(i); lcd.print(bezeichnungLeitung[i]); lcd.print(farbcodeLeitung[i]); lcd.print(zaehler);

             while(!digitalRead(leitung[i])){}      //busy loop solange Low

             lcd.print(zaehler); lcd.print("             ");   //um die restliche Zeile zu löschen
          }          
     }

Nachteil damit, ist das er während der while-Schleife auf gar nichts mehr reagiert, aber wenn sonst nichts gemacht wird, kann das ok sein. Geht sicher auch besser, aber sonstige Interaktivität hast du ja nicht was ich so sehe. Jedenfalls nicht an dieser Stelle.

Da bin ich mir jetzt aber nicht 100%ig sicher. Müsste ich auch ausprobieren. Mach es erst mal so einfach wie es geht und wenn das läuft kannst du die Anzeige hinbiegen so wie du es willst. Da gibt es noch genug andere Fehlerquellen.

Was da auch noch fehlt ist ein lcd.setCursor(0,0) vor jeder print Zeile!

Und mach wie gesagt deine Arrays auf die passende Größe:
char farbcodeLeitung[leitungsAnzahl][6]

Das war mein Fehler. Sorry. Die erste Dimension kannst du nur weglassen, wenn du alle Strings initialisiert. Es müssen nicht alle Strings initialisiert werden, aber der Speicher muss reserviert werden.

Du kannst natürlich auch "leitungsAnzahl" testweise mal auf 4 reduzieren. Das geht wenn du die Dimension im leitung Array weglässt (da brauchst du sie wirklich nicht, da die Initialisierung vollständig ist).

Und wie gesagt, damit Pin 0 und 1 gehen musst du Serial.end() in loop setup machen! Sonst beißt sich das mit USB.