If - Abfrage macht nicht was ich erwarte und ich komme nicht drauf was falsch is

Hallo Gemeinde,

ich bin ziemlicher Anfänger mit dem Ardu...
Hab bisher eine Kaffeemühlensteuerung mit Abschaltung per Waage,
einen Gateway für die serielle Kommunikaton zwischen KTLCD3 Display und Pedelec - Controller
sowie eine Füllstandserkennung mit getakteten IR - Dioden gebaut.
Hat alles wochenlang gedauert wird ehr konservativ programmiert, aber funktioniert alles ziemlich gut.
Und macht richtig Spaß!

Nun aber bin ich in einer Sackgasse:

Ich möchte einfach nur zwei fertige DC - PWM - Controller ansteuern um ein kleines Raupenlaufwerk zu steuern.
Kein Ding, dachte ich... und nun ich bin noch ganz am Anfang und schon komme ich nicht weiter.

Derzeit versuche ich erstmal nur vier Relais anzusteuern. Mehr nicht.
Später sollen noch Analogsignale dazukommen und eine APP...

Die vier Relais sind über Optokoppler an vier Digitalausgänge eines MEGA angeschlossen.
Als Eingang verwende ich vier Taster zur Ansteuerung von vier Digitaleingängen
Die Eingänge des Mega liegen über 1K an Masse, wenn ich taste werden sie an 5V gelegt.

Wenn ich alle Taster nacheinander drücke und immer einen loslasse bevor ich den nächsten drücke funktioniert alles so wie erwartet. Mit jedem Tastendruck zieht das jeweilige Relais an und beim Loslassen des Tasters fällt es wieder ab.

Sobald ich mehrere Taster gleichzeitig drücke und gedrückt halte gehen auch mehrere Relais gleichzeitig an und bleiben an.

Also bis hierher alles nach Plan.

Nun zum Problem:
Wenn ich jetzt von den zwei bis vier gedrückten Tasten eine loslasse, dann passiert nichts. Alle vorher angezogenen Relais bleiben so. Auch das, dessen Taste ich eben losgelassen habe! Und zwar solange, bis ich den letzten Taster auch noch loslasse. Dann gehen alle bisher bestromten Relais gleichzeitig aus.

Ich meine programmiert zu haben, dass die Relais wenn ich die Taster nach und nach loslasse, auch nach und nach ausgehen. Hab ich aber anscheinend nicht.

Im Seriellen Monitor sieht man eindeutig, dass Eingänge zu den Tastern wie erwartet abfallen, wenn die Taster losgelassen werden. (Variable "Zustand" wechselt, siehe Code)
Und auch wenn ich die Digitalausgänge von der Relaiskarte abklemme und an einen Logic anaylzer anklemme sehe ich, dass die Ausgänge erst zurück auf 0 V gehen, wenn ich den letzten Taster loslasse.
Es hat also nichts mit der Relaiskarte zu tun...

Ich rätsele nun schon eine Woche rum...

  • habe den Mega getauscht => keine Änderung
  • habe von if - Abfrage auf switch case umgebaut => keine Änderung
  • habe in jeder if - Abfrage "Zustand" neu berechnet => keine Änderung

Das Problem ist mein Code, kein Hardwareproblem, glaube ich.

Ich weiß einfach nicht weiter... hab riesige Tomaten vor den Augen?

Hat einer von Euch eine Idee???

// this constants won't change:
const int PinStart = 25;               // Eingang von Knopf 1
const int PinDrehR_M1 = 22;       // Eingang von Knopf 2
const int PinDrehR_M2 = 23;       // Eingang von Knopf 3
const int PinPowerOn = 24;         // Eingang von Knopf 4

const int Start_REL = 31;             // Ausgang geschaltet von Knopf 1
const int DrehR_M1REL = 32;       // Ausgang geschaltet von Knopf 2
const int DrehR_M2REL = 33;       // Ausgang geschaltet von Knopf 3
const int PowerOn_REL = 34;       // Ausgang geschaltet von Knopf 4

// Variables will change:
int    Zustand  = 0;              // Summe der Fälle 1 bis 4
int    Zustand1 = 0;              // Zustand von Knopf 1
int    Zustand2 = 0;              // Zustand von Knopf 2
int    Zustand3 = 0;              // Zustand von Knopf 3
int    Zustand4 = 0;              // Zustand von Knopf 4

