Relais mit Taster Schalten und LCD Lauftext

Weil das eine Funktion ist, die von mehreren Stellen aus aufgerufen wird.
Ich benutze die also immer wieder und schreibne den Code nicht jedes Mal neu.
Am Beispiel der Anzeige:
Ich setze mit static uint32_t myMillis = millis(); einen Ausgangswert fest.
Wenn jetzt der counter unter 14 und das erste scrollen -> nach links, abgefragt wird, übergebe ich der funktion tik die Startzeit und einen weiteren Wert, der in der Funktion verglichen wird.
In tik passiert jetzt der Vergleich der aktuellen Zeit mit der übergebenen Zeiot, ob der ist als der übergebene Wert.
Ist das nicht der Fall, weil millis()-übergebener Wert z.B. "nur" 200 ergibt, bekomme ich ein einen Rückgabvewert - false - der mich in der aufrufenden Funktion veranlasst einfach nichts zu machen.
Ist der errechnete Abstand aber größer als 400, bekomme ich true zurück.
Damit stimmt die Bedingung if (tik(myMillis, 400)) und da geht es weiter indem ich jetzt geskrollt wird und als letztes merke ich mir wieder die aktuelle Zeit - die Bedingung beginnt also wieder von vorn - bis 400ms vergangen sind.

Diese Funktion macht es auch im nächsten und übernächsten und im relais...

1 Like

Ach.. Zeile 54 - Du benutzt ja eine andere Logik.
Das muss heissen:

  if (digitalRead(rel) && tik(relaisEinZeit, 2000)) #

Noch kurz zum Verständnis:
if (digitalRead(rel))
bedeutet das selbe wie:
if (digitalRead(rel) == HIGH)
und
if (!digitalRead(rel))
bedeutet das selbe wie:
if (digitalRead(rel) == LOW)
Spart Schreibarbeit und wenn man sich das angewöhnt hat, geht das schon automatisch :wink:
So essen machen....

1 Like

ES FUNNKTIONIERT :heart_eyes: :heart_eyes: :heart_eyes:

#include <LiquidCrystal.h>

unsigned int  Contrast = 75;
LiquidCrystal lcd(41, 42, 43, 40, 45, 46);

const byte contrastPin = 44;

const byte rel = 31;
const byte taster = 30;
byte posCounter = 0;
bool tasterstatus = LOW;
byte richtung = 0;
unsigned long relaisEinZeit = 0;

void setup()
{
  analogWrite(contrastPin, Contrast);
  lcd.begin(16, 2);
  lcd.print("Lauftext Zeile 1");
  lcd.setCursor(0, 1);
  lcd.print("Lauftext Zeile 2");
  pinMode(rel, OUTPUT);
  digitalWrite(rel, LOW);
  pinMode(taster, INPUT_PULLUP);
}


void loop()
{
  anzeige();
  relais();
}

bool tik(const uint32_t startmillis, const uint32_t pause)
{
  if (millis() - startmillis >= pause)
  {
    return true;
  }
  return false;
}

void relais()
{
  if (!digitalRead(taster))             // Taster gedrückt? ...
  {
    if (!digitalRead(rel))             // ... und Relais ist aus? ...
    {
      digitalWrite(rel, HIGH);         // ... relais an ....
      relaisEinZeit = millis();        // ... merke zeit für delay (2000);
    }
  }
  if (digitalRead(rel) && tik(relaisEinZeit, 2000))  // taste ist losgelassen UND Zeit abgelaufen?
  {
    digitalWrite(rel, LOW);            // mache relais aus
  }
}

void anzeige()
{
  static uint32_t myMillis = millis();
  switch (richtung)
  {
    case 0:
      if (posCounter < 14)
      {
        if (tik(myMillis, 400))
        {
          lcd.scrollDisplayLeft();
          posCounter++;
          myMillis = millis();
        }
      }
      else
      {
        richtung = 1;
        posCounter = 0;
        myMillis = millis();
      }
      break;
    case 1:
      if (posCounter < 28)
      {
        if (tik(myMillis, 400))
        {
          lcd.scrollDisplayRight();
          posCounter++;
          myMillis = millis();
        }
      }
      else
      {
        richtung = 2;
        posCounter = 0;
        myMillis = millis();
      }
      break;
    case 2:
      if (posCounter < 14)
      {
        if (tik(myMillis, 400))
        {
          lcd.scrollDisplayLeft();
          posCounter++;
          myMillis = millis();
        }
      }
      else
      {
        richtung = 3;
        posCounter = 0;
        myMillis = millis();
      }
      break;
    case 3:
      if (tik(myMillis, 3000))
      {
        posCounter = 0;
        richtung = 0;
      }
      break;
  }
}

Sehr, sehr, sehr geil @my_xy_projekt !!! Jetzt kann ich mich definitv dran machen das besser zu verstehen und am ende drei Taster und vier Relais zu betreiben :grin:

Daran werde ich mich aber definitiv erstmal selbst versuchen - ich denke das bekomme schon irgendwie hin. Müsste ja grobgesagt mehr oder weniger nur Copy-Paste sein.

Noch mal für mich zum weiteren Verständnis

if (digitalRead(rel))  =  if (digitalRead(rel) == HIGH)

if (!digitalRead(rel)) = if (digitalRead(rel) == LOW)

Kann ich dann jedes HIGH und LOW durch (digitalRead()) oder (!digitalRead()) ersetzen? Funktioniert das auch mit (digitalWrite())?

ich rate davon ab.
digitalRead gibt ein HIGH oder LOW zurück, daher sollst du darauf abfragen.

Wenn der Compiler der Meinung ist dass er das kürzen kann, dann tut er das eh.

Aber wenn der Compiler das eh kürzt und (digitalRead()) das selbe ist wie (digitalRead() == HIGH), dann wird ja explizit auf HIGH oder LOW abgefragt? Also macht es keinen unterschied abgesehen davon das ich weniger schreiben muss, so wie my_xy_projekt schon sagte. Wenn dem nicht so ist und ich da was falsch verstehe, berichtigt mich bitte! Noch ist da kaum was fest in meinem Kopf verankert :wink:
Denn wenn jemand von etwas abrät - dann muss es ja ein Fehlerpotential geben.
Also immer her mit den Erklärungen =)

Es gibt m.E. (mindestens) zwei Gründe:

  • Diese Kurzschreibweise geht davon aus, dass HIGH = true = irgendwas größer 0 und LOW = false = 0 gilt. Es ist zwar nicht zu erwarten, dass HIGH oder LOW mal umdefiniert werden, aber man weiß ja nie...
  • Es handelt sich hier um Port-Zustände HIGH oder LOW und eigentlich nicht um Boolsche Variablen true oder false. Um besser | schneller zu erkennen was da gemeint ist, hilft die ausgeschriebene Variante.

Das stimmt nicht ganz. irgendwas ungleich 0 ist richtig. Also auch -1 usw. ist true.

Gruß Tommy

2 Likes

@ greez2k5

du arbeitest mit einem API das für digitalRead und digitalWrite definiert wurde. Das API ist definiert mit HIGH und LOW.
https://www.arduino.cc/reference/de/language/functions/digital-io/digitalwrite/

Du weist maximal wie heute HIGH und LOW definiert sind (weist du wo du das aktuell findest?)

Würde sich an HIGH und LOW irgendwann mal was ändern - bricht dein verkürzter Code.
Ja viele andere auch - ist mir bewusst. Aber man muss ja nicht absichtlich in diese Falle laufen.

Und ja - es gab in der Vergangenheit schon mal Versuche an HIGH und LOW zu drehen, und das ist böse schief gelaufen. Beispiel pinmodes https://github.com/arduino/ArduinoCore-API/issues/25

Vieleicht bleibt es ewig so wie es aktuell definiert ist, aber ich werde mich nicht darauf verlassen.

Unterm Strich bleibt für mich: halte dich ans definierte API. Und im Falle von digitalWrite und digitalRead ist das halt LOW (und HIGH) und nicht ein false.

1 Like

NEeNEe!

digitalRead(digitalPin) gibt dir den Zustand des Pin zurück, ob er LOW oder HIGH ist. Das was ich oben mache ist ein abkürzen des Vergleich, indem ich nur das Ergebnis nutze.

Nein. digitalRead() ist eine Funktion, der muss ein PIN übergeben werden, zurück kommt der Zustand.

Da kann es nicht funktionieren, da die Funktion zwei Parameter erwartet.
Der erste ist der PIN der zweite der Zustand in den dieser versetzt werden soll.

Lesestoff: https://www.arduino.cc/reference/de/language/functions/digital-io/digitalread/ und https://www.arduino.cc/reference/de/language/functions/digital-io/digitalwrite/
Und eine Gute Nacht Lektüre zum durchlesen. Nicht auswendig lernen. Nur wissen was drin steht: ArduinoForum.de - Das deutschsprachige Forum rund um den Arduino - Arduino Code-Referenz (deutsch) da das pdf runterladen.

1 Like

Okay, klingt einleuchtend für mich. Wir gehen mal davon aus das das Rad immer rund bleibt, aber sicher sein kann man da nicht. Und solange ich eh noch nicht wirklich weiß was ich da tue - und natürlich auch für die bessere Übersicht - sollte ich bei der ausgeschriebenen Form bleiben. Aber zu wissen das es eine Kurzform gibt und was sie bedeutet ist natürlich von Vorteil wenn ich einen Code nicht selbst geschrieben habe. Somit habe ich wieder eine Menge gelernt.

Man kann Code abkürzen, es ist nicht aber nicht immer von Vorteil und kann Fehleranfällig sein.
HIGH bedeutet true und ungleich 0
LOW bedeutet false und gleich 0
Ich habe ein anschauliches Bespiel von Funktionen und wie ich sie benutzen kann
Ich kann mich langsam in die "millis()" Materia einarbeiten da ich einen greifbaren Versuchsaufbau habe
Nebenbei habe ich (const) byte kennengelernt und mich drüber schlau gemacht
Einen Taster als PULLUP anzuschließen und den internen Widerstand des Arduino zu nutzen
Und jede Menge Lesestoff

Für die Kurze Zeit doch gar nicht schlecht =)

Ein großes Danke an alle die mitgeholfen haben! Wenn am ende alles funktioniert und mein Projekt fertig ist, werde ich es hier präsentieren. Dafür muss ich aber noch einiges Basteln und das Ergebnis ist für den Sommer geplant. Also habt Geduld mit mir :wink:

2 Likes

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.