Programm für Temperofen, Menüstruktur und millis Help???

Hallo liebes Forum. ich habe schon vor längeren angefangen am Arduino zu Programmieren und mich mit der Zeit an immer größeren Projekten Probiert. Mein derzeitiges Projekt handelt sich um einen Temperofen. Ich habe bereits einen Sketch geschrieben welcher auch mit der millis Aktion funktioniert. Mein Problem liegt in der Umsetzung folgender Punkte:

  • Aufbau eines Menüs, mit mehreren Programmen
  • Aufgabe eines Programmes soll es sein die Temperatur einen Sensors Abzufragen und Halbstündlich durch zuschalten von Heizelementen die Temperatur um 5C zu erhöhen, bis beispielsweise 60C erreicht sind, und diese dann für 6 Stunden halten.
  • Das ganze für ca 5 Programme die alle verschiedene Endtemperaturen und Laufzeiten haben(nur die Aufheizzeit bleibt gleich)

Hier der erste sketch den ich geschrieben habe. Dieser Funktioniert soweit, bloß das das Programm nach starten des Arduinos sofort startet, und keine anderen Programme ausgewählt werden können.( Zeiten und Temperaturen stimmen noch nicht mit dem oben geschriebenen überein, da es nur zum testen gedacht ist.

#include<dht11.h>      
#include<LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);

byte punkt [8] = {B00110,B01001,B01001,B00110,B00000,B00000,B00000,B00000,};
byte voll  [8] = {B11111,B11111,B11111,B11111,B11111,B11111,B11111,B11111,}; 

#define dht_dpin 8 
dht11 DHT1; 

#define        Initialisieren     5000UL

#define        laufzeit_1   60000UL     //Heizen 1
#define        laufzeit_2   120000UL    //Heizen 2
#define        laufzeit_3   180000UL    //Heizen 3  
#define        laufzeit_4   240000UL    //Halten  
#define        laufzeit_5   300000UL    //Kühlen 1  
#define        laufzeit_6   360000UL    //Kühlen 2
#define        laufzeit_7   420000UL    //Kühlen 3

unsigned long time;
unsigned long StartMonitor = 0;


int Heat1 = 22;
int Heat2 = 24;
int Heat3 = 26;
int Heat4 = 28;
int Steuerung1 = 42;
int Steuerung2 = 43;
int Steuerung3 = 44;
int Steuerung4 = 45;
int SteuerungA = 50;
int SteuerungB = 51;
int SteuerungC = 52;
int SteuerungD = 53;

void setup()
{
  Serial.begin(9600);
  
  pinMode(SteuerungA, INPUT); 
  pinMode(SteuerungB, INPUT);
  pinMode(SteuerungC, INPUT);
  pinMode(SteuerungD, INPUT);
  
  pinMode(Steuerung1, OUTPUT);
  pinMode(Steuerung2, OUTPUT);
  pinMode(Steuerung3, OUTPUT); 
  pinMode(Steuerung4, OUTPUT); 
  pinMode(Heat1,      OUTPUT);
  pinMode(Heat2,      OUTPUT);
  pinMode(Heat3,      OUTPUT); 
  pinMode(Heat4,      OUTPUT);

  lcd.begin(20,4);
  lcd.createChar (1, punkt); 
  lcd.createChar (2, voll); 
  lcd.clear();
  lcd.setCursor(5,1);
  lcd.print("Temperofen");
  delay(5000);
  lcd.clear();
}

void loop()

{
  
  DHT1.read(dht_dpin);
  int temp = DHT1.temperature;

  lcd.setCursor ( 0 , 0 );
  lcd.print("Temp ist :");
  lcd.print((float)DHT1.temperature, 0);
  lcd.setCursor(15,0);
  lcd.write(1);
  lcd.print("C");
  lcd.setCursor ( 0 , 1 );
  lcd.print("Temp soll:");
  lcd.setCursor(15,1);
  lcd.write(1);
  lcd.print("C");
  delay(1000);


  
//Programmablauf--------------------------------------------------------------------------------------------------
 
   if (millis() <= laufzeit_1) {digitalWrite (Steuerung1, HIGH);}
   
   if (millis() >= laufzeit_1) {digitalWrite (Steuerung2, HIGH); digitalWrite (Steuerung1, LOW);}
   
   if (millis() >= laufzeit_2) {digitalWrite (Steuerung3, HIGH); digitalWrite (Steuerung2, LOW);}
   
   if (millis() >= laufzeit_3) {digitalWrite (Steuerung4, HIGH); digitalWrite (Steuerung3, LOW);}

   if (millis() >= laufzeit_4) {digitalWrite (Steuerung3, HIGH); digitalWrite (Steuerung4, LOW);}
   
   if (millis() >= laufzeit_5) {digitalWrite (Steuerung2, HIGH); digitalWrite (Steuerung3, LOW);}
   
   if (millis() >= laufzeit_6) {digitalWrite (Steuerung1, HIGH); digitalWrite (Steuerung2, LOW);}

   if (millis() >= laufzeit_7) {digitalWrite (Steuerung1, LOW);}

   
//Heizstufe 1-----------------------------------------------------------------------------------------------------

 
  if (digitalRead(SteuerungA) == HIGH  && temp <= 21)    
    { 
      digitalWrite  (Heat1, HIGH);
      lcd.setCursor ( 10 , 1 );
      lcd.print("22");
    }
    
    else if (digitalRead(SteuerungA) == LOW || temp >= 22)
    {
      digitalWrite  (Heat1, LOW);
    }

//Heizstufe 2-----------------------------------------------------------------------------------------------------
    
    if (digitalRead(SteuerungB) == HIGH  && temp <= 24)
    { 
      digitalWrite  (Heat1, HIGH);
      digitalWrite  (Heat2, HIGH);
      lcd.setCursor ( 10 , 1 );
      lcd.print("25");
    }
    
    else if(digitalRead(SteuerungB) == LOW || temp >= 25)
    {
      digitalWrite  (Heat2, LOW);
    }

    
//Heizstufe 3-----------------------------------------------------------------------------------------------------
    
     if (digitalRead(SteuerungC) == HIGH  && temp <= 27)
    { 
      digitalWrite  (Heat1, HIGH);
      digitalWrite  (Heat2, HIGH);
      digitalWrite  (Heat3, HIGH);
      lcd.setCursor ( 10 , 1 );
      lcd.print("28");
    }
    
    else if(digitalRead(SteuerungC) == LOW || temp >= 28)
    {
      digitalWrite  (Heat3, LOW);
     }

    
//Heizstufe 4-----------------------------------------------------------------------------------------------------
    
     if (digitalRead(SteuerungD) == HIGH  && temp <= 30)
    { 
      digitalWrite  (Heat1, HIGH);
      digitalWrite  (Heat2, HIGH);
      digitalWrite  (Heat3, HIGH);
      digitalWrite  (Heat4, HIGH);
      lcd.setCursor ( 10,1 );
      lcd.print("31");
    }
    
    else if(digitalRead(SteuerungD) == LOW || temp >= 31)
    {
      digitalWrite  (Heat4, LOW);
    }

   temp= map(DHT1.temperature, 0, 410, -50, 150);
  if (millis() - StartMonitor >= Initialisieren) {
  StartMonitor = millis();
  Serial.print(DHT1.temperature);
  Serial.println(" Grad Celsius");
  }
}

Außerdem mein erster Test eine Menüstruktur mit der millis Funktion zu vereinen. Daran bin ich leider gescheitert. Das Menü wird zwar richtig angezeigt, aber bei der Auswahl des Menüpunkts passiert nichts. Ich möchte keinen fertigen Sketch, aber über ein einfaches Beispiel anhand meines Sketchs mit einer kleinen Erklärung, warum was so geschrieben wird wäre ich sehr Dankbar. Bitte verurteilt mich nicht, da ich seit Tagen im Netz nach Lösungen suche aber nicht verstehe wie ich millis richtig einsetzte bzw verwende.

#include <LiquidCrystal.h>
#include <Menu.h>
#include <MenuItem.h>
LiquidCrystal lcd(7,6,5,4,3,2); 
Menu myMenu; 

//                Name            Number  For    Back  up    down
MenuItem item100("Start     ",     100,    101,   102,  100,  100);
MenuItem item101("Programm 1",     101,    102,   100,  101,  101);
MenuItem item102("Programm 2",     102,    100,   101,  102,  102);

int readButton; // Variable to store the last pressed Button
int select;  

#define        Timer_1   2000UL    
#define        Timer_2   6000UL    
#define        Timer_3   63000UL 


unsigned long time;
unsigned long startzeit_1 = 0;

void Programm1(){
 lcd.clear();
 lcd.print("programm 1");
 if (millis() - startzeit_1 <= Timer_1) {
 startzeit_1 = millis();
 digitalWrite(24, HIGH);}
 
 if (millis() - startzeit_1 >= Timer_2) {
 startzeit_1 = millis();
 digitalWrite(24, LOW);
 delay(2000);
 myMenu.begin(100);}
 }
void Programm2(){
 lcd.clear();
 lcd.print("Programm 2");
 digitalWrite(26, HIGH);
 delay(3000);
 digitalWrite(26, LOW);
 delay(100);
 lcd.clear();
 myMenu.begin(100);
}

void setup(){

 Serial.begin(9600);
 
 myMenu.addLCD(&lcd); 
 
 myMenu.addItem(item100);  
 myMenu.addItem(item101);
 myMenu.addItem(item102);

 lcd.begin(16, 2);
 lcd.print("Temperofen");
 delay(2000);

  myMenu.begin(100); // Start at the Menu with at the MenuItem you want
 
  pinMode(24, OUTPUT); 
  pinMode(26, OUTPUT);
  pinMode(28, OUTPUT);
  pinMode(30, OUTPUT); 
    
  pinMode(51,INPUT);
  pinMode(52,INPUT);
  pinMode(53,INPUT);

}

void loop(){
 readButton = analogRead(0); // read the value from a pushed button
                                                    
  if(digitalRead(53) == HIGH){
    myMenu.goForward();                                    
    } 
  if(digitalRead(51) == HIGH){
    myMenu.goBack();
    }
  if(digitalRead(52) == HIGH){
   select = myMenu.select(); //use select() to check if the item you are at has a runable function
  
   switch(select){
     case 101: //if found a funtion for a item run it
       Programm1();
       break;

     case 102: //if found a funtion for a item run it
       Programm2();
       break;

       default: 
       break;
   } 
 }
 readButton = 1000;

}

Warum fängst Du dazu einen zweiten Thread an?

Gruß Tommy

Das war versehentlich. Tschuldigung, versuche den ersten zu löschen

bloß das das Programm nach starten des Arduinos sofort startet

Du verwendest absolute millis() - Werte.

Wenn das Heizprogramm erst später starten soll, musst du dir merken, wann der Startzeitpunkt gewesen ist, und immer mit der Differenz zu diesem Zeitpunkt arbeiten.

Wenn es nie sofort nach Reset loslaufen soll, kannst du (Startzeit == 0) als Kennzeichen verwenden, dass erst noch auf die Auswahl und den Start gewartet wird.

Könntest du mir zu meinen zweiten sketch ein beispiel geben wie ich diesen startpunkt in der Menu funktion verwende? Oder ist es garnicht möglich Menü und den Timer unter einen Hut zu bekommen?

ist es garnicht möglich Menü und den Timer unter einen Hut zu bekommen?

Ich verstehe dein Problem nicht. Du wirst je nach Bedien-Zustand völlig unterschiedliche Menü Punkte haben:

  • Programm wahl
  • Start
  • Abbruch etc. und Anzeige von Temp. / Laufzeit

Ja genau. Ich weiß aber nicht, wie ich die Zeiten im Menü setup setzen kann, da die Programme ja im setup stehen und nicht im loop, und daher nicht die Zeit gezählt wird. Ich müsste das Programm anwählen und dann müsste die Regelung der Temperatur über einen zeitlichen Raum stattfinden. Und da komme ich nicht weiter. Probiere jetzt schon seit einigen Tagen dran rum, kann aber auch im Netz kein richtiges Beispiel finden wie ich es umsetzen kann.

da die Programme ja im setup stehen und nicht im loop, und daher nicht die Zeit gezählt wird.

?
Verstehe nicht, was du damit meinst.

Hallo,

so richtig verstehe ich das Problem auch nicht. Das was du im setup hast sind irgendwelche definierten Zeiten für die Dinge die so und so lange dauern sollen. Richtig? millis ist deine immer stetig fortlaufende Uhr. Deine Armbanduhr. Im realen Leben merkst du dir von deiner Armbanduhr zwei Uhrzeiten und kannst damit die Differenz ausrechnen die Vergangen ist. Diese millis Differenz vergleichst du mit deinen definierten Zeiten. Mehr ist das nicht. Ich hoffe das ich damit einigermaßen das Problem getroffen habe. Ansonsten hier nochmal lesen.

Theseus erklärt millis()
http://forum.arduino.cc/index.php?topic=400102.msg2752141#msg2752141

GuntherB - BlinkwithoutDelay - Die Nachtwächtererklärung
http://forum.arduino.cc/index.php?topic=423688.0

Hallo,
mir ist da auch noch nicht ganz klar was Du vorhast, hört sich aber interessant an.

Ich hab da jetz so verstanden.
Du willst feste Programme hinterlegen. Ein Program ist deffiniert duch die Anzahl verschiedener Zeite und oder Temperaturen. Du willlst keine Werte mit dem Menue eingeben, also keine Variable ändern. Du hast 3 Taster auf / ab / start.
miit auf oder ab wählst du eines der Programme aus und mit start wird das ausgewählte Programm gestartet.

Eigendlich bieten sich dazu Arrays oder noch besser Strukturen an. Jedes Programm hat eine Nummer (Index) mit der du dann Zugriff auf die Variablen hast.

Heinz

Am besten wäre es wenn ich mehrere Potis als Eingänge habe. Mit dem ich "endlich" viele Programme starten kann.

Poti 1 Einstellung der Temperaturzunahme um 10*C in einer bestimmten Zeit.
Poti 2 Einstellung der Maximalen Temperatur die gehalten werden Soll für den Tempervorgang
Poti 3 Einstellung der Temperzeit

Beispiel

Poti 1 10C in 30min
Poti 2 80
C
Poti 3 4Stunden

Der Arduino sollte nach dieser Einstellung alle 30min die Temperatur in der Kammer durch zuschalten der Heizelemente um 10C steigern bis die Endtemperatur von 80C erreicht ist. Dann soll die Temperatur für 4 Stunden gehalten werden und danach wie die Aufheizphase mit 10*C/30min Abkühlen.

Ist eine solche komplexe steuerung möglich, und wie kann ich vorgehen um ein Programm zu erstellen.

Hallo,

im Prinzip ist das machbar, ob das mit den Potis eine glückliche Lösung ist ist sicher Geschmackssache. Du kannst mit zwei /drei Tastern durch die Sollwerteingabe scrollen und die eingestellten Sollwerte abspeichern. Oder sind die Potis dann immer scharf und jederzeit änderbar?, Wie willst Du alles auf zwei Zeilen darstellen. Mit den Tastern auf/ ab kannst Du einen counter (Index ) bilden mit dem Du die verschieden Werte dann anzeigst. Das ergibt dann das Menue. Oder Du bekommst die 3 Werte ink. Text irgendwie auf die beiden Zeilen drauf. Analogwerte einlesen, skalieren und anzeigen ist sicher nicht das Problem. Irgendwie willst Du dann aber sicher auch noch den momentanen Sollwert und Istwert wärend des eigentlichen Ablaufs anzeigen. Also ohne Umschaltung der Anzeige wirds nicht gehen.

Ich sehe da aber ehr noch ein anderes Problem. Ich denke abgängig von dem Temperatur-Endwert und der Zeit wird der auch mit 1 oder 2 Heizstufen erreicht. Also mal angenommen Du willst wie in deinem Beispiel in 30 minuten 10 Grad ansteigen , dann musst Du ja bereits nach z.B 11 minuten entscheiden können ob das auch mit z.B 2 Stufen geht oder ob du drei benötigst. zu dem ist das ganze nicht Linear, denn es folt einer e-Funktion (Verzögerung 2. Ordnung) vereifacht angenommen. Also bei kleinen Temperaturen ist der Anstieg schneller als bei hohen Temperaturen.

Genau genommen benötigst Du da einen "Rampen Generator" als Sollwert für deine "Regelung" um bei dem Beispiel zu bleiben nach 3 minuten benötigst Du Startwert+1 Grad , nach 6 min Startwert+2 Grad usw. Das must Du dann bis 80 Grad so weiter treiben, und dann den Sollwert für 4 Stunden konstant halten.

Ob Du die Regelung jetzt mittels Vergleicher aufbaust oder einen P-I Regler nimmst muss man mal sehen. Denke aber ohne PI wurds nicht gehen. Hängt sicher auch von den Ofen-Verlusten und der installieren Heizleistung ab. Natürlich kannst Du auch erst mal so eine Art Versuchskurven fahren und die dazu erforderlichen Heizstufen ermitteln und dann damit weiterarbeiten, wir daber sicher ungenau und ne ewige lange Probiererei.

Alles in Allem ist das aber sicher schon ein anspruchsvolleres Projekt. Dennoch würde ich sagen das geht.

Heinz

Hi

Habe an einem Brenn-/Härteofen einen chinesischen Temperatur-Kontroller dran, Der eine Einlern-Phase besitzt, Der heizt 1x auf eine vorgegebene Temperatur auf und errechnet sich aus dem zeitlichen Verlauf, welche Werte für PID anzunehmen sind.
Funktionierte ganz gut - Ofen ist mittlerweile kaputt, da mir darin ein Glas-Unterleger geschmolzen ist und sich beim 'Ausbau' der innere Ofenaufbau mit demontieren ließ :confused:

Laut Wikipedia kann man einen PID-Regelkreis recht einfach zumindest rudimentär einstellen - man braucht halt mehrere Durchläufe, was bei einer kleinen Heizung aber durchaus machbar sein sollte.

MfG