Arduino Uno Lüfersteuerung mit Drehgeber / PWM Problem

Hallo zusammen, ich bin gerade dabei ein Lüftersteuerung aufzubauen die sich selbst nach einem eingegebenen Sollwert regelt. Die Programmteile habe ich aus verschiedenen Vorlagen zusammenkopiert und nach bestem Wissen auf meine Bedürfnisse angepasst. Generell war die Funktion bisher auch gegeben!

Ich habe heute den Temperatursensor von einem DHT 11 auf einen DS18B20 gewechselt, da der DHT zu ungenau war.

Seitdem habe ich das Problem, dass meine 4 parallel geschalteten Lüfter in der "Stufe LOW" anlaufen und kurze Zeit später wieder ausgehen. Dabei wird der Temperaturwert des Temperatursensors kurz auf -127 °C angezeigt. Das geschieht immer nur in der Stufe Low und selten in der Stufe 1. Mit dem DHT hatte ich diese Probleme nicht und die Lüfter liefen sauber auf kleinster Stufe! Ich vermute das der one wire Temperatursensor mit der PWM Steuerung für die Lüfter "durcheinander" kommt. Mir fehlt leider die Erfahrung um hier weiterzukommen.

Wer kann helfen?

Verwendete Hardware:

  • Arduino Uno
  • 12V externe Spannungsversrgung
  • Temperatursensor DS18B20
  • 4x IRF520 Treiber Modul (parallel angeschlossen)
  • Rotary Encoder um die Solltemperatur einzugeben

So verhält sich das Problem: Dropbox - File Deleted

So schaut der Sketch aus:

// Library for I2C / TWI device communication
#include <Wire.h>

// Library to control the LCD screen
#include <LiquidCrystal_I2C.h>

// Library to control Temperature Controler
#include <OneWire.h>
#include <DallasTemperature.h>


/* 
 * Set the correct chip for your LCD
 * Use 0x27 when you have the PCF8574 chip made by NXP
 * The last two digits represent the LCD size
 * e.g. 20x4 or 16x2
 */ 
LiquidCrystal_I2C lcd(0x27, 20, 4);

float solltemp = 25;                              // Setze solltemperatur auf Startwert

volatile int pinA = 4;                            // Rotary encoder Pin A
int pinB = 3;                                     // Rotary encoder Pin B
volatile int pinAstateCurrent = LOW;              // Current state of Pin A
volatile int pinAStateLast = pinAstateCurrent;    // Last read value of Pin A

//====================================== Temperatureinstellungen
#define stufe1 solltemp+1
#define stufe2 solltemp+2
#define stufe3 solltemp+3
#define stufe4 solltemp+4
#define stufe5 solltemp+5
//==============================================================


#define ONE_WIRE_BUS 2                     //Datenbus für onewire ist auf 2 gesteckt
#define FanPin 9                           //Lüfter Pin setzen

OneWire oneWire(ONE_WIRE_BUS);            // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
DallasTemperature sensors(&oneWire);      // Pass oneWire reference to Dallas Temperature.


float temp;
String status;


void setup() {
  pinMode (pinA, INPUT);                    // Set PinA as input
  pinMode (pinB, INPUT);                    // Set PinB as input
  pinMode(FanPin,OUTPUT);                   // Set FanPin as output


// Einstellung der PWM Frequenz //
TCCR1B = TCCR1B & B11111000 | B00000001;    // set timer 1 divisor to     1 for PWM frequency of 31372.55 Hz

  
// Atach a CHANGE interrupt to PinB and exectute the update function when this change occurs.
attachInterrupt(digitalPinToInterrupt(pinB), update, CHANGE);

// LCD
  lcd.init();                         // initialise the LCD
  lcd.backlight();                    // turn backlight on

//i°2 Sensoren 
  sensors.begin();                    // Startup the library
  
}

void loop() {
sensors.requestTemperatures();        // Send the command to get temperatures

delay(500);                           //Verzögerung

temp = sensors.getTempCByIndex(0);    //Ausgelesene Temperatur in Variable schreiben

//Show on LCD
lcd.setCursor(0,0);
lcd.print("L\365ftersteuerung");
lcd.setCursor(0,1);
lcd.print("Aktuell: ");
lcd.print(temp);
lcd.print("\337C");
lcd.setCursor(0,2);
lcd.print("Soll: ");
lcd.print(solltemp);
lcd.print("\337C");
lcd.setCursor(0,3);
lcd.print("Status: ");
lcd.print(status);


//Control FAN
if (temp <= solltemp) { digitalWrite(FanPin,LOW); status = "AUS      "; }else
if (temp >= stufe5) { digitalWrite(FanPin,HIGH); status = "Stufe-MAX"; }else
if (temp >= stufe4) { analogWrite(FanPin,195); status = "Stufe-4  "; }else
if (temp >= stufe3) { analogWrite(FanPin,155); status = "Stufe-3  "; }else
if (temp >= stufe2) { analogWrite(FanPin,125); status = "Stufe-2  "; }else
if (temp >= stufe1) { analogWrite(FanPin,45); status = "Stufe-1  "; }else
if (temp >= solltemp) { analogWrite(FanPin,25); status = "Stufe-LOW";}


  
}

//Update Funkiton
void update() {

  // ROTATION DIRECTION
  pinAstateCurrent = digitalRead(pinA);    // Read the current state of Pin A
  
  // If there is a minimal movement of 1 step
  if ((pinAStateLast == LOW) && (pinAstateCurrent == HIGH)) {
    
    if (digitalRead(pinB) == HIGH) {      // If Pin B is HIGH
      solltemp++;            
    } else {
      solltemp--;
    }
  }
  
  pinAStateLast = pinAstateCurrent;        // Store the latest read value in the currect state variable
 
  

}```

Normal sollte die Dallas Lib sorgen für Verzögerung, den die Zeit zum messen der Temp ist um die 750ms.
Mach mal dein delay auf 900

Das habe ich schon versucht leider kein Erfolg. Die Temperatur ist bei mir auch auffällig instabil und springt um die 0,5 Grad beim Lesen eines neuen Werts...

Dan hast Du schlechten Sensor erwischt, alle unter 3,60€ sind nachbauten.
Habe gerade auch mit DS18B20 rumgespielt meine 5 zeigen um 2°C zu viel aber alle Konstant.
Bin allerdings auf DS18B20.h umgestiegen, die Dallas Lib hat bei mir irgend welsche Probleme gemacht ist aber einige Zeit her. Mit der DS18B20.h wird folgender Maßen ausgelesen

#include <DS18B20.h>
DS18B20 ds(12);
float temp;

byte gradZeichen[] = {
  B00011,
  B00011,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000
};
void setup() {

  ds.setResolution(12);
}

void loop() {
  temp = ds.getTempC();  // Temperatur auslesen
  lcd.print(temp, 1);
  lcd.write(byte(0));
  lcd.print("C");

}

Ok versuche ich einmal umzubauen, danke. Oben im Post habe ich mal ein Video verlinkt...

Die zwei Nachkommastellen kannst dir sparen, mach eine

lcd.print("Aktuell: ");
lcd.print(temp,1);

Und damit das Grad Zeichen auch in richtiger Stelle ist benutze ich selbst definierten Zeichen,
im Beispiel #4 eingefügt

Du kannst Meßwerte, die nicht plausibel sind, einfach in der Mittelwertberechnung nicht berücksichtigen bzw ignorieren.
Darunter verstehe ich unmögliche Werte wie zB -127°C aber auch solche die Sprünge haben Du mißt 25°C wenn nun plötzlich 15°C gemessen wird ist was faul weil der Sensor im normalen Gebrauch (Messung Lufttemperatur) in 1 Sekunde nicht um 10° abgekühlt / erwärmt werden kann.

Dann Genauigkeit:
Aus dem Datenblättern:

DHT11:
Resolution:16Bit
Repeatability:±1°C
Accuracy:25°C ±2°C
Response time:1/e (63%) 10S
DS18B20:
Resolution:9 to 12 bit
Accuracy: ±0.5°C Accuracy from -10°C to +85°C
±2°C Accuracy from -55°C to +125°C

Für beide sind Dezimalstellen reines Rätselraten.

Grüße Uwe

Hallo Uwe ja stimmt ich habe den Sketch nach Vorschlag von fony umgebaut, leider hatte ich immer noch das Problem, dass die Werte in der LOW - Stufe springen. zwar nicht mehr bis -127 dafür jetzt bis -0,5. Zudem habe ich Temperatursprünge von ca 2 Grad im Sekundentakt. Wie du schon geschrieben hast ist die Temperatur viel zu träge um unter normalen Bedingungen so zu springen. Ich habe versucht das Problem einzugrenzen und den dritten Temperatursensor angeschlossen. Siehe da jetzt bis jetzt sind die Temperaturwerte stabil. Ein MOS Fet zur Ansteuerung der Lüfter hat auch noch Probleme gemacht. Schlussendlich läuft es jetzt aber.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.