void setup()
 {
  //Relaisanschlüsse:
  pinMode(Start_REL,OUTPUT);    
  pinMode(DrehR_M1REL,OUTPUT);  
  pinMode(DrehR_M2REL,OUTPUT);  
  pinMode(PowerOn_REL,OUTPUT);  

// Eingänge
  pinMode(PinStart, INPUT);      
  pinMode(PinDrehR_M1, INPUT);   
  pinMode(PinDrehR_M2, INPUT);      
  pinMode(PinPowerOn, INPUT);    

  
//  Serial.begin(9600);
}

void loop() {

  // read the pushbutton input pin:
    if (digitalRead(PinStart) == HIGH){Zustand1 = 1;}            // erzeugt Wert 1 wenn Knopf 1 gedrückt         
    if (digitalRead(PinStart) == LOW) {Zustand1 = 0; }                     
    
    if (digitalRead(PinDrehR_M1) == HIGH){Zustand2 = 2; }      // erzeugt Wert 2 wenn Knopf 2 gedrückt               
    if (digitalRead(PinDrehR_M1) == LOW) {Zustand2 = 0; }                      

    if (digitalRead(PinDrehR_M2) == HIGH){Zustand3 = 4; }     // erzeugt Wert 4 wenn Knopf 3 gedrückt                
    if (digitalRead(PinDrehR_M2) == LOW) {Zustand3 = 0; }                      
      
    if (digitalRead(PinPowerOn) == HIGH) {Zustand4 = 8; }      // erzeugt Wert 8 wenn Knopf 4 gedrückt                
    if (digitalRead(PinPowerOn) == LOW)  {Zustand4 = 0; }                      
      
     Zustand = Zustand1 + Zustand2 + Zustand3 + Zustand4;          // bildet die Summe aller Zustände
  
      
/*      Serial.print("Zustand: ");
      Serial.println(Zustand);

      Serial.println(Zustand1); 

      Serial.println(Zustand2);

      Serial.println(Zustand3);

      Serial.println(Zustand4); 
      delay(300);*/
              
     

    if (Zustand==0) {                                 //kein Knopf gedrückt => alle Relais aus
      digitalWrite(Start_REL, LOW);
      digitalWrite(DrehR_M1REL, LOW);
      digitalWrite(DrehR_M2REL, LOW);
      digitalWrite(PowerOn_REL, LOW);
    }
  
    if (Zustand == 1)                             // Start (Kn1) gedrückt
    { digitalWrite(Start_REL, HIGH);    }  

    if (Zustand == 2)                           // DrehrWechselM1(Kn2) gedrückt
    {  digitalWrite(DrehR_M1REL, HIGH); }  


    if (Zustand == 3) {                          // Start (Kn1) und DrehrWechselM1(Kn2) gedrückt
      digitalWrite(Start_REL, HIGH);
      digitalWrite(DrehR_M1REL, HIGH);
    } 

    if (Zustand == 4) {                           // DrehrWechselM2(Kn3) gedrückt
      digitalWrite(DrehR_M2REL, HIGH);
      }    
 
     if (Zustand == 5) {                           // Start (Kn1) und DrehrWechselM2(Kn3) gedrückt
      digitalWrite(Start_REL, HIGH);
      digitalWrite(DrehR_M2REL, HIGH);
      }    

    if (Zustand == 6) {                          // DrehrWechselM1(Kn2) und DrehrWechselM2(Kn3) gedrückt
      digitalWrite(DrehR_M1REL, HIGH);
      digitalWrite(DrehR_M2REL, HIGH);
     }       
    
    if (Zustand == 7) {                          // Start (Kn1) und DrehrWechselM1(Kn2) und DrehrWechselM2(Kn3) gedrückt
      digitalWrite(Start_REL, HIGH);
      digitalWrite(DrehR_M1REL, HIGH);
      digitalWrite(DrehR_M2REL, HIGH);
     }       

    if (Zustand == 8) {                           // PowerOn (Kn4) gedrückt
      digitalWrite(PowerOn_REL, HIGH);
     } 
    
    if (Zustand == 9) {                            // Start (Kn1) und PowerOn (Kn4) gedrückt
      digitalWrite(Start_REL, HIGH);
      digitalWrite(PowerOn_REL, HIGH);
     }         
    
    if (Zustand == 10) {                           // DrehrWechselM1(Kn2) und PowerOn(Kn4) gedrückt
      digitalWrite(DrehR_M1REL, HIGH);
      digitalWrite(PowerOn_REL, HIGH);
     }      

    if (Zustand == 11) {                           // Start (Kn1) und DrehrWechselM1(Kn2) und PowerOn(Kn4) gedrückt
      digitalWrite(Start_REL, HIGH);
      digitalWrite(DrehR_M1REL, HIGH);
      digitalWrite(PowerOn_REL, HIGH);
     }      

    if (Zustand == 12) {                            // DrehrWechselM2(Kn3) und PowerOn(Kn4) gedrückt
      digitalWrite(DrehR_M2REL, HIGH);
      digitalWrite(PowerOn_REL, HIGH);
     }     

    if (Zustand == 13) {                           // Start (Kn1) und DrehrWechselM2(Kn3) und PowerOn(Kn4) gedrückt
      digitalWrite(Start_REL, HIGH);
      digitalWrite(DrehR_M2REL, HIGH);
      digitalWrite(PowerOn_REL, HIGH);
     }      

    if (Zustand == 14) {                            // DrehrWechselM1(Kn2) und DrehrWechselM3(Kn3) und PowerOn(Kn4) gedrückt
      digitalWrite(DrehR_M1REL, HIGH);
      digitalWrite(DrehR_M2REL, HIGH);
      digitalWrite(PowerOn_REL, HIGH);
     }    

    if (Zustand == 15) {                           // Start (Kn1) und DrehrWechselM1(Kn2) und DrehrWechselM3(Kn3) und PowerOn(Kn4) gedrückt
      digitalWrite(Start_REL, HIGH);
      digitalWrite(DrehR_M1REL, HIGH);
      digitalWrite(DrehR_M2REL, HIGH);
      digitalWrite(PowerOn_REL, HIGH);
    }

}

