Go Down

Topic: Schleife durch Taster unterbechen (Read 2171 times) previous topic - next topic

Milkypants

Hallo Zusammen,

ich bin neu in der Arduino Branche und stehe vor einem Problem bei meiner Steuerung.
Ich baue auf der Arbeit eine Steuerung die ein Hubwerk hoch und runter fahren soll.
Der Automatik Betrieb wird mit einem Taster gestartet und meine Automatik Variable wird auf 1 gesetzt.
Danach habe ich eine While Schleife gesetzt die solange Automatik == 1 ist das Hubwerk ein und ausfahren lässt. Mein Problem ist jedoch das ich nicht weiß wie ich eine Eingabekontrolle machen soll während ich in der Schleife festhänge.
Durch einen zweiten Taster (Stopp) soll die Schleife beendet werden nach ihrem Durchlauf.
Zurzeit müsste ich den Taster bis zu einer Abfrage in der Schleife gedrückt halten um die Variable wieder 0 zu setzen. Gibt es eine andere Möglichkeit ?

Über hilfreiche Kommentare wäre ich sehr dankbar


Tommy56

Du darfst nicht in einer Schleife fest hängen. Du hast ja schon eine große Schleife - Loop() - die wird immer wieder abgearbeitet.

Benutze kein delay(), das blockiert den ganzen Prozessor.
Schau Dir statt dessen BlinkWithoutDelay an.

Wenn es dann noch Probleme gibt, dann stelle den Sketch (in Codetags </> oben links hier rein und schreibe dazu, was Du erwartest und was es tut / nicht tut.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

uwefed


combie

#3
Dec 11, 2016, 07:41 pm Last Edit: Dec 11, 2016, 07:49 pm by combie
Ablaufsteuerung
Quote
Meine Standardantwort zu Ablaufsteuerungen:
Eine Stichworte Sammlung für Google Suchen:
Endlicher Automat,
State Machine,
Multitasking,
Coroutinen,
Ablaufsteuerung,
Schrittkette,
BlinkWithoutDelay, 
--
Blink Without Delay
Der Wachmann
--
Multitasking Macros
Intervall Macros
Wer seine Meinung nie zurückzieht, liebt sich selbst mehr als die Wahrheit.

Quelle: Joseph Joubert

gregorss

#4
Dec 11, 2016, 07:42 pm Last Edit: Dec 11, 2016, 07:45 pm by gregorss
Über hilfreiche Kommentare wäre ich sehr dankbar
Tommy hat ja schon delay() und BlinkWithoutDelay erwähnt. Das sind auf jeden Fall Stichworte zu Themen, die Du Dir bei Gelegenheit reinziehen solltest. Zur Vermeidung von delay() habe ich vor einiger Zeit das hier getextet. Vielleicht hilft das.

Ansonsten: Wenn Du in einer while()-Schleife eine Tastenabfrage machen willst, kannst Du das tun, wie sonst auch. Zum Beispiel:

Code: [Select]
while(1)
{
  // bla
  if(digitalRead(tasterpin)==0) // oder ==1, je nachdem
  {
    break; // führt zum Abbruch der Schleife
  }
}


HTH

Gregor
Können kommt von kunst.

michael_x

In den seltensten Fällen kommt es auf die Reihenfolge von "bla" und digitalRead(tasterPin) an.
(Erst recht, wenn man ohne delay arbeitet)

Da ist also die Konstruktion

Code: [Select]
while (digitalRead(tasterPin) == HIGH) { // oder == LOW, je nach dem
   // bla
}

identisch zu Gregors Vorschlag. Auch da ist das digitalRead innerhalb der Schleife (Nur leichter lesbar, finde ich)

Mal abgesehen davon, dass if statt while die bessere Lösung wäre.
Weil man dann eben nicht in der Schleife festhängt.

Mehr als die eine loop() Schleife macht es nur unnötig kompliziert.

gregorss

... identisch zu Gregors Vorschlag. Auch da ist das digitalRead innerhalb der Schleife (Nur leichter lesbar, finde ich)
Stimmt, so kann man das auch machen. Mir war halt wichtig, die Tastenabfrage unabhängig von der Bedingung für while() deutlich zu machen.

Gruß

Gregor
Können kommt von kunst.

Milkypants

Hallo nochmal,

nachdem ich das Blinkwithoutdelay Beispiel durchgegangen bin habe ich den code mit millis versucht umzusetzen.

Ob dies funktioniert weiß ich leider noch nicht da ich schon ein Problem bei der Tasterabfrage habe.
Obwohl ich die nach den Tastern pull-down Widerstände eingebaut habe bekomme ich teilweise kurze High Signale bei offenem Taster.
Beim Messen der Spannung messe ich 0V also dürfte der Eingang eigenlich nicht High sein.

Dementsprechend schalten meine Relais sehr merkwürdig.

Die Relais die ich eingebaut habe sollen 24V schalten. Wenn ich an dem Ausgang des Arduinos also das 5V Schaltsignal für die Relais messe habe ich teilweise 0.1-0.2V anliege was ich auch nicht verstehe weil das Arduino doch nur 0 oder 5V schaltet, oder könnte das von dem kurzen High Signal vom Ein Taster kommen?

Die Serial Ausgabe hatte ich mal eingefügt um zu verfolgen wie oft meine Variable schaltet.

Ich bin derzeit ein wenig überfragt und hoffe das ihr Ideen habt bzw. irgendwelche Fehler im Code oder in meiner Denkweise findet.

Danke schonmal.







Code: [Select]
const int S2_rot = 2 ;
const int S3_gruen = 3 ;
const int H_aus = 4 ;
const int H_ein = 5 ;
const int Dauerluft = 6 ;
unsigned long previousMillis;
int Automatik = 0;
int S2;
int S3 = LOW;



void setup() {
 
Serial.begin(9600);
pinMode(S2_rot , INPUT);
pinMode(S3_gruen , INPUT);
pinMode(H_aus , OUTPUT);
pinMode(H_ein , OUTPUT);
pinMode(Dauerluft , OUTPUT);
digitalWrite(Dauerluft, LOW);


}

void loop() {

  S2 = digitalRead(S2_rot);
  S3 = digitalRead(S3_gruen);
 
  if(S3 == HIGH){
    digitalWrite(Dauerluft, HIGH);
    Automatik = 1;
    Serial.println("Automatik = 1");
    }
   
  if(S2 == LOW){
    Automatik = 0;
    Serial.println("Automatik = 0");
    digitalWrite(Dauerluft, LOW);
    digitalWrite(H_aus, LOW);
    delay(10);
    digitalWrite(H_ein, HIGH);
    delay(3000);
    digitalWrite(H_ein, LOW);
   
   
    }
 
 
if(Automatik == 1){
    previousMillis = millis();
    if(millis() - 10 >= previousMillis){
    digitalWrite(H_aus, HIGH);
    previousMillis = millis();
    }
      if(millis() - 4000 >= previousMillis){
      digitalWrite(H_aus, LOW);
      previousMillis = millis();
      }
        if(millis() - 10 >= previousMillis){
        digitalWrite(H_ein, HIGH);
        previousMillis = millis();
        }
          if(millis() -  4000 >= previousMillis){
          digitalWrite(H_ein, LOW);
          previousMillis = millis();
         
         }   
         }
 
  }

Doc_Arduino

#8
Dec 20, 2016, 12:00 pm Last Edit: Dec 20, 2016, 12:03 pm by Doc_Arduino
Hallo,

gegen ein "zucken" nach Reset hilft bestimmt folgende Maßnahme.

Code: [Select]
void setup() {
 
Serial.begin(9600);
pinMode(S2_rot , INPUT);   // kannste weglassen
pinMode(S3_gruen , INPUT); // kannste weglassen
digitalWrite(H_aus, LOW);
digitalWrite(H_ein, LOW);
digitalWrite(Dauerluft, LOW);
pinMode(H_aus , OUTPUT);
pinMode(H_ein , OUTPUT);
pinMode(Dauerluft , OUTPUT);


Nur, wenn du an deinen Tastern überall extern Pull-Down Widerstände hast, dann haben die im Ruhezustand LOW Signal und bei Betätigung erst ein HIGH Signal inkl. prellen. Das prellen sollte bei dir nicht stören bzw. noch nicht.

Das bedeutet, in deiner Loop wird
if (S2 == LOW) {  ...
permanent ausgeführt inkl. den delays darin.

Schaue dir am besten einen "endlosen Automaten" an. Das ist wie bei dir eine Zustandssteuerung.

Wegen deinem Spannungsproblem, zeige mal den Schaltplan bitte.

Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Milkypants

Mein S2 ist der Stopp Taster und den habe ich wegen der Drahtbruchsicherheit als NC Kontakt verdrahtet, daher das S2 == LOW.

Doc_Arduino

Hallo,

dann hilft erstmal nur, den Code besser zu kommentieren und samt Schaltplan das Problem noch einmal besser zu erklären.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

gregorss

dann hilft erstmal nur, den Code besser zu kommentieren und samt Schaltplan das Problem noch einmal besser zu erklären.
Das kann ich unterstreichen. Ein gut kommentierter und formatierter Code ist ein riesiger Schritt in Richtung Problemlösung.

Gruß

Gregor
Können kommt von kunst.

Milkypants

#12
Dec 20, 2016, 11:22 pm Last Edit: Dec 20, 2016, 11:29 pm by Milkypants
So um alles noch einmal zusammenzufassen

Ich hoffe das auf dem Schaltplan nun alles drauf ist. Es ist ein Sicherheitsventil verbaut das den Druck freigibt und ein Not-Aus-Relais was unter anderem dem Arduino den Strom nimmt.

Funktion der Anlage:

Bei Betätigung des Start Knopfes soll eine Hubvorichtung mit einem doppeltwirkenden Zylinder und einem Unterstützung Zylinder, der Dauerluft bekommt, in gewissen Abstände auf und abfahren bist der Stop Taster gedrückt wird.
Bei Betätigung des Stopp Taster soll das Hubwerk entweder direkt zurückfahren in Ausgangsposition
(was derzeit passiert) oder den Zyklus zuende fahren und dann in Ausgangsposition verbleiben(dazu ist mir noch kein Code eingefallen).


Festgestellte Probleme:

- Durch den Befehl "Serial.println("Automatik = 1");" habe ich überwacht wann mein Start Taster     gedrückt wird also dem Arduino ein HIGH Signal liefert. Dies geschah ziemlich regelmäßig bei eigentlich nicht gedrücktem Taster. Allerdings nicht so regelmäßig wie bei wirklich gedrücktem Taster.
Durch die kurzfristigen HIGH Signale schalten meine Relais nicht wie gewollt.
Pull-Down Widerstände sind am Start(NO-Kontakt) und auch am Stopp(NC-Kontakt) angebracht.

- Die Ausgänge 4,5,6 schalten meine Relais für die Ventile, die Druckluft an die Zylinder weitergeben.
Obwohl der Ausgang 0V sein sollte schwankt er von 0 bis 0.11V hoch und runter.
bei HIGH Ausgängen liegen ganz normal 5V an.


Code: [Select]
const int S2_rot = 2 ;
const int S3_gruen = 3 ;
const int H_aus = 4 ;
const int H_ein = 5 ;
const int Dauerluft = 6 ;
unsigned long previousMillis;
int Automatik = 0;
int S2;
int S3;



void setup() {
 
Serial.begin(9600);
pinMode(S2_rot , INPUT);
pinMode(S3_gruen , INPUT);
pinMode(H_aus , OUTPUT);
pinMode(H_ein , OUTPUT);
pinMode(Dauerluft , OUTPUT);
digitalWrite(Dauerluft, HIGH); //Dauerluft freigeben


}

void loop() {

  //Einlesen der Taster Signale
  S2 = digitalRead(S2_rot);
  S3 = digitalRead(S3_gruen);
  
  // Wenn Start gedrückt
  if(S3 == HIGH){                                  
    Automatik = 1;  //Automatikbetrieb starten
    Serial.println("Automatik = 1");
    }
    
    //Wenn Stopp Taster gedrückt
  if(S2 == LOW){
    Automatik = 0;  //Automatikbetrieb stoppen
    Serial.println("Automatik = 0");
    digitalWrite(H_aus, LOW);  //Falls Hubwerk noch ausfährt, stoppen
    delay(10);
    digitalWrite(H_ein, HIGH);  //Hubwerk einfahren
    delay(3000);
    digitalWrite(H_ein, LOW);   //Einfahren Drucklos schalten
    
  
    }
  
  // Automatikbetrieb
if(Automatik == 1){
    previousMillis = millis();
    if(millis() - 10 >= previousMillis){  //Nach 10ms
    digitalWrite(H_aus, HIGH);  // Hubwerk ausfahren
    previousMillis = millis();
    }
      if(millis() - 4000 >= previousMillis){  //Nach 4s  
      digitalWrite(H_aus, LOW);  //Ausfahren stoppen
      previousMillis = millis();  
      }
        if(millis() - 10 >= previousMillis){  //Nach 10ms
        digitalWrite(H_ein, HIGH);  //Hubwerk einfahren
        previousMillis = millis();
        }
          if(millis() -  4000 >= previousMillis){  //Nach 4s
          digitalWrite(H_ein, LOW);  //Hubwerk einfahren stoppen
          previousMillis = millis();
          
         }  
         }
  
  }

Doc_Arduino

Hallo,

die Bilder werden klarer.
Du schaltest wirklich an den Pins direkt Relais?
Was sind das für Relais? Kannst du die verlinken?
Weil eigentlich geht das nicht direkt, weil das Spulen sind.
Induktionsspannung ist für Halbleiter erstmal gefährlich ohne Schutzmaßnahmen.
Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

Milkypants

Die Relais sind ziemlich groß da ich noch alte Teile aus der Firma benutzen wollte um die Kosten niedrig zu halten. Da die Relais ab 3.5V schalten können dachte ich das sie dafür nutzbar wären. Ich werde morgen einen Link oder Datenblatt dazu suchen und hochladen.

Go Up