Code startet falsch und ich komme nicht drauf

Hallo,
ich bin neu hier und finde bei einem Problem die Ursache nicht.
Ich habe eine Kennlinie vorgegeben. Diese soll auf Tastendruck abgefahren werden als Sollwertvorgabe. Die Kennline, die Darstellung und auch der Taster funktioniert, jedoch nicht beim ersten Durchlauf. Ich komme nicht drauf, warum das so ist.
Ich habe eine Variable z eingeführt. Diese soll bei Tastendruck auf 1 gesetzt werden, nach Ablauf der Zeit wieder auf 0, bei dTastendruck wieder auf 1 und es beginnt von vorne. Das geht alles wie es soll, aber eben nicht beim ersten mal. Obwohl ich die Vriable mit 0 vorfülle, steht schon eine 1 drin.
Bitte stoßt mich drauf

Danke

Gruß

Flo

hier der Code

#include <PID_v1.h> // PID Library
#include <Relay.h> // Relay duty cycle control library
#include <MAX6675_Thermocouple.h>
#include <HX711_ADC.h>
#include <EEPROM.h>
#include <Wire.h>

#include <LiquidCrystal_I2C.h>

#define WINDOW_SAMPLE_WIDTH 5
#define RELAY_PIN 3

//Relais Heizung

int startdruck = 6;
int enddruck = 1;
float prezeit = 3;
float geszeit = 20;
unsigned long startzeit = 0;
float zeit = 0;
float rampe;
float soll;
float diffdruck;
float rampendauer;
float p = 0;
float zeit1;
int taster = 7;
int tasterstatus = 0;
int z;


LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 20, 4);  //in “20, 4” ändern wenn 20x04 benutzt wird

void setup() {

  Serial.begin(9600);

  rampe = (geszeit - prezeit - 5) * 1000;  //Berechnung der Rampenzeit
  diffdruck = startdruck - enddruck;      // Berechnung der Druckdifferenz

  lcd.init();
  lcd.backlight();
  delay(250);

  pinMode(taster, INPUT);
  z = 0;
}

void loop() {

  tasterstatus = digitalRead(taster);     //Auslesen des Tasters
                                 
  if ((tasterstatus == 1)) {              //Wenn Taster gedrückt wird Startzeit gesetzt
    startzeit = millis();                 //und Variable z von 0 auf 1 gesetzt
    z = 1;
  }
  if (z = 1) {
    zeit = millis() / 1000 - startzeit / 1000;    //Wenn z=1 wird Zeit hochgezählt in sec
    zeit1 = millis() - startzeit;                 //und in ms
    rampendauer = zeit1 - ((prezeit + 5) * 1000); //Rampenposition wird berechnet

    if (zeit <= prezeit)   p = 2;                  // Druckvorgabe für Vorfüllung
    if ((zeit > prezeit) && (zeit <= prezeit + 5)) p = startdruck;    // Druckvorgabe für max Füllung
    if ((zeit > prezeit + 5) && (zeit <= geszeit)) p = startdruck - (rampendauer * diffdruck / rampe);  //Berechnung des Druckgradienten bis zur Endzeit
    if  (zeit > geszeit) {    
      p = 0;                       //wenn Endzeit erreicht, Druck auf 0 
      z = 0;                      // z wieder auf 0
      zeit = geszeit;             // Zeit bleibt auf der geszeit stehen
    }
  }


  lcd.setCursor(0, 0);          //Werte auf Display
  lcd.print("Kennlinie");
  lcd.setCursor(0, 1);
  lcd.print("p-Faktor   ");
  lcd.print( p);
  lcd.print(" bar");
  lcd.setCursor(0, 2);
  lcd.print("Zeit   " );
  lcd.print(zeit);
  lcd.print(" sec");


  Serial.print(p);            //Werte für Kontrolle auf seriellen Monitor
  Serial.print(',');
  Serial.println(zeit);
  Serial.print(',');
  Serial.println(zeit1);
  Serial.print(',');
  Serial.println(tasterstatus);
  Serial.print(',');
  Serial.println(z);
  Serial.print(',');

}

Hast Du einen PullDown-Widerstand am Taster dran?

Gruß Tommy

Hallo Tommy,
ja hab ich. 1kOhm.
Wenn es das erste mal durchgelaufen ist funktioniert es auch. z wird am Ende auf 0 gesetzt und wenn ich den Taster drücke wird die 1 geschrieben und der Durchlauf startet wie er soll. Nur beim ersten mal steht im Wert z schon die 1, obwohl ich ihn mit 0 vorbelegt habe und noch nichts gedrückt habe. Die Variable tasterstatus reagiert auch richtig auf Tastendruck.
Ich versteh es nicht :frowning:

Das sollte wohl eher == heißen.

Gruß Tommy

oh man, ja. Das war die Lösung. Danke.
Ich verstehe es aber trotzdem nicht. Warum sorgt das dafür, dass die Variable z auf 1 gesetzt wird, obwohl sie mit 0 vorbelegt ist?
Denn Zusammenhang kriege ich nicht hin. Ich hätte jetzt eher erwartet, dass die Schleife dann nicht funktioniert.

Gruß
Flo

Teil das gedanklich auf:
if (z=1) ergibt:
z=1
if (z==HIGH)

Das ist immer noch eine Zuweisung. Auch wenn es in einer if-Abfrage steht. Dafür gibt es auch legitime Anwendungen (Auslesen und direkte Abfrage auf Null-Terminatoren). Meistens ist es aber ein Fehler.

Danke für die schnelle Hilfe und Erklärung. Ich habe es einfach übersehen und der Zusammenhang mit der direkten Zuweisung ist mir neu. Mann lernt eben auch asu Fehlern:-)

Danke

Frau auch :wink:
Beste Grüße!

Tipp:
Warnungen aktivieren, dann zeigts dir der Compiler.

Dafür sind sie ja da :wink:
Frei nach combie: Man sollte den gleichen Fehler nicht mehrmals machen. Die Auswahl ist schließlich groß genug.

Gruß Tommy

1 Like

So ist es!

Wenn Du
if(1 == z )
schreibst ist das das gleiche wie
if(z == 1)
aber wenn ein = abhanden kommt ergibt
if( 1 = z)
einen Fehler.

Grüße Uwe

Ergänzung:
Wenn man die auftretende Meldung nicht sehen möchte, kann man den Ausdruck auch explizit als erwünscht markieren.

Und zwar so:

if((1 = z))
1 Like

Bei Sadomaso-Anwendungen - :wink: :wink: :wink:

Naja....
Der Sadist stellt Regeln auf, welche einer Folter entsprechen.
Um mal einige zu nennen:

  1. verwende kein Goto
  2. statische Variablen sind besser als globale
  3. in if Bedingungen darf keine Zuweisung stehen

Es gibt noch viel mehr davon.
Der Masochist unterwirft sich diesen Regeln, wird unter beidseitigem Lustgewinn gefügig gehalten.

Meine klare Ansage:
Zuweisungen dürfen durchaus auch als Bedingung in ifs verwendet werden. Denn Zuweisungen haben einen Wert, sind als Bedingung auswertbar. Und wenn man das tut, tun möchte, dann stört die Meldung. Denn die Meldung soll auf die unbeabsichtigten Zuweisungen hinweisen. Nicht die Beabsichtigten anprangern.

Ist eine differenzierende Sichtweise wirklich eine Sadomaso Erscheinung?

Ja, ich weiß, dass einfache Regeln leichter zu händeln sind, als komplexe Zusammenhänge. Nur, dummer weise, besteht die Welt und auch die Programmierung nicht nur aus einfachen Zusammenhängen, aus Gut und Böse.

Nö, sowas macht schon Sinn und wenn man die Meldung an der Stelle, wo man das wirklich will unterdrücken kann (Danke @combie, das kannte ich noch nicht) hilft das bei der Übersicht, da man das an den Verschreiber-Stellen wohl nicht so schreiben wird.

Gruß Tommy

Gerne doch!
Es erfreut mich, dass ich eine weitere Klarheit beseitigen konnte.

Vielleicht ist das nicht von einem Sadisten aufgestellt worden, sondern von jemandem, der den Glauben an die menschliche Lernfähigkeit verloren hat ... :innocent:

Ist es nicht einfacher daß wenn man Zuweisungen im if explizit wünscht dann z=1 schreibt und wenn man einen == Unfall verhindern will 1 =(=) z. Die Klammer steht in diesem Fall für fakultatives Fehlen des 2. =

Grüße Uwe