Taster muss man eigentlich entprellen

Ich weiß zwar nicht, warum du es so kompliziert machst, aber auf jeden Fall hast du vergessen, die Relais abzuschalten, außer im Fall (Zustand == 0)

   if (Zustand==1) {                                 //Nur Knopf 1 gedrückt => drei Relais aus, eins an 
     digitalWrite(Start_REL, HIGH);
     digitalWrite(DrehR_M1REL, LOW);
     digitalWrite(DrehR_M2REL, LOW);
     digitalWrite(PowerOn_REL, LOW);
   }

usw.

Aber, wie gesagt, warum so umständlich?

void loop() {
   digitalWrite(Start_REL, digitalRead(PinStart)); 
   ... // die 3 anderen genauso 
}

Hi

Du schaltest zwar Deine Relais auf HIGH, je nach Zustand, aber die nicht benötigten NICHT auf LOW!

Auch könnte man ein/zwei Kleinigkeiten an dem Code verbessern.

MfG

Du hast Deinen Sketch leider sehr schlecht formatiert, was dazu führt, das die Übersicht verloren geht. Drück mal STRG-T

Ich hab das mal neu gemacht:

// this constants won't change:
const int PinStart = 25;               // Eingang von Knopf 1
const int PinDrehR_M1 = 22;       // Eingang von Knopf 2
const int PinDrehR_M2 = 23;       // Eingang von Knopf 3
const int PinPowerOn = 24;         // Eingang von Knopf 4

const int Start_REL = 31;             // Ausgang geschaltet von Knopf 1
const int DrehR_M1REL = 32;       // Ausgang geschaltet von Knopf 2
const int DrehR_M2REL = 33;       // Ausgang geschaltet von Knopf 3
const int PowerOn_REL = 34;       // Ausgang geschaltet von Knopf 4

// Variables will change:
int    Zustand  = 0;              // Summe der Fälle 1 bis 4
int    Zustand1 = 0;              // Zustand von Knopf 1
int    Zustand2 = 0;              // Zustand von Knopf 2
int    Zustand3 = 0;              // Zustand von Knopf 3
int    Zustand4 = 0;              // Zustand von Knopf 4

void setup()
{
  //Relaisanschlüsse:
  pinMode(Start_REL, OUTPUT);
  pinMode(DrehR_M1REL, OUTPUT);
  pinMode(DrehR_M2REL, OUTPUT);
  pinMode(PowerOn_REL, OUTPUT);

  // Eingänge
  pinMode(PinStart, INPUT);
  pinMode(PinDrehR_M1, INPUT);
  pinMode(PinDrehR_M2, INPUT);
  pinMode(PinPowerOn, INPUT);


  //  Serial.begin(9600);
}

void loop()
{

  // read the pushbutton input pin:
  if (digitalRead(PinStart) == HIGH)
  {
    Zustand1 = 1; // erzeugt Wert 1 wenn Knopf 1 gedrückt
  }
  if (digitalRead(PinStart) == LOW)
  {
    Zustand1 = 0;
  }

  if (digitalRead(PinDrehR_M1) == HIGH)
  {
    Zustand2 = 2;  // erzeugt Wert 2 wenn Knopf 2 gedrückt
  }
  if (digitalRead(PinDrehR_M1) == LOW)
  {
    Zustand2 = 0;
  }

  if (digitalRead(PinDrehR_M2) == HIGH)
  {
    Zustand3 = 4;  // erzeugt Wert 4 wenn Knopf 3 gedrückt
  }
  if (digitalRead(PinDrehR_M2) == LOW)
  {
    Zustand3 = 0;
  }

  if (digitalRead(PinPowerOn) == HIGH)
  {
    Zustand4 = 8;  // erzeugt Wert 8 wenn Knopf 4 gedrückt
  }
  if (digitalRead(PinPowerOn) == LOW)
  {
    Zustand4 = 0;
  }

  Zustand = Zustand1 + Zustand2 + Zustand3 + Zustand4;          // bildet die Summe aller Zustände


  /*      Serial.print("Zustand: ");
        Serial.println(Zustand);
        Serial.println(Zustand1);
        Serial.println(Zustand2);
        Serial.println(Zustand3);
        Serial.println(Zustand4);
        delay(300);
  */

  if (Zustand == 0)                                 //kein Knopf gedrückt => alle Relais aus
  {
    digitalWrite(Start_REL, LOW);
    digitalWrite(DrehR_M1REL, LOW);
    digitalWrite(DrehR_M2REL, LOW);
    digitalWrite(PowerOn_REL, LOW);
  }

  if (Zustand == 1)                             // Start (Kn1) gedrückt
  {
    digitalWrite(Start_REL, HIGH);
  }

  if (Zustand == 2)                           // DrehrWechselM1(Kn2) gedrückt
  {
    digitalWrite(DrehR_M1REL, HIGH);
  }


  if (Zustand == 3)                            // Start (Kn1) und DrehrWechselM1(Kn2) gedrückt
  {
    digitalWrite(Start_REL, HIGH);
    digitalWrite(DrehR_M1REL, HIGH);
  }

  if (Zustand == 4)                             // DrehrWechselM2(Kn3) gedrückt
  {
    digitalWrite(DrehR_M2REL, HIGH);
  }

  if (Zustand == 5)                             // Start (Kn1) und DrehrWechselM2(Kn3) gedrückt
  {
    digitalWrite(Start_REL, HIGH);
    digitalWrite(DrehR_M2REL, HIGH);
  }

  if (Zustand == 6)                            // DrehrWechselM1(Kn2) und DrehrWechselM2(Kn3) gedrückt
  {
    digitalWrite(DrehR_M1REL, HIGH);
    digitalWrite(DrehR_M2REL, HIGH);
  }

  if (Zustand == 7)                            // Start (Kn1) und DrehrWechselM1(Kn2) und DrehrWechselM2(Kn3) gedrückt
  {
    digitalWrite(Start_REL, HIGH);
    digitalWrite(DrehR_M1REL, HIGH);
    digitalWrite(DrehR_M2REL, HIGH);
  }

  if (Zustand == 8)                             // PowerOn (Kn4) gedrückt
  {
    digitalWrite(PowerOn_REL, HIGH);
  }

  if (Zustand == 9)                              // Start (Kn1) und PowerOn (Kn4) gedrückt
  {
    digitalWrite(Start_REL, HIGH);
    digitalWrite(PowerOn_REL, HIGH);
  }

  if (Zustand == 10)                             // DrehrWechselM1(Kn2) und PowerOn(Kn4) gedrückt
  {
    digitalWrite(DrehR_M1REL, HIGH);
    digitalWrite(PowerOn_REL, HIGH);
  }

  if (Zustand == 11)                             // Start (Kn1) und DrehrWechselM1(Kn2) und PowerOn(Kn4) gedrückt
  {
    digitalWrite(Start_REL, HIGH);
    digitalWrite(DrehR_M1REL, HIGH);
    digitalWrite(PowerOn_REL, HIGH);
  }

  if (Zustand == 12)                              // DrehrWechselM2(Kn3) und PowerOn(Kn4) gedrückt
  {
    digitalWrite(DrehR_M2REL, HIGH);
    digitalWrite(PowerOn_REL, HIGH);
  }

  if (Zustand == 13)                             // Start (Kn1) und DrehrWechselM2(Kn3) und PowerOn(Kn4) gedrückt
  {
    digitalWrite(Start_REL, HIGH);
    digitalWrite(DrehR_M2REL, HIGH);
    digitalWrite(PowerOn_REL, HIGH);
  }

  if (Zustand == 14)                              // DrehrWechselM1(Kn2) und DrehrWechselM3(Kn3) und PowerOn(Kn4) gedrückt
  {
    digitalWrite(DrehR_M1REL, HIGH);
    digitalWrite(DrehR_M2REL, HIGH);
    digitalWrite(PowerOn_REL, HIGH);
  }

  if (Zustand == 15)                             // Start (Kn1) und DrehrWechselM1(Kn2) und DrehrWechselM3(Kn3) und PowerOn(Kn4) gedrückt
  {
    digitalWrite(Start_REL, HIGH);
    digitalWrite(DrehR_M1REL, HIGH);
    digitalWrite(DrehR_M2REL, HIGH);
    digitalWrite(PowerOn_REL, HIGH);
  }

}

