Hallo zusammen
Vor einigen Wochen habe ich beschlossen mein erstes Arduino-Projekt in angriff zu nehmen.
Über 3 Lüfter soll warme Luft aus einem kleinen Serverrack befördert werden. Dazu habe ich 2 Temperatursensoren vorgesehen, welche die Temperatur im und ausserhalb des Gehäuses messen.
Ein PID-Regler regelt die Lüfter auf eine Temperaturdifferenz von 3°C zwischen Innen- und Aussentemperatur. Alle relevanten Werte werden im Anschluss als JSON-String via MQTT an einen Broker gesendet.
Mein Code funktioniert soweit, allerdings habe ich ab und an reconnet's. Ich habe festgestellt, dass die Abbrüche bei höheren Drehzahlen der Lüfter häufiger auftreten. Kann dies mit den Interrupts zur Ermittlung der Lüfterdrehzahl zusammen hängen?
Anbei mein aktueller Code:
#include <Arduino.h>
#include <WiFiNINA.h>
#include <MQTT.h>
#include <ArduinoJson.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <PID_v1.h>
#include "arduino_secrets.h"
// WiFi Client
WiFiClient net; // Setup WiFi Client
char ssid[] = SECRET_SSID; // network SSID
char pass[] = SECRET_PASS; // network password
int status = WL_IDLE_STATUS; // Wifi radio's status
// MQTT Client
MQTTClient client; // Setup MQTT Client
// OneWire
#define ONE_WIRE_BUS 8
OneWire oneWire(ONE_WIRE_BUS); // Setup oneWire instance
DallasTemperature sensors(&oneWire); // Pass oneWire reference to Dallas Temperature sensor
// PID
double SP, PV, CV, Kp=2, Ki=5, Kd=1;
PID FanControl(&PV, &CV, &SP, Kp, Ki, Kd, REVERSE); //Setup PID
// Set Pins
int FanPwm1Pin = 0;
int FanPwm2Pin = 4;
int FanPwm3Pin = 6;
int FanRpm1Pin = 1;
int FanRpm2Pin = 5;
int FanRpm3Pin = 7;
// Var
unsigned long lastMillis = 0;
unsigned long Fan1Last = 0;
unsigned long Fan2Last = 0;
unsigned long Fan3Last = 0;
unsigned long Fan1Duration = 0;
unsigned long Fan2Duration = 0;
unsigned long Fan3Duration = 0;
void messageReceived(String &topic, String &payload) {
Serial.println("incoming: " + topic + " - " + payload);
}
void connect() {
Serial.print("checking wifi...");
while ( status != WL_CONNECTED) {
status = WiFi.begin(ssid, pass);
Serial.print(".");
delay(1000);
}
Serial.println("\nconnected to WiFi!\n");
client.begin(mqttServer, mqttServerPort, net);
Serial.println("connecting to broker...");
while (!client.connect(device, key, secret)) {
Serial.print(".");
delay(1000);
}
Serial.println("Connected to MQTT");
client.onMessage(messageReceived);
}
void rpmFan1(){
unsigned long cm = micros();
Fan1Duration = (cm - Fan1Last);
Fan1Last = cm;
}
void rpmFan2(){
unsigned long cm = micros();
Fan2Duration = (cm - Fan2Last);
Fan2Last = cm;
}
void rpmFan3(){
unsigned long cm = micros();
Fan3Duration = (cm - Fan3Last);
Fan3Last = cm;
}
void setup() {
Serial.begin(115200);
// PWM Pins
pinMode(FanPwm1Pin, OUTPUT);
pinMode(FanPwm2Pin, OUTPUT);
pinMode(FanPwm3Pin, OUTPUT);
analogWrite(FanPwm1Pin, 0);
analogWrite(FanPwm2Pin, 0);
analogWrite(FanPwm3Pin, 0);
// RPM Pins
pinMode(FanRpm1Pin, INPUT_PULLUP);
pinMode(FanRpm2Pin, INPUT_PULLUP);
pinMode(FanRpm3Pin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(FanRpm1Pin), rpmFan1, RISING);
attachInterrupt(digitalPinToInterrupt(FanRpm2Pin), rpmFan2, RISING);
attachInterrupt(digitalPinToInterrupt(FanRpm3Pin), rpmFan3, RISING);
// MQTT Broker
connect();
sensors.begin();
//PID
SP=3;
FanControl.SetMode(AUTOMATIC);
}
void loop() {
// Check Connection
if (!net.connected()) {
connect();
}
// Fan
PV = sensors.getTempCByIndex(0) - sensors.getTempCByIndex(1);
FanControl.Compute();
analogWrite(FanPwm1Pin, CV);
analogWrite(FanPwm2Pin, CV);
analogWrite(FanPwm3Pin, CV);
// Send Data
if (millis() - lastMillis > 5000) {
StaticJsonDocument<200> doc;
JsonObject Rpm = doc.createNestedObject("Rpm");
Rpm["Fan1"] = 100000000 / Fan1Duration * 60 / 200;
Rpm["Fan2"] = 100000000 / Fan2Duration * 60 / 200;
Rpm["Fan3"] = 100000000 / Fan3Duration * 60 / 200;
JsonObject PID = doc.createNestedObject("PID");
PID["SP"] = SP;
PID["PV"] = PV;
PID["CV"] = map(CV, 0, 255, 0, 100);
sensors.requestTemperatures();
JsonObject Temperature = doc.createNestedObject("Temperature");
Temperature["IN"] = sensors.getTempCByIndex(0);
Temperature["OUT"] = sensors.getTempCByIndex(1);
char payload[200];
serializeJson(doc, payload);
client.publish("Server", payload);
lastMillis = millis();
}
client.loop();
}
Für Anregungen und Tipps bin ich dankbar.
Grüsse
Asiris