Taupunktlüfter für Kühlschrank und Hauswand ca. 2cm mit FHEM MYSENSORS DHT22 MOSFET IRLZ34N 12V PV Lüfter 4Pin PWM

/**
* MySensors PC-Lüfter-Steuerung mit IRLZ34N MOSFET & DHT22 Klimasensor
* Hardware: ARDUINO UNO
* – Gate des IRLZ34N: PIN 3 (3,92 kHz Fast-PWM)
* – DHT22 Datenleitung: PIN 4
* Feature: Berechnet RPM, Temperatur, Feuchte und den Taupunkt lokal auf dem Uno
*/

#define MY_RADIO_RF24
//#define MY_DEBUG // Einkommentieren für den Seriellen Monitor (9600 Baud)

#include <MySensors.h>
#include <DHT.h>

// 1. PIN & SENSOR ID DEFINITIONEN
#define CHILD_ID_FAN 1
#define CHILD_ID_RPM 2
#define CHILD_ID_TEMP 3
#define CHILD_ID_HUM 4
#define CHILD_ID_DEW 5 // Neue ID für den Taupunkt

const byte PWM_PIN = 3;
const byte DHT_PIN = 4; // DHT22 Datenleitung an Pin 4

#define DHTTYPE DHT22
DHT dht(DHT_PIN, DHTTYPE);

// 2. KONSTANTEN & VARIABLEN
const word MAX_FAN_RPM = 2000;

int currentSpeed = 50;
bool currentStatus = false;

// Zeitsteuerung (Alle 30 Sekunden das Klima messen, alle 10 Sekunden RPM senden)
unsigned long lastSendTimeRPM = 0;
unsigned long lastSendTimeKlima = 0;
const unsigned long INTERVAL_RPM = 10000;
const unsigned long INTERVAL_KLIMA = 30000;

// MySensors Nachrichtenobjekte
MyMessage msgFanSpeed(CHILD_ID_FAN, V_PERCENTAGE);
MyMessage msgFanStatus(CHILD_ID_FAN, V_STATUS);
MyMessage msgFanRPM(CHILD_ID_RPM, V_WATT);
MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
MyMessage msgHum(CHILD_ID_HUM, V_HUM);
MyMessage msgDew(CHILD_ID_DEW, V_TEMP); // Taupunkt wird ebenfalls als V_TEMP übertragen

void before() {
pinMode(PWM_PIN, OUTPUT);

// 3,92 kHz Fast-PWM für Timer 2 (Pin 3) initialisieren
TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20);
TCCR2B = _BV(CS21);

analogWrite(PWM_PIN, 0);
dht.begin();
}

void setup() {
currentSpeed = loadState(CHILD_ID_FAN);
if (currentSpeed < 0 || currentSpeed > 100) {
currentSpeed = 50;
}
}

void presentation() {
sendSketchInfo(„Uno Fan & DHT22 Node“, „3.0“);
wait(200);

present(CHILD_ID_FAN, S_DIMMER, „PC Luefter Regler“);
wait(200);
present(CHILD_ID_RPM, S_POWER, „Luefter Drehzahl“);
wait(200);

// DHT22 Sensoren im Gateway anmelden
present(CHILD_ID_TEMP, S_TEMP, „Temperatur“);
wait(200);
present(CHILD_ID_HUM, S_HUM, „Luftfeuchtigkeit“);
wait(200);
present(CHILD_ID_DEW, S_TEMP, „Taupunkt“);
}

void loop() {
unsigned long currentTime = millis();

// ZYKLUS 1: RPM alle 10 Sekunden senden
if (currentTime – lastSendTimeRPM >= INTERVAL_RPM) {
lastSendTimeRPM = currentTime;
word calculatedRPM = 0;
if (currentStatus) {
calculatedRPM = (word)((float)currentSpeed * (float)MAX_FAN_RPM / 100.0);
}
send(msgFanRPM.set(calculatedRPM));
}

// ZYKLUS 2: DHT22 & Taupunkt alle 30 Sekunden auslesen
if (currentTime – lastSendTimeKlima >= INTERVAL_KLIMA) {
lastSendTimeKlima = currentTime;

float temperature = dht.readTemperature();
float humidity = dht.readHumidity();

// Prüfen ob das Auslesen des DHT22 geklappt hat
if (!isnan(temperature) && !isnan(humidity)) {

// 🧮 Taupunkt-Berechnung via Magnus-Formel
float a = 17.625;
float b = 243.04;
float alpha = ((a * temperature) / (b + temperature)) + log(humidity / 100.0);
float dewPoint = (b * alpha) / (a – alpha);

// Werte an das FHEM-Gateway übertragen
send(msgTemp.set(temperature, 1));
send(msgHum.set(humidity, 1));
send(msgDew.set(dewPoint, 1));
}
}
}

void receive(const MyMessage &message) {
if (message.sensor == CHILD_ID_FAN) {
if (message.type == V_PERCENTAGE) {
currentSpeed = message.getInt();
currentStatus = (currentSpeed > 0);
saveState(CHILD_ID_FAN, currentSpeed);
}
else if (message.type == V_STATUS) {
currentStatus = message.getBool();
if (currentStatus && currentSpeed == 0) {
currentSpeed = 50;
}
}

word calculatedRPM = 0;
if (currentStatus) {
int pwmValue = (currentSpeed * 255) / 100;
analogWrite(PWM_PIN, pwmValue);
calculatedRPM = (word)((float)currentSpeed * (float)MAX_FAN_RPM / 100.0);

send(msgFanStatus.set(true));
send(msgFanSpeed.set(currentSpeed));
} else {
analogWrite(PWM_PIN, 0);
send(msgFanStatus.set(false));
calculatedRPM = 0;
}
send(msgFanRPM.set(calculatedRPM));
}
}

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert