Darf es etwas mehr sein? Anschluss von Umweltsensoren
Immer wieder war in dieser Blog-Serie von Sensoren die Rede. Gegenstand der Betrachtungen waren unter anderem Temperatur, Luftfeuchtigkeit, Gewittererkennung, Feinstaub, Luftdruck oder Radioaktivität. In der vorliegenden Folge geht es um Sensorik und eine ganze Reihe weiterer analoger Umweltsensoren.
- Dr. Michael Stal
Immer wieder war in dieser Blog-Serie von Sensoren die Rede. Gegenstand der Betrachtungen waren unter anderem Temperatur, Luftfeuchtigkeit, Gewittererkennung, Feinstaub, Luftdruck oder Radioaktivität. In der vorliegenden Folge geht es um Sensorik und eine ganze Reihe weiterer analoger Umweltsensoren.
Um nicht jedes Mal eine komplett neue Komponente entwerfen zu müssen, sobald weitere Sensoren zu einer Messstation hinzukommen, liegt die Idee nahe, einen modularen Ansatz zu entwickeln. Zu diesem Zweck sollten sowohl Hardware als auch Software entsprechend strukturiert sein. Die Messstation Marke Eigenbau lässt sich dann auch preisgünstig ins Web integrieren, etwa per ESP8266.
Sensor Shields
Wer sehr viele Sensoren an einen Arduino anschließen möchte, dürfte irgendwann durch das daraus resultierende "Drahtgestrüpp" ohnehin die Übersicht verlieren. Jeder analoge Sensor benötigt mindestens einen Datenanschluss sowie Versorgungsspannung und Erde. Noch etwas aufwendiger ist freilich der Anschluss von Sensoren mit I2C-, SPI- oder 1-Wire-Bus, wie wir ihnen bereits über den Weg gelaufen sind.
Um das Ganze zu vereinfachen, bieten Elektronikhersteller für das Arduino-Ökosystem sogenannte Sensor-Shields an. Hinter diesem Namen ließe sich einige technische Raffinesse vermuten, aber letztlich handelt es lediglich sich um Shields, die nicht bloß die Pins eines Arduino mit R3-Layout (dazu gehören unter anderem Uno, Leonardo, Mega) nach außen führen, sondern die explizit Anschlussstellen für Sensoren mit allen benötigten Leitungen kompakt anbieten. Es geht also um Kompaktheit und Bequemlichkeit. Hier ein Beispiel für ein solches Shield:
Auf dem abgebildeten Shield sind zum Beispiel verschiedene Buchsen und 3er-Pin-Reihen zum Anschluss von analogen und digitalen Sensoren zu sehen sowie Kommunikationsanschlüsse für I2C-basierte beziehungsweise serielle Kommunikation, wobei Entwickler die Wahl des Protokolls über Jumper einzustellen vermögen.
"Sensor Shields" fĂĽr den Arduino gibt es eine ganze Menge, meistens in Version 4.0 oder 5.0, wobei der Maker auf etliche unterschiedliche Shields trifft, die sich allesamt als Arduino Sensor Shield v4.0 bezeichnen. Name ist also nicht immer Programm.
FĂĽr den vorliegenden Beitrag kam ĂĽbrigens ein Sainsmart Shield fĂĽr wenige Euro zum Einsatz: siehe Produktseite.
Braucht der Maker ein solches Sensor Shield unbedingt? Nein, aber es ist ein "Nice to have"-Accessoire.
UV-Sensor ML8511
Dass UV-Strahlung der Haut und damit der Gesundheit schaden kann, wissen wir alle aus Erfahrung. Die WHO (World Health Organization) der UN hat daher den sogenannten UV-Index standardisiert. Eine Verdoppelung dieser linearen Messgröße halbiert die Zeit bis zu einem potenziellen Sonnenbrand. In der Nacht beträgt der UV-Index wenig überraschend 0, während sein Wert zur Mittagszeit an einem Sommertag mit klarem Himmel bei 10 liegt.
Zur Messung der UV-Einstrahlung gibt es UV-Sensoren wie den ML8511, der mit einem Frequenzspektrum von 280 bis 390 nm fast den kompletten Bereich von UV-A (UV-Strahlung die zur Hautbräunung führt) und UV-B (UV-Strahlung, die zu Verbrennungen führt) abdeckt.
UV-Sensoren funktionieren aufgrund des photoelektrischen Effekts, bei dem Bestrahlung eines Halbleitermaterials durch Photonen zum Fluss von Elektronen und damit zu höherer Leitfähigkeit führt. Dabei fällt die Wahl auf Halbleiter, die sich für die UV-Wellenlängen als empfindlich erweisen.
Zum Anschluss des Sensors an den Arduino sind folgende Verbindungen notwendig:
Arduino ML8511
3.3V 3.3V
GND GND
A3 OUT
A4 3.3V
3.3V EN
Eine Frage der Genauigkeit
Um die Genauigkeit der Analog-Digital-Wandlung zu verbessern, bedarf es einer zusätzlichen Maßnahme. Die Genauigkeit hängt von der Kenntnis der tatsächlichen Versorgungsspannung Vcc ab. Bei Speisung aus einer ungeregelten Spannungsquelle wie bei einem USB-Port kann es aber durchaus Schwankungen von bis zu 5 Prozent geben. Vcc kann also ±5 Prozent um den vermuteten Spannungswert von 5 V liegen, was die Ergebnisse von ADC-Umwandlungen zwar nicht unbrauchbar aber sehr ungenau macht.
Daher bietet sich folgender Trick an: Den Analogeingang A4 des Arduino legen wir an den 3,3-V-Ausgang des ML8511, den wir wiederum über den sehr genauen 3,3-V-Ausgang (Toleranz ±1 %) des Arduino versorgen.
Den Analogeingang A3 legen wir an den OUT-Ausgang des ML8511.
Bekanntlich ergibt sich bei einer Analog-Digital-Umwandlung an einem analogen Eingang genau dann 1023, wenn wir die tatsächliche Vorsorgungsspannung Vcc dort vorfinden. Angenommen, wir erhalten an Analogeingang A4, der an 3,3 V des ML8511 liegt, den digitalen Wert 700. Dann muss für die reale Spannung Vcc gelten:
3.3V / 700 = Vcc / 1023
Vcc am Arduino beträgt also in Wirklichkeit nicht 5 V sondern 4,8227 V.
Der Code zur UV-Messung lässt sich nun leicht erstellen. Um Messfehler beziehungsweise Schwankungen zu kompensieren, misst der Sketch mehrfach (WIEDERHOLUNGEN) und berechnet dann Mittelwerte.
Eine map-Funktion für Gleitkommazahlen hilft bei der Konvertierung der gemessenen Spannungen in mW/cm2-Werte. Die messbaren Spannungen bewegen sich von knapp unter 1 V (UV-Intensität = 0) bis zu 2,8 V (UV-Intensität 15). Daher lautet der Aufruf der map-Funktion:
mapfloat(spannung, 0.99, 2.8, 0.0, 15.0)
Der nachfolgende Code sollte problemlos zu verstehen sein, da er sich im Wesentlichen auf das analoge Lesen von Sensorwerten reduziert.
////////////////////////////////////////////////////////
//
// Umweltmessstation
//
////////////////////////////////////////////////////////
// UV-Sensor *******************************************
// Anschluss an Arduino ĂĽber Sensor Shield v4
int ML8511OUT = A3; // ML8511 Messwert
int Arduino3V3 = A4; // Anschluss an 3.3V des Arduino
const int WIEDERHOLUNGEN = 50;
// *****************************************************
////////////////////////////////////////////////////////
//
// setupUV
// Beide Eingänge als analoge Inputs.
// Deklaration eigentlich nicht nötig
//
////////////////////////////////////////////////////////
void setupUV()
{
pinMode(ML8511OUT, INPUT);
pinMode(Arduino3V3, INPUT);
}
////////////////////////////////////////////////////////
//
// Gesamt Setup
// der Messstation
// Aufruf der Setups einzelner Sensoren
//
////////////////////////////////////////////////////////
void setup()
{
Serial.begin(9600);
Serial.println("***************");
Serial.println("* Messstation *");
Serial.println("***************");
setupUV();
}
////////////////////////////////////////////////////////
//
// Map-Funktion fĂĽr Gleitkommazahlen
// Quelle:
// http://forum.arduino.cc/index.php?topic=3922.0
//
////////////////////////////////////////////////////////
float mapfloat(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
////////////////////////////////////////////////////////
//
// UV-Messung
//
////////////////////////////////////////////////////////
void messenUV()
{
unsigned int summeMesswert = 0;
unsigned int summeDelta = 0;
// Mehrere Messungen durchfĂĽhren:
for (int iteration = 0; iteration < WIEDERHOLUNGEN; iteration++) {
summeMesswert += analogRead(ML8511OUT);
summeDelta += analogRead(Arduino3V3);
}
// Aus statistischen GrĂĽnden => Mittelwertberechnung
int messwert = summeMesswert / WIEDERHOLUNGEN;
int delta = summeDelta / WIEDERHOLUNGEN;
// Nutzen des 3.3V Ausgangs, um eine genaue Referenz zu erhalten
float spannung = 3.3 / delta * messwert;
// Spannung nach UV-Intensitaet umwandeln:
float uvIntensitaet = mapfloat(spannung, 0.99, 2.8, 0.0, 15.0);
Serial.println("******************* UV Messung *******************");
Serial.print("Gemessenen am 3.3V Ausgang des ML8511 : ");
Serial.println(delta);
Serial.print("Gemessen als UV-Messwert : ");
Serial.println(messwert);
Serial.print("Tatsaechliche Spannung : ");
Serial.println(spannung);
Serial.print("UV-Intensitaet in mW/cm^2 : ");
Serial.println(uvIntensitaet);
Serial.println();
}
////////////////////////////////////////////////////////
//
// Alle Messungen werden hier in loop aufgerufen
//
////////////////////////////////////////////////////////
void loop()
{
messenUV(); // UV-Messung
delay(1000);
}
Regensensor
Nicht immer herrscht Sonnenschein. Stattdessen ist es hierzulande häufig bewölkt oder verregnet. Dass daher Regensensoren existieren, dürfte niemand überraschen. Wir wollen im nächsten Schritt einen solchen Sensor in unsere Messstation integrieren.
Ein Regensensor wie der unten abgebildete YL-83 beziehungsweise FC-37 besteht aus einem PCB-Board, dessen aufgedruckten Elektroden durch Wassertropfen ihre Leitfähigkeit erhöhen, sodass der gemessene Spannungsabfall sinkt. Gibt es keinen Regen, liefert der Analogport des Arduino, an dem der Anschluss des Regensensors erfolgt, relativ hohe Werte im Bereich unter 1023 zurück. Bei sintflutartigem Regen nähern sich die ausgegebenen Werte hingegen 0 an.
Die resultierende Anschlussbelegung lautet:
Arduino Regensensor
A1 A0
GND GND
5V Vcc
Über ein Poti auf dem Breakout-Board des Regensensors lässt sich die Empfindlichkeit regeln, ab welcher Regenmenge, also ab welchem Schwellwert die LED D0 aufleuchten soll. Gleichzeitig besitzt der Regensensor einen digitalen Ausgang D0,
an dem der Sensor zusätzlich ein HIGH-Signal sendet, sobald dies der Fall ist. Der nachfolgende Sketch verwendet diese Option allerdings nicht.
Er ist so strukturiert, dass er sich entweder eigenständig ausführen lässt. Alternativ können Entwickler die neuen Teile den bereits vorhandenen der beschriebenen Messstation hinzufügen.
Die vom Analog-Digital-Wandler gelieferten Messwerte kategorisiert der Sketch in 4 Bereiche mit unterschiedlichen Regenstärken. Sie können diese Aufteilung natürlich auch nach eigenem Gusto ändern.
// UV-Sensor Deklarationen
// ...
// Regen-Sensor ***************************************
// Anschluss an Arduino ĂĽber Sensor Shield v4
int REGENPIN = A1; // Regensensor Anschlusspin
// *****************************************************
// Setup UV-Sensor
// ...
////////////////////////////////////////////////////////
//
// setupRegen
// A1 als analoger Input
// Deklaration eigentlich nicht nötig
//
////////////////////////////////////////////////////////
void setupRegen()
{
pinMode(REGENPIN, INPUT);
}
////////////////////////////////////////////////////////
//
// Gesamt Setup
// der Messstation
// Aufruf der Setups einzelner Sensoren
//
////////////////////////////////////////////////////////
void setup()
{
Serial.begin(9600);
Serial.println("***************");
Serial.println("* Messstation *");
Serial.println("***************");
// setupUV();
// ...
setupRegen(); // Regensensor initialisieren
}
// UV-Messung
// ...
////////////////////////////////////////////////////////
//
// Regen-Messung
//
////////////////////////////////////////////////////////
void messenRegen()
{
unsigned int messwert = analogRead(REGENPIN);
Serial.println("******************* Regen Messung *******************");
if(messwert < 256) {
Serial.println("Wolkenbruch");
}
else
if(messwert < 512) {
Serial.println("Starkregen");
}
else
if(messwert < 768) {
Serial.println("Leichtregen");
}
else { // messwert in [768, 1024[
Serial.println("Trocken => Kein Regen");
}
Serial.println();
}
////////////////////////////////////////////////////////
//
// Alle Messungen werden hier in loop aufgerufen
//
////////////////////////////////////////////////////////
void loop()
{
// messenUV();
// ...
messenRegen(); // Regensensor aufrufen
delay(1000);
}
Bodensensor/Hygrometer YL-69
Der Wechsel von Sonne und Regen spielt in der Landwirtschaft natürlich eine wichtige Rolle. Vor allem Trockenheit hat fatale Auswirkungen. Aber auch Hobbygärtner möchten wissen, wann es Zeit ist, die eigenen Pflanzen mit Wasser zu versorgen, ohne sie zu ertränken.
Der Bodensensor YL-69 erlaubt fĂĽr wenig Geld, die eigene Flora vor dem Trockentod zu bewahren. Er besteht aus der eigentlichen Messeinheit, einem Breakout-Board, und Verbindungskabeln:
Auch Sparkfun bietet entsprechende Bodensensoren an: siehe Anleitung.
Die genannten Sensoren beruhen ebenso wie der weiter oben beschriebene Regensensor auf Veränderung von Leitfähigkeit aufgrund von Bodenfeuchtigkeit. Je feuchter der Boden, desto leitfähiger der Sensor und desto geringer die am Sensor gemessene Spannung bzw. der dort gemessene Wert nach Analog-Digital-Konvertierung.
Anschlussmäßig gestaltet sich die Verbindung wie folgt:
Arduino YL-69 Bodensensor
A0 A0
GND GND
5V Vcc
Was die vom Sensor gemessenen Werte bedeuten, müssen Maker noch auf ihren eigenen Kontext übertragen, also kalibrieren. Beim Versuch mit einer Topfpflanze veränderte sich der gemessene Wert durch mittleres Gießen von 967 auf rund 630. An der freien Luft gab der Sensor seinen Maximalwert von 1023 aus. Der Wertebereich kann aber von Sensor zu Sensor durchaus schwanken. Und natürlich hängt es von der Pflanzenart ab, wie die optimale Bodenfeuchtigkeit aussieht.
Bodensensoren wie der YL-69 sollten Entwickler allerdings nicht ständig mit Strom versorgen, weil sie sonst schnell anfangen zu korrodieren. Um Korrosion zu vermeiden, empfiehlt es sich demzufolge, längere Pausen zwischen Messungen einzuhalten und den Sensor zwischendrin zu deaktivieren. Das ist beispielsweise über fernsteuerbare Schalter wie Relais zu bewerkstelligen. Oder der Stromanschluss des Sensors erfolgt durch einen digitalen Ausgang des Arduino, über den der Sketch für Messungen HIGH-Signal, sonst aber LOW-Signal anlegt.
Der Sensor von Sparkfun ist übrigens in Gegensatz zu vielen chinesischen Billigsensoren mit einer goldenen Nickelimmersionsschicht versehen, um die Korrosion zu verhindern oder zumindest weit hinauszuzögern.
Wie sein Cousin zur Regenmessung, besitzt der Bodensensor YL-69 einen digitalen Ausgang und ein Poti zur Einstellung eines Schwellwerts, bei dessen Erreichen der Sensor ein Signal ausgibt. Und analog fängt dann auch die am Breakout-Board des Sensors dafür vorgesehene LED an zu leuchten.
Der nachfolgende Sketch lässt sich entweder eigenständig nutzen oder seine Teile dem Gesamtcode der Messstation hinzufügen.
// Andere Sensordeklarationen ...
// Boden-Sensor ***************************************
// Anschluss an Arduino ĂĽber Sensor Shield v4
int BODENPIN = A0; // Bodensensor Anschlusspin
// *****************************************************
////////////////////////////////////////////////////////
//
// setupBoden
// A0 als analoger Input
// Deklaration eigentlich nicht nötig
//
////////////////////////////////////////////////////////
void setupBoden()
{
pinMode(BODENPIN, INPUT);
}
////////////////////////////////////////////////////////
//
// Gesamt Setup
// der Messstation
// Aufruf der Setups einzelner Sensoren
//
////////////////////////////////////////////////////////
void setup()
{
// Aufruf anderer setupXXX()-Methoden ...
setupBoden();
}
// ... andere messenXXX() Methoden
////////////////////////////////////////////////////////
//
// Boden-Messung
//
////////////////////////////////////////////////////////
void messenBoden()
{
unsigned int messwert = analogRead(BODENPIN);
Serial.println("******************* Boden Messung *******************");
Serial.print("Gemessen als Messwert : ");
Serial.println(messwert);
Serial.println();
}
////////////////////////////////////////////////////////
//
// Alle Messungen werden hier in loop aufgerufen
//
////////////////////////////////////////////////////////
void loop()
{
// Aufrufe anderer Messungen ...
messenBoden(); // Bodenfeuchtigkeit ermitteln
delay(1000);
}
Wer möchte, kann über ein Motor-Shield eine Wasserpumpe anschließen, die Pflanzen abhängig von der Erdfeuchtigkeit beziehungsweise -trockenheit mit Wasser versorgt. In der bereits erwähnten Anleitung von Sparkfun ist ein solches Projekt beschrieben.
Zusammenfassung
Die vorliegende Folge hat konkrete Umwelt-Sensoren fĂĽr UV-Strahlung (ML8511) sowie den Bodensensor YL-69 und den Regensensor YL-83 adressiert. Die Sensoren dienen als Komponenten einer Umwelt- und Wettermessstation.
Außerdem war von Sensor Shields die Rede. Wer mehrere Sensoren benutzen möchte, etwa um eine modulare Messstation aufzubauen, ist mit einem Sensor-Shield im Vorteil, da es sich genau für diese Art von Anwendung eignet. Speziell gilt dies dann, wenn es sich um dreipolige Sensoren handelt, die neben einem analogen/digitalen Anschluss noch Spannung und Erde benötigen, und nicht übermäßig Strom ziehen.
Allerdings funktioniert einfaches Anschließen von Sensor an Spannung, Erde und Dateneingang plus anschließendes Messung über einen Analogeingang nicht immer. Einige Sensoren benötigen stattdessen spezielle Messmethoden und -umrechnungen, andere erfordern diverse Interaktionen über I2C, 1-Wire oder SPI. Aus gutem Grund gibt es daher Arduino-Bibliotheken für komplexere Sensoren.
In Zukunft lernen wir weitere Beispiele von Sensoren kennen. Bei Mikrocontrollern und IoT geht es schließlich in erster Linie um Sensorik und Aktorik. Unter anderem begegnen uns auch noch solche Sensoren, die ein etwas komplexeres Handling benötigen, beispielsweise MQ-Gassensoren. ()