Stopp­uhr

Lese­zeit: 7 Minu­ten

Lösung
Seite als PDF

Zunächst soll eine Stopp­uhr pro­gram­miert wer­den, die nach jedem Tas­ter­druck die Stopp­uhr neu star­tet und anschlie­ßend das Ergeb­nis anzeigt. Hier sol­len die Sekun­den noch in Minu­ten umge­rech­net wer­den, wenn jeweils 60 Sekun­den über­schrit­ten werden.

So soll es aussehen:

Download

Stopp­uhr Seri­el­ler Monitor

Schlie­ße das LCD an:

LCD

Nor­ma­ler­wei­se wäre eine kom­ple­xe Ver­ka­be­lung zum Betrieb eines LCDs nötig. Der ➨I2C-Bus regelt über einen eige­nen Mikro­pro­zes­sor die Kom­mu­ni­ka­ti­on der Daten­lei­tun­gen unter­ein­an­der. Es wer­den des­halb nur vier Anschlüs­se benötigt.

Die Hel­lig­keit kann mit einem Poten­tio­me­ter auf der Rück­sei­te des LCDs ein­ge­stellt werden.

Benö­tig­te Bauteile:

  • Tas­ter
  • LCD 1602
  • Lei­tungs­dräh­te

Baue die Schal­tung auf.
(Fah­re mit der Maus über das Bild, um die Bezeich­nun­gen der Bau­tei­le zu sehen)

Benö­tig­te Bibliotheken:

Bin­de die benö­tig­ten Biblio­the­ken ein und defi­nie­re die Variablen:

# include "LCDIC2.h"
# include "OneButton.h"
int TASTER = 7;

// Name des Tasters
OneButton NameTaster(TASTER, true);

// Name des LCDs
LCDIC2 lcd(0x27, 20, 4);

// Variablen der Zeit
float StartZeit;
float VerstricheneZeit;
float Sekunden;
bool Anzeige = true;

// TasterStatus sorgt für Start/Neustart
bool TasterStatus = true;

Der set­up-Teil star­tet das LCD und legt die benö­tig­ten Ein­stel­lun­gen für die Biblio­thek One­But­ton fest.

void setup()
{
  lcd.begin();

  // Cursor "verstecken"
  lcd.setCursor(false);
  lcd.setCursor(0, 0);
  lcd.print("Taste -> Start");
  lcd.setCursor(0, 1);
  lcd.print("--------------------");

  // Aktionen dem Modus des Tasters zuordnen
  NameTaster.attachClick(einKlick);
  /*
    Anzahl der Millisekunden festlegen
    Standardwerte gesetzt:
    PressTicks: 1000
    ClickTicks: 600
    DebounceTicks: 50
    wenn die Standardwerte gesetzt werden sollen
    können die nächsten Zeilen auskommentiert werden
  */
  NameTaster.setPressTicks(1000);
  NameTaster.setClickTicks(500);
  NameTaster.setDebounceTicks(50);
}

Der loop-Teil sorgt ledig­lich dafür, dass der Tas­ter abge­fragt wird:

void loop()
{
  // Taster alle 10 Millisekunden abfragen
  NameTaster.tick();
  delay(10);
}

Die Funk­ti­on ein­Klick() misst die Zeit und sorgt für die Aus­ga­be auf dem LCD:

void einKlick()
{
  if (TasterStatus)
  {
    StartZeit = millis();
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Taste - Stopp");
    lcd.setCursor(0, 2);
  }

  else
  {
    // Zeit berechnen
    float Sekunden;
    VerstricheneZeit = millis() - StartZeit;

    Sekunden = VerstricheneZeit / 1000;
    String GesamtSekunden = String(Sekunden);

    // . durch , ersetzen
    GesamtSekunden.replace(".", ",");

    // Ausgabe im Seriellen Monitor
    Serial.println("Sekunden insgesamt: " + GesamtSekunden + " Sekunden");

    // Minuten berechnen
    int Minute  = int(Sekunden) / 60;

    // nur Ausgabe der Minuten wenn Minute > 0
    if (Minute > 0)
    {
      // Ausgabe verschönern, wenn Minute > 1 -> Ausgabe "Minuten"
      // "Minute"
      if (Minute > 1)
      {
        lcd.setCursor(0, 2);
        lcd.print(String(Minute) + " Minuten ");
      }

      else
      {
        lcd.setCursor(0, 2);
        lcd.print(String(Minute) + " Minute ");
      }
    }

    // von Sekunden Anzahl der Minuten abziehen
    Sekunden = Sekunden - Minute * 60;

    // Sekunden in String umwandeln
    // damit . durch , ersetzt werden kann
    String AnzahlSekunden = String(Sekunden);

    // . durch , ersetzen
    AnzahlSekunden.replace(".", ",");

    // Ausgabe LCD
    lcd.setCursor(0, 0);
    lcd.print("Neustart -> Taste");
    lcd.setCursor(0, 3);
    lcd.print(AnzahlSekunden + " Sekunden");
  }

  // Tasterstatus umkehren
  TasterStatus = !TasterStatus;
}

Die Stopp­uhr soll jetzt erwei­tert wer­den. Ein Druck auf den Tas­ter star­tet die Stopp­uhr, der nächs­te Druck stoppt sie. Es sol­len vier Run­den erfasst werden.

Ein Dop­pel­klick auf den Tas­ter zeigt die Ergeb­nis­se der bis­he­ri­gen Run­den an, ein lan­ger Druck star­tet die Stopp­uhr wie­der bei Run­de eins.

Download

Eine Stopp­uhr für den Seri­el­len Moni­tor fin­dest du ➨hier.

So soll es aussehen:

Ergän­ze die Variablen:

# include "LiquidCrystal_I2C.h"
# include "OneButton.h"

int TASTER = 7;

// Name des Tasters
OneButton NameTaster(TASTER, true);

// Name des LCDs
LiquidCrystal_I2C lcd(0x27, 20, 4);

// Variablen der Zeit
float StartZeit;
float VerstricheneZeit;
float Sekunden;

int AnzahlRunden = 1;

// muss als Konstante definiert werden 
// -> Größe des Arrays darf nicht gändert werden
const int RundenMax = 5;

// Array Runden
String RundenZeit[RundenMax];

// TasterStatus sorgt für Start/Neustart
bool TasterStatus = true;

bool Neustart = false;

Im set­up-Teil müs­sen die Aktio­nen für den Dop­pel­klick und den lan­gen Tas­ter­druck zusätz­lich defi­niert werden:

void setup()
{
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Taste -> Start");
  lcd.setCursor(0, 1);
  lcd.print("--------------------");

  // Aktionen dem Modus des Tasters zuordnen
  NameTaster.attachClick(einKlick);
  NameTaster.attachDoubleClick(DoppelKlick);
  NameTaster.attachLongPressStop(langerDruckStopp);

  /*
    Anzahl der Millisekunden festlegen
    Standardwerte gesetzt:
    PressTicks: 1000
    ClickTicks: 600
    DebounceTicks: 50
    wenn die Standardwerte gesetzt werden sollen
    können die nächsten Zeilen auskommentiert werden
  */
  NameTaster.setPressTicks(1000);
  NameTaster.setClickTicks(500);
  NameTaster.setDebounceTicks(50);
}

Im loop-Teil gibt es kei­ne Änderungen.

Die Funk­ti­on ein­Klick() wird ergänzt. Beach­te die Kommentare.

void einKlick()
{
  if (TasterStatus)
  {
    // beim Neustart Variablen auf Standard zurücksetzen
    // Rundenzeiten löschen
    if (Neustart)
    {
      AnzahlRunden = 1;

      // String leeren
      for (int i = 1; i < RundenMax; i ++)
      {
        RundenZeit[i] = "";
      }
      Neustart = false;
    }
    StartZeit = millis();
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Runde: " + String(AnzahlRunden));
    lcd.setCursor(0, 1);
    lcd.print("Taste -> Stopp");
  }
  else
  {
    // Zeit berechnen
    float Sekunden;
    VerstricheneZeit = millis() - StartZeit;
    Sekunden = VerstricheneZeit / 1000;

    // Sekunden in String umwandeln
    // damit . durch , ersetzt werden kann
    String AnzahlSekunden = String(Sekunden);

    // . durch , ersetzen
    AnzahlSekunden.replace(".", ",");

    // Ausgabe LCD
    lcd.clear();
    lcd.print("Runde: " + String(AnzahlRunden));

    lcd.setCursor(0, 1);
    lcd.print("Weiter -> Taste");

    lcd.setCursor(0, 3);
    lcd.print(AnzahlSekunden + " Sekunden");

    // letzte Runde -> Ergebnis anzeigen
    if (AnzahlRunden == RundenMax - 1)
    {
      RundenZeit[AnzahlRunden] = AnzahlSekunden;
      lcd.clear();
      Neustart = true;
      DoppelKlick();
    }
    else
    {
      RundenZeit[AnzahlRunden] = AnzahlSekunden;
      AnzahlRunden ++;
    }
  }

  // Tasterstatus umkehren
  TasterStatus = !TasterStatus;
}

Die Funk­ti­on Dop­pel­Klick() zeigt das Ergeb­nis der Run­den an, die Funk­ti­on lan­ger­Druck­Stopp() sorgt für den Neustart.

void DoppelKlick()
{
  lcd.clear();
  int Zeile = 0;
  for (int i = 1; i <= RundenMax - 1; i ++)
  {
    lcd.setCursor(0, Zeile);
    if (RundenZeit[i] != "") lcd.print(String(i) + ": " + RundenZeit[i] + " Sekunden");
    Zeile ++;

    // Serieller Monitor
    if (RundenZeit[i] != "") Serial.println(String(i) + ": " + RundenZeit[i] + " Sekunden");

  }
}

void langerDruckStopp()
{
  AnzahlRunden = 1;
  TasterStatus = true;
  Neustart = true;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Neustart: Runde 1");
}

Startseite
Aufgaben A-Z
Suchen
Downloads
Fehlermeldungen
Seite als PDF

Ver­wand­te Aufgaben:


Letzte Aktualisierung: 17. Apr 2024 @ 17:19