Hey Leute, ich habe so gut wie keine Ahnung in diesem Thema, aber ich möchte einen Tiefpassfilter in Arduino programmieren.
Ich hab schon nahezu das ganze Internet nach Informationen und Codes abgesucht, aber nichts gefunden (zumindest nichts, womit ich was anfangen könnte). Könnte mir einer von euch einen funktionierenden universellen Code zur Verfügung stellen?
Ich benutze das ESP8266 mit dem DHT22 und dem SDS011. Die Version von der Arduino IDE ist die momentan aktuellste (Stand: 28.11.2022).
mit was kannst du was anfangen?
Welches Problem willst du lösen zu dem du glaubst ein Tiefpassfilter zu benötigen?
du solltest deinen funktionierenden Code für deinen Controller, deinen Sensor hier einstellen und dann beschreiben, welches Problem (bei welchem Werten?) du lösen möchtest.
Hallo,
was verstehst Du unter Tiefpassfilter in dem Zusammenhang.?
Such mal nach "gleitender Mittelwert" vermutlich meinst du sowas.
Heinz
Da ist der Verdacht naheliegend, dass du mit etwas, was man hier bringt, auch nichts anfangen kannst.
Je universeller, desto komplizierter solltest du auch bedenken.
Dann gibt es evtl. Unterschiede, ob Rechenbelastung eine (welche) Rolle spielt, und man z.B. auf Divisionen oder float-Arithmetik verzichtet.
Dass es sich um einen Staubsensor handeln soll, ist vermutlich noch am irrelevantesten. Wie oft (regelmaßig ?) du Werte bekommst, und warum du denkst, einen Tiefpass zu brauchen, wäre schon eher interessant.
Ganz prinzipiell geht Tiefpass (erster Ordnung) so (wenn neue Werte x in einem festen Zeitraster kommen):
xF = (xF*n + x)/(n+1);xF ist der gefilterte Wert der Rohwerte x
je größer n, desto träger der Filter.
Also erstmal vielen Dank für die schnellen Antworten ![]()
Vermutlich kann ich auch einen gleitenden Mittelwert verwenden (wie gesagt, nicht viel Ahnung). Allerdings habe ich gehört, dass der Tiefpassfilter die "elegantere" Methode ist und jetzt habe ich den Anspruch an mich so einen Filter zu programmieren.
Ich versuche trozdem mal den Code hier einzufügen:
1.#include <DHT.h>
2.//Bibliothek einbeziehen
3.#define DHTTYPE DHT22
4.#define DHTPIN 2
5.DHT dht(DHTPIN, DHTTYPE);
6.//zusätzliche Informationen zum dht speichern
7.#include <SdsDustSensor.h>
8.#define SDS_RX_PIN 3
9.#define SDS_TX_PIN 4
10.SdsDustSensor sds(SDS_RX_PIN, SDS_TX_PIN);
11. void setup() {
12. Serial.begin(115200);
13. //Starten des Programms
14. delay(500);
15. Serial.println("Messung startet...");
16. dht.begin();
17. sds.begin();
18. Serial.println(sds.setQueryReportingMode().toString());
19. //stellt sicher, dass der SDS im reporting mode ist
20. }
21.void loop() {
22. delay(1000);
23. float h = dht.readHumidity();
24. //Feuchtigkeit auslesen, als float speichern
25. float t = dht.readTemperature();
26.
27. PmResult pm = sds.readPm();
28. if (pm.isOk()) {
29. //überprüfen ob Messwert vorliegt
30. Serial.print(pm.pm25);
31. Serial.print(",");
32. //Feinstaub PM2.5
33. Serial.print(pm.pm10);
34. Serial.print(",");
35. //Feinstaub PM10
36. Serial.print(t);
37. Serial.print(",");
38. //Temperatur
39. Serial.println(h);
40. //Luftfeuchtigkeit
41. } else {
42.
43. Serial.print("Es ist folgendes Problem aufgetreten: ");
44. Serial.println(pm.statusToString());
45. //Falls Messung fehlerhaft, den aktuellen Status ausgeben
46. }
47. }
Statt dem aktuellen print in der if-Schleife würde ich gerne die Messwerte filtern die gefilterten Werte ausgeben oder im Diagramm anzeigen lassen, weil z.B. die pm10 Werte im Diagramm stark "springen":
Wenn Du den Anspruch an Dich hast, wieso fragst Du dann uns? ![]()
Gruß Tommy
Guter Konter ![]()
Dann muss ich das nochmal unmformulieren: und jetzt möchte ich bei meinem kleinen Programm den "elegantesten" Filter nutzen ![]()
D.h. Du weißt eigentlich überhaupt nicht, was Du willst. Kleiner Tipp: Der gleitende Mittelwert ist ein Tiefpassfilter und die eleganteste Lösung kann sich nur aus dem Gesamtkontext ergeben und der ist schwammig.
Gruß Tommy
Okay also meinst du, ich bin mit dem Tiefpassfilter erster Ordnung von michael_x gut bedient?
Ja, meine ich.
Gruß Tommy
Warum sollte man das wollen? Außerdem hat das nichts mit der Frage zu tun.
Gruß Tommy
Den kann man auch um Ausreisser bereinigen.
Als Anregung, da ich nicht so recht schlau daraus werde warum pm10 ein float ist, mal nur so in die Tasten getippt.
// Forensketch - Mittelwert bilden
// https://forum.arduino.cc/t/tiefpassfilter-staubsensor/1059266/
#include <Streaming.h>
#include <SdsDustSensor.h>
constexpr uint8_t SDS_RX_PIN {3};
constexpr uint8_t SDS_TX_PIN {4};
SdsDustSensor sds(SDS_RX_PIN, SDS_TX_PIN);
constexpr uint8_t anzahlWerte {12};
uint32_t pm10Array[anzahlWerte] = {0};
uint8_t index;
void setup()
{
Serial.begin(115200);
//Starten des Programms
delay(500);
Serial.println("Messung startet...");
sds.begin();
Serial.println(sds.setQueryReportingMode().toString());
//stellt sicher, dass der SDS im reporting mode ist
for (byte b = 0; b < anzahlWerte; b++)
{
sensorLesen(); // Alle Elemente einmal befüllen
}
}
void loop()
{
sensorLesen();
sensorAusgeben();
delay(1000);
}
void sensorLesen()
{
PmResult pm = sds.readPm();
if (pm.isOk())
{
//Feinstaub PM2.5
Serial << F("Wert gelesen: ") << pm.pm10 << endl;
pm10Array[index] = pm.pm10;
index++;
}
else
{
Serial << F("Es ist folgendes Problem aufgetreten: ") << pm.statusToString() << endl;
//Falls Messung fehlerhaft, den aktuellen Status ausgeben
}
if (index >= anzahlWerte)
{ index = 0; }
}
void sensorAusgeben()
{
uint32_t minWert = 4294967295;
uint32_t maxWert = 0;
uint32_t sensorWert = 0;
for (byte b = 0; b < anzahlWerte; b++)
{
if (pm10Array[b] > maxWert) // obersten Ausreisser finden
{ maxWert = pm10Array[b]; }
if (pm10Array[b] < minWert) // untersten Ausreisser finden
{ minWert = pm10Array[b]; }
sensorWert += pm10Array[b]; // Summe bilden
}
sensorWert -= maxWert; // Ausreisser abziehen
sensorWert -= minWert;
sensorWert /= anzahlWerte - 2; // Ergebnis bilden
}
Warum ein Rad wieder ausfinden? Diese software werd benutzt bei Tausende uber die ganse welt. Sie hat ihren einwandfreien wirkung bewiesen.
Hast Du mal gelesen und verstanden, worum es in dem Thread geht?
Gruß Tommy
