2 gleiche Codes, 2 unterschiedliche Ergebnisse

Hi, Ich hab diesen kurzen Code, um zu testen, ob er funktioniert:

void setup() {
  // put your setup code here, to run once:

  Serial.begin(115200);

  char question[15] = "frage_000_0.txt";
  question[7] += random(5);
  question[8] += random(8);

  Serial.print(question);

}

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

}

Output im Serial Monitor: frage_021_0.txt

Eingebaut in meinen Code (155 - 159 markiert mit <=======):

// SD CARD ===============================================================

#include <SD.h>
#include <SPI.h>

const int chipSelect = 9;

// KEYBOARD ==============================================================

#include <SoftPathElectronics.h>

CustomKeyboard keyboard;

// LCD ===================================================================

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20, 4);

// LEDs ==================================================================

#include <FastLED.h>

#define NUM_LEDS 16
#define DATA_PIN 5
#define CLOCK_PIN 13

CRGB leds[NUM_LEDS];

// VARIABLEN =============================================================

  int player = 0;                                       // Zeigt an, welcher Spieler dran ist
  int playerS;                                          // playerSelect, damit man während der Auswahl in der while-Schleife bleibt
  int playerN;                                          // playerNumber, Anzahl der Spieler
  int r = 1;                                            // round, Nummer der Runde
  int i = 0;                                            // index, sorgt dafür, dass unsigned long nicht überschritten wird (9 Nummern max.)

  int qC = 0;                                           // questionCheck
  unsigned long a;                                      // answer, Antwort nach eingabe

  int cursorX = 5;                                      // cursorXVariable, um den Cursor bei der Eingabe zu steuern
  int old_inp[9];                                       // Array, der die vorherige Eingabe speichert, sodass man löschen kann

  int ledC = 0;                                         // ledCound, steuert dei LEDs

  // a als Antwort auf die Frage
  int ans = 1000;

  // y für Serial.print Zwecke
  int y = 0;

// SETUP =================================================================

void setup() {
  delay(1000);
  Serial.begin(115200);

  // LEDS ====================
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);

  // KEYBOARD ================
  String key = "3 12 6 1 1022 315 186 511 241 158 340 195 136 255 164 120 0 0 0 0";
  keyboard.setupKey(key);

  // LCD =====================
  lcd.init();
  lcd.backlight();

  // SD ======================
  if (!SD.begin(chipSelect)) {
    lcd.setCursor(3, 1);
    lcd.print(F("Keine SD-Karte"));
    lcd.setCursor(4, 2);
    lcd.print(F("gefunden ://"));
    delay(10000);
  }

  // WELCOME =================
  lcd.setCursor(0, 0);                                  // Welcome LCD
  lcd.print(F("--------------------"));
  lcd.setCursor(3, 1);
  lcd.print(F("Willkommen bei"));
  lcd.setCursor(4, 2);
  lcd.print(F("Trivia Guess"));
  lcd.setCursor(0, 3);
  lcd.print(F("--------------------"));

  for (;ledC < 32; ledC ++) {                           // Welcome LED
    if (ledC < 4) {leds[ledC] = CRGB::Blue;}
    else if (ledC < 8) {leds[ledC] = CRGB::Red;}
    else if (ledC < 12) {leds[ledC] = CRGB::Green;}
    else if (ledC < 16) {leds[ledC] = CRGB::Yellow;}
    else if (ledC < 20) {leds[ledC -4] = CRGB::Black;}
    else if (ledC < 24) {leds[ledC -12] = CRGB::Black;}
    else if (ledC < 28) {leds[ledC -20] = CRGB::Black;}
    else if (ledC < 32) {leds[ledC -28] = CRGB::Black;}

    if (ledC == 3 || ledC == 7 || ledC == 11 || ledC == 15 || ledC == 19 || ledC == 23 || ledC == 27 || ledC == 31) {
      FastLED.show();
      delay(150);
    }
  }

  ledC = 0;

}

// LOOP ==================================================================

void loop() {

  int lcdP[4] = {0,-7,8,-15};

  lcd.clear();
  lcd.setCursor(2, 1);
  lcd.print(F("Spieleranzahl:"));
  lcd.blink();

  while (playerN == 0) {

    int inp = keyboard.getKeyPressed();

    if (inp > 0) {

      if (inp < 5) {

        lcd.setCursor(16, 1);
        lcd.print(inp);
        playerS = inp;

        delay(250);
      }
      if (inp == 12 && playerS > 0) {

        playerN = playerS;

        delay(250);
      }
    }
  }

  lcd.clear();
  lcd.setCursor(cursorX,3);

  long solution[playerN];      // Array um Lösungen besser zu testen 
  int points[4] = {0,0,0,0};

  while (r < 2) {

    int inp = keyboard.getKeyPressed();

    if (qC == 0) {

      char question[15] = "frage_000_0.txt";           // <==========
      question[7] += random(5);                                // <==========
      question[8] += random(8);                                // <==========

      Serial.print(question);

      for (y = 1; y < 4; y++) {
        File text = SD.open(question, FILE_READ);
      }

      qC = 1;
    }
  
    if (inp >= 0) {

      if (inp < 10 && i < 9 || inp == 11 && i < 9) {

        if (inp == 11) {
          inp = 0;
        }

        lcd.setCursor(cursorX, 3);
        lcd.print(inp);

        Serial.print(a);
        Serial.print(" * 10 + ");
        Serial.print(inp);

        a = a * 10 + inp;
        cursorX ++;

        Serial.print(" = ");
        Serial.println(a);

        old_inp[i] = inp;
        i ++;

        delay(250);
      }

      if (inp == 10 && cursorX > 0) {
        cursorX --;
        lcd.setCursor(cursorX, 3);
        lcd.print(" ");

        i --;
        a = (a - old_inp[i]) / 10;

        delay(250);
      }

      if (inp == 12 && i > 0) {

        solution[player] = a;

        // Reset
        i = 0;
        a = 0;
        cursorX = 5;
        memset(old_inp, 0, sizeof(old_inp));
        lcd.clear();
        lcd.setCursor(cursorX ,3);

        for(y = 0; y < 9; y++){
          Serial.print(old_inp[y]);
          Serial.print(",");
        }

        if (player +1 == playerN) {
          lcd.noBlink();

          for (; i < playerN; i++) {
            lcd.setCursor(0,i);
            lcd.print(F("S"));
            lcd.print(i +1);
            lcd.print(F(": "));
            lcd.print(solution[i]);
            delay(1000);      // Maybe verlängern, nach Testen

            solution[i] = abs(ans - solution[i]);
          }

          for (i = 0; i < playerN; i++) {
            lcd.setCursor(4,i);
            lcd.print(F("         "));
            lcd.setCursor(4,i);
            lcd.print(solution[i]);
          }

          Serial.println(solution[3]);

          delay(1000);      // Maybe verlängern, nach Testen

          lcd.clear();

          lcd.setCursor(0,0);
          lcd.print(F("A: "));
          lcd.print(ans);
          delay(1000);       // Maybe verlängern, nach Testen

          lcd.setCursor(0,1);

          int check = 0;
          int minV = solution[0];

          for (y = 0; y < sizeof(points); y++) {
            Serial.print(points[y]);
            Serial.print(", ");
          }

          for (; check < playerN; check++) {
            minV = min(solution[check], minV);
          } 

          Serial.println(minV);

          for (check = 0; check < playerN; check++) {      // Punktevergabe
            if (minV == solution[check]) {      // Falls der Kleinste Wert des Arrays an Position 0(1,2,3) ist...
              points[check] +1;                 // Im Punkte-Array an dieser Stelle +1
              Serial.println("points: ");
              Serial.print(points[check]);
              if (points[check] == 4) {
                r++;
              }
              if (check == 0) {    
                leds[abs(lcdP[check])] = CRGB::Blue;      // Je nach Spieler wird die enstprechende LED angesteuert
                lcdP[check] ++;                           
              }
              if (check == 1) {
                leds[abs(lcdP[check])] = CRGB::Red;
                lcdP[check] ++;
              }
              if (check == 2) {
                leds[abs(lcdP[check])] = CRGB::Green;
                lcdP[check] ++;
              }
              if (check == 3) {
                leds[abs(lcdP[check])] = CRGB::Yellow;
                lcdP[check] ++;
              }
              FastLED.show();
            }
          } 

          delay(2500);

          //Reset
          lcd.clear();
          lcd.setCursor(cursorX ,3);
          lcd.blink();
          player = 0;
          
        }

        else {
        player ++;
        }

        delay(250);
      }
    }
  }

  playerN = 0;
  
}

Serial Output: Error: Key string does not have enough values.

Woran könnte das liegen?

das sind doch keine gleichen Codes !
Außer der Teil, den du rein kopiert hast.

Schon, die char sind aber in beiden Fällen umangerührt und den Error bekomme ich erst, seitdem ich diesen Code-Schnipsel reinkopiert habe

Ich habe herausgefunden, dass er nicht an dieser Stelle im Code ausgelöst wird, sondern beim starten.

Dann solltest du das Problem mittels "serieller Ausgaben" in deinem Code lokalisieren.

Mach mal das + vor dem = weg.

nein, das plus vor dem = bei question[7] += random(5); muss bleiben, die Random-Funktion liefert einjen integerwert, damit das ein ascii-Zeichen wird (für den Dateinamen), muss er ihn auf '0' (0x30) addieren. Da du schreibst, dass der Fehler direkt beim Start kommt, tippe ich einfach mal (ohne weiteren Beleg, da ich mit dem Keyboard selber noch nie gearbeitet habe) auf die Zeilen 63 und 64, das ist die einzige Stelle, wo was mit String gemacht wird.

ok, ich bin jetzt etwas näher an der Lösung. Der Error tritt nur dann auch, wenn ich versuche question in Serial auszugeben. Sehr merkwürdig. Davor kommen auch 3 komische Zeichen im Serial, als würde er versuchen was auszugeben und dann aufgeben

Ok, also das Problem hat sich nach einem Neustart von Arduino IDE von selbst behoben.War wohl ein Bug oder so. ich bekomme allerdings dieses Zeichen dahinter ??

kann das vielleicht das Serial.print(a); aus Zeile 179 sein? du solltest mal schauen, dass du nach dem Ausgeben zusammenhängender Werte ein Serial.println() machst, damit man die Ausgaben auch den einzelnen Stellen im Code zuordnen kann.

Das ist es tatsächlich nicht. Wenn ich aus solution[15] solution[16] mache, verschwindet es auch. Der Error ist auch wieder da, es hat wohl irgendwas mit der SD Karte zu tun. Er kam Nämlich wieder als ich den Teil mit der SD Karte hinzugefügt habe

      char question[15] = "frage_000_0.txt";
      
      randomSeed(analogRead(0));
      question[7] += random(5);            // Zufallszahl von '0' bis '4'
      question[8] += random(8);            // Zufallszahl von '0' bis '7'

      Serial.println(question);

      for (y = 1; y < 4; y++) {
        File text = SD.open(question, FILE_READ);
        if (!text) {
          Serial.println("Fehler: Datei konnte nicht geöffnet werden!");
          return;
        }
      }

Selbst wenn y irgendwo definiert sein sollte, ist die Schleife Mist.
Wozu 4 mal eine Datei öffnen und den File handle wegwerfen ?

Ist das ein Serial Output oder eine Fehlermeldung beim Übersetzen?
Hat auf jeden Fall nicht viel mit deinem geschilderten Problem zu tun, außer dass bei RAM-Problemen ( 4 offene Dateien ) natürlich alles passieren kann.
Wo der Text "Error: key "... herkommt, wenn er in deinem Sketch nicht existiert, ist eine Frage an deine Libs.

Bugs gibt es nicht. Alles was passiert, hast du so programmiert. :slight_smile:

Aber wenn alles passieren kann, kann natürlich bei der kleinsten Änderung irgendwo, auch etwas ganz anderes passieren.

Wozu 4 mal eine Datei öffnen und den File handle wegwerfen ?

Der Code an der Stelle ist noch nicht fertig. Die Dateiendung wird abgeändert und dann 4 mal auf ein LCD in jeweils andere Zeilen geprinted.

Hat auf jeden Fall nicht viel mit deinem geschilderten Problem zu tun, außer dass bei RAM-Problemen ( 4 offene Dateien ) natürlich alles passieren kann.

Mittlerweile ist die for schleife im code weg und ich hab ihn auf ein bare Minimum gestrippt:

char question[15] = "frage_000_0.txt";
      
      randomSeed(analogRead(0));
      question[7] += random(5);            // Zufallszahl von '0' bis '4'
      question[8] += random(8);            // Zufallszahl von '0' bis '7'

      Serial.println(question);


        File text = SD.open("frage_023_1.txt", FILE_READ);
        if (text) {
          while (text.available()) {
            char tx = text.read();
            Serial.println(tx);
          }
          text.close();
        }
        else {
          Serial.println("Datei konnte nicht gefunden werden");
        }

Leider bekomme ich immer noch den Error :confused:

du meinst wohl question und nicht solution? ja, question[16] muss sein, ein string (char array) muss immer mit einem zeichen mehr deklariert werden, da die Zeichenkette mit einem 0x00 abgeschlossen ist. Und du solltest schon immer dabei sagen, was du geändert hast, sonst müssen wir Olga mit der Glaskugel bemühen, hier sind nur Programmierer aber keine Hellseher...... davon abgesehen, was bezweckst du mit der Schleife? entweder funktioniert die SD-Karte und die Datei ist da oder halt nicht, da nützt es aber auch nichts, das mehrfach zu versuchen. zumahl du ja garnichts weiter mit dem File-Handle machst.

Was sehr seltsam ist, ist das dieser Code zumindest funktioniert und keinen Error ausgibt:

#include <SD.h>
#include <SPI.h>

const int chipSelect = 9;

void setup() {
  // put your setup code here, to run once:
  delay(1000);
  Serial.begin(115200);

  if (!SD.begin(chipSelect)) {
    Serial.println("Keine SD-Karte");
  }

  char question[16] = "frage_000_1.txt";
      
  randomSeed(analogRead(0));
  question[7] += random(5);            // Zufallszahl von '0' bis '4'
  question[8] += random(8);            // Zufallszahl von '0' bis '7'

  Serial.println(question);


  File text = SD.open(question, FILE_READ);
  if (text) {
    while (text.available()) {
      char tx = text.read();
      Serial.println(tx);
    }
    text.close();
  }
  else {
    Serial.println("Datei konnte nicht gefunden werden");
  }

}

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

}

Und das einfach kopierte Teile aus dem HauptCode sind

wie meinst du das?

Hast du vollkommen recht. Ich bin zu schnell über den Code gegangen ohne weiter nachzudenken.

Aber da wäre meine bevorzugte Variante, wenn es schon so gemacht werden soll,
eher folgende:

randomSeed(analogRead(0));
  question[7] = random(0x30, 0x35);           // Zufallszahl (ASCII) von '0' bis '4'
  question[8] = random(0x30, 0x38);           // Zufallszahl (ASCII) von '0' bis '7'  

Das erscheint mit klarer.

Mach daraus mal
char question[] = "frage_000_0.txt";
und schau, was dir Serial.println(sizeof(question)); dazu sagt.

Ich meinte, dass du Teile aus dem Code rausnimmst und wieder reinnimmst, uns das aber nicht direkt mitteilst, sondern zuerst nur das Ergebnis, nämlich das 'plötzlich' der Fehler weg war.....

Ich hatte ein bisschen umprobiert und dachte die ganze Zeit der Fehler liegt bei random. Ich hab also die ganze Sektion (inkl. SD) rausgenommen und umprobiert. Ich hab nicht daran gedacht sie wieder mit einzubauen. Ist mir auch jetzt erst aufgefallen

question[7] = random('0', '4'+1);           // Zufallszahl (ASCII) von '0' bis '4' einschließlich
question[8] = random('0', '7'+1);     

Hätte auch generell den Vorteil, dass question nicht jedesmal neu mit dem Basistext initialisiert werden müsste.

Aber @brotchen hat zum Glück andere Probleme :slight_smile:
Dass man mit allen Warnungen übersetzt und so.
Bei mir ist es übrigens ein error
initializer-string for 'char [15]' is too long [-fpermissive]

[Nachtrag]
Beim Uno und der IDE 1.8.19 tatsächlich nur

warning: initializer-string for array of chars is too long [-fpermissive]
 char question[15] = "frage_000_0.txt";

[/Nachtrag]