Inhaltsverzeichnis
Für dieses Projekt benötigst du
BME 280 Sensor am Arduino Mikrocontroller verwenden
Aufgabenstellung
https://www.high-endrolex.com/48
mit mehr als ~3,6V kann permanenten Schaden am Modul verursachen! Des Weiteren können Erschütterungen die Messwerte des BME280 beeinträchtigen. Der BME280 Sensor verfügt über sechs Pins. Bei der Bearbeitung dieser Aufgabe verwenden wir die Pins: VCC – Pin für die Spannungsversorgung, anzuschließen an den 3,3V Pin des Arduinos GND – „Ground Pin“, anzuschließen an den GND Pin des Arduinos SCL – „Serial Clock“ Pin , wird zusammen mit dem SDA(Serial Data) Pin als Signalleitung des I²C verwendet, anzuschließen an den A5 Pin des Arduinos SDA – „Serial Data“ Pin , wird zusammen mit dem SCL(Serial Clock) Pin als Signalleitung des I²C verwendet, anzuschließen an den A4 Pin des Arduinos Ausserdem findet man noch zwei weitere Pins, welche wir in dieser Aufgabe jedoch nicht verwenden. SDO – Pin für die Festlegung der Hexcodierung, die normale I²C Adresse lautet 0x77. Verbindet man den SDO und einen Ground Pin, so verändert sich die Adresse zu 0x76. CSB – „Chip Select“ PinSchaltplan
Sobald die Verkabelung abgeschlossen ist und wir unser Ergebnis noch einmal überprüft haben, schauen wir uns den Sketch an.
Bitte beachte, dass der Sensor sowohl die I²C Bibliothek „<Wire.h>“, als auch eine eigene „<Seeed_BME280.h>“ benötigt. Die „<Wire.h>“ Bibliothek ist bereits auf deinem Arduino vorinstalliert. Die Bibliothek „<Seeed_BME280.h>“ muss manuell installiert werden. In der Bibliotheksverwaltung findet man die Bibliothek unter dem Suchbegriff „Grove – Barometer Sensor BME280“.
Eine ausführliche Anleitung des Installationsprozesses findest du hier.
Beispielsketch
#include <Seeed_BME280.h> // Implementieren der Seeed Bibliothek, ermöglicht die Kommunikation mit dem BME
#include <Wire.h> // Implementieren der Wire Bibliothek, ermöglicht dem Arduino mit Geräten zu kommunizieren, welche das I²C Protokoll verwenden
BME280 bme280;
void setup()
{
Serial.begin(9600); // Einstellen der Baudrate
if (!bme280.init()) // Wenn keine Daten vom BME abgefragt werden können...
{
Serial.println("FEHLER!"); // ...dann soll eine Fehlermeldung ausgegeben werden.
}
}
void loop() // Starten unserer Schleife
{
float Druck; // Deklarieren der Variablen
float Pascal;
double Bar;
Serial.print("Temperatur : ");
Serial.print(bme280.getTemperature()); // Abfrage und Ausgabe der Temperatur
Serial.println("C");
Serial.print("Druck : ");
Pascal = bme280.getPressure(); // Abfrage des Drucks in Pascal
Serial.print(Pascal); // Ausgabe des Drucks in Pascal
Serial.print(" Pascal oder auch ");
Bar = (Pascal / 100000); // Wandlung des Pascal-Werts in Bar
Serial.print(Bar); // Ausgabe des Drucks in Bar
Serial.println(" Bar");
Serial.print("Feuchtigkeit : ");
Serial.print(bme280.getHumidity()); // Abfrage und Ausgabe der Feuchtigkeit
Serial.println("%");
Serial.println(" ");
delay(1000);
}
Der BME680
Anzeige der Messdaten mit der Bibliothek Adafruit BME680
Für dieses Projekt benötigst du
Aufgabenstellung
Im Seriellen Monitor sollen die Messwerte für Temperatur, Luftfeuchtigkeit, Luftdruck und die Luftqualität angezeigt werden. Aus dem Verhältnis des aktuellen Luftdrucks zum Luftdruck auf Meereshöhe kann die ungefähre Höhe in Metern des Standorts bestimmt werden.
Die Hardware
Der Bosch Sensor BME680 misst Temperatur, Luftfeuchtigkeit und den Luftdruck. Außerdem enthält er einen MOX (Metalloxid)-Sensor. Je nach Konzentration der flüchtigen organischen Verbindungen (VOC = Volatile Organic Compounds) in der Luft ändert das beheizte Metalloxid seinen Widerstand. Die Luftqualität wird zunächst als Widerstand in Ohm gemessen. Je höher die Konzentration von VOC, desto geringer ist der Widerstandswert. Ein niedriger Wert entspricht einer höheren Luftqualität.
Der MOX-Sensor benötigt etwa 30 Minuten für die Kalibrierung. Um einen Anhaltspunkt für die Luftqualität zu haben empfiehlt es sich, den Sensor draußen oder in einem gut durchlüfteten Raum zu kalibrieren. Diesen Wert kann man dann als Referenzwert für eine gute Luftqualität nehmen.
Viele Materialien in Innenräumen setzen Gase frei:
- Reinigungs- und Pflegemittel
- Möbel, Einrichtungsgegenstände
- Teppiche, Tapeten
- Baumaterialien (Farben)
- elektronische Geräte (Computer, Drucker)
- Heizgeräte (Herde, Öfen)
- menschliche Atemluft, Schweiß
Der Schaltplan
Der Quellcode
#include "Wire.h"
#include "Adafruit_Sensor.h"
#include "Adafruit_BME680.h"
// Luftdruck auf Meereshöhe
#define SEALEVELPRESSURE_HPA (1013.25)
// i2c-Anschluss
Adafruit_BME680 bme;
void setup()
{
// Seriellen Monitor starten
Serial.begin(9600);
while (!Serial);
delay(1000);
Serial.println(F("BME680 Test"));
// BME680 starten
if (!bme.begin()) {
Serial.println("BME680 Sensor nicht gefunden!");
// Programm anhalten
while (1);
}
/*
oversampling: Setzen einer höheren Abtastrate als die Standardrate
mögliche Werte:
BME680_OS_NONE -> ausgeschaltet
BME680_OS_1X
BME680_OS_4X
BME680_OS_8X
BME680_OS_16X
bme.setTemperatureOversampling(BME680_OS_NONE);
bme.setHumidityOversampling(BME680_OS_2X);
bme.setPressureOversampling(BME680_OS_4X);
// IIR = infinite impulse response (Filter mit unendlicher Impulsantwort)
// liefert eine unendlich lang andauernde Impulsantwort
bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme.setGasHeater(320, 150);
Standardwerte sind für die Messung ausreichend
*/
}
void loop()
{
// wenn der Sensor keine Daten übermittelt ...
if (!bme.performReading())
{
Serial.println("Keine Messdaten");
return;
}
Serial.print("Temperatur: ");
// Messwert in String umwandeln
String Temperatur = String(bme.temperature);
// . durch , ersetzen
Temperatur.replace(".", ",");
Serial.println(Temperatur + " °C");
String Luftfeuchtigkeit = String(bme.humidity);
Luftfeuchtigkeit.replace(".", ",");
Serial.print("Luftfeuchtigkeit: ");
Serial.println(Luftfeuchtigkeit + " %");
Serial.print("Luftdruck = ");
String Luftdruck = String(bme.pressure / 100.0);
Luftdruck.replace(".", ",");
Serial.println(Luftdruck + " hPa");
Serial.print("Widerstandswert Gas = ");
String GasWiderstand = String(bme.gas_resistance / 1000.0);
Serial.println(GasWiderstand + " KOhm");
Serial.print("Ungefähre Höhe: ");
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(" m");
Serial.println();
delay(2000);
}
Anzeige der Messdaten mit der Bibliothek BSEC
Für dieses Projekt benötigst du
Aufgabenstellung
Die Luftqualität wird zunächst als Widerstand in Ohm gemessen. Je höher die Konzentration von VOC, desto geringer ist der Widerstandswert.
Ein interner Algorithmus der Bosch-Software (BSEC) wandelt diesen Rohwert in einen Wert für die Luftqualität (IAQ = Index for Air Quality) um.
Natürlich kommt die Genauigkeit dieser Messwerte nicht an die Präzision professioneller Messgeräte heran. Sie können aber zuverlässige Hinweise auf die Qualität der Raumluft geben. Die Daten für Temperatur, Luftfeuchtigkeit und Luftdruck stehen kurz nach der Aktivierung des Sensors zur Verfügung. Der MOX-Sensor benötigt bis zu 30 Minuten, um erste Messdaten anzuzeigen. Stabilität und Zuverlässigkeit der Messdaten sind erst nach mehreren Tagen gewährleistet.
Der Wert für die Genauigkeit IAQ muss 3 erreichen.
Die Tabelle zeigt den IAQ und die Bewertung der Luftqualität:
Der Schaltplan
Vorbereitungen
Installiere über den Boardverwalter das Board ESP32-Wroom
Sketch -> Bibliothek einbinden -> Bibliotheken verwalten
Funktionen der Bibliothek BSEC
Der Quellcode
Benötigte Bibliothek und Variable
#include "bsec.h"
// Objekt (iaqSensor) der Klasse Bsec definieren
Bsec iaqSensor;
Der setup-Teil
void setup()
{
Serial.begin(9600);
// auf Serielle Verbindung warten
while (!Serial);
delay(1000);
// Hex-Adresse des BME680
// BME68X_I2C_ADDR_HIGH = 0x77 (Standard)
// BME68X_I2C_ADDR_LOW = 0x76 (Verbindung SDO zu GND)
iaqSensor.begin(BME68X_I2C_ADDR_HIGH, Wire);
// Array der verfügbaren Sensoren
bsec_virtual_sensor_t sensorList[13] =
{
BSEC_OUTPUT_IAQ,
BSEC_OUTPUT_STATIC_IAQ,
BSEC_OUTPUT_CO2_EQUIVALENT,
BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
BSEC_OUTPUT_RAW_TEMPERATURE,
BSEC_OUTPUT_RAW_PRESSURE,
BSEC_OUTPUT_RAW_HUMIDITY,
BSEC_OUTPUT_RAW_GAS,
BSEC_OUTPUT_STABILIZATION_STATUS,
BSEC_OUTPUT_RUN_IN_STATUS,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
BSEC_OUTPUT_GAS_PERCENTAGE
};
// BSEC_SAMPLE_RATE_ULP: Ultra Low Powermode -> Messung alle 5 Minuten
// BSEC_SAMPLE_RATE_LP: Low Powermode -> Messung alle 3 Sekunden
iaqSensor.updateSubscription(sensorList, 13, BSEC_SAMPLE_RATE_LP);
}
Der loop-Teil
void loop()
{
// wenn der Sensor arbeitet ...
if (iaqSensor.run())
{
// Messwerte ermitteln, in Strings umwandeln, . durch , ersetzen
String Temperatur = String(iaqSensor.temperature);
Temperatur.replace(".", ",");
String Luftfeuchtigkeit = String(iaqSensor.humidity);
Luftfeuchtigkeit.replace(".", ",");
String Luftdruck = String(iaqSensor.pressure / 100);
Luftdruck.replace(".", ",");
String IAQ = String(iaqSensor.iaq);
IAQ.replace(".", ",");
String StatischerIAQ = String(iaqSensor.staticIaq);
StatischerIAQ.replace(".", ",");
String CO2 = String(iaqSensor.co2Equivalent);
CO2.replace(".", ",");
// Ausgabe Serieller Monitor
Serial.println("Statusmeldungen:");
Serial.println("-----------------------------");
Serial.println("Sensor bereit (0-1): " + String(int(iaqSensor.runInStatus)));
Serial.println("Genauigkeit IAQ (0-3): " + String(int(iaqSensor.iaqAccuracy)));
Serial.println("-----------------------------");
Serial.println("Messwerte:");
Serial.println("-----------------------------");
Serial.println("Temperatur: " + Temperatur + " °C");
Serial.println("Feuchtigkeit: " + Luftfeuchtigkeit + " %");
Serial.println("Luftdruck: " + Luftdruck + " hPa");
Serial.println("IAQ: " + IAQ);
Serial.println("Statischer IAQ: " + StatischerIAQ);
Serial.println("Schätzung CO2: " + CO2 + " ppm");
Serial.println("-----------------------------");
}
}
Erweiterung des Programms: Anzeige der Messdaten auf einem LCD
Der Schaltplan
Zusätzliche Bibliothek installieren
Sketch -> Bibliothek einbinden -> Bibliotheken verwalten
Der Quellcode
#include "bsec.h"
#include "LCDIC2.h"
// 4-zeiliges LCD
LCDIC2 lcd(0x27, 20, 4);
// Objekt (iaqSensor) der Klasse Bsec definieren
Bsec iaqSensor;
void setup()
{
Serial.begin(9600);
// auf Serielle Verbindung warten
while (!Serial);
delay(1000);
// LCD starten
lcd.begin();
// Cursor "verstecken"
lcd.setCursor(false);
// Hex-Adresse des BME680
// BME68X_I2C_ADDR_HIGH = 0x77 (Standard)
// BME68X_I2C_ADDR_LOW = 0x76 (Verbindung SDO zu GND)
iaqSensor.begin(BME68X_I2C_ADDR_HIGH, Wire);
// Array der verfügbaren Sensoren
bsec_virtual_sensor_t sensorList[13] =
{
BSEC_OUTPUT_IAQ,
BSEC_OUTPUT_STATIC_IAQ,
BSEC_OUTPUT_CO2_EQUIVALENT,
BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
BSEC_OUTPUT_RAW_TEMPERATURE,
BSEC_OUTPUT_RAW_PRESSURE,
BSEC_OUTPUT_RAW_HUMIDITY,
BSEC_OUTPUT_RAW_GAS,
BSEC_OUTPUT_STABILIZATION_STATUS,
BSEC_OUTPUT_RUN_IN_STATUS,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
BSEC_OUTPUT_GAS_PERCENTAGE
};
// BSEC_SAMPLE_RATE_ULP: Ultra Low Powermode -> Messung alle 5 Minuten
// BSEC_SAMPLE_RATE_LP: Low Powermode -> Messung alle 3 Sekunden
iaqSensor.updateSubscription(sensorList, 13, BSEC_SAMPLE_RATE_LP);
}
void loop()
{
// wenn der Sensor arbeitet ...
if (iaqSensor.run())
{
// Messwerte ermitteln, in Strings umwandeln, . durch , ersetzen
String Temperatur = String(iaqSensor.temperature);
Temperatur.replace(".", ",");
String Luftfeuchtigkeit = String(iaqSensor.humidity);
Luftfeuchtigkeit.replace(".", ",");
String Luftdruck = String(iaqSensor.pressure / 100);
Luftdruck.replace(".", ",");
String IAQ = String(iaqSensor.iaq);
IAQ.replace(".", ",");
String StatischerIAQ = String(iaqSensor.staticIaq);
StatischerIAQ.replace(".", ",");
String CO2 = String(iaqSensor.co2Equivalent);
CO2.replace(".", ",");
// Ausgabe Serieller Monitor
Serial.println("Statusmeldungen:");
Serial.println("-----------------------------");
Serial.println("Sensor bereit (0-1): " + String(int(iaqSensor.runInStatus)));
Serial.println("Genauigkeit IAQ (0-3): " + String(int(iaqSensor.iaqAccuracy)));
Serial.println("-----------------------------");
Serial.println("Messwerte:");
Serial.println("-----------------------------");
Serial.println("Temperatur: " + Temperatur + " °C");
Serial.println("Feuchtigkeit: " + Luftfeuchtigkeit + " %");
Serial.println("Luftdruck: " + Luftdruck + " hPa");
Serial.println("IAQ: " + IAQ);
Serial.println("Statischer IAQ: " + StatischerIAQ);
Serial.println("Schätzung CO2: " + CO2 + " ppm");
Serial.println("-----------------------------");
// Ausgabe LCD
lcd.setCursor(0, 0);
lcd.print("Temperatur: " + Temperatur + "\337C");
lcd.setCursor(0, 1);
lcd.print("Feuchtigkeit: " + Luftfeuchtigkeit + "%");
lcd.setCursor(0, 2);
lcd.print("IAQ: " + IAQ);
lcd.setCursor(0, 3);
lcd.print("CO2: " + CO2 + " ppm");
}
}
Erweiterung des Programms: Anzeige der Messdaten im Web
Der Quellcode
#include "bsec.h"
#include "WiFi.h"
#include "WebServer.h"
#include "time.h"
// Objekt (iaqSensor) der Klasse Bsec definieren
Bsec iaqSensor;
char Router[] = "Router_SSID";
char Passwort[] = "xxxxxxxx";
// ip und gateway müssen an das lokale Netz angepasst werden
IPAddress ip(192, 168, 1, 100);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
/*
öffentliche DNS-Server
-----------------------------------------------
OpenDNS 208, 67, 222, 222 (USA)
Google 8, 8, 8, 8 (USA)
Cloudfare 1, 1, 1, 1 (USA)
DNSWWatch 84, 200, 69, 80 (Deutschland)
Quad9 9, 9, 9, 9 (Schweiz)
Neustar UltraDNS 56, 154, 70, 3 (USA, gefiltert)
Deutsche Telekom 217, 5,100, 185
------------------------------------------------
oder die im Router eingetragene IP
im Beispiel: 192, 168, 1, 20
*/
IPAddress primaryDNS(192, 168, 1, 20);
IPAddress secondaryDNS(9, 9, 9, 9);
// NTP-Server aus dem Pool
#define Zeitserver "de.pool.ntp.org"
/*
Liste der Zeitzonen
https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv
Zeitzone CET = Central European Time -1 -> 1 Stunde zurück
CEST = Central European Summer Time von
M3 = März, 5.0 = Sonntag 5. Woche, 02 = 2 Uhr
bis M10 = Oktober, 5.0 = Sonntag 5. Woche 03 = 3 Uhr
*/
#define Zeitzone "CET-1CEST,M3.5.0/02,M10.5.0/03"
// time_t enthält die Anzahl der Sekunden seit dem 1.1.1970 0 Uhr
time_t aktuelleZeit;
/*
Struktur tm
tm_hour -> Stunde: 0 bis 23
tm_min -> Minuten: 0 bis 59
tm_sec -> Sekunden 0 bis 59
tm_mday -> Tag 1 bis 31
tm_wday -> Wochentag (0 = Sonntag, 6 = Samstag)
tm_mon -> Monat: 0 (Januar) bis 11 (Dezember)
tm_year -> Jahre seit 1900
tm_yday -> vergangene Tage seit 1. Januar des Jahres
tm_isdst -> Wert > 0 = Sommerzeit (dst = daylight saving time)
*/
tm Zeit;
WebServer server(80);
// benötigte Strings
String Nachricht;
String Temperatur;
String Luftfeuchtigkeit;
String Luftdruck;
String CO2;
String IAQ;
String StatischerIAQ;
void setup()
{
// Zeitzone: Parameter für die zu ermittelnde Zeit
configTzTime(Zeitzone, Zeitserver);
// localtime_r -> Zeit in die lokale Zeitzone setzen
localtime_r(&aktuelleZeit, &Zeit);
Serial.begin(9600);
// auf Serielle Verbindung warten
while (!Serial);
delay(1000);
// WiFi starten
WiFi.begin(Router, Passwort);
WiFi.config(ip, gateway, subnet, primaryDNS, secondaryDNS);
Serial.print("Verbunden mit ");
Serial.println(Router);
// IP anzeigen
Serial.print("Statische IP: ");
Serial.println(ip);
server.begin();
server.on("/", handleRoot);
// Hex-Adresse des BME680
// BME68X_I2C_ADDR_HIGH = 0x77
// BME68X_I2C_ADDR_LOW = 0x76
iaqSensor.begin(BME68X_I2C_ADDR_HIGH, Wire);
// Array der verfügbaren Sensoren
bsec_virtual_sensor_t sensorList[13] =
{
BSEC_OUTPUT_IAQ,
BSEC_OUTPUT_STATIC_IAQ,
BSEC_OUTPUT_CO2_EQUIVALENT,
BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
BSEC_OUTPUT_RAW_TEMPERATURE,
BSEC_OUTPUT_RAW_PRESSURE,
BSEC_OUTPUT_RAW_HUMIDITY,
BSEC_OUTPUT_RAW_GAS,
BSEC_OUTPUT_STABILIZATION_STATUS,
BSEC_OUTPUT_RUN_IN_STATUS,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
BSEC_OUTPUT_GAS_PERCENTAGE
};
// BSEC_SAMPLE_RATE_ULP: Ultra Low Powermode -> Messung alle 5 Minuten
// BSEC_SAMPLE_RATE_LP: Low Powermode -> Messung alle 3 Sekunden
iaqSensor.updateSubscription(sensorList, 13, BSEC_SAMPLE_RATE_LP);
}
void loop()
{
// wenn der Sensor arbeitet ...
if (iaqSensor.run())
{
// aktuelle Zeit holen
// es kann bis zu 30 Sekunden dauern
// bis die Zeit ermittelt wird
time(&aktuelleZeit);
// localtime_r -> Zeit in die lokale Zeitzone setzen
localtime_r(&aktuelleZeit, &Zeit);
server.handleClient();
// Messwerte ermitteln, in Strings umwandeln, . durch , ersetzen
Temperatur = String(iaqSensor.temperature);
Temperatur.replace(".", ",");
Luftfeuchtigkeit = String(iaqSensor.humidity);
Luftfeuchtigkeit.replace(".", ",");
Luftdruck = String(iaqSensor.pressure / 100);
Luftdruck.replace(".", ",");
IAQ = String(iaqSensor.iaq);
IAQ.replace(".", ",");
StatischerIAQ = String(iaqSensor.staticIaq);
StatischerIAQ.replace(".", ",");
CO2 = String(iaqSensor.co2Equivalent);
CO2.replace(".", ",");
String VOC = String(iaqSensor.breathVocEquivalent);
VOC.replace(".", ",");
String GasInProzent = String(iaqSensor.gasPercentage);
GasInProzent.replace(".", ",");
}
}
void handleRoot()
{
// Seite zusammenbauen
// Kopf der HTML-Seite: aktualisierung alle 60 Sekunden
// kann angepasst werden
Nachricht = "";
Nachricht += "Messwerte BME680
";
// Datum anzeigen
// formatieren: Schrift 14pt, ohne Serifen, Zeilenhöhe
Nachricht += "";
Nachricht += "Letzte Aktualisierung: ";
// wenn der Tag < 10
if (Zeit.tm_mday < 10) Nachricht += "0";
Nachricht += String(Zeit.tm_mday) + ".";
// wen der Monat < 10, Zählung beginnt mit 0
if ((Zeit.tm_mon + 1) < 10) Nachricht += "0";
Nachricht += String(Zeit.tm_mon + 1) + ". ";
// Zeit anzeigen
// wenn die Stunde < 10
if (Zeit.tm_hour < 10) Nachricht += "0";
Nachricht += String(Zeit.tm_hour) + ":";
// wenn die Minute < 10
if (Zeit.tm_min < 10) Nachricht += "0";
Nachricht+= String(Zeit.tm_min) + " Uhr
";
Nachricht += "Temperatur: " + Temperatur + " °C
";
Nachricht += "Luftfeuchtigkeit: " + Luftfeuchtigkeit + " %
";
Nachricht += "Luftdruck: " + Luftdruck + " hPa
";
Nachricht += "IAQ: " + IAQ + "
";
Nachricht += "Statischer IAQ: " + StatischerIAQ + "
";
Nachricht += "Schätzung CO2: " + CO2 + " ppm
";
Nachricht += "Genauigkeit IAQ (0-3): " + String(int(iaqSensor.iaqAccuracy)) + "";
// Button aktualisieren
Nachricht += "
";
Nachricht += "
";
// Nachricht senden -> Seite anzeigen
server.send(200, "text/html", Nachricht);
}
Funduino - Dein Onlineshop für Mikroelektronik
-
Dauerhaft bis zu 10% Rabatt für Schüler, Studenten und Lehrkräfte
-
Mehr als 3.500 Artikel sofort verfügbar!
-
Über 8 Jahre Erfahrung mit Arduino, 3D-Druck und co.