Pages: 1 [2]   Go Down
Author Topic: Startknopf  (Read 2437 times)
0 Members and 1 Guest are viewing this topic.
Germany S-H
Offline Offline
Faraday Member
**
Karma: 135
Posts: 2862
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Im loop geht es nur drum, das die 4 Temp. sensoren ausgelesen werden und auf dem lcd angezeigt werden genauso wie der mpx drucksensor.
Desweiteren soll der wert "fade" angezeigt werden. Und wenn ich den knopf1 drücke soll das programm1 angehen und bei wiederholten drücken wieder aus gehen und wiederverwendbar sein.
Was nicht klappt ist der teil nach status1 wo eigentlich nach 30sec k[1-3] angehen sollen. Und das funktioniert nicht. Statdessen geht das programm1 an und aus wie es will und funktioniert ab status1 nicht.

OK, ich fasse mal zusammen, was ablaufen soll

- Temperaturen messen
- Druck messen
- Messwerte Temperatur und Druck auf LCD anzeigen
- ein Normalprogramm
- ein Programm, das nach 30 Sekunden nur einmalig ausgeführt wird
- und ein Spezialprogramm, das beim Drücken eines Tasters ein- und beim nächsten Drücken ausgeschaltet wird

So?

Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 287
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
void loop(){
  // check if conversion is done
  if (oneWire.read_bit()) {
    
    uint8_t i;
    for (i = 0; i < 4; i++) {
      lcd.setCursor(0, i);
      lcd.print("T");
      lcd.print(i+1, DEC);
      lcd.print(":");
      if (sensors.isConnected(Sensor[i])) {
        lcd.print(sensors.getTempC(Sensor[i]));
        lcd.print("C");
      } else {
        lcd.print("AUS   ");
      }
    }
    // start next conversion
    sensors.requestTemperatures();
  
    mpx = analogRead(mpxPin);
    pkPa = (mpx/1023.0-0.04)/0.0018;
    lcd.setCursor(10, 0);
    lcd.print(pkPa);
    lcd.print("mb   ");
    lcd.setCursor(10, 1);
  lcd.print(fade);
  }
    
  
  
  if ( bouncer.update() ) {
     if ( bouncer.read() == HIGH) {
       if ( buttonState == LOW ) {
         programm1();
         buttonState = HIGH;
       } else {
         uint8_t i;
  for (i = 0; i < 4; i++) {
    digitalWrite(k[i], HIGH);
  }
    analogWrite(ledPin, 0);
    thresholdMillis = 0;
    nextMillis = 0;
    status = 0;
    
         buttonState = LOW;
      
      }
   }
}
}
Das ist der teil wo die sensorwerte und der fadewert abgefragt und auf das display übertragen wird. Und der meine frage betreffende teil mit dem startknopf ist enthalten:
Code:
if ( bouncer.update() ) {
     if ( bouncer.read() == HIGH) {
       if ( buttonState == LOW ) {
         programm1();
         buttonState = HIGH;
       } else {
         uint8_t i;
  for (i = 0; i < 4; i++) {
    digitalWrite(k[i], HIGH);
  }
    analogWrite(ledPin, 0);
    thresholdMillis = 0;
    nextMillis = 0;
    status = 0;
    
         buttonState = LOW;
      
      }
   }
}
Der nächste teil ist das programm1 das mit dem startknopf(knopf1) gestartet und resetet werden soll, sodass man es wieder verwenden kann:
Code:
void programm1() {
  
 if (status == 0){
    digitalWrite(k[0], LOW);
    status = 1;
  } else if (sensors.getTempC(Sensor[0]) >= 22.5 && status == 1) {
    digitalWrite(k[0], HIGH);
    status = 2;
    nextMillis = millis() + 30000L;
  } else if (status == 2 && millis() > nextMillis) {
    digitalWrite(k[1], LOW);
    digitalWrite(k[2], LOW);
    digitalWrite(k[3], LOW);
    fade = 0;
    analogWrite(ledPin, fade);
    fade = 51;
    analogWrite(ledPin, fade);
  
status = 3;
nextMillis = millis() + 30000L;

  } else if (status == 3 && millis() > nextMillis) {
    fade = 102;
    analogWrite(ledPin, fade);
      status = 4;
      nextMillis = millis() + 30000L;
  } else if (status == 4 && millis() > nextMillis) {
    fade = 153;
    analogWrite(ledPin, fade);
  
      status = 5;
      nextMillis = millis() + 30000L;
    
  } else if (status == 5 && millis() > nextMillis) {
    fade = 255;
      status = 6;
    
  }
  if (sensors.getTempC(Sensor[0]) >= 22.7 && thresholdMillis == 0) {
    digitalWrite(k[1], HIGH);
    thresholdMillis = millis() + 30000L;
  } else if (thresholdMillis && millis() > thresholdMillis) {
    digitalWrite(k[2], HIGH);
    digitalWrite(k[3], HIGH);
    analogWrite(ledPin, 0);
    thresholdMillis = 0;
    nextMillis = 0;
    status = 0;
    fade = 0;
  }  
}
Frag einfach falls ich etwas schlecht beschreibe oder du noch fragen hast.
« Last Edit: December 08, 2012, 09:27:51 am by strohhirn » Logged

Gruß

strohhirn

Germany S-H
Offline Offline
Faraday Member
**
Karma: 135
Posts: 2862
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Frag einfach falls ich etwas schlecht beschreibe oder du noch fragen hast.

Heißt das zu der Zusammenfassung und Frage in meinem letzten Posting jetzt "Ja" oder "Nein"?

Falls nein: Schreibe bitte mal eine Zusammenfassung des beabsichtigen Programmablaufs in klarem Deutsch auf!

Das wiederholte Posten von fehlerhaftem und nicht funktionierendem Code hilft irgendwie nicht weiter dabei, um zu verstehen, was wann tatsächlich ablaufen soll.
Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 287
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

loop:
- Temperaturen messen
- Druck messen
- Messwerte Temperatur und Druck auf LCD anzeigen
- Fadewert anzeigen
- Startknopf (knopf1) abfragen:
    -startet programm1
    -resetet und verlässt es wenn es läuft

programm1:
1.relais k0 einschalten (LOW = an)
2.wenn Sensor1 25.8 °C erreicht/überschreitet soll k1 aus gehen (HIGH = aus)
3.nachdem k0 aus ist soll eine minute gewartet werden(ohne delay),nach dieser minute sollen relais k1 , k2 und k3 angehen (also LOW)
4.gleichzeitig soll mit den relais k1 und k2 und k3 eine LED mit einem PWM signal von 51 aufleuchten, denn sollen 2min gewartet werden(ohne delay)
5.nach diesen 2 min soll die LED leuchtkraft auf ein PWM signal von 102 steigen,denn sollen 3 min gewartet werden(ohne delay)
6.nach diesen 3 min soll die LED leuchtkraft auf ein PWM signal von 153 steigen,denn sollen 4 min gewartet werden(ohne delay)
7.nach diesen 4 min soll die LED leuchtkraft auf ein PWM signal von 255 steigen und so bleiben bis das programm beendet ist
8.wenn Sensor1 27°C ereicht/überschreitet soll k1 ausgehen (HIGH)
9.denn sollen 5 min gewartet werden(ohne delay)
10.nach diesen 5 min soll k2 und k3 ausgehen(HIGH)
11.wenn nach diesen 5 min k2 un k3 aus sind soll das Programm1 verlassen werden und wiederverwendbar sein

(die zeiten temp.werte und fadewerte sind nur testwerte und beispiele)
Logged

Gruß

strohhirn

Germany S-H
Offline Offline
Faraday Member
**
Karma: 135
Posts: 2862
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Allmählich kommen wir der Sache näher.

Du hast also eine loop, die ständig läuft:
- Temperaturen messen
- Druck messen
- Messwerte Temperatur und Druck auf LCD anzeigen
- Fadewert anzeigen
- Startknopf (knopf1) abfragen:

Und beim Drücken des Startknopfes soll eine Schrittsteuerung anfangen zu laufen, die von Schritt-1 bis Schritt-11 abgearbeitet wird.

Jetzt kann ich mir was darunter vorstellen. Ich überlege mir mal ein Programmgerüst dafür, und wenn das logisch korrekt steht, kannst Du einfach Deine Schritte an den Stellen dort hineinkopieren, wo sie stattfinden sollen.

Soll es vielleicht auch irgeneine Überwachung mit einem Alarm geben, wenn irgendein Schritt zu lange dauert und die Endbedingung nicht in der vorgegebenen Höchstzeit erreicht wird? Wenn beispielsweise in Schritt 8:
> 8.wenn Sensor1 27°C ereicht/überschreitet soll k1 ausgehen (HIGH)
Die Temperatur nie erreicht wird, z.B. weil die Heizung ausgefallen ist, dann würde ja Schritt 9 nie erreicht werden, weil die Ende-Bedingung von Schritt 8 nicht erreicht wird. Soll es da noch zeitliche Vorgaben geben, wenn in Schritt 1 und 8 die Temperaturen nicht in vorgegebener Höchstzeit eintreten, und danach gibt es Alarm? Oder soll dann einfach unendlich lange in Schritt 8 gewartet werden und es ist egal, ob Schritt 8 vielleicht bis zum nächsten Sommer dauert, ohne dass eine Warnung ausgegeben wird?

So, erster logischer Fehler in "Schritt 3":
programm1:
1.relais k0 einschalten (LOW = an)
2.wenn Sensor1 25.8 °C erreicht/überschreitet soll k1 aus gehen (HIGH = aus)
3.nachdem k0 aus ist soll eine minute gewartet werden(ohne delay),nach dieser minute sollen relais k1 , k2 und k3 angehen (also LOW)

Wenn in Schritt-1 k0 eingeschaltet wird und am Ende von Schritt-2 wird k1 ausgeschaltet, wie soll dann "k0" in Schritt-3 aus sein?`

Wo liegt der Fehler?
Soll in Schritt-2 k0 statt k1 ausgeschaltet werden?
Oder soll am Anfang von Schritt-3 k0 ausgeschaltet werden?
« Last Edit: December 08, 2012, 12:49:09 pm by jurs » Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 287
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Das problem ist nicht programm1, das klapt einwandfrei so wie ich es will, aber nur mit der alten variante des startknopfes :
Code:
buttonState = digitalRead(knopf1);
  if (buttonState != lastButtonState && buttonState == HIGH) {
    buttonPushCounter++;
  }
  lastButtonState = buttonState;
  if (buttonPushCounter % 2 == 0 && status == 0) {
    digitalWrite(k[0], HIGH);
  } else {
    programm1();
  }
Aber das problem an dieser variante ist das ich das programm1 nur 1mal anschalten kann, danach kann ich es nicht verlassen oder reseten ich muss erst den ganzen arduino reseten.
Und das ist mein problem nicht programm1 sondern der teil im sketch mit dem startknopf.
Deswegen habe ich versucht mein problem mit bounce zu lösen also so:
Code:
if ( bouncer.update() ) {
     if ( bouncer.read() == HIGH) {
       if ( buttonState == LOW ) {
         programm1();
         buttonState = HIGH;
       } else {
         uint8_t i;
  for (i = 0; i < 4; i++) {
    digitalWrite(k[i], HIGH);
  }
    analogWrite(ledPin, 0);
    thresholdMillis = 0;
    nextMillis = 0;
    status = 0;
   
         buttonState = LOW;
       
      }
   }
}

Doch bei dieser variante ist das problem das programm1 sich an und ausschaltet wie es will und das das programm1 nicht läuft k[1] geht zwar beim start des programms an aber weiter geht es nicht.
Logged

Gruß

strohhirn

Germany S-H
Offline Offline
Faraday Member
**
Karma: 135
Posts: 2862
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Aber das problem an dieser variante ist das ich das programm1 nur 1mal anschalten kann, danach kann ich es nicht verlassen oder reseten ich muss erst den ganzen arduino reseten.

Bei einer Schrittsteuerung machst Du es so, dass jeder Programmschritt eine Nummer bekommt. Gültige Programmschrittnummern sind dann beispielsweise 1 bis 9 und alles andere oder eine bestimmte andere Zahl wird betrachtet als "keinen Programmschritt ausführen".

Für Dich kannst Du z.B. definieren, dass Programmschrittnummer 999 für "Schrittsteuerung wird nicht ausgeführt" steht. "0" könnte man auch nehmen, aber Deine Programmschrittnummer heißt offenbar "status" und die "0" verwendest Du auch bereits als gültigen Programmschritt, also bietet sich 999 schon an für "Schrittsteuerung wird nicht ausgeführt".

Wenn Du nun die Variable "status" in der setup()-Funktion auf 999 setzt:
status=999;
Und dann beim Drücken des Tasters änderst Du den Status auf den ersten auszuführenden Programmschritt:
status=0;
Zwischen den Programmschritten schaltest Du weiter 1, 2, 3, usw. bis zum letzten Programmschritt,
da setzt Du dann am Ende des letzten Programmschritts wieder
status=999;

Und immer wenn in der loop der Status 999 gefunden wird, macht die Schrittsteuerung (Programm1) eben nichts.

Erst wenn beim nächsten Drücken des Tasters wird status wieder auf 0 gesetzt und die Schrittsteuerung läuft wieder neu ab.

Am Ende darf auch kein logischer Fehler in der Schrittabfolge drin sein, sonst laufen einzelne Schritte oder das gesamte Programm mehrfach ab, oder die Schrittsteuerung bleibt stehen und blockiert sich selbst. Damit man keine logischen Fehler einbaut, ist es sinnvoll dem Programm eine klare Struktur zu geben und die Funktionen übersichtlich zu halten.
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 56
Posts: 2983
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Programm1() wird nur einmal aufgerufen, wenn der Taster gerade gedrückt wurde. Also kommt es auch nur bis Status 1 ...

Programm starten und beenden ist eine "normale", aber unpassende Sichtweise:

Bei Controllern hört das Programm nie auf, sondern läuft ewig (bis Reset oder Strom aus). Es wird nur festgestellt ob sich was geändert hat, z.B. Zeit abgelaufen, Temperatur erreicht, Taste gedrückt, etc.
Der neue Zustand wird passend gespeichert damit die "Programme" die gerade laufen oder auch nicht, wissen was los ist.
Ein einzelner loop-Durchlauf dauert praktisch keine Zeit.  (Na ja, analogRead kostet mehr als 100 µs, aber man sollte sich nicht darauf verlassen, dass im nächsten Durchlauf millis() einen anderen Wert als jetzt hat.)

D.h. in deinem Fall:
- entweder loop() muss immer Programm1() aufrufen, und Programm1 stellt fest was zu tun ist: nichts (da eine gerade Anzahl Tastendrucke), oder evtl von status1 nach status2 wechseln ...
- oder loop weiss, dass gerade Programm1 aktiv ist und ruft es in jedem Durchlauf auf, bis Programm1 "beendet" ist.

Aber das sind Feinheiten und eher philosophischer Natur -- gehört der Taster zu programm1() oder zu loop()  ?

edit: wenn schon komplizierte Wörter, dann auch mit richtiger Grammatik
« Last Edit: December 08, 2012, 03:56:23 pm by michael_x » Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 287
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich hab das jetzt mal folgendermaßen umgesetzt:
Code:
if ( bouncer.update() ) {
     if ( bouncer.read() == HIGH) {
       if ( buttonState == LOW ) {
         uint8_t i;
  for (i = 0; i < 4; i++) {
    digitalWrite(k[i], HIGH);
  }
    analogWrite(ledPin, 0);
    thresholdMillis = 0;
    nextMillis = 0;
    status = 0;
       } else {
         
    status = 20;
         buttonState = LOW;
       
      }
   }
}
programm1();
}  //(endklammer des loops)

Die probleme jetzt sind das das programm1 gleich bei stromanschluss startet.
Das programm1 funktioniert aber wenn ich es ausschalten will (also nochmal auf den knopf drücke) springt das programm1 nur auf status 0 zurück anstatt auf status 20 ( 20 entspricht 999 von jurs).

Was habe ich diesmal falsch gemacht?
Logged

Gruß

strohhirn

Germany S-H
Offline Offline
Faraday Member
**
Karma: 135
Posts: 2862
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

> Die probleme jetzt sind das das programm1 gleich bei stromanschluss startet.

Dann fehlt vermutlich ein "status = 20;" in Deiner Setup-Routine, wenn 20 jetzt Dein "aus" Status ist.

> Das programm1 funktioniert aber wenn ich es ausschalten will (also nochmal auf den knopf drücke)
> springt das programm1 nur auf status 0 zurück anstatt auf status 20 ( 20 entspricht 999 von jurs).
> Was habe ich diesmal falsch gemacht?

Im Endeffekt mußt Du beim Schalterdrücken entweder mitzählen, wie oft der Taster gedrückt wird.

Ungerade Anzahl mal gedrückt: "status = 0;" setzen, also "starten".
Gerade  Anzahl mal gedrückt: "status = 20;" setzen, also "aus".
Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 287
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Erst mal vielen Dank an alle die mitgedacht und mitgeholfen haben.
Quote
Dann fehlt vermutlich ein "status = 20;" in Deiner Setup-Routine, wenn 20 jetzt Dein "aus" Status ist.
Ja 20 ist jetzt mein aus status und du hattest recht im setup war status noch auf 0 gesetzt.
Hab jetzt noch mal ein bisschen durchprobiert und jetzt klappt es erst mal endlich wie gewollt.   smiley
Hier mal jetzt das gesamtergebnis:
Code:
#include <Bounce.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal.h>


#define ONE_WIRE_BUS 30  // Temperatursensor pin 30
#define FADE_DELAY 3 // Verzögerung beim Faden
LiquidCrystal lcd(22, 23, 24, 25, 26, 27, 28);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

DeviceAddress Sensor[] = {{0x28, 0xCD, 0x9B, 0xDA, 0x03, 0x00, 0x00, 0xF2},
                          {0x28, 0x1F, 0xA3, 0xDA, 0x03, 0x00, 0x00, 0xE2},
                          {0x28, 0x2D, 0xB9, 0xDA, 0x03, 0x00, 0x00, 0xA0},
                          {0x28, 0x37, 0x88, 0xDA, 0x03, 0x00, 0x00, 0x7D}};

int backLight = 29;
uint8_t k[] = {31, 32, 33, 35};   //relais HIGH = Aus; LOW = An

uint8_t knopf1 = 34;
uint8_t buttonState = 0; //knopf
int buttonPushCounter = 0;
uint8_t lastButtonState = 0;
Bounce bouncer = Bounce( knopf1, 5 );

uint32_t previousMillis = 0;


int   mpxPin =  5; //drucksensor
int   mpx;
float pkPa;

uint8_t ledPin = 9; // (kemo)
uint8_t fade;
uint8_t status;

 uint32_t nextMillis = 0;
 uint32_t thresholdMillis = 0;

void setup() {
  pinMode(backLight, OUTPUT);
  digitalWrite(backLight, HIGH);
  lcd.begin(20, 4);
  sensors.begin();
  uint8_t i;
  for (i = 0; i < 4; i++) {
    pinMode(k[i], OUTPUT);
    digitalWrite(k[i], HIGH);
  }
  pinMode(knopf1, INPUT);
 
  status=20; // 20 = aus
  sensors.setWaitForConversion(false);
  sensors.requestTemperatures();
}

void loop(){
  // check if conversion is done
  if (oneWire.read_bit()) {
   
    uint8_t i;
    for (i = 0; i < 4; i++) {
      lcd.setCursor(0, i);
      lcd.print("T");
      lcd.print(i+1, DEC);
      lcd.print(":");
      if (sensors.isConnected(Sensor[i])) {
        lcd.print(sensors.getTempC(Sensor[i]));
        lcd.print("C");
      } else {
        lcd.print("AUS   ");
      }
    }
    // start next conversion
    sensors.requestTemperatures();
 
    mpx = analogRead(mpxPin);
    pkPa = (mpx/1023.0-0.04)/0.0018;
    lcd.setCursor(10, 0);
    lcd.print(pkPa);
    lcd.print("mb   ");
    lcd.setCursor(10, 1);
    lcd.print(fade);
  }
   
 
 
  if ( bouncer.update() ) {
     if ( bouncer.read() == HIGH) {
       if ( buttonState == LOW ) {
         uint8_t i;
         for (i = 0; i < 4; i++) {
          digitalWrite(k[i], HIGH);
          }
         analogWrite(ledPin, 0);
         thresholdMillis = 0;
         nextMillis = 0;
         
         status = 0;
         
         buttonState = HIGH;
       } else {
         
         status = 20; // programm1 aus
         uint8_t i;
         for (i = 0; i < 4; i++) {
          digitalWrite(k[i], HIGH);
          }
         analogWrite(ledPin, 0);
         thresholdMillis = 0;
         nextMillis = 0;
   
         buttonState = LOW;
      }
    }
  }
  programm1();
} // endklammer des loops

void programm1() {
 
 if (status == 0){
    digitalWrite(k[0], LOW);
    status = 1;
  } else if (sensors.getTempC(Sensor[0]) >= 23.0 && status == 1) {
    digitalWrite(k[0], HIGH);
    status = 2;
    nextMillis = millis() + 30000L;
  } else if (status == 2 && millis() > nextMillis) {
    digitalWrite(k[1], LOW);
    digitalWrite(k[2], LOW);
    digitalWrite(k[3], LOW);
    fade = 0;
    analogWrite(ledPin, fade);
    fade = 51;
    analogWrite(ledPin, fade);
 
status = 3;
nextMillis = millis() + 30000L;

  } else if (status == 3 && millis() > nextMillis) {
    fade = 102;
    analogWrite(ledPin, fade);
      status = 4;
      nextMillis = millis() + 30000L;
  } else if (status == 4 && millis() > nextMillis) {
    fade = 153;
    analogWrite(ledPin, fade);
 
      status = 5;
      nextMillis = millis() + 30000L;
   
  } else if (status == 5 && millis() > nextMillis) {
    fade = 255;
      status = 6;
   
  }
  if (sensors.getTempC(Sensor[0]) >= 25.0 && thresholdMillis == 0) {
    digitalWrite(k[1], HIGH);
    thresholdMillis = millis() + 30000L;
  } else if (thresholdMillis && millis() > thresholdMillis) {
    digitalWrite(k[2], HIGH);
    digitalWrite(k[3], HIGH);
    analogWrite(ledPin, 0);
    thresholdMillis = 0;
    nextMillis = 0;
    fade = 0;
   
    status = 20;
  }   
}

Als nächstes will ich noch einen pausenknopf, um programm1 anhalten und fortführen zu können, einbauen, aber das versuch ich erstmal selbst zu machen.

Noch mal vielen Dank, besonders an jurs der sehr aktiv und interesiert mitgewirkt hat.

Mfg

strohhirn

Logged

Gruß

strohhirn

Pages: 1 [2]   Go Up
Jump to: