Verständnisproblem: Arduino zu schnell??

Tach,
wollt mir ne geregelte Heizplatte zusammenbasteln, hat auch so weit alles gut funktioniert. Allerdings hab ich nu ein Problem bei der Software.

kurze Beschreibung der Hardware:

Heizplatte-----------SolidStateRelais--------------230V
| ^
v |
MAX6675----------------Arduino

Arduino schaltet mit Hilfe vom MAX6675 ermittelten Werte das SolidStateRelais, so war es zumindestens gedacht XD

hab beim testen aber nu gemerkt dass er die Temperatur nur ein einziges mal ausliest und zwar ganz am anfang
wenn ich nu n delay einbau klappts einwandfrei, wollte wegen der Regelung komplett auf delay verzichten

/*
 Programm für Geregelte Heizplatte aus Teilen vom alten Bügeleisen,
   + LCD-Display
   + Temperatur Messung mit Thermoelement und MAX6675
   + Rotary-Encoder für Temperatur-Einstellung
   
 */

// librarys
#include <LiquidCrystal.h>
#include <max6675.h>
#include <PID_v1.h>


// Pins 
#define RWPin 10
#define thermoDO 4
#define thermoCS 3
#define thermoCLK 12
#define encoder0PinA 2
#define encoder0PinB 13
#define SCHALTAUSGANG 10

// Variablen 
volatile unsigned int encoder0Pos = 20;
double IST = 0;
double SOLL = 0;
//                                                                  ====================
//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters                  Sachen für REGELUNG
PID myPID(&Input, &Output, &Setpoint,2,5,1, DIRECT);

int WindowSize = 1000;
unsigned long windowStartTime;
//                                                                  ====================


// LCD init.  lcd(RS, EN, D4, D5, D6, D7)  R/W auf GND
LiquidCrystal lcd(9, 11, 8, 7, 6, 5);

// MAX6675 init.
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

// make a cute degree symbol
uint8_t degree[8]  = {140,146,146,140,128,128,128,128};

// ////////////////////////////////////////  SETUP ////////////////////////////////
void setup() {
   pinMode (encoder0PinA,INPUT);
   pinMode (encoder0PinB,INPUT);
   pinMode (SCHALTAUSGANG,OUTPUT);
   Serial.begin (9600);
   
   attachInterrupt(0, doEncoder, CHANGE); 
//                                                                  ====================   
   windowStartTime = millis();
  
   //initialize the variables we're linked to
   Setpoint = 100;

   //tell the PID to range between 0 and the full window size      Sachen für REGELUNG
   myPID.SetOutputLimits(0, WindowSize);

   //turn the PID on
   myPID.SetMode(AUTOMATIC);
//                                                                  ====================   
   pinMode(RWPin, OUTPUT);
   digitalWrite(RWPin, LOW);
   
   // set up the LCD's number of columns and rows: 
   lcd.begin(16,2);
   lcd.createChar(0, degree);
}

// ////////////////////////////////////////// LOOP ////////////////////////////////
void loop() {
  
   // Temperatur einlesen
   Input = thermocouple.readCelsius();
   Setpoint =  encoder0Pos;
   myPID.Compute();                          //    <- Regelungsberechnung

   
   Serial.print(Setpoint);
   Serial.print(" / ");
   Serial.print(Input);
   Serial.print(" / ");
   Serial.print(Output);
    
   unsigned long now = millis();
   if(now - windowStartTime>WindowSize)
   { //time to shift the Relay Window                                          REGELUNG
     windowStartTime += WindowSize;
   }
   if(Output > now - windowStartTime) {
     digitalWrite(SCHALTAUSGANG,HIGH);
    Serial.println("    high");
   }
   else {
     digitalWrite(SCHALTAUSGANG,LOW);
     Serial.println("    low");
   }
 
  // Ausgabe auf LCD
  lcd.setCursor(1, 0);
  lcd.print("IST: ");
  lcd.print(Input);
  lcd.print(0, BYTE);
  lcd.print("C ");
  lcd.setCursor(0, 1);
  lcd.print("SOLL: ");
  lcd.print(encoder0Pos);
  lcd.print(0, BYTE);
  lcd.print("C ");
  lcd.print("   ");
  if (SCHALTAUSGANG == HIGH){
    lcd.print("*");
   }
  //lcd.clear();
  delay(500);
}

void doEncoder() {
  if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) {
    encoder0Pos++;
  } else {
    encoder0Pos--;
  }
  if (encoder0Pos == 19) {encoder0Pos++;}        // Begrenzung auf > 0
  if (encoder0Pos == 300) {encoder0Pos--;}      // Begrenzung auf < 100
}

weiss da zufällig jmd warum dies so ist?

edit:
hab noch mal n bissl rumgetestet und gluab das hängt irgendwie mit der Kommunikation mitn LCD zusammen.
hab das LCD-ausgabe in eine Funktion getan und beim Aufruf jeweils vor und hinter ein delay von 100 getan -> funzt
schon auf jeden fall ne verbesserung zum 500er delay, aber immer noch nicht so wie gewünscht

geänderter Coder:

/*
 Programm für Geregelte Heizplatte aus Teilen vom alten Bügeleisen,
   + LCD-Display
   + Temperatur Messung mit Thermoelement und MAX6675
   + Rotary-Encoder für Temperatur-Einstellung
   
 */

// librarys
#include <LiquidCrystal.h>
#include <max6675.h>
#include <PID_v1.h>


// Pins 
#define RWPin 10
#define thermoDO 4
#define thermoCS 3
#define thermoCLK 12
#define encoder0PinA 2
#define encoder0PinB 13
#define SCHALTAUSGANG 10

// Variablen 
volatile unsigned int encoder0Pos = 20;
int IST = 0;
int SOLL = 0;
//                                                                  ====================
//Regelungs-Variablen
double Setpoint, Input, Output;

//Regel-Parameter und Variablen aufzeigen                  Sachen für REGELUNG
//                                 Kp,Ki,Kd
PID myPID(&Input, &Output, &Setpoint,1,1,4, DIRECT);            //REVERSE      DIRECT

int WindowSize = 1000;
unsigned long windowStartTime;
//                                                                  ====================


// LCD        (RS, EN, D4, D5, D6, D7)  R/W auf GND
LiquidCrystal lcd(9, 11, 8, 7, 6, 5);

// MAX6675 init.
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

// Grad-Symbol für Display
uint8_t degree[8]  = {140,146,146,140,128,128,128,128};

// ////////////////////////////////////////  SETUP ////////////////////////////////
void setup() {
   pinMode (encoder0PinA,INPUT);
   pinMode (encoder0PinB,INPUT);
   pinMode (SCHALTAUSGANG,OUTPUT);
   Serial.begin (9600);
   
   attachInterrupt(0, doEncoder, CHANGE); 
//                                                                  ====================   
   windowStartTime = millis();
  
   //initialisierung der Regelungs-Variablen
   Setpoint = 100;

   //tell the PID to range between 0 and the full window size      Sachen für REGELUNG
   myPID.SetOutputLimits(60, WindowSize);

   //turn the PID on
   myPID.SetMode(AUTOMATIC);
//                                                                  ====================   
   pinMode(RWPin, OUTPUT);
   digitalWrite(RWPin, LOW);
   
   //LCD Initialisieren
   lcd.begin(16,2);
   lcd.createChar(0, degree);
}

// ////////////////////////////////////////// LOOP ////////////////////////////////
void loop() {
  // Temperatur einlesen
   Input = thermocouple.readCelsius();
   Setpoint =  encoder0Pos;
   myPID.Compute();                          //    <- Regelungsberechnung
   
   Serial.print(Setpoint);
   Serial.print(" / ");
   Serial.print(Input);
   Serial.print(" / ");
   Serial.print(Output);
    
   unsigned long now = millis();
   if(now - windowStartTime>WindowSize)
   { //time to shift the Relay Window                                          REGELUNG
     windowStartTime += WindowSize;
   }
   if(Output > now - windowStartTime) {
     digitalWrite(SCHALTAUSGANG,HIGH);
    Serial.println("    high");
   }
   else {
     digitalWrite(SCHALTAUSGANG,LOW);
     Serial.println("    low");
   }
   
   
   delay(100);
   doDisplay(Input,encoder0Pos);
   delay(100);
   
}

void doEncoder() {
  if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) {
    encoder0Pos++;
  } else {
    encoder0Pos--;
  }
  if (encoder0Pos == 19) {encoder0Pos++;}        // Begrenzung auf > 0
  if (encoder0Pos == 200) {encoder0Pos--;}      // Begrenzung auf < 100
}

void doDisplay(int IST,int SOLL) {
  lcd.setCursor(1, 0);
  lcd.print("IST: ");
  lcd.print(IST);
  lcd.print(0, BYTE);
  lcd.print("C ");
  lcd.setCursor(0, 1);
  lcd.print("SOLL: ");
  lcd.print(SOLL);
  lcd.print(0, BYTE);
  lcd.print("C ");
  lcd.print(" ");
  if (SCHALTAUSGANG == HIGH){
    lcd.print("*");
   }
  //lcd.clear();
}

greetz
akrlfix

void doDisplay(int IST,int SOLL) {
  static double IST_alt = 0;
  static double SOLL_alt = 0;

  if(    !(  (SOLL == SOLL_alt) && (IST == IST_alt)  )   ) {
    // was neues zu tun ?
    lcd.setCursor(1, 0);
    lcd.print("IST: ");
    lcd.print(IST);
    lcd.print(0, BYTE);
    lcd.print("C ");
    lcd.setCursor(0, 1);
    lcd.print("SOLL: ");
    lcd.print(SOLL);
    lcd.print(0, BYTE);
    lcd.print("C ");
    lcd.print(" ");
    if (SCHALTAUSGANG == HIGH){
      lcd.print("*");
     }
    //lcd.clear();
  }
  IST_alt = IST;
  SOLL_alt = SOLL;
}

thx für die nette abfrage, hat aber leider auch net gefunzt
habs jetzt mit ner millis()-Abfrage gelöst und n intervall von einer sekunde, er liest also jetzt jede sekunde die temp und alles ohne delay, jhuh :smiley:
jetzt noch die regelparameter einstellen :expressionless:

/*
 Programm für Geregelte Heizplatte aus Teilen vom alten Bügeleisen,
   + LCD-Display
   + Temperatur Messung mit Thermoelement und MAX6675
   + Rotary-Encoder für Temperatur-Einstellung
   
 */

// librarys
#include <LiquidCrystal.h>
#include <max6675.h>
#include <PID_v1.h>


// Pins 
#define RWPin 10
#define thermoDO 4
#define thermoCS 3
#define thermoCLK 12
#define encoder0PinA 2
#define encoder0PinB 13
#define SCHALTAUSGANG 10

// Variablen 
long interval = 1000;
volatile long previousMillis = 0;
volatile unsigned int encoder0Pos = 20;
int IST = 0;
int SOLL = 0;
//                                                                  ====================
//Regelungs-Variablen
double Setpoint, Input, Output;

//Regel-Parameter und Variablen aufzeigen                  Sachen für REGELUNG
//                                 Kp,Ki,Kd
PID myPID(&Input, &Output, &Setpoint,1,1,4, DIRECT);            //REVERSE      DIRECT

int WindowSize = 1000;
unsigned long windowStartTime;
//                                                                  ====================


// LCD        (RS, EN, D4, D5, D6, D7)  R/W auf GND
LiquidCrystal lcd(9, 11, 8, 7, 6, 5);

// MAX6675 init.
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO);

// Grad-Symbol für Display
uint8_t degree[8]  = {140,146,146,140,128,128,128,128};

// ////////////////////////////////////////  SETUP ////////////////////////////////
void setup() {
   pinMode (encoder0PinA,INPUT);
   pinMode (encoder0PinB,INPUT);
   pinMode (SCHALTAUSGANG,OUTPUT);
   Serial.begin (9600);
   
   attachInterrupt(0, doEncoder, CHANGE); 
//                                                                  ====================   
   windowStartTime = millis();
  
   //initialisierung der Regelungs-Variablen
   Setpoint = 100;

   //tell the PID to range between 0 and the full window size      Sachen für REGELUNG
   myPID.SetOutputLimits(30, WindowSize);

   //turn the PID on
   myPID.SetMode(AUTOMATIC);
//                                                                  ====================   
   pinMode(RWPin, OUTPUT);
   digitalWrite(RWPin, LOW);
   
   //LCD Initialisieren
   lcd.begin(16,2);
   lcd.createChar(0, degree);
}

// ////////////////////////////////////////// LOOP ////////////////////////////////
void loop() {
  
    unsigned long currentMillis = millis();
    if(currentMillis - previousMillis > interval) {
      previousMillis = currentMillis;  
      Input = thermocouple.readCelsius();
      Serial.println(Input);
     }
    
  // Temperatur einlesen
   Setpoint =  encoder0Pos;
   myPID.Compute();                          //    <- Regelungsberechnung
   
   Serial.print(Setpoint);
   Serial.print(" / ");
   Serial.print(Input);
   Serial.print(" / ");
   Serial.print(Output);
    
   unsigned long now = millis();
   if(now - windowStartTime>WindowSize)
   { //time to shift the Relay Window                                          REGELUNG
     windowStartTime += WindowSize;
   }
   if(Output > now - windowStartTime) {
     digitalWrite(SCHALTAUSGANG,HIGH);
    Serial.println("    high");
   }
   else {
     digitalWrite(SCHALTAUSGANG,LOW);
     Serial.println("    low");
   }
   
   doDisplay(Input,encoder0Pos);
  
}

void doEncoder() {
  if (digitalRead(encoder0PinA) == digitalRead(encoder0PinB)) {
    encoder0Pos++;
  } else {
    encoder0Pos--;
  }
  if (encoder0Pos == 19) {encoder0Pos++;}        // Begrenzung auf > 0
  if (encoder0Pos == 200) {encoder0Pos--;}      // Begrenzung auf < 100
}

void doDisplay(int IST,int SOLL) {
  static double IST_alt = 0;
  static double SOLL_alt = 0;

  if(    !(  (SOLL == SOLL_alt) && (IST == IST_alt)  )   ) {
    // was neues zu tun ?
    lcd.setCursor(1, 0);
    lcd.print("IST: ");
    lcd.print(IST);
    lcd.print(0, BYTE);
    lcd.print("C ");
    lcd.setCursor(0, 1);
    lcd.print("SOLL: ");
    lcd.print(SOLL);
    lcd.print(0, BYTE);
    lcd.print("C ");
    lcd.print(" ");
    if (SCHALTAUSGANG == HIGH){
      lcd.print("*");
     }
     //lcd.clear();
     IST_alt = IST;
     SOLL_alt = SOLL;
  }

}

Datenblatt seite 2: conversion time 0.22s ... das sollte alles erklaeren.

ahh, thx :smiley: