Lauschen mit Sensoren

Der Pragmatische Architekt  –  0 Kommentare

Diese Folge soll zum Einstieg in die Welt der Sensorik verhelfen. Sensoren messen bekanntlich Umweltgrößen wie Infrarotsignale, Ultraschallsignale, Temperatur, Druck, und Feuchtigkeit. In den gezeigten Schaltungen finden zwei unterschiedliche Sensoren Verwendung, um die Spannbreite der Sensorik kennenzulernen.

Sensoren liefern die Messwerte häufig als analoge Größen. Für das Lesen dieser Messwerte bieten Mikrocontroller wie der Arduino dementsprechend analoge Eingänge. Dort befindet sich ein Analog-Digital-Wandler (ADC), der den analogen Messwert linear in eine digitale Größe überführt. Am Arduino Uno bietet die Analog-Digital-Umwandlung 10 Bit Auflösung, also Werte von 0 bis 1023. 5 V am Eingang wandelt der ADC in 1023 um, 0 V entsprechend in 0. Der Arduino Due schafft sogar 12 Bit Auflösung (0 bis 4095 bei 0 V bis 3,3 V).

Es wird heiß

Die Schaltungen in dieser Episode sind ausschließlich der Messung von Temperaturen gewidmet. Dabei lernen wir zum einen den Umgang mit Temperatursensoren kennen, zum anderen die Tatsache, dass mehrere Wege nach Rom führen bzw. mehrere, unterschiedlich angesteuerte Sensoren zur Temperatur.

Ich benutze für die jeweiligen Schaltungen zum einen den TMP36-Temperatursensor, zum anderen den 18B20-Temperatursensor. Beide sind verbreitet, weisen aber größere Unterschiede auf.

Der Temperatursensor TMP36

Derr TMP36 Sensor in voller Pracht (Bild: ladyada.com)

Liest man das Datenblatt zum TMP36, so ist dort erläutert, dass der Baustein eine Eingangsspannung von 2,7 V bis 5,5 V verträgt, dabei von -40 °C bis 125 °C messen kann, eine Messgenauigkeit von +-2 Prozent garantiert, und einen Skalierungsfaktor von 10 mV pro 1 °C besitzt. Die benötigte Stromstärke befindet sich im Micro-Ampere Bereich.

Verbinden wir also den Temperatursensor direkt mit einem Analog-Eingang des Arduino.

Angenommen, wir verwenden den Sensor und schauen direkt auf dem flachen Teil des Kopfes. Dann verbinden wir das linke Beinchen des TMP36 mit 5 V Versorgungsspannung des Arduino, das rechte Beinchen mit GND und das mittlere mit dem analogen Eingang A0.

Schaltung mit Arduino Uno und TMP36-Sensor

Es wird spannend

Die gemessene Spannung am analogen Pin eines Arduino Uno errechnet sich aus 5/1023 * digitaler Wert (also dem vom Analog-Digital-Wandler gemeldeten Wert). Wir kehren also gewissermaßen die Analog-Digital-Wandlung um, um die Eingangsspannung zu ermitteln.

Die Temperatur errechnet sich anhand der Formel (gemessene Spannung - 0.5) * 100. Der Faktor 100 kommt dadurch zustande, dass der Skalierungsfaktor 10 mV pro °C beträgt und wir folglich mit 100 multiplizieren müssen, um die Spannung in mV zu erhalten, woraus sich dann die Temperatur in Celsius errechnet. Die subtrahierten 0,5 dienen zur Kalibrierung. Es handelt sich um die sogenannte Offsetspannung von 0,5 V.

Laut Datenblatt beträgt der Stromverbrauch des TMP36 rund 250 Micro-Ampere. Kein Problem also für ein Arduino-Board.

Das Programm

Nun können wir die Erkenntnisse in Code umsetzen:

const int tmp36_pin = 0; // tmp36 verbunden mit Analogeingang A0
void setup(void) {
// Wir senden die Daten zum seriellen Monitor der Arduino IDE
Serial.begin(9600);
}

void loop() {
float measureV, temperatureC;
// // Spannung = Wert von A0 * 5/1023
measureV = analogRead(tmp36_pin) * 0.004882814;
temperatureC = (measureV – 0.5) * 100;// Errechnen der Temperatur
Serial.print(“Temperature in °C = “); // Messwert an IDE senden
Serial.println(temperatureC);
delay(2000); // 2 Sekunden pausieren
}

Lassen Sie den Sketch auf dem Arduino-Board ablaufen. Um die Ausgabe des seriellen Monitors zu sehen, klicken Sie auf das Lupen-Symbol rechts oben im Sketch-Fenster.

Wenn Sie den Temperatursensor mit zwei Fingern umschließen, stellen Sie eine Erhöhung der Messwerte fest. Nach dem Loslassen, sinken die Werte wieder. Wie schnell (oder besser langsam) sich Messwerte ändern, finden Sie ebenfalls auf dem Datenblatt des Sensors.

Der Temperatursensor DS18B20

Der DS18B20 (Dallas) Temperatursensor

Der zweite betrachtete Temperatursensor DS18B20 (hier finden Sie das Datenblatt) ist insofern speziell, als er mit dem Mikrocontroller über das sogenannte 1-Wire-Protokoll kommuniziert. Sprich, die Temperaturwerte erhält der Mikrocontroller über eine digitale Datenleitung vom Sensor, ganz im Gegensatz zum TMP36, der analoge Werte liefert. Im parasitären Modus versorgt sich der Sensor über diese Datenleitung sogar mit Energie.

Schaltung mit Arduino Uno und Dalla-Sensor (DS18B20)

Das 1-Wire-Protokoll ähnelt ein wenig dem I2C-Protokoll, dem wir in Zukunft ebenfalls begegnen. Der Arduino agiert als Master, der Sensor als Slave. Jeder DS18B20-Sensor besitzt eine eindeutige 64-Bit Identifikation. Wir könnten daher auch mehrere Sensoren an denselben Eingang des Arduino anschließen.

Abläufe im 1-Wire Protokoll für Reset, Senden, und Lesen (Bild: wikipedia.org)

Der Messbereich des Sensors liegt zwischen -55 °C und 125 °C. Die Genauigkeit ist mit +-0,5 % besser als die des TMP36. Im aktiven Betrieb benötigt der DS18H20 um die 1,5 mA.

In dieser zweiten Schaltung verbinden wir das rechte Beinchen des Sensors mit der Versorgungsspannung (5 V) des Arduino Uno. Das linke Beinchen verbinden wir mit Arduino GND. Das mittlere Beinchen des Temperatursensors ist mit dem digitalen Pin 2 des Arduino verbunden. Zwischen diesem mittleren Beinchen und der Versorgungsspannung am rechten Beinchen fungiert ein 4,7 KOhm als Verbindung. Dies dient zum Unterbinden von ungewollten Signalen. Haben Sie keinen 4,7 KOhm vorrätig, können Sie stattdessen zwei andere Widerstände in serieller Schaltung verwenden, etwa zwei 2,2-KOhm-Widerstände.

Ganz programmatisch

Für den Arduino-Sketch benötigen wir noch zwei Bibliotheken: eine zum Kommunizieren mit 1-Wire und eine weitere zum Zugriff auf den Temperatursensor. Erstellen Sie einen neuen Sketch und inkludieren Sie die beiden Bibliotheken jeweils im Sketch-Menü der Arduino IDE. Dort gelangen Sie durch Auswählen von Include Library zu einem Pull-Down-Menü, dessen zweiter Menüpunkt Add .ZIP Library... das Einbinden von gezippten Bibliotheken erlaubt.

Hier der Sketch:

#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2 // Data wire => Digitaler Pin 2 des Arduino
OneWire oneWire(ONE_WIRE_BUS); // Initialisieren des 1-Wire Bus
DallasTemperature sensors(&oneWire); // Übergabe der 1-Wire Info

void setup(void) {
// Wie üblich nutzen wir den seriellen Monitor
Serial.begin(9600);
// Arduino als Master startet die Übertragung
sensors.begin();
}

void loop(void) {
// Nun starten die eigentlichen Abfragen
Serial.println("Arduino als Master ersucht um Messwerte");
sensors.requestTemperatures();
Serial.print(”Augenblickliche Temperatur: ");
// Wir nehmen einfach den ersten Sensor, den wir finden:
Serial.println(sensors.getTempCByIndex(0));
// …ByIndex(0) => :Gib mir den ersten Sensor
}

Falls Sie sich fragen, woher der Name Dallas kommt. Der Hersteller hieß früher Dallas.

Übrigens hat der Temperatursensor noch viele weitere Möglichkeiten, etwa das programmatische Konfigurieren der Auflösung von 9 bis 12 Bits. Falls Sie Interesse haben, studieren Sie einfach das Datenblatt.

Strategy Pattern

Wenn wir in einer Schaltung den TMP36-Sensor nutzen, dann aber auf den DS18B20 umsteigen wollen, müssen wir unsere Sketche anpassen. Dummerweise ist dies für alle Sensoren/Aktoren nötig, für die es verschiedene Varianten gibt, zwischen denen wir wechseln. Der Aufwand potenziert sich dadurch. (Zu) viel Arbeit für eine kleine Änderung!

Lässt sich der systemnahe Code von der eigentlichen Anwendung so trennen, dass es für den Anwendungscode weitgehend transparent bleibt, welche Variante von Temperatursensor wir nutzen? Voilà, hier kommt das Strategy-Pattern ins Spiel. Um zwei Fliegen mit einer Klappe zu schlagen, verwenden wir erneut die IoT/Robotik-JavaScript-Bibliothek johnny-five unter Node.js. Dort ist der Zugriff auf Komponenten genau so realisiert, wie wir es wünschen.

TMP36 an JavaScript

Ein JavaScript-Programm für die obige Schaltung wäre das folgende. Bitte nicht vergessen, vorher StandardFirmata aus dem Examples-Menü der Arduino-IDE auf Ihr Arduino-Board zu laden. Sonst funktioniert die Kommunikation zwischen Host und Microcontroller nicht.

// Programm j5-temperature-TMP36.js:
var five = require("johnny-five");

five.Board().on("ready", function() {
var temperature = new five.Thermometer({
controller: "TMP36",
pin: "A0"
});

temperature.on("change", function() {
console.log(this.celsius + "°C");
});
});

Der Funktion temperature.on übergeben wir einen Anweisungsblock, dessen Ausführung immer dann erfolgt, wenn sich die Temperatur ändert ("change"). Im besagten Codeblock erfolgt lediglich die Konsolenausgabe der gemessenen Temperatur.

Starten Sie das Programm mit

node j5-temperature-TMP36.js

DS18B20 an JavaScript

Nun dasselbe Skript angepasst für DS18B20. In diesem Fall reicht StandardFirmata nicht aus. Stattdessen installieren wir zunächst ConfigurableFirmata als Bibliothek und benötigen zusätzlich den Firmata-Builder, mit dem wir die gewünschten Features wie 1-Wire konfigurieren. Das Werkzeug generiert online einen Arduino-Sketch (Endung .ino), den wir herunterladen und auf das Arduino-Board laden. Nachdem das erledigt ist, können wir das serverseitige JavaScript-Programm unter Node.js starten. Sie erkennen sehr leicht, dass sich der Code nur bezüglich der Instanziierung des Thermometer-Objekts vom vorangegangenen Script unterscheidet.

// Programm j5-temperature-DS18B20.js

var five = require("johnny-five");
five.Board().on("ready", function() {
var temperature = new five.Thermometer({
controller: "DS18B20",
pin: 2
});

temperature.on("change", function() {
console.log(this.celsius + "°C");
});
});

Starten Sie das Script mit

node j5-temperature-DS18B20.js

Interessant ist übrigens auch ein Vergleich der Messwerte beider Temperatursensoren, sollten Sie beide Typen besitzen.

How it works

Wie funktioniert eigentlich ein Temperatursensor? Eine gute Beschreibung bietet diese Seite bei Instructables.com. Kurz umrissen, bestehen Temperatursensoren aus Dioden. Deren Spannungsabfall verhält sich direkt proportional zur Temperatur. Eine Verstärkung des resultierenden Signals sorgt für präzisere Messwerte.

Zusammenfassung

In dieser Folge haben wir uns mit den Temperatursensoren TMP36 und DS18B20 beschäftigt, die völlig unterschiedlich angesteuert werden. Johnny-Five zeigt aber, dass sich die Unterschiede durch Anwendung des Strategy-Patterns geschickt verbergen lassen.

In der nächsten Folge erweitern wir unseren Temperatursensor mit der Temperatur-Ausgabe auf einem kostengünstigen 16x2 oder 20x4-LCD-Display. Dadurch erhalten wir eine rudimentäre aber ausbaubare Wetterstation. Ganz nebenbei kommt dann auch der IIC-Bus zur Sprache.