Und hier kommst Du drauf, was Dir fehlt.

Es gibt nur einen Zustand, an dem auch nur ein PIN auf Low geht - und das ist nur der Zustand == 0

if (Zustand == 0)                                 //kein Knopf gedrückt => alle Relais aus
  {
    digitalWrite(Start_REL, LOW);
    digitalWrite(DrehR_M1REL, LOW);
    digitalWrite(DrehR_M2REL, LOW);
    digitalWrite(PowerOn_REL, LOW);
  }

Der Code ist nicht perfekt - soll er auch nicht, aber mache Dir mal Gedanken, ob das nicht evtl. anders gelöst werden kann.

Um Deinem Gedankengang zu folgen hier ein Beipiel, wie Du es weiterführen müsstest, damit es funktioniert, wie gedacht:

 if (Zustand == 1)                             // Start (Kn1) gedrückt
  {
    digitalWrite(Start_REL, HIGH);
    digitalWrite(DrehR_M1REL, LOW);
    digitalWrite(DrehR_M2REL, LOW);
    digitalWrite(PowerOn_REL, LOW);
  }

Mach was draus .-)

Peer

Vielen Dank! Ich mach heute Abend was draus!

Die Taster hab ich nicht entprellt, weil ich deren Aufgabe in Zukunft eh durch eine Software machen will.

Ihr habt recht, es ist kompliziert gemacht, ich bin aber auch schon fast 60 und habe erst drei Projekte gemacht. Mit Eurer Hilfe wird es bestimmt noch ein bischen besser. Für mich war das so einfacher nachzuvollziehen was da passiert.

Eigentlich ziemlich peinlich, dass ich nicht darauf gekommen bin...

DANKE!

In deinem Fall ist das Entprellen nicht sooo wichtig, weil ein Relais ziemlich träge ist.
Auch kommt es nicht auf die (Anzahl der) Flankenwechsel an.

Eigentlich braucht deine Aufgabe überhaupt keinen Controller:
Schalter an den Relaismodul-Eingängen, fertig

michael_x:
Eigentlich braucht deine Aufgabe überhaupt keinen Controller:
Schalter an den Relaismodul-Eingängen, fertig

Ja, das ist richtig, nur lernt er dann auch nicht, wie sowas per arduino und der Programmierung dessen gemacht wird.
Um ne LED blinken zu lassen , braucht es auch keinen Arduino, aber ohne ist eben auch kein Lerneffekt im arduino-programmieren vorhanden. Der TO hat ja im Eröffnungspost geschrieben, was er schlussendlich machen will, und sogar, was er bisher gemacht hat, und dass er hier mit den Relais einfach mal einen Versuch macht.
Ich finde es gut, dass er so sich erstmal mit den Basics beschäftigt und da dann darauf aufbaut.

LG Stefan

@michael_x:

Klar, Du hast Recht, dafür brauche ich keinen Controller.
Das Relaisgesteuere ist aber nur ein kleines Teilstück von einem größeren Ganzen.
Zum Beispiel müssen die Relais wiederholbar in einer bestimmten Reihenfolge geschaltet werden, sonst gibt der Gleichstromregler keinen Strom ab und es wird auch noch eine Analogausgabe hinzukommen, die die Drehzahl von zwei Gleichstrommotoren steuert.
Ganz am Ende soll es eine App dafür geben, mit der man das Ganze steuern kann. Mal sehn ob ich das schaffe...

        digitalWrite(Start_REL, digitalRead(PinStart));
        digitalWrite(DrehR_M1REL, digitalRead(PinDrehR_M1));
        digitalWrite(DrehR_M2REL, digitalRead(PinDrehR_M2));
        digitalWrite(PowerOn_REL, digitalRead(PinPowerOn));

Michael_x, das ist der Hammer, meine ca. 120 Zeilen ersetzt durch vier Stück!
Ich habs probiert, es läuft...

Ich hab wohl noch viel zu lernen...