Feuchtigkeitssensor und RS-232 mit Java

In diesem Projekt ging es um die Ansteuerung bzw. das Auslesen eines (Luft-)Feuchtigkeitssensors mit Hilfe der Programmiersprache Java. Das Projekt entstand im Rahmen der b.i.b. Ausbildung in Paderborn zusammen mit André Knaub. Die komplette Schaltung und der Quellcode sind vorhanden.

Planung des Projektes

Aufgabenstellung

Aufbau einer Schaltung zum Messen der relativen Luftfeuchtigkeit. Schaltungsidee von Dr. O. Hochmuth. Javaprogramm zum Auslesen der Frequenz (die Schaltung setzt den Widerstand des Sensors in eine Frequenz um) und Umrechnen in die relative Luftfeuchtigkeit.

Originalschaltung:

In unserer Schaltung wurde der Feuchtigkeitssensor H515P durch den ähnlichen Baustein EFS-10 (Datenblatt) ersetzt. Die Operationsverstärker TLC272 wurden durch gleichwertige ICs ersetzt, in unserem Fall durch den TL084 (Datenblatt). Die Schottky-Diode BAT46 wurde durch eine BAT43 ersetzt, da keine BAT46 vorhanden war.

Zielsetzung

Das Ziel der LEA war das erstellen einer passenden Schaltung und das Schreiben eines kompletten Programms zum Auslesen des Sensors und Darstellen der Werte auf einem Computer.

Analyse benötigter Soft- und Hardware

Zum Auslesen der Frequenz benötigten wir eine Zwischenstation zwischen Computer und Schaltung. Wir benutzten das Digitalmultimeter Metex M-3660D das über eine serielle Schnittstelle (RS-232) als Ausgang verfügt, über die der aktuelle Messwert der Frequenz ausgelesen werden konnte. Auf der Softwareseite nutzten wir Eclipse 3.1 zum Programmieren des Javaprogramms.

Die Komponenten wurden wie folgt verbunden:

Zeitplanung

Die Zeitplanung für die Ausführung der einzelnen Phasen wurde bereits im Vorfeld getätigt.
Alle benötigten elektronischen Bausteine, das Digitalmultimeter sowie Informationen zum Ansprechen der RS-232 Schnittstelle unter Java wurden vor der LEA besorgt und getestet.
Dadurch konnte direkt am ersten Tag mit dem Aufbau der Schaltung begonnen werden und die Arbeit ging gut voran.

Durchführung des Projektes

Aufbau der Schaltung

Die Schaltung wurde vorerst auf einem einfachen Steckbrett realisiert um etwaige Änderungen schnell und unkompliziert durchführen zu können. Nach dem Aufbau entstanden beim Testen folgende Probleme:

GND war an einer Stelle nicht richtig verbunden, dadurch entstanden seltsame Messwerte und große Schwankungen der Frequenz.
Ein weiteres Kabel hatte schlechten Kontakt zum Steckbrett, dadurch ähnliche Folgen wie im ersten Punkt.
Potentiometer hatte zu kurze Beinchen bzw. es passte mechanisch nicht in das Steckbrett. Daher wurden 3 kurze Kabel an das Potentiometer gelötet um es ohne Probleme in das Steckbrett einsetzen zu können.

Nach der Lösung der oben stehenden Probleme wurde die Schaltung auf eine Platine gelötet um eine feststehende Schaltung zu erhalten.
Dabei war besonders darauf zu achten, dass die Lötpunkte guten Kontakt zu den einzelnen Verbindungspunkten hatten und besonders die ICs beim löten nicht überhitzt wurden.
Zur Stromversorgung (schwarz und rot) und zur Messung der Frequenz (blau) wurden die Bananensteckerbuchsen angebracht.

Bei dem Aufbau der Schaltung kamen folgende Fragen auf:

  • Mit welcher Spannung muss die Schaltung betrieben werden?
  • Gleichstrom oder Wechselstrom?

Durch studieren der Datenblätter wurden die Fragen wie Folgt gelöst:

Laut des Datenblattes des ICs kamen wir auf 12V Gleichspannung zur Stromversorgung der Schaltung und der ICs.

Testen der Schaltung

Zum Testen der Schaltung wurde das DSO benutzt, da an verschiedenen Punkten in der Schaltung verschiedenen Schwingungsarten auftreten mussten.

Insgesamt wurden 3 verschiedene Arten gemessen.

Die gelbe Kennlinie zeigt das Auf- und Entladen des Kondensators C1 in der Oszillatorschaltung (siehe Schaltung oben).
Die violette Kennlinie zeigt die Spannung am Ausgang des ICs der Oszillatorschaltung.
Die pinke Kennlinie zeigt die Spannung am zweiten Kondensators C2 (siehe Schaltung).

Die Kennlinien entstehen durch folgende Komponenten:

Der Kondensator C1 (gelbe Kennlinie) der Oszillatorschaltung wird in Form einer e-Funktion auf- und entladen.
Der IC der Oszillatorschaltung macht aus diesem Signal ein Rechtecksignal (violette Kennlinie) mit einer widerstandsabhängigen Frequenz. Als widerstandsbestimmender Baustein dient der Feuchtigkeitssensor EFS-10 (siehe Schaltung).
Der zweite Kondensator (siehe Schaltung) wird aufgeladen und sehr schnell entladen. Dadurch entsteht eine Sägezahnspannung (pinke Kennlinie).

Da durch den Feuchtigkeitssensor, der als Widerstand dient, die Frequenz gesteuert werden soll, sollte am Ausgang der Schaltung (Output) eine veränderliche Frequenz gemessen werden können.

Dies wurde mit dem DSO überprüft und bestätigt.

Niedrige Frequenz:

Hohe Frequenz:

Auch kann an dem betrachten der Spannung am Kondensator C1 (siehe Schaltung) und dem Ausgang des ersten ICs die Funktion des selbigen verdeutlicht werden.

Sobald sich der Kondensator C1 auflädt, setzt der IC den Ausgang auf high, also eine bestimmte Spannung. Sobald der Kondensator sich wieder zu entladen beginnt, wird der Ausgang auf low (Spannung gegen 0) gesetzt. Somit steuert der Kondensator C1 den Ausgang der ICs.

Programmieren des Javaprogramms

Um das Digitalmultimeter auslesen zu können musste mit Java die serielle Schnittstelle (RS-232) angesteuert werden.

Auf der Seite von Sun Microsystems1 gibt es dazu eine fertige Klassensammlung inklusive DLL Dateien zum ansprechen der Schnittstelle unter Java. Von Haus aus ist diese Funktion bei Java nämlich nicht vorgesehen und muss extra installiert werden. Da für die Installation Administratorrechte benötigt werden war dies nicht ohne weiteres auf den Rechnern des b.i.b. Paderborn möglich. Als Workaround wurde das komplette JRE (Java Runtime Environment) auf unser Arbeitslaufwerk kopiert und dort angepasst. Anschließend wurde in Eclipse 3.1 der Pfad geändert sodass unser angepasstes JRE genutzt wurde. Somit war das Ansteuern der Schnittstelle rein technisch möglich.

Das Digitalmultimeter M-3660D von Metex2 schickt seine Messwerte über ein spezielles Kabel zur RS-232 Schnittstelle.
Das Kabel ist in Deutschland schwer zu bekommen, war dann aber nach einer freundlichen Mail über die CL Electronics GmbH3, einem Schweizer Elektronikunternehmen, erhältlich.

Ein weiteres Problem war die Kommunikation mit dem Messgerät, welches nur Daten an die serielle Schnittstelle sendet wenn man es explizit dazu auffordert.
Hierzu muss ein „D“ an das Messgerät geschickt werden, eine Fehlerquelle ist hier das man kein großes „D“ sondern ein kleines „d“ schickt, was dann nicht verstanden wird.

Leider funktionierte dies mit der Standart Communication API4 von Sun nicht. Durch nachlesen in diversen Javaforen5 kam die Idee eine andere API zur Kommunikation zu benutzen. Das RXTX Projekt6 von Keane Jarvi bietet zahlreiche Möglichkeiten mit Java auf die serielle oder parallele Schnittstelle zuzugreifen. Auch werden auf der Seite und besonders im zugehörigen Wiki7 gute Informationen und Tipps zum Steuern der Schnittstelle geliefert.
Unser Javaprogramm basiert auf einer Beispielklasse8 die unter der GNU Free Documentation License9 veröffentlicht wurde. Somit ist die Klasse für den freien Gebrauch zugänglich und muss, laut Lizenz, nach der Veränderung wieder öffentlich zugänglich gemacht werden.

Nach der Installation der RXTX Komponenten und dem kompilieren der Beispielklasse lief die Kommunikation problemlos.
Das einzige Problem war noch das senden des „D“ um Werte vom Messgerät lesen zu können. Um gleichzeitig etwas zu schreiben und zu lesen war die Nutzung von Threads unumgänglich.
Threads sind einzelne Programmteile die für sich selbst laufen, mehrere Threads können somit parallel laufen und jeder Thread kann für sich angehalten oder schlafen gelegt werden, ohne dass das ganze Programm gestoppt werden muss.
Die Beispielklasse des RXTX Projektes arbeitete auch schon mit Threads, diese wurden übernommen und erweitert bzw. an unsere Aufgaben angepasst.

Senden von Daten:

Das Senden erfolgt in Java über die Methode write(), die jedoch nur Integerwerte, also Ganzzahlen, senden kann. Das „D“ muss demnach vorher in eine Ganzzahl konvertiert werden (Quellcode).

Lesen von Daten:

Das Lesen erfolgt über die Methode read(), diese liest Bytes in einen Puffer der dann weiter verwendet werden kann.

Kommunikationsschema Metex M-3660D <=> Java:

Die Kommunikation läuft so ab das wir jede Sekunde ein „D“ an das Messgerät senden und alle 2 Sekunden ein Messwert auslesen. So ist gewährleistet das immer ein aktueller Wert gelesen wird. Schreiben bzw. Lesen laufen in jeweils eigenen Threads ab, sind somit also voneinander unabhängig.

Umsetzen der ausgelesenen Frequenz in relative Luftfeuchtigkeit:

Die Frequenz liegt nun im Programm vor, muss aber noch in die relative Luftfeuchte umgerechnet werden. Dies geschieht anhand einer größeren Formel die am Besten im Quelltext ersichtlich wird. Da im Datenblatt des Sensors nur eine Tabelle für den Widerstand in Bezug auf Temperatur und Luftfeuchtigkeit zu finden war, mussten wir die Formel selber entwickeln. Leider ist sie nicht 100% genau da uns passende Kalibrierungswerkzeuge fehlten.
Sie passt jedoch schon recht gut und für grobe Messungen (± 2%) reicht es vollkommen aus.

Somit konnte der Messwert auf der Konsole ausgegeben werden.
Als nächstes musste das Ganze in eine grafische Oberfläche gepackt werden.

Hierzu wurden die Swingklassen von Java benutzt. Nachdem die grobe Oberfläche kein Problem darstellte gab es einen großen Haken, das JLabel was die aktuellen Messwerte darstellen sollte aktualisierte sich nicht.
Das Problem konnte erst nicht erklärt werden da an der Syntax alles stimmte.
Nach einigen Recherchen bei Google war klar das Swing nicht threadsicher ist.
Das heißt, dass Swingkomponenten nicht synchronisiert sind, wenn sie also in verschiedenen Threads laufen, können diese nicht untereinander kommunizieren und sich nicht gegenseitig verändern. Um das Problem zu lösen wurde ein Workaround genutzt der Swingthreads in AWT-Threads packt. Das AWT (Abstract Window Toolkit) ist zwar älter, wurde damals aber threadsicher konzipiert und ermöglicht das synchronisieren unter verschiedenen Threads.
Mit einer speziellen Methode (invokeLater()) kann ein Swing Thread in ein AWT Thread eingebettet werden und wird dann dort ausgeführt10.

Am Ende wurde noch ein Messbalken zum Programm hinzugefügt der die aktuelle Frequenz grafisch darstellt, so ist eine Veränderung noch besser sichtbar.

Quellenverzeichnis

1) http://java.sun.com

2) http://www.imetex.com

3)

4) http://java.sun.com/products/javacomm/

5) bzw.

6) http://www.rxtx.org

7) http://www.gnu.org/copyleft/fdl.html

8) http://openbook.galileocomputing.de/javainsel7/

7 Gedanken zu „Feuchtigkeitssensor und RS-232 mit Java

  • 22. September 2008 um 19:32
    Permalink

    Super! Das hilft mir bei meinem eigenen Projekt schon sehr viel weiter! Sehr gut wie viel Arbeit ihr dort investiert habt.

    Antworten
  • 9. Oktober 2008 um 05:03
    Permalink

    Hallo,
    ein WordPressnutzer mehr ;).
    Respekt bisher kann ich nur staunen o_O^^

    Antworten
  • 10. Februar 2012 um 16:03
    Permalink

    hallo,

    kan man den verfasser diese artikels irgendwie erreichen?

    DAnke im Voraus,

    christian

    Antworten

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.