Go Down

Topic: Ansteuerung eines 3-Wege-Mischers für eine Fußbodenheizung (Read 31508 times) previous topic - next topic

bello12

x ist die Aussentemperatur y der errechnete Wert der Vorlauftemperatur.

x1 also dann z.b. -15 Grad
x2 +15 Grad
y1 =30 Grad
y2 = 80 Grad

dann gilt
SW = y1 +  (AT - X1)/(X2-X1) * (y2-y1)


die formel im ganzen kann ich so nicht eingeben weil nur die erste klammer ausgerechnet wird oder gibt es da einen bestimmten variablentyp für solche rechnungen.
gruß

inside-man

Wenn du einzelne rechnungen machst, brauchst du gar keine Klammern. Versuch das doch mal, das sollte mit Sicherheit funktionieren! Sorry ich habe keinen Arduino hier, erst ab Freitag, dann teste ichs mal!

Yeahuno

Quote
float x1 = -15;
float x2 = +15;
float y1 = +30;
float y2 = +80;
float SW;
float AT = +5;

void setup()
{
Serial.begin(9600);
}

void loop()
{
SW = y1+((AT - x1)/(x2-x1))*(y2-y1);
Serial.println(SW);
}


so klappt es bei mir

Gruß

bello12


Berry07

Hallo Leute,

ich habe mal wieder ein Brett vor dem Kopf und brauche Eure Hilfe:

Am Anfang diese Threads hat mir "Komputer.de" seine Version der Mischersteuerung gepostet. Danke dafür nochmal an dieser Stelle.

Ich wollte nun die "Delays" mit millis() oder metro oder timer ersetzen und bekomme es einfach nicht hin.

Also im Loop wird die Vorlauftemperatur ermittelt und mit der Solltemperatur verglichen. Nun soll zur Anpassung der Mischer kurz (für 2 Sek) auf- oder zufahren. Dann soll aber 10 Sek gewartet werden, bis wieder neu verglichen wird, weil die Temperatur sich nicht so schnell ändert. Das ist eigentlich alles, aber wenn 2 millis-Funktionen in den if-Verkettungen hängen, geht es nicht mehr.
Könnt Ihr mal schauen, was ich falsch gemacht habe?

Code: [Select]
/* Erster Versuch Mischersteuerung  20101025 mb[ALT-Q]komputer.de   */
#include <OneWire.h>
#include <DallasTemperature.h>
// DS1820 an PIN 2
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
#define Mischer_AUF 8
#define Mischer_ZU 9
/********************************************************************************/
// Solltemperatur
int tempsoll = 21;
// Hysterese
int hyst = 2;
unsigned long MischenA, MischenB;   
unsigned long WartenA,WartenB;
int ZustandAUF = LOW;
int ZustandZU = LOW;

/********************************************************************************/

void setup() {               
  pinMode(Mischer_AUF, OUTPUT); //Mischer auf
  pinMode(Mischer_ZU, OUTPUT); //Mischer zu
  digitalWrite(Mischer_AUF, ZustandAUF);
  digitalWrite(Mischer_ZU, ZustandZU);
  // start serial port
  Serial.begin(9600);
  sensors.begin(); 
}

void loop() {
  sensors.requestTemperatures();
  int tempist = sensors.getTempCByIndex(0);
  Serial.print("Ist Temp: ");
  Serial.println(tempist);
 
  /////////////////////////
        WartenA = millis();    //Warten bis wieder verglichen werden soll
        MischenA= millis();    //die Dauer, die der Mischer Strom bekommt, um zu korrigieren
        if (WartenA - WartenB > 10000){
          if (tempist > (tempsoll + hyst)) {    // Mischer zu - Temperatur runter
                  Serial.println("tempist zu hoch, also Mischer ZU ");
             ZustandZU = HIGH;
             digitalWrite(Mischer_ZU, ZustandZU);
                  Serial.println(digitalRead(Mischer_ZU));
          if (ZustandZU = HIGH){
           if (MischenA - MischenB > 2000){
              digitalWrite(Mischer_ZU, LOW);
              MischenB = (millis());
            }
            }
        WartenB = millis(); 
       }
     }
   }
         


Danke schon mal im Voraus

Andreas

maverick1509

Hallo Andreas,
ich habs nur überflogen, aber die Abfrag
if (MischenA - MischenB > 2000) gilt ja immer, denn du läufst ja nur alle 10 sec in die Schleife und das ist auf jeden
Fall >2 sec.
Das heißt du machst den Mischer auf und im gleichen Moment auch wieder zu, da die o.g. Bedingung ja true ergibt.
Oder hab ich auch einen Denkfehler?
Gruß
Bernward

maverick1509

P.S. meiner Meinung nach brauchst du keine zweite millis Abfrage.
Wenn du alle 10 sec die Schleife abfragst, dann mach doch einfach 2 sec auf und dann wieder zu.
Sollte doch gehen oder nicht?

Berry07

Das ist ja gerade mein Problem:

2 Sek "lang" offenlassen, mit delay geht das ganz einfach:
Quote

WartenA = millis();    //alles 10 Sekunden die Temperaturen vergleichen
       if (WartenA - WartenB > 10000){
          if (tempist > (tempsoll + hyst)) {
            digitalWrite(Mischer_ZU, HIGH);
            delay(2000);  // 2 Sekunden lang den Mischer laufen lassen
            digitalWrite(Mischer_ZU, LOW);
             }}


Aber mit millis? dann habe ich wieder eine zweite Schleife, die als 2-Sek-Schleife in der 10-Sek-Schleife hängt.
Genau da drehe ich mich gedanklich im Kreis.

Andreas

inside-man

Hallo, ich habe auch nur mal kurz überflogen, aber folgendes sieht wirklich komisch aus:

  MischenB = (millis());

Also Mischen B wird nur mit den normalen Millis beschrieben, wenn er in der Schleife hängt.

Und jetzt diese Stelle:

MischenA - MischenB > 2000

Wenn ich schauen will, ob ich schon laenger 2 sekunden an dieser Stelle bin, dann muesste es ja heissen
MischenA - millis() > 2000

Ich glaube an dieser Stelle muesste nachgebessert werden. Ich schaue gleich mal in Ruhe drüber.



Hallo Leute,

ich habe mal wieder ein Brett vor dem Kopf und brauche Eure Hilfe:

Am Anfang diese Threads hat mir "Komputer.de" seine Version der Mischersteuerung gepostet. Danke dafür nochmal an dieser Stelle.

Ich wollte nun die "Delays" mit millis() oder metro oder timer ersetzen und bekomme es einfach nicht hin.

Also im Loop wird die Vorlauftemperatur ermittelt und mit der Solltemperatur verglichen. Nun soll zur Anpassung der Mischer kurz (für 2 Sek) auf- oder zufahren. Dann soll aber 10 Sek gewartet werden, bis wieder neu verglichen wird, weil die Temperatur sich nicht so schnell ändert. Das ist eigentlich alles, aber wenn 2 millis-Funktionen in den if-Verkettungen hängen, geht es nicht mehr.
Könnt Ihr mal schauen, was ich falsch gemacht habe?

Code: [Select]
/* Erster Versuch Mischersteuerung  20101025 mb[ALT-Q]komputer.de   */
#include <OneWire.h>
#include <DallasTemperature.h>
// DS1820 an PIN 2
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
#define Mischer_AUF 8
#define Mischer_ZU 9
/********************************************************************************/
// Solltemperatur
int tempsoll = 21;
// Hysterese
int hyst = 2;
unsigned long MischenA, MischenB;   
unsigned long WartenA,WartenB;
int ZustandAUF = LOW;
int ZustandZU = LOW;

/********************************************************************************/

void setup() {               
  pinMode(Mischer_AUF, OUTPUT); //Mischer auf
  pinMode(Mischer_ZU, OUTPUT); //Mischer zu
  digitalWrite(Mischer_AUF, ZustandAUF);
  digitalWrite(Mischer_ZU, ZustandZU);
  // start serial port
  Serial.begin(9600);
  sensors.begin(); 
}

void loop() {
  sensors.requestTemperatures();
  int tempist = sensors.getTempCByIndex(0);
  Serial.print("Ist Temp: ");
  Serial.println(tempist);
 
  /////////////////////////
        WartenA = millis();    //Warten bis wieder verglichen werden soll
        MischenA= millis();    //die Dauer, die der Mischer Strom bekommt, um zu korrigieren
        if (WartenA - WartenB > 10000){
          if (tempist > (tempsoll + hyst)) {    // Mischer zu - Temperatur runter
                  Serial.println("tempist zu hoch, also Mischer ZU ");
             ZustandZU = HIGH;
             digitalWrite(Mischer_ZU, ZustandZU);
                  Serial.println(digitalRead(Mischer_ZU));
          if (ZustandZU = HIGH){
           if (MischenA - MischenB > 2000){
              digitalWrite(Mischer_ZU, LOW);
              MischenB = (millis());
            }
            }
        WartenB = millis(); 
       }
     }
   }
         


Danke schon mal im Voraus

Andreas


inside-man

Hallo, also in Deinem Programm steckt irgendwo der Wurm drin.

Schau mal hier, wenn ich das nachvollziehe geht das schon mal nicht richtig:
Ich sage mal was ich sehe, vielleicht kannst Du es nachvollziehen und merkst was da nicht stimmt.

also
MischenA wird auf einen Wert gesetyt sagen wir mal 100000


           if (MischenA - MischenB > 2000){
              digitalWrite(Mischer_ZU, LOW);
              MischenB = (millis());

Dann kommt der oben genannte Durchlauf, plötzlich wird MischenB mit dem aktuellen millis beschrieben, (später) also 105000, jetzt fragst Du MischanA (100000) - MischenB (105000) > 2000 , wie gesagt der kann nie grösser 2000 werden, da MischenB ja später mit millis beschrieben wird.

Ich glaube das muss ganz anders gemacht werden, hier mal ein ungeprüften schnipsel, habe kein Arduino da:

Du musst dran denken, alle Programmteile sind so zu konstruieren, da sie ja immer durchlaufen werden, das Programm bleibt ja nicht mehr stehen wie bei delay. Also die Erkärung zu meinem snippet:

einmalig wird millis auf mischenA geschrieben (also ein Merker muss aus sein, schreiben, merker einschalten fertig). Dann wird verglichen ob der Merker aktiv ist, und geschaut ob 2 Sekunden um sind, wenn ja, dann merker aus, und die gewuenschte Aktion ausführen. Es muss noch ein Flag angelegt werden (hier flag wait 2 seconds also eine bool Variable mit diesem Namen)
Ich hoffe das hilft etwas weiter.

         if (ZustandZU = HIGH & FLAGW2S=FALSE) {
           MischenA=millis()
           FLAGW2S=TRUE;
         }
         
         if (ZustandZU = HIGH & FLAGW2S=TRUE) {
         
           if (MischenA - millis() > 2000){
              digitalWrite(Mischer_ZU, LOW);
              FLAGW2S=TRUE;


maverick1509

Hallo Andreas, wie wäre es denn mit while????
ist nicht getestet, aber sollte doch so gehen.

   WartenA = millis();    //alles 10 Sekunden die Temperaturen vergleichen
       if (WartenA - WartenB > 10000){
          if (tempist > (tempsoll + hyst)) {
             aktuell=millis();
             while (millis() - aktuell <2000 {
              digitalWrite(Mischer_ZU, HIGH);
             }// 2 Sekunden lang den Mischer laufen lassen
             digitalWrite(Mischer_ZU, LOW);
             }}

gruß
Bernward

Berry07

Vielen Dank für die schnelle Hilfe!!

Also es klappt mit der while Schleife. Danke Bernward.

Ich hatte es auch schon damit versucht, aber eben mit :

if (ZustandZU = HIGH){
      while (MischenA - MischenB < 2000){
              digitalWrite(Mischer_ZU, LOW);
              MischenB = (millis());

...und das geht eben nicht. Aber Bernwards Version ist dann:

if (ZustandZU = HIGH){
               MischenA=millis();
      while (millis() - MischenA <2000) {
              digitalWrite(Mischer_ZU, LOW);

das geht, weil es ja gar keine Schleife sein soll, sondern nur einmal die 2 Sek abgearbeitet werden soll. Aha, jetzt dämmert mir es langsam.

Ich poste später noch den funktionierenden Code.

Super, vielen Dank nochmal

Andreas

             

inside-man

Ohh das mit der while Schleife ist wirklich ne gute Loesung, da kann man sich das mit dem Flag ja sparen.. Nicht schlecht

Berry07

Nochmal Dank an Michi (komputer.de) und Bernward (maverick1509).

Hier nun also eine einfache und funktionierende Festwert-Mischersteuerung ohne delays:

Code: [Select]
/* Erster Versuch Mischersteuerung  20101025 mb[ALT-Q]komputer.de   
Die delays durch millis ersetzt von Berry07*/
#include <OneWire.h>
#include <DallasTemperature.h>
// DS1820 an PIN 2
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
#define Mischer_AUF 8
#define Mischer_ZU 9
/********************************************************************************/
// Solltemperatur
int tempsoll = 21;
// Hysterese
int hyst = 2;
unsigned long MischenA;   
unsigned long WartenA,WartenB;
/********************************************************************************/
void setup() {               
  pinMode(Mischer_AUF, OUTPUT);
  pinMode(Mischer_ZU, OUTPUT);
  digitalWrite(Mischer_AUF, LOW);
  digitalWrite(Mischer_ZU, LOW);
  Serial.begin(9600);
  sensors.begin(); 
}
/********************************************************************************/
void loop() {
  sensors.requestTemperatures();
  int tempist = sensors.getTempCByIndex(0);
  Serial.print("Ist Temp: ");
  Serial.println(tempist);
  //------> MISCHEN Anfang
  WartenA = millis();    //alles 10 Sekunden die Temperaturen vergleichen
       if (WartenA - WartenB > 10000){
          if (tempist > (tempsoll + hyst)) {    // Mischer zu - Temperatur runter
             MischenA = millis();   
            while (millis() - MischenA < ((tempist - tempsoll) * 500)) { 
                //z.B.tempist=27(Grad) und tempsoll= 22(Grad) dann geht der Mischer 5*500ms also 2,5sec lang zu 
                digitalWrite(Mischer_ZU, HIGH);
                Serial.print("Mischzeit ist ");
                Serial.println(((tempist - tempsoll) * 500));
                Serial.println("Mischer faehrt ZU");
             }
                digitalWrite(Mischer_ZU, LOW);
           }
          if (tempist < (tempsoll - hyst)) {    // Mischer auf - Temperatur erhoehen
             MischenA = millis();   
            while (millis() - MischenA < ((tempsoll - tempist) * 500)) {   
                digitalWrite(Mischer_AUF, HIGH);
                Serial.print("Mischzeit ist ");
                Serial.println(((tempsoll - tempist) * 500));
                Serial.println("Mischer faehrt AUF");
             }
                digitalWrite(Mischer_AUF, LOW);
           }
          WartenB = millis(); 
       } //--------MISCHEN Ende-----------------
  }      //Loop Ende
         


Gruß Andreas

Berry07

So und nun noch mit Fernverstellung:

10 kOhm Poti an Analog0 und den Messwert von 0 bis 1023 in 40er Schritte aufteilen, dann kann man mit dem Poti in einem Bereich von 25 Grad verstellen. Da ich meinen Vorlauf von 20 bis 45 Grad stellen möchte, zähle ich noch 20 dazu. Also: alle Messwerte von 0 bis ca. 40 ergeben 0 +20 = 20 Grad, von 40 bis 80 ergeben 1 +20= 21, von 80 bis ca. 120 ergeben 3 +20= 23Grad usw. Damit stelle ich jetzt am Poti in der Küche meine gewünschte Vorlauftemperatur ein.

Vielleicht kann es ja noch jemand anderes gut gebrauchen:
Code: [Select]
/* Erster Versuch Mischersteuerung  20101025 mb[ALT-Q]komputer.de   
Die delays durch millis ersetzt und Fernversteller eingefügt von Berry07*/
#include <OneWire.h>
#include <DallasTemperature.h>
// DS1820 an PIN 2
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
#define Mischer_AUF 8
#define Mischer_ZU 9
/********************************************************************************/
// Solltemperatur
int tempsoll = 20;
int poti=0;
// Hysterese
int hyst = 2;
unsigned long MischenA;   
unsigned long WartenA,WartenB;
/********************************************************************************/
void setup() {               
  pinMode(A0, INPUT);
  pinMode(Mischer_AUF, OUTPUT);
  pinMode(Mischer_ZU, OUTPUT);
  digitalWrite(Mischer_AUF, LOW);
  digitalWrite(Mischer_ZU, LOW);
  Serial.begin(9600);
  sensors.begin(); 
}
/********************************************************************************/
void loop() {
  sensors.requestTemperatures();
  int tempist = sensors.getTempCByIndex(0);
  Serial.print("Ist Temp: ");
  Serial.println(tempist);
  //------> MISCHEN Anfang
  poti = analogRead(A0);    //10 kOhm-Poti
               //Serial.print("poti zeigt ");Serial.println(poti);
  tempsoll = (poti/40 + 20);    //Messwert in 40 Teile zerlegen und dadurch in 25 Grad-Schritten regeln
  Serial.print("tempsoll ist :");Serial.println(tempsoll);
  WartenA = millis();    //alles 10 Sekunden die Temperaturen vergleichen
       if (WartenA - WartenB > 10000){
          if (tempist > (tempsoll + hyst)) {    // Mischer zu - Temperatur runter
             MischenA = millis();   
            while (millis() - MischenA < ((tempist - tempsoll) * 500)) { 
                                        //z.B.tempist=27(Grad) und tempsoll= 22(Grad)
                                        //dann geht der Mischer 5*500ms also 2,5sec lang zu 
                digitalWrite(Mischer_ZU, HIGH);
                //Serial.print("Mischzeit ist ");
                //Serial.println(((tempist - tempsoll) * 500));
                Serial.println("Mischer faehrt ZU");
             }
                digitalWrite(Mischer_ZU, LOW);
           }
          if (tempist < (tempsoll - hyst)) {    // Mischer auf - Temperatur erhoehen
             MischenA = millis();   
            while (millis() - MischenA < ((tempsoll - tempist) * 500)) {   
                digitalWrite(Mischer_AUF, HIGH);
                //Serial.print("Mischzeit ist ");
                //Serial.println(((tempsoll - tempist) * 500));
                Serial.println("Mischer faehrt AUF");
             }
                digitalWrite(Mischer_AUF, LOW);
           }
          WartenB = millis(); 
       } //--------MISCHEN Ende-----------------
  }      //Loop Ende
         
         



Gruß Andreas

Go Up