PWM je nach Messwert ändern

Hallo zusammen!
Ich probiere mit meinem Arduino UNO eine Temperaturschaltung zu bauen. Diese sieht wie folgt aus:
Mit einem LM35 wird die Temperatur gemessen, über ein Poti wird eine Zahl eingestellt. Nun soll je nach größe der Temperatur (im Verhältniss zur Zahl vom Poti) das PWM Signal geändert werden. Hintergrund ist, das die Temperatur nicht über den Wert der Potizahl kommen soll, sich aber nachher asymptotisch daran annähern soll.
Hat irgendjemand eine Idee wie man das machen kann? Mit meinem Code klappts nicht so ganz...

float celsius1 = 0;    //storage for Temperature 1
float setcelsius = 0;  //storage for the Temperature set

void setup()
{
  Serial.begin(9600);                            //Allow the board to communicate with computer
  Serial.println("Temperaturmessung");   //caption on monitor
  pinMode(11,OUTPUT);
}


void loop()
{
  findTemps();                           //function mesuring the temperatures
  setTemps();                            //function to set the temperature
  displayTemps();                        //function displaying the temperatures
  delay(1000);
  heat1(); 
}


void findTemps()
{
  float sensor1 = 0;
  
  //Read the temperature and convert to °C
  
  sensor1 = analogRead(0);
  celsius1 = (5.0 * sensor1 * 100.0) / 1024;
  delay(5);
}


void displayTemps()
{
  
  Serial.print ("Temperatur 1 ist");
  Serial.print (celsius1 , 2);
  Serial.println (" °C ");

  Serial.print("Temperatur soll");      //temperatur set
  Serial.print (setcelsius , 2 );
  Serial.println(" °C "); 
}

void setTemps()
{
  float poti = 0;
  
  poti = analogRead(3);
  setcelsius = poti / 40;
  setcelsius = setcelsius + 15;
  delay(5);
 }

void heat1()
{
  int d;

  for (setcelsius - 20 < celsius1 ; d=255;)
  for (setcelsius - 20 < celsius1 < setcelsius - 10 ; d = 255 ;)
  for (setcelsius - 10 < celsius1 < setcelsius - 5 ; d = 180 ;)
  for (setcelsius - 5 < celsius1 < setcelsius - 3 ; d = 50 ;)
  for (setcelsius - 3 < celsius1 < setcelsius - 1 ; d = 25 ;)
  for (setcelsius - 1 < celsius1 < setcelsius ; d = 10 ;)
  for (celsius1 < setcelsius ; d = 0 ;)
 
  analogWrite(11,d);
  delay(200);
  analogWrite(11,0);

  delay(100);
}

vielen Dank schonmal im Vorraus!

Was klappt mit deinem Sketch, was nicht?

Fange erst einmal an, die delay() mit der millis() Methode umzuschreiben. Die Funktion sollte verboten und aus der Arduino IDE entfernt werden. ]:smiley:
delay() hält dein Programm nur unnötig auf, es arbeitet in dem Moment wo es steht nicht weiter.

Dann ist dein Subfunktion heat1() schlecht geschrieben. Das geht ohne for-schleifen, zumal ich mir nicht mal sicher bin ob die so überhaupt funktionieren.
Der dreht sich doch ganze Zeit da im Kreis, wenn der Wert nicht unwahr wird.

for-Schleifen sind nicht die einzigen Schleifen in der Arduino IDE, die du nutzen kannst. Mit einer einfachen if-Abfrage ist es noch nicht schön gelöst, aber defenitv besser.

byte wertPwm;
if(cSet - 20 < c) wertPwm = 100;

Wenn du dich in die millis() "Verzögerung" einarbeitest, wird dir evtl. eine Möglichkeit einfallen, wie dieser Ansatz.

"wenn cSet - 20 < c länger als x millis wahr ist, erhöhe den PWM Wert um y.

Eventuell kannst du uns ein bisschen zu dem Anwenungsgebiet sagen. Heizungssteuerung? Es gibt auch richtige Regelungen für sowas. Müsste man schaun, in wie fern diese in Arduino möglich sind, wobei ich fest davon ausgehe. Zauberwort nennt sich hier P-Regler, PID-Regler, .....

Die Subfunktion setTemps kannst du ebenfalls einkürzen,

cSet = (poti / 40) + 15;

Ich kenne den LM35 selber nicht, aber in der Playground haben sie es einfacher gelöst und dem Datenblatt nach ist dieser relativ einfach auszuwerten. Er gibt eine Spannung aus, die du mit den Analog Pins auswerten kannst.

0 mV + 10.0 mV/°C

http://playground.arduino.cc/Main/LM35HigherResolution

der LM35 funktioniert...

Nur eben habe ich das Problem, das mir die heat1 Funktion den ganzen Rest blockiert...sprich: ist sie drin bekomme ich einen Messwert der Temperatur und das wars, ohne heat1 jede Sekunde...

es geht einfach um eine Wasserheizung, sprich träge...
genaue Eigenschaften kenne ich nicht, die wollte ich damit experimentell herausfinden um die PWM Leistung dann anzupassen....

Hab als du das geschrieben hast, meinen Beitrag angepasst. Hatte befürchtet das heat() nicht klappt, da solange die Bedingung nicht true ist, nicht weitergemacht wird :wink:

Wenn Du eine Temperaturregelung bauen willst, dann würde ich die PID Library vorschlagen: Arduino Playground - PIDLibrary. Mittlerweile gibt es die auch mit autotune. Das ist garantiert besser als alles was man mal einfach so aus dem Handgelenk schüttelt.

Zunächst, wie schon beschrieben: alle delay() raus.

Dann wirst du mit deinem "Stufenautomaten" keine vernünftige Regelung hinbekommen.
Was du da baust ist ja ein P-Regler mit stark nichtlinarer, gestufter Kennlinie. Das wird so nicht vernünftig funktionieren.
Für eine Temperaturregelung brauchst du mindestens einen I-Regler, besser einen PI-Regler.
Du kannst ja mal bei Wikipedia zum Thema Regler nachlesen.

Am einfachsten ist es wirklich, wenn du die PID-Library nimmst.
Den D-Anteil brauchst bei Temperaturregelung nicht, den kannst du zu Null setzen.
Das wird besser funktionieren, als jeder selbstgebaute Regler.