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

Aufbau

Foto von https://xplore-dna.net/mod/page/view.php?id=1495

FHEM:

define nt_KuehlschrankSchimmelschutz notify TPLKS:Taupunkt_Abstand:.* { my $val = int($EVTPART1 * 10);;;; fhem(„set TPLKS percentage1 $val“) }

 

/**
* ====================================================================
* MySensors PC-Lüfter-Steuerung mit IRLZ34N MOSFET & DHT22
* ====================================================================
* Hardware: ARDUINO UNO (Gate an PIN 3, DHT22 an PIN 4)
* Frequenz: 3,92 kHz Fast-PWM
*
* Bereinigte Version: Schaltet AUSSCHLIESSLICH über Prozentwerte (0-100).
* Der ungenutzte Ein/Aus-Status (V_STATUS) wurde komplett entfernt.
*/

#define MY_RADIO_RF24
//#define MY_DEBUG

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

#define CHILD_ID_FAN 1 // Lüfter Steuerung (Nur Slider / Prozent)
#define CHILD_ID_RPM 2 // Berechnete Drehzahl
#define CHILD_ID_TEMP 3 // Temperatur (DHT22)
#define CHILD_ID_HUM 4 // Luftfeuchtigkeit (DHT22)
#define CHILD_ID_DEW 5 // Berechneter Taupunkt

const byte PWM_PIN = 3;
const byte DHT_PIN = 4;

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

const word MAX_FAN_RPM = 1500; // Maximale Drehzahl deines Lüfters
int currentSpeed = 50; // Startgeschwindigkeit bei Erststart

// Zeitsteuerung für die Sendeintervalle (in Millisekunden)
unsigned long lastSendTimeRPM = 0;
unsigned long lastSendTimeKlima = 0;
const unsigned long INTERVAL_RPM = 10000;
const unsigned long INTERVAL_KLIMA = 30000;

// MySensors Nachrichtentypen
MyMessage msgFanSpeed(CHILD_ID_FAN, V_PERCENTAGE);
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);

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

// Timer 2 Modifikation für fiepfreie 3,92 kHz am Pin 3
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 Pure Pct“, „3.3“);
wait(200);

present(CHILD_ID_FAN, S_DIMMER, „PC Luefter Regler“);
wait(200);
present(CHILD_ID_RPM, S_POWER, „Luefter Drehzahl“);
wait(200);
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;
// Die Berechnung greift nun direkt auf den Prozentwert (currentSpeed) zu
word calculatedRPM = (word)((float)currentSpeed * (float)MAX_FAN_RPM / 100.0);
send(msgFanRPM.set(calculatedRPM));
}

// ZYKLUS 2: Klima alle 30 Sekunden messen
if (currentTime – lastSendTimeKlima >= INTERVAL_KLIMA) {
lastSendTimeKlima = currentTime;

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

if (!isnan(temperature) && !isnan(humidity)) {
float a = 17.625;
float b = 243.04;
float alpha = ((a * temperature) / (b + temperature)) + log(humidity / 100.0);
float dewPoint = (b * alpha) / (a – alpha);

send(msgTemp.set(temperature, 1));
send(msgHum.set(humidity, 1));
send(msgDew.set(dewPoint, 1));
}
}
}

// Reagiert NUR noch auf den Prozent-Slider aus FHEM
void receive(const MyMessage &message) {
if (message.sensor == CHILD_ID_FAN && message.type == V_PERCENTAGE) {

currentSpeed = message.getInt();
if (currentSpeed > 100) currentSpeed = 100;
if (currentSpeed < 0) currentSpeed = 0;

saveState(CHILD_ID_FAN, currentSpeed);

// Prozentwert linear in Hardware-PWM (0-255) übersetzen
int pwmValue = (currentSpeed * 255) / 100;
analogWrite(PWM_PIN, pwmValue);

// Aktuelle RPM berechnen
word calculatedRPM = (word)((float)currentSpeed * (float)MAX_FAN_RPM / 100.0);

// Status an FHEM zurückmelden
send(msgFanSpeed.set(currentSpeed));
send(msgFanRPM.set(calculatedRPM));
}
}