Vorhandenen Sketch erweitern

Hallo,

ich bin brandneu in diesem Forum. Ich hab nicht die Riesenahnung von dem was ich mit meinem Uno tue. Aber bisher hats nach vielen probieren etc. immer ein wenig funktioniert. Nun ist aber eine Passage gekommen, an der ich komplett verzweifel. Ich hatte gestern schon in diesen Forum gestöbert um eine Lösung zu finden. Ich hab auch schon zwei Anhaltspunkte von jemanden bekommen und den Tipp hier im Forum zu fragen. Ich hoffe, auf nette Leute, die sich meiner erbarmen und mir weiter helfen :slight_smile: Nun mein Problem:

Ich bin seit vielen Jahren Paintballspieler und hab mir vorgenommen, unser Team mit einer Spielvariation zu bereichern. Ein Simultancountdown muss her. Gemacht, getan... Ein Arduino Uno, ein LCD Display, ein Keypad, LED´s und Tröten wurden verbaut. Alles in eine Kiste rein und es funktioniert sogar. Der Sketch wurde zur freien Verfügung in einem Forum veröffentlicht. Der Programmierer war damit einverstanden, das auch änderungen getätigt werden können. Leider gibts den Account nicht mehr um den Programmier zu fragen. Denn ich würde gern noch zusätzlich die festgelegte Timerzeit in eine von mir wählbaren Zeit, die ich per Keypad eingebe erweitern. Noch dazu würde ich gern bei einer Codefalscheingabe demjenigen die Chance geben, nochmal den Code ein zu geben. Das ganze drei mal und erst dann, wenns immernoch falsch ist, gehen die Tröten los.
Der Tipp den ich bekommen hatte, war ein Array zu erstellen. Da fängt bei mir schonmal das Problem an. Ich weiss nicht wie, und wie ich das dann in einem vorhandenen Sketch einbinde. Genauso wie die drei Fehlversuche.

Ich würde mich riesig freuen, wenn mir da jemand weiter helfen könnte. Ich bin grad in einer tiefen Depressionsphase :slight_smile: :slight_smile:

Viele Grüße aus Potsdam
Frank

Wie stellst Du Dir vor, dass wir Dir helfen, wenn wir den vorhandenen Code noch nicht gesehen haben?

Hi,
hast Du Dir das schonmal angeschaut: Arduino - Home

Und hast Du irgendwas vom Sketch oder fängst Du bei Null an?
Und hast Du irgend eine grobe Idee wie Du das Problem angehen kannst?

Wenn alle Antworten "Nein" heißen dann bedeutet das für Dich: ran an die Basics!
Und da liefert Dir die IDE schon ne Menge mit.

Und dann: hier konkret fragen. Wird schon!

Oh, ehm, sorry. Da war ja noch was. Hab ich echt vergessen mit rein zu kopieren. :sweat_smile: Hier hab ich mal den kompletten Code.

/////////////////////////////
//      Airsoft Bomb       //
// by Malthe Falkenstjerne //
/////////////////////////////

#include <Keypad.h>
#include <LiquidCrystal.h>
#include <Tone.h>
#define pound 14

Tone tone1;

int Scount = 00; // count seconds
int Mcount = 15; // count minutes
int Hcount = 0; // count hours
int DefuseTimer = 0; // set timer to 0

long secMillis = 0; // store last time for second add
long interval = 1000; // interval for seconds

char password[4]; // number of characters in our password
int currentLength = 0; //defines which number we are currently writing
int i = 0; 
char entered[4];

int ledPin = 4; //red led
int ledPin2 = 3; //yellow led
int ledPin3 = 2; //green led

LiquidCrystal lcd(7,8,10,11,12,13); // the pins we use on the LCD



const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {5, A5, A4, A2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {A1, A0, A3}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
  pinMode(ledPin, OUTPUT); // sets the digital pin as output
  pinMode(ledPin2, OUTPUT); // sets the digital pin as output
  pinMode(ledPin3, OUTPUT); // sets the digital pin as output
  tone1.begin(9);
  lcd.begin(16, 2);
  Serial.begin(9600);
  lcd.clear();
  lcd.setCursor(2,0);
  
  lcd.print (" Paintstorm ");
lcd.setCursor(0,1);
lcd.print(" Paintball Bomb ");
delay (4000);
lcd.clear();
lcd.setCursor(2,0);
lcd.print ("15 min Zeit zum");
lcd.setCursor(0,1);
lcd.print("*entschärfen*");
delay(1500);
lcd.clear();
  
  lcd.print("Enter Code: ");
  while (currentLength < 4)
  {
    lcd.setCursor(currentLength + 12, 0);
    lcd.cursor();
    char key = keypad.getKey();
    key == NO_KEY;
    if (key != NO_KEY)
    {
      if ((key != '*')&&(key != '#'))
      { 
      lcd.print(key);
      password[currentLength] = key;
      currentLength++;
      tone1.play(NOTE_D8, 75);
      }
    }
  }

  if (currentLength == 4)
  {
    
    
    delay(500);
    lcd.noCursor();
    lcd.clear();
    lcd.home();
    lcd.print("You've Entered: ");
    lcd.setCursor(6,1);
    lcd.print(password[0]);
    lcd.print(password[1]);
    lcd.print(password[2]);
    lcd.print(password[3]);

    tone1.play(NOTE_FS4, 250);
    delay(3000);
    lcd.clear();
    currentLength = 0;
  }
}



void loop()
{
  timer();
  char key2 = keypad.getKey(); // get the key
  
  if (key2 == '*')
    {
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("Code: ");
      
      while (currentLength < 4)
        {
          
          timer();
          
          char key2 = keypad.getKey(); 
          if (key2 == '#')
            {
              currentLength = 0;
              lcd.clear();
              lcd.setCursor(0,0);
              lcd.print("Code: ");
            }
          else                  
          if (key2 != NO_KEY)    
            {
              
              lcd.setCursor(currentLength + 7, 0);
              lcd.cursor();
              
              lcd.print(key2);
              entered[currentLength] = key2;
              currentLength++;
              tone1.play(NOTE_C6, 200);
              delay(100);
              lcd.noCursor();
              lcd.setCursor(currentLength + 6, 0);
              lcd.print("*");
              lcd.setCursor(currentLength + 7, 0);
              lcd.cursor();
            }
        }

      if (currentLength == 4) 
        {
          if (entered[0] == password[0] && entered[1] == password[1] && entered[2] == password[2] && entered[3] == password[3])
            {
              lcd.noCursor();
              lcd.clear();
              lcd.home();
              lcd.print("**Bomb Defused**");
              currentLength = 0;
              digitalWrite(ledPin3, HIGH);
              delay(2500);
              lcd.setCursor(0,1);
              lcd.print("-Reset the Bomb-");
              delay(1000000);
            }
      else
        {
          lcd.noCursor();
          lcd.clear();
          lcd.home();
          lcd.print("Wrong Password!");
    
          if (Hcount > 0)
            {
              Hcount = Hcount - 1;
            }
    
          if (Mcount > 0)
            {
              Mcount = Mcount - 59;
            }
          if (Scount > 0)
            {
              Scount = Scount - 59;
            }
        delay(1500);
        currentLength = 0;
  
        }
      }  
    }
}

void timer()
{
  Serial.print(Scount);
  Serial.println();
  
  if (Hcount <= 0)
  {
    if ( Mcount < 0 )
    {
      lcd.noCursor();
      lcd.clear();
      lcd.home();
      lcd.print("Bomb is exploded");
      lcd.setCursor (0,1);
      lcd.print("Have a nice Day.");
      
      while (Mcount < 0) 
      {
        digitalWrite(ledPin, HIGH); // sets the LED on
        tone1.play(NOTE_A2, 90);
        delay(100); 
        digitalWrite(ledPin, LOW); // sets the LED off
        tone1.play(NOTE_A2, 90);
        delay(100); 
        digitalWrite(ledPin2, HIGH); // sets the LED on
        tone1.play(NOTE_A2, 90);
        delay(100); 
        digitalWrite(ledPin2, LOW); // sets the LED off
        tone1.play(NOTE_A2, 90);
        delay(100); 
        digitalWrite(ledPin3, HIGH); // sets the LED on
        tone1.play(NOTE_A2, 90);
        delay(100); 
        digitalWrite(ledPin3, LOW); // sets the LED off
        tone1.play(NOTE_A2, 90);
        delay(100);
      }
    } 
  }

  lcd.setCursor (0,1); // sets cursor to 2nd line
  lcd.print ("Timer:");

  if (Hcount >= 10)
    {
      lcd.setCursor (7,1);
      lcd.print (Hcount);
    }
  if (Hcount < 10) 
    {
      lcd.setCursor (7,1);
      lcd.write ("0");
      lcd.setCursor (8,1);
      lcd.print (Hcount);
    }

  lcd.print (":");

  if (Mcount >= 10)
    {
      lcd.setCursor (10,1);
      lcd.print (Mcount);
    }
  if (Mcount < 10) 
    {
      lcd.setCursor (10,1);
      lcd.write ("0");
      lcd.setCursor (11,1);
      lcd.print (Mcount);
    }
    
  lcd.print (":");

  if (Scount >= 10) 
    {
      lcd.setCursor (13,1);
      lcd.print (Scount);
    }
  if (Scount < 10) 
    {
      lcd.setCursor (13,1);
      lcd.write ("0");
      lcd.setCursor (14,1);
      lcd.print (Scount);
    }

  if (Hcount <0) 
    {
      Hcount = 0; 
    }

  if (Mcount <0) 
    {
      Hcount --; 
      Mcount = 59; 
    }

  if (Scount <1) // if 60 do this operation
    {
      Mcount --; // add 1 to Mcount
      Scount = 59; // reset Scount
    }

  if (Scount > 0) // do this oper. 59 times
    {
      unsigned long currentMillis = millis();
  
      if(currentMillis - secMillis > interval) 
        {
          tone1.play(NOTE_G5, 200);
          secMillis = currentMillis;
          Scount --; // add 1 to Scount
          digitalWrite(ledPin2, HIGH); // sets the LED on
          delay(10); // waits for a second
          digitalWrite(ledPin2, LOW); // sets the LED off
          delay(10); // waits for a second
          //lcd.clear();
        }
    }
}

Bitte editiere Deinen Post und mach Code-Tags um den Code, ohne diese kann das Forum-System Teile davon unterdrücken.

Denn ich würde gern noch zusätzlich die festgelegte Timerzeit in eine von mir wählbaren Zeit, die ich per Keypad eingebe erweitern. Noch dazu würde ich gern bei einer Codefalscheingabe demjenigen die Chance geben, nochmal den Code ein zu geben. Das ganze drei mal und erst dann, wenns immernoch falsch ist, gehen die Tröten los.

Die beiden Änderungswünsche haben - ausser dass sie sich auf den gleichen Arduino-Sketch beziehen - , nichts miteinander zu tun.
Die erste Aufgabe hat die Besonderheiten, dass

  • Ein Eröffnungstext 4 Sekunden lang angezeigt wird,
  • Dann der feste Text "15 min Zeit zum / entschärfen" kommt,
  • Dann nach weiteren 1,5 sec "Enter Code",
  • und erst danach jede Eingabe als Code interpretiert wird

Eine Änderung die du evtl. hinkriegst:
Statt 4 sec am Stück zu warten, warte 8 mal 0,5 sec und frage jedesmal ab, ob eine Taste gedrückt wurde. Falls ja, mach was anderes als den Text "15 min Zeit zum / entschärfen" auszugeben.

Als Vorübung: Brich das 8 * 0,5 sec warten ab und gib den Text "Level: " aus, wenn die Taste ein '#' war.
Wenn das klappt ( Glückwunsch ), lies danach solange das keypad , bis eine der Tasten '0' .. '9' erkannt wurde.

Die Sache mit dem Array, und wie du die bisherigen festen 15 Minuten änderst und das auch anstelle des festen Textes anzeigst, kommt danach. Erstmal den sketch mit kleinsten Änderungen in den Griff kriegen.

Wenn es zwar fehlerfrei kompiliert, aber danach nicht das macht was es soll, hilft dir Serial.print( ... );
Beispiele dazu sind schon drin.

Viel Spass.

Hoffentlich schreibt dir keiner mal eben schnell dein Spielchen um, oder schimpft "was'n Schrott, da sind ja delays drin " :wink:
Das mit dem "Schrott" stimmt zwar, und mein Vorschlag (1 * 4 sek) in (8 * 0,5 sek) zu ändern, liegt nur daran, dass es mal so schon drin war, und dadurch die erste Änderung nicht so groß ausfällt.
(Musst natürlich die erste Taste '#' ziemlich lange (bis zu 0,5 s) drücken, bevor der Arduino es merkt)

Hallo,

ich bin grad ziemlich überfordert. Worin besteht der Unterschied zwischen 4 sek und 8 mal 0.5 sek? Ich bin ein ziemlich grüner Anfänger in der Arduinowelt. Ich kann schon Texte und Töne ändern, LCD´s ansteuern aber wie frage ich ab, ob eine Taste gedrückt wird? Falls ich das noch in diesem Leben (ich bin 52) hinbekomme, wo setze ich diese "Abfragezeilen" dann in den vorhandenen Sketch ein?
Dass das kompliziert ist, hab ich mit gerechnet, das es aber sooo kompliziert ist, zumindest für mich, konnte ich nicht ahnen.

Gruß Frank

delay() macht genau was es impliziert. Es dreht sich für x ms im Kreis und blockiert alles andere. Wenn man jetzt nur kurze Delays macht, aber mehrmals im auf die Zeit zu kommen, kann man dazwischen mal kurz einen Taster abfragen oder was anderes machen.

Achsooo, wenn ich das richtig verstehe, sieht es dann so aus?
Teaxtausgabe
delay();
abfrage
delay();
abfrage
delay();
u.s.w.

Nitri:
Denn ich würde gern noch zusätzlich die festgelegte Timerzeit in eine von mir wählbaren Zeit, die ich per Keypad eingebe erweitern. Noch dazu würde ich gern bei einer Codefalscheingabe demjenigen die Chance geben, nochmal den Code ein zu geben. Das ganze drei mal und erst dann, wenns immernoch falsch ist, gehen die Tröten los.
Der Tipp den ich bekommen hatte, war ein Array zu erstellen. Da fängt bei mir schonmal das Problem an. Ich weiss nicht wie, und wie ich das dann in einem vorhandenen Sketch einbinde. Genauso wie die drei Fehlversuche.

Ich würde mich riesig freuen, wenn mir da jemand weiter helfen könnte. Ich bin grad in einer tiefen Depressionsphase :slight_smile: :slight_smile:

Also ist Euer aktueller Status:

  • Ihr habt viel Ahnung vom Paintballspielen
  • Ihr habt ein bisschen Ahnung wie Eure Eletronikkiste mit LCD, Keypad und Tröten zusammengeschaltet ist
  • Ihr habt bereits ein teilweise funktionierendes Programm für die Kiste, das aber geändert werden soll
  • Ihr habt die Möglichkeit, mit der Arduino-Software ein neues Programm in die Kiste zu laden
  • Aber alle zusammen haben null Ahnung vom Programmieren (und beginnende Depressionen)

Ich habe das von Dir gepostete Programm mal überflogen, so sieht es aus:

Änderungswunsch "Timerzeit": So wie ich den Sketch lese, kann jedesmal beim Einschalten (bzw. nach einem Reset des Boards) als erstes der vierstellige Schlüsselcode eingegeben werden. Das kannst Du mit der Timerzeit vom Prinzip her genau so machen. Reicht eine maximal einstellbare Timer-Zeit von 9999 Sekunden, entsprechend gut 2 Stunden und 45 Minuten? Oder eine maximal einstellbare Timer-Zeit von 9999 Minuten, entsprechend knapp einer Woche? Dann machst Du vor oder nach der Schlüsselcode-Eingabe eine vierstellige Timerzeit-Eingabe zwischen 0000 und 9999. Nach Eingabe der Timerzeit wird das nur noch in Stunden, Minuten, Sekunden umgerechnet und das Spiel kann mit einer frei konfigurierten Timerzeit beginnen.

Schwieriger ist es mit der mehrmaligen Falscheingabe-Möglichkeit für das Codeschloss. Das Problem ist, dass das Programm nur wenig modular gegliedert ist, sondern als ziemlicher Spaghetticode zusammengestrickt wurde. Da es sich um ein recht simples Programm handelt, also im wesentlichen um einen Countdown-Timer mit einer Codeschloss-Logik, würde ich das Programm eher in einer übersichtlicheren (und danach auch leichter wartbaren) und klar gegliederten Form nahezu komplett neu programmieren als zu versuchen, die Codeschlosslogik noch in dem vorhandenen Spaghetticode einzufügen.

Hallo,

mein Status ist:
-ich bin Spaß- und Gelegenheitsspieler, weil auf dauer zu teuer
-vor ca. 30 Jahren hatte ich mich mit Elektronik befasst. Da gabs noch keine Mikrocontroller, LCD etc (Transistoren waren da in ^^)
-ich habe das mehr oder weniger funktionierende Programm aus einem Forum bekommen
-ich hab schon oft (vergeblich) versucht etwas in die Kiste zu laden
-ich bin der einzige, der weiß, das Spannung anliegt und Strom fließt :slight_smile:

Und das verrückteste ist, ich lese, lese und lese Tutorials, Beschreibungen und Anleitungen. Schau mir Videos an etc. und bewege mich kein bischen nach vorn. Immer wieder seh ich in der Arduinosoftware die nette rote Schrift die mir sagt, das was ich mache Mist ist. Ich hab auch ein anderes Programm bekommen. Aber da funktioniert nichtmal das Überprüfen. Da kommt immer "Das Keywort 'BYTE' wird nicht mehr unterstützt"
Ich bin Modellflieger und mus sagen, das ein Helicopter oder Flugzeug einfacher zu fliegen ist als ein Microprozessor zu Progrmmieren :slight_smile:
Wenn ich das schon hin bekommen würde das ich die Zeit bis 2 Stunden einstellen könnte, wär das ein extremer Quantensprung.
Hut ab vor allen, die ein Programm schreiben, als wärs ´ne E-Mail. :slight_smile:

Ich glaube, mich kann mein Uno nicht leiden :slight_smile:

Gruß Frank

Nitri:
mein Status ist:
-ich bin Spaß- und Gelegenheitsspieler, weil auf dauer zu teuer
-vor ca. 30 Jahren hatte ich mich mit Elektronik befasst. Da gabs noch keine Mikrocontroller, LCD etc (Transistoren waren da in ^^)
-ich habe das mehr oder weniger funktionierende Programm aus einem Forum bekommen
-ich hab schon oft (vergeblich) versucht etwas in die Kiste zu laden
-ich bin der einzige, der weiß, das Spannung anliegt und Strom fließt :slight_smile:

Und Du hast offensichtlich die Kiste schon mal mit den Einzelteilen passend verdrahtet bekommen, so dass sie mit dem fremden Sketch so leidlich läuft.

Nitri:
Und das verrückteste ist, ich lese, lese und lese Tutorials, Beschreibungen und Anleitungen. Schau mir Videos an etc. und bewege mich kein bischen nach vorn. Immer wieder seh ich in der Arduinosoftware die nette rote Schrift die mir sagt, das was ich mache Mist ist. Ich hab auch ein anderes Programm bekommen. Aber da funktioniert nichtmal das Überprüfen. Da kommt immer "Das Keywort 'BYTE' wird nicht mehr unterstützt"

Das beim Arduino verwendete C++ ist keine typische "Lehrsprache" oder "Anfängersprache", sondern die typische Universalsprache, mit der heute Profis alles programmieren. Für Anfänger sind viele Dinge nicht direkt einsichtig, z.B. dass Groß- und Kleinschreibung NICHT EGAL sind. D.h. "byte" und "BYTE" und "Byte" und "ByTe" sind vier ganz verschiedene Dinge.

Vorteilhaft für den Einstieg wäre jedenfalls, wenn man wenigstens irgendeine Programmiersprache einigermaßen beherrscht, wenn man selbst etwas machen möchte.

Nitri:
Ich bin Modellflieger und mus sagen, das ein Helicopter oder Flugzeug einfacher zu fliegen ist als ein Microprozessor zu Progrmmieren :slight_smile:
Wenn ich das schon hin bekommen würde das ich die Zeit bis 2 Stunden einstellen könnte, wär das ein extremer Quantensprung.
Hut ab vor allen, die ein Programm schreiben, als wärs ´ne E-Mail. :slight_smile:

OK, ich habe Dir mal was vorbereitet, wie Du wenigstens die Zeiteingabe leicht einbauen kannst. Als erstes oben im Sketch eine zusätzliche Variable für die Eingabe der Spieldauer deklarieren, die Zeile mit der playtime-Deklaration ist neu:

char password[4]; // number of characters in our password
char playtime[4]; // number of characters in our playtime

Und dann habe ich die Spieldauer-Eingabe mal in der typischen Spaghetticode-Art wie der Code geschrieben ist mit in die setup-Funktion eingebaut. Dies wäre dann die neue setup-Funktion im Austausch:

void setup(){
  pinMode(ledPin, OUTPUT); // sets the digital pin as output
  pinMode(ledPin2, OUTPUT); // sets the digital pin as output
  pinMode(ledPin3, OUTPUT); // sets the digital pin as output
  lcd.begin(16, 2);
  Serial.begin(9600);
  lcd.clear();
  lcd.setCursor(2,0);
  
  lcd.print (" Paintstorm ");
lcd.setCursor(0,1);
lcd.print(" Paintball Bomb ");
delay (4000);
lcd.clear();
lcd.setCursor(2,0);
lcd.print ("15 min Zeit zum");
lcd.setCursor(0,1);
lcd.print("*entsch\341rfen*");
delay(1500);
  lcd.clear();
  lcd.print("Enter Code: ");
  while (currentLength < 4)
  {
    lcd.setCursor(currentLength + 12, 0);
    lcd.cursor();
    char key = keypad.getKey();
    key == NO_KEY;
    if (key != NO_KEY)
    {
      if ((key != '*')&&(key != '#'))
      { 
      lcd.print(key);
      password[currentLength] = key;
      currentLength++;
      tone(TONEPIN,NOTE_D8, 75);
      }
    }
  }

  if (currentLength == 4)
  {
    delay(500);
    lcd.noCursor();
    lcd.clear();
    lcd.home();
    lcd.print("You've Entered: ");
    lcd.setCursor(6,1);
    lcd.print(password[0]);
    lcd.print(password[1]);
    lcd.print(password[2]);
    lcd.print(password[3]);

    tone(TONEPIN, NOTE_FS4, 250);
    delay(3000);
    lcd.clear();
    currentLength = 0;
  }

  lcd.clear();
  lcd.print("Enter TIME: ");
  while (currentLength < 4)
  {
    lcd.setCursor(currentLength + 12, 0);
    lcd.cursor();
    char key = keypad.getKey();
    key == NO_KEY;
    if (key != NO_KEY)
    {
      if ((key != '*')&&(key != '#'))
      { 
      lcd.print(key);
      playtime[currentLength] = key;
      currentLength++;
      tone(TONEPIN,NOTE_D8, 75);
      }
    }
  }

  if (currentLength == 4)
  {
    delay(500);
    lcd.noCursor();
    lcd.clear();
    lcd.home();
    lcd.print("Spieldauer: ");
    lcd.setCursor(6,1);
    lcd.print(playtime[0]);
    lcd.print(playtime[1]);
    lcd.print(playtime[2]);
    lcd.print(playtime[3]);

    tone(TONEPIN, NOTE_FS4, 250);
    delay(3000);
    lcd.clear();
    currentLength = 0;
    Mcount = (playtime[0]-'0')*1000 + (playtime[1]-'0')*100 + (playtime[2]-'0')*10 + (playtime[3]-'0'); // count minutes
    Hcount = Mcount/60; // Stunden als Ganzzahldivision durch 60
    Mcount = Mcount%60; // Minuten als Divisionsrest beim Teilen durch 60
  }

}

Die Spieldauer muss dann zu Anfang genau wie der Keycode vierstellig numerisch in Minuten eingegeben werden. D.h. für eine Spieldauer von 2 Stunden = 120 Minuten wäre die Eingabe "0120".

Vielleicht bekommst Du es ja hin.

Außerdem glaube ich irgendwie nicht, dass Dir Dein LCD mit "entschärfen" das "ä" richtig anzeigt. Diese LCDs haben als Zeichensatz nämlich nicht denselben Zeichensatz wie Dein PC-Betriebssystem. Ich habe den Code mal so geändert, dass Du den "ä" Umlaut in "entschärfen" möglicherweise doch auf dem LCD angezeigt bekommst.

Probier's mal aus!

Außerdem sehe ich gerade, dass Dein Spiel mit einem erfolgreichen "Bomb Defused" nicht beendet ist, sondern der Countdown nach einem delay von 1000 Sekunden fortgesetzt wird:

              lcd.print("-Reset the Bomb-");
              delay(1000000);

Eine Million Millisekunden sind 1000 Sekunden = knappe 17 Minuten

Der Countdown ist also nach Eingabe des Keycodes nicht zuende, sondern nur für knappe 17 Minuten unterbrochen.

Da würde ein James Bond-Film wie Goldfinger ein ganz anderes Ende nehmen, wenn er die Bombe des Bösewichts in fast letzter Sekunde nur vermeintlich entschärft hat, der Countdown bei "007" stehen bleibt, und es nur ein "delay" bewirken würde, bevor der Countdown weiterläuft.

Auch das Spielende mit "Wrong Password!" ist vom Prinzip her falsch programmiert. Sieht man wegen des Spaghetticodes und der Programmierung mit diversen Seiteneffekten nicht, aber ich sage mal: Das Spielende mit "Wrong Password!" und der oben von mir geposteten Änderung für die freie Eingabe der Spieldauer ist nur in dem Fall sichergestellt, dass keine Spieldauer von mehr als 58 Minuten verwendet wird. Für Spieldauern über 58 Minuten kann die Logik beim Spielende mit "Wrong Password!" versagen und müßte ebenfalls geändert werden.

Wie gesagt: Eigentlich müßte das Ding komplett neu programmiert werden, modular und übersichtlich statt mit unübersichtlichem Spaghetticode.

Vielen Dank für die lehrreichen Worte. Die Hardware war eigentlich nicht das Problem. Das verdraten und anschließen ging relativ flott.
Die Software ist für mich echt heavy. Ganz, ganz früher, hatte ich mich mal mit C64 und Basic probiert. Aber irgendwie steh ich mit Programmiersprachen auf dem Kriegsfuß. Das mit dem Keywort BYTE ist nur ein Schreibfehler? Aber warum wurde der "Schreibfehler" mal unterstützt? Denn es steht ja da, das es nicht mehr unterstützt wird. Komische Welt :slight_smile:
Das vorbereitete hatte ich einbinden können. Und, es hat sogar funktioniert. Was hab ich mir das einen Kullerkeks gefreut :slight_smile: Vielen Dank dafür nochmal.
Aaber . . . das Licht der Freude wurde kurzerhand in völliger Dunkelheit umgewandelt.
Meine Frau war der Meinung heute Vormittag draußen die Hecke mit einer Elektrischen Heckenschere zu schneiden. Ich hab ihr schon von anfang an gesagt, nimm ein Akkugerät. Naaaaiiin, die haben kein Power und sind zu teuer und halten nicht lange durch. Es ist gekommen wie es kommen musste. Sie schnitt das Kabel durch . . . Jeder moderne Haushalt hat ein RCD installiert, der natürlich auslöste. Ich hab Ewigkeiten gebraucht um das Programm so hin zu bekommend das es funktionierte. Ich habs glücklicherweise aufs Arduino aufgespielt. Trotzdem hatte ich es dummerweise, wie sollte es auch anders sein, noch nicht gespeichert. Es ist ja so, das nicht täglich eine Sicherung hier kommt und mein PC sehr stabil läuft.

Kann man irgendwie das Programm aus dem Arduino auslesen? Ansonsten darf ich mich wieder drei Stunden hinsetzen und alles vorn vorne wieder eintippern.

Nitri:
Kann man irgendwie das Programm aus dem Arduino auslesen? Ansonsten darf ich mich wieder drei Stunden hinsetzen und alles vorn vorne wieder eintippern.

Nein, den "Quellcode" eines Programms kannst Du nicht aus dem Arduino auslesen.
Der Quellcode wird auf Deinem PC in ein "Maschinenprogramm" für den Controller übersetzt und nur das wird in den Controller geladen. Das Maschinenprogramm könnte man zwar mit einigem Aufwand auslesen, aber das kannst Du nicht weiterbearbeiten, das sind nur tausende von Zahlencodes

Eintippen brauchst Du doch auch gar nichts!
Du hast Deinen Quellcode gestern hier gepostet.
Ich habe als Änderung eine Zeile zusätzlichen Code und eine geänderte setup-Funktion gepostet.

Sowas "tippt" man nicht, sondern man übernimmt es per Copy-and-Paste (Kopieren und Einfügen) direkt aus dem Webbrowser rauskopiert und in den Arduino-Editor eingefügt.

Sorry, ich hab mich falsch ausgedrückt. Ich meinte natürlich per Copy/Paste. Aber hatte da ein paar Fehler gemacht, die ich aber hinbekommen hatte.
Aber worauf ich mich am meisten freue, ist das dein Programmteil funktioniert. Nun hab ich aber schnell eine funktionierende Version abgespeichert :cold_sweat:
Gestern hatte ich noch einen anderen Scetch bekommen, der weitaus komplizierter ist und viel mehr Funktionen hat. Leider gibts da auch Fehler beim Überprüfen.
Z.B. sowas hier

'EEPROM_readAnything' was not declared in this scope

Naja, erstmal das eine, dann das andere ^^

Nitri:
Aber worauf ich mich am meisten freue, ist das dein Programmteil funktioniert. Nun hab ich aber schnell eine funktionierende Version abgespeichert :cold_sweat:

OK. Es ist aber nur ein Änderungswunsch (Spielzeitvorgabe) berücksichtigt, und selbst bei dem würde ich nur für Spieldauern bis zu 0058 Minuten für einwandfreie Funktion garantieren. Darüber hinaus: Keine Garantie von meiner Seite.

Ich habe mir auch mal angesehen, wieviel Aufwand es mit einer kompletten "sauberen" Neuprogrammierung und Eingabe-Versuchszähler ist, dabei habe ich dann gesehen, dass es doch nicht ganz so trivial ist und weit über 100 Zeilen Code werden. Der Hauptaufwand kommt daher, dass bei Eingaben auch immer Soundausgaben erfolgen ("Tasten-Kontrollpieps") und durch das Handling von Cursor-On und Cursor-Off beim sekündlichen Aktualisieren der Restzeit mit gleichzeitiger Eingabemöglichkeit mit Anzeigen einer Cursor-Schreibmarke. Muss ich mal schauen, ob ich da irgendwann zwischendurch mal Zeit genug finde, versprechen kann ich nichts.

Eine Frage habe ich aber mal überhaupt zur Soundausgabe Deiner Kiste: Wie laut ist die und was machst Du als Soundausgabe? Weil wenn man nur einen kleinen Lautsprecher mit Kondensator an den Sound-Pin ankoppelt, ist es ja eher knappe Zimmerlautstärke. Hast Du an Deiner Kiste einen Audioverstärker angekoppelt oder soll gar nicht ein ganzes Paintball-Spielfeld mit dem Sound beschallt werden?

Nitri:
Gestern hatte ich noch einen anderen Scetch bekommen, der weitaus komplizierter ist und viel mehr Funktionen hat. Leider gibts da auch Fehler beim Überprüfen.
Z.B. sowas hier

'EEPROM_readAnything' was not declared in this scope

Naja, erstmal das eine, dann das andere ^^

Bei dem fehlenden EEPROM_readAnything könnte es sich um diese beiden Templates handeln. Im Zweifelsfall mal oben in Deinen Code reinkopieren und ausprobieren, ob es damit funktioniert:

#include <EEPROM.h>

template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
    const byte* p = (const byte*)(const void*)&value;
    int i;
    for (i = 0; i < sizeof(value); i++)
     EEPROM.write(ee++, *p++);
    return i;
}

template <class T> int EEPROM_readAnything(int ee, T& value)
{
    byte* p = (byte*)(void*)&value;
    int i;
    for (i = 0; i < sizeof(value); i++)
     *p++ = EEPROM.read(ee++);
    return i;
}

Ansonsten kannst Du ja ggf. auch mal den anderen Sketch posten, wenn das ohne Verletzung von Urheberrechten frei möglich ist. Vielleicht ist der ja tatsächlich einfacher an Deine Kiste anpassbar als der von Dir oben gepostete Sketch mit dem Spaghetticode, den man für eine saubere Programmlogik eigentlich nur komplett neu programmieren kann.

Du musst die verwendeten Libs auch installieren.

Oder in diesem Fall erstellen:
http://playground.arduino.cc/Code/EEPROMWriteAnything

Wie da steht:

put this in a file named "EEPROMAnything.h":

Die 58 min sin völlig ausreichend. :slight_smile:
Die Soundausgabe ist mit einem 12V, 125 db Piezo"pieper" gestaltet. Da der ordentlich Strom zieht und das Arduinoboard mit einer 9V Blockbatterie läuft, geht der über einen Schaltverstärker.
Im Wald beim ambienten Paintballspiellärm ist der nicht zu überhören. Sollte den mal doch einer nicht gehört haben, wäre ein Arztbesuch ratsam. Dann gibts ein "Kind" im Ohr :slight_smile:

Ich wollte den anderen Code hier mit einsetzen. Aber die Forumsoftware sagt, dass das zu viel an Buchstaben ist :slight_smile:
Ich sagte ja, das ist bei weitem komplizierter geschrieben als mein Spaghetticode. Was ist eigentlich ein Spaghetticode? ^^
Ich hab den Code mal als Anhang hier mit drann.

Seriallcd_bombe.ino (23.9 KB)

Nitri:
Die Soundausgabe ist mit einem 12V, 125 db Piezo"pieper" gestaltet. Da der ordentlich Strom zieht und das Arduinoboard mit einer 9V Blockbatterie läuft, geht der über einen Schaltverstärker.

Verstehe, also "mit Verstärker".

Nitri:
Ich hab den Code mal als Anhang hier mit drann.

Ich habe mal kurz reingeschaut: Ja, der ist ein bisschen anders. Und umfangreicher, mit Admin-Passwort und Speicherung von Parametern im EEPROM. Und mit über 800 Zeilen vor allem viel umfangreicher als der andere Code. Die Soundausgabe läuft allerdings nur über "Buzzer", die von sich aus nur Piepsen und nicht mit Tonausgabe in verschiedener Tonhöhe. Ist also insbesondere auf der Soundseite für etwas andere Hardware als Du sie hast.

Nitri:
Ich sagte ja, das ist bei weitem komplizierter geschrieben als mein Spaghetticode. Was ist eigentlich ein Spaghetticode? ^^

Ich verstehe unter Spaghetticode vor allem, dass im Sketch die Teilfunktionen:

  • Eingabe von Daten
  • Verarbeitung von Daten
  • Ausgabe von Daten
    nicht sauber getrennt sondern munter miteinander vermischt sind.
    Hier ein bisschen Keypad-Abfrage, da ein bisschen auf LCD ausgeben, dort ein bisschen Zeit runterzählen und das alles vermischt an vielen Stellen im Programm, teils mit "delay" Programmblockierungen und undurchschaubarer Ausnutzung von Seiteneffekten, wie z.B. beim Spielende: Da wird von der verbleibenden Spielzeit mal eben 1 Stunde, 59 Minuten und was weiß ich abgezogen, um dann an irgendeiner anderen Stelle im Code festzustellen: Wenn die Minuten ein negativer Wert sind, ist das Spiel zu Ende und die virtuelle Bombe ist explodiert statt entschärft. Diese kaum durchschaubaren Kontrollstrukturen machen das Programm so schlecht wartbar.

Andererseits funktioniert der Code auf Deiner vorhandenen Hardware und Dir fehlt nun im wesentlichen nur noch eine einzige Funktion, um eine mehrmalige Falscheingabe beim Entschärfen zu ermöglichen. Im Moment fehlt mir dazu eine geniale Idee, wie das mit einer kleinen Änderung am vorhandenen Programm oder mit einer kurzen, knackigen Neuprogrammierung mal eben auf die Schnelle hinzubekommen ist.

Ursprünglich sollte auch ein Lautsprecher ans Arduinoboard angeschlossen werden. Aber wie deine Vermutung war, ist der zu leise. Und extra einen richtigen Verstärker einbauen mit entsprechendem Lautsprecher, der vom mir aus 15 W hat, war mir derzeit zu aufwendig. Eine Schaltstufe ist nur ´n Transistor, paar Widerstände fertig :slight_smile: Zwar gibt der Piezo keine verschiedene Frequenzen wieder. Dafür ist der schön laut.
Ich hab noch so ein programmierbares MP3 Modul. Urprünglich kommt das aus dem Modellbau. Das hat grob gesagt, 5 "Auslöseanschlüsse" und jeder hat ein eigenes Soundfile, was man aufspielen kann. Mist ist, das alle Pins des Uno belegt sind.
Ja, der andere Code hat schon was und eine Versuchung wert eine zweite Kiste zu bauen :slight_smile: :slight_smile:

Es kamen ja noch Vorschläge, das die Zeit schneller abläuft, wenn der Code falsch eingegeben worden ist und ab der letzten Minute die Tonhöhe immer mehr ansteigt. Never change a running system :slight_smile: :slight_smile: Ich bin froh, dass das so wie es momentan ist, läuft. Auch wenn´s ein Teller Spaghetti ist ^^