Problem mit Zählfunktion

Melde mich gleich

Setze Deinen Sketch bitte in Codetags. Wie das geht, steht hier.
Außerdem formatiere den Code bitte ordentlich. Strg+T in der IDE hilft Dir dabei.
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

<

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
int button_li = 3;   // Lichtschranke 1, links
int button_re = 4;   // Lichtschranke 2, rechts
int Motor_li = 5;    // Relais 1 zum Motor links
int Motor_re = 6;    // Relais 2 zum Motor rechts
int Relais_auf = 7;  // Relais 3 auf
int Relais_ab = 8;   // Relais 4
int Schalter_auf = 9;
int Schalter_ab = 10;
long zaehler_li;
long zaehler_re;
int zaehler_liLastState = 1;
int zaehler_reLastState = 1;

void setup() {
  pinMode(button_li, INPUT_PULLUP);
  pinMode(button_re, INPUT_PULLUP);
  digitalWrite(Relais_auf, HIGH);
  digitalWrite(Relais_ab, HIGH);
  digitalWrite(Motor_li, HIGH);
  digitalWrite(Motor_re, HIGH);
  pinMode(Motor_li, OUTPUT);    // links Relais 1 links
  pinMode(Motor_re, OUTPUT);    // rechts Relais 2 rechts
  pinMode(Relais_auf, OUTPUT);  // Relais 3 auf
  pinMode(Relais_ab, OUTPUT);   // Relais 4 ab
  pinMode(Schalter_auf, INPUT_PULLUP);
  pinMode(Schalter_ab, INPUT_PULLUP);

  zaehler_li = 500;
  zaehler_re = 500;
  zaehler_liLastState = 1;
  zaehler_reLastState = 1;
  lcd.init();
  lcd.backlight();
  lcd.clear();
}

void loop() {

  if (digitalRead(Schalter_auf) == LOW) { digitalWrite(Relais_auf, LOW); }
  if (digitalRead(Schalter_auf) == HIGH) { digitalWrite(Relais_auf, HIGH); }


  if (digitalRead(Schalter_ab) == LOW) { digitalWrite(Relais_ab, LOW); }
  if (digitalRead(Schalter_ab) == HIGH) { digitalWrite(Relais_ab, HIGH); }

  // Zählen Lichtschranke 1
  byte zaehler_liNewState = digitalRead(button_li);
  if (zaehler_liNewState == 0 && zaehler_liLastState == 1 && digitalRead(Relais_auf)) { zaehler_li++; }
  if (zaehler_liNewState == 0 && zaehler_liLastState == 1 && digitalRead(Relais_ab)) { zaehler_li--; }
  zaehler_liLastState = zaehler_liNewState;
  lcd.setCursor(0, 0);
  lcd.print(zaehler_li);
  lcd.setCursor(4, 0);
  lcd.print("Motor l inks");

  //Zählen Lichtschranke 2
  byte zaehler_reNewState = digitalRead(button_re);
  if (zaehler_reNewState == 0 && zaehler_reLastState == 1 && digitalRead(Relais_auf)) { zaehler_re++; }
  if (zaehler_reNewState == 0 && zaehler_reLastState == 1 && digitalRead(Relais_ab)) { zaehler_re--; }
  zaehler_reLastState = zaehler_reNewState;
  lcd.setCursor(0, 1);
  lcd.print(zaehler_re);
  lcd.setCursor(4, 1);
  lcd.print("Motor 2 rechts");


  // Vergleichen auf
  if (zaehler_li < (zaehler_re - 6)) { digitalWrite(Motor_li, HIGH); }
  if (zaehler_li == zaehler_re) { digitalWrite(Motor_li, LOW); }

  if (zaehler_re < (zaehler_li - 6)) { digitalWrite(Motor_re, HIGH); }
  if (zaehler_re == zaehler_li) { digitalWrite(Motor_re, LOW); }

  // vergleichen ab
  if (zaehler_li > (zaehler_re + 6)) { digitalWrite(Motor_li, HIGH); }
  if (zaehler_li == zaehler_re) { digitalWrite(Motor_li, LOW); }

  if (zaehler_re > (zaehler_li + 6)) { digitalWrite(Motor_re, HIGH); }
  if (zaehler_re == zaehler_li) { digitalWrite(Motor_re, LOW); }
}>

Hast Du die Zeichen < und > ganz am Anfang und am Ende auch in deinem Quellcode drin?

Dann klappt das mit dem Compilieren sicher nicht....

Nein, ist wohl beim formatieren passiert, sorry

Der Code lässt sich ohne die Zeichen aber anstandslos compilieren...

ja, das ist richtig. Aber in meiner Simulation auf einem Steckbrett mit 4 Relais und zwei Funktionsgeneratoren als Ersatz für die entsprechenden Lichtschranken. Die befunden sich ja an den Motoren der Hebebühne.funktioniert das nicht. So wie ich es im Anfang beschrieben habe.

Dann verstehe ich das Posting nicht

Wenn ich die beiden Codeblöcke "vergleichen" einzeln in den Nano lade funktioniert alles so wie es soll.
Aber wenn beide Blöcke geladen werden werden bei der Funktion Hochfahren beide Relais für auf und ab abgeschaltet. hab lange hin und her probiert, und möchte jetzt die Blöcke trennen. Werner hat vorgelschlagen mit if und {} zu trennen. Weiss aber nicht wo genau diese Anweisung eingebaut wird.

Also die beiden Blöcke auf und ab sollen nicht beide vom Nano gelesen werden sondern nur den auf, wenn Taste auf gedrückt ist, und andersherum dann ab

Mit einzeln meine ich, wenn der eine oder der andere auskommentiert wird. Dann läuft es perfekt

Vielleicht so

  if (Schalter_auf) {
    if (zaehler_li < (zaehler_re - 6)) { digitalWrite(Motor_li, HIGH); }
    if (zaehler_li == zaehler_re) { digitalWrite(Motor_li, LOW); }

    if (zaehler_re < (zaehler_li - 6)) { digitalWrite(Motor_re, HIGH); }
    if (zaehler_re == zaehler_li) { digitalWrite(Motor_re, LOW); }
  }

  // vergleichen ab
  if (Schalter_ab) {
    if (zaehler_li > (zaehler_re + 6)) { digitalWrite(Motor_li, HIGH); }
    if (zaehler_li == zaehler_re) { digitalWrite(Motor_li, LOW); }

    if (zaehler_re > (zaehler_li + 6)) { digitalWrite(Motor_re, HIGH); }
    if (zaehler_re == zaehler_li) { digitalWrite(Motor_re, LOW); }
  }

Wobei das hier

    if (zaehler_li == zaehler_re) { digitalWrite(Motor_li, LOW); }
    if (zaehler_re == zaehler_li) { digitalWrite(Motor_re, LOW); }

dafür sorgt, dass immer beide Seiten auf LOW gehen.

Das ist dasselbe wie

if (zaehler_li == zaehler_re) { 
  digitalWrite(Motor_li, LOW); 
  digitalWrite(Motor_re, LOW); 
}

Das soll ja auch so sein. Wenn der schnellere Motor gestoppt wird bis der langsamere Motor den eingeholt hat soll der schnellere, auch wieder laufen, solange wie der entsprechende Schalter gedrückt wird, also bei auf lo

Also ich habe jetz durch die beiden if mit den geschweiften Klammern getrennt. dachte ich jedenfalls. Ist aber nicht so.
Wenn Tastre auf dann fähert er nach dem Stop nicht mehr weiter, weil durch die Funktion ab ja schon ein HIGH hat. Also bleibt mir nur übrig die au und ab so zu trennen das der Nano nur entweder auf oder ab lesen kann. Mit dem 1. Vorschlag klappt das nicht. Er liest weiterhin beide auf und ab. und das geht nicht

Könnte ich das nicht so regeln das ich Methoden, Klassen oder Lib. verwende? Aber davon hab ich leider keinen Plan. Auf jeden Fall darf der Nano nicht auf und ab gleichzeitig sehen, bzw benutzen

Naja was ich da gepostet habe ist von daher falsch, das "Schalter_auf" und "Schalter_ab" immer wahr ist, weil es Pin Definitionen sind. Ich habe das gerade erst gesehen.

In der (äußeren) IF Bedingung muss halt eine Variable abgefragt werden die wahr ist wenn es sich um eine Aufwärtsbewegung handelt. Ist sie nicht wahr müsste es ja eine Abwärtsbewegung sein.

Ist jetzt ein bisschen aus der Hüfte geschossen...

Aber vielleicht so:

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

LiquidCrystal_I2C lcd(0x27, 20, 4);
int button_li = 3;    // Lichtschranke 1, links
int button_re = 4;    // Lichtschranke 2, rechts
int Motor_li = 5;     // Relais 1 zum Motor links
int Motor_re = 6;     // Relais 2 zum Motor rechts
int Relais_auf = 7;   // Relais 3 auf
int Relais_ab = 8;    // Relais 4
int Schalter_auf = 9;
int Schalter_ab = 10;
long zaehler_li;
long zaehler_re;
int zaehler_liLastState = 1;
int zaehler_reLastState = 1;

enum class Motion : byte {down, up, hold};
constexpr byte THRESHOLD {6};

void setup() {
  pinMode(button_li, INPUT_PULLUP);
  pinMode(button_re, INPUT_PULLUP);
  digitalWrite(Relais_auf, HIGH);
  digitalWrite(Relais_ab, HIGH);
  digitalWrite(Motor_li, HIGH);
  digitalWrite(Motor_re, HIGH);
  pinMode(Motor_li, OUTPUT);     // links Relais 1 links
  pinMode(Motor_re, OUTPUT);     // rechts Relais 2 rechts
  pinMode(Relais_auf, OUTPUT);   // Relais 3 auf
  pinMode(Relais_ab, OUTPUT);    // Relais 4 ab
  pinMode(Schalter_auf, INPUT_PULLUP);
  pinMode(Schalter_ab, INPUT_PULLUP);

  zaehler_li = 500;
  zaehler_re = 500;
  zaehler_liLastState = 1;
  zaehler_reLastState = 1;
  lcd.init();
  lcd.backlight();
  lcd.clear();
}

void loop() {
  static Motion state {Motion::hold};

  if (digitalRead(Schalter_auf) == LOW) { digitalWrite(Relais_auf, LOW); }
  if (digitalRead(Schalter_auf) == HIGH) { 
    digitalWrite(Relais_auf, HIGH); 
    state = Motion::up;  
  }

  if (digitalRead(Schalter_ab) == LOW) { digitalWrite(Relais_ab, LOW); }
  if (digitalRead(Schalter_ab) == HIGH) { 
    digitalWrite(Relais_ab, HIGH);
    state = Motion::down; 
  }

  // Zählen Lichtschranke 1
  byte zaehler_liNewState = digitalRead(button_li);
  if (zaehler_liNewState == 0 && zaehler_liLastState == 1 && digitalRead(Relais_auf)) { zaehler_li++; }
  if (zaehler_liNewState == 0 && zaehler_liLastState == 1 && digitalRead(Relais_ab)) { zaehler_li--; }
  zaehler_liLastState = zaehler_liNewState;
  lcd.setCursor(0, 0);
  lcd.print(zaehler_li);
  lcd.setCursor(4, 0);
  lcd.print("Motor l inks");

  // Zählen Lichtschranke 2
  byte zaehler_reNewState = digitalRead(button_re);
  if (zaehler_reNewState == 0 && zaehler_reLastState == 1 && digitalRead(Relais_auf)) { zaehler_re++; }
  if (zaehler_reNewState == 0 && zaehler_reLastState == 1 && digitalRead(Relais_ab)) { zaehler_re--; }
  zaehler_reLastState = zaehler_reNewState;
  lcd.setCursor(0, 1);
  lcd.print(zaehler_re);
  lcd.setCursor(4, 1);
  lcd.print("Motor 2 rechts");

  if (state == Motion::up) {
    if (zaehler_li < (zaehler_re - THRESHOLD)) { digitalWrite(Motor_li, HIGH); }
    if (zaehler_re < (zaehler_li - THRESHOLD)) { digitalWrite(Motor_re, HIGH); }
    if (zaehler_li == zaehler_re) { 
      digitalWrite(Motor_li, LOW); 
      digitalWrite(Motor_re, LOW); 
      state = Motion::hold;
    }
  }

  // vergleichen ab
  if (state == Motion::down) {
    if (zaehler_li > (zaehler_re + THRESHOLD)) { digitalWrite(Motor_li, HIGH); }
    if (zaehler_re > (zaehler_li + THRESHOLD)) { digitalWrite(Motor_re, HIGH); }
    if (zaehler_li == zaehler_re) {
      digitalWrite(Motor_li, LOW);
      digitalWrite(Motor_re, LOW); 
      state = Motion::hold;
    }
  }
}

Wobei ich das selber noch nicht ganz verstehe. Wenn beide Motoren aus sind, ändert sich der Zählerwert ja nicht mehr .. Dann passiert auch nichts mehr.

Hallo,
ich muss kurz weg. Werde Morgen weiter probieren. Hab Deine Lösung geladen, funktioniert auch, aber zwischendurch werden, wie bei meinem Code auf einmal beide Mororen abgeschaltet, und nicht mehr eingeschaltet.
Mit der anderen Lösung(if und {} funktioniert es auch. Melde mich Morgen nochmal. Erst mal tausend Dank.

Grüsse
Dieter

Wahrscheinlich würde es sich auch hier anbieten, statt der vielen ifs auf eine Statemaschiene zu gehen. Da kann man leichter verhindern, das man in einer Sackgasse landet.

Da hast Du sicher recht...

Ich stimme auch zu!
Bin selber ganz schnell mit vielen IF überfordert.
Und so viele IF habe ich selten in einem Programm gesehen.