www.imkerei-hilgertshausen.de

Süße Bienen voll verkabelt

Die Bienenstockwaage

Allgemeines

Wägezellen (Wägesensoren)

Wägezellen sind eine Sonderform der Kraftaufnehmer (Kraftsensoren) zum Aufbau von Wägevorrichtungen, z. B. Waagen. Sie sind in Gramm (g) Kilogramm (kg) oder Tonnen (t) kalibriert, nicht in Newton (N) wie die Kraftaufnehmer. In der Praxis sind jedoch weit mehr Wägezellen als Kraftaufnehmer im Einsatz. Man unterscheidet grundsätzlich zwischen elektronischen Waagen, die Masse ohne mechanische Zwischenstufen oder -größen ermitteln (EMK = Elektronische Kraftkompensation) und elektromechanischen Waagen, die Masse über mechanische Zwischenstufen und –größen ermitteln (z. B. über Dehnungsmessstreifen = DMS). DMS-Wägezellen gehören zu den erfolgreichsten elektromechanischen Waagen.

Das DMS-Messprinzip entspricht dem Prinzip einer Federwaage. Diese stellt sich selbst in die Gleichgewichtslage und zeigt auf einer entsprechenden Anzeige den Massenwert an. Die Funktion der Feder wird durch einen verformbaren und elastischen Messkörper, eine spezielle Messfeder, einen Hohlzylinder, einen Stab oder einen Ring ersetzt. Interessant ist die besondere Federsteifigkeit des Messkörpers. Diese wird besonders groß ausgelegt (c > 5*104N/mm), um die Auslenkung des verwogenen Materials oder Objektes möglichst gering zu halten. Die Gewichtskraft selbst erzeugt eine Auslenkung, bzw. eine Längenänderung des Messkörpers. Dies geschieht innerhalb von Grenzen, die durch das Hookesche Gesetz beschrieben werden. So wird die Messung der Längenänderung des Messkörpers durch die DMS auf dem Messkörper sehr exakt messbar.

Die folgende Abbildung zeigt verschiedene Bauformen:


(Quelle: "Handbuch Dosieren" von G. Vetter, Vulkan Verlag, Essen, 1994)

a) Stauchzylinder 5 t - 1000 t; b) Stauchzylinder (hohl) 1 t - 10 t; c) Ringverwölbung/Ringtorsion 60 kg - 1000 t; d) Ring 1 t – 10 t; e) Doppelbiegebalken (vereinfacht) mit Kraftrückführung 10 kg - 500 kg; f) Plattformwägezelle 5 kg - 20 kg; g) Doppelbiegebalken (vereinfacht) 50 kg - 5 t; h) Scherbiegebalken 100 kg - 50 t; i) Doppelbiegebalken 10 kg - 1 t; k) Einfachbiegebalken mit Kraftrückführung 5 kg - 100 kg

Biegebalken-Sensoren

Hier soll nur die Technik des Biegebalken-Sensors weiter betrachtet werdden. Die Sensoren haben alle ungefähr den gleichen Aufbau. Das folgende Foto zeigt einen typischen Vertreter dieser Gattung.

Beim Biegebalken mit Dehnungsmessstreifen wird die Zelle in einer "Z"-Form aufgebaut, so dass ein auf die Wägeplatte ausgeübtes Drehmoment auf vier Dehnungsmessstreifen an der Zelle wirkt. Zwei der DMS (blau) werden gedehnt und zwei DMS (rot) gestaucht. Wenn diese vier Dehnungsmessstreifen in einer Brückenschaltung aufgebaut sind, ist es einfach, die kleinen Widerstandsänderungen von den Dehnungsmessstreifen genau zu messen.

Die Dehnungsmessstreifen haben einen typischen Widerstnadswert von 120 Ω, 350 Ω oder 1000 Ω. Die Widerstandsänderung bei der Verformung des Sensors ist sehr klein. So wird eine Elektronik benötigt, welche diese kleinen Änderungen im Widerstand verstärkt. Dieser Verstärker arbeitet als sogenannter Brückenverstärker.

Messverstärker und Interface

Widerstands-Messbrücke

Eine Widerstands-Messbrücke ist eine Schaltung aus zwei parallelgeschalteten Spannungsteilern. Die Verbindung zwischen A und B wird als Brücke bezeichnet. Die Gesamtspannung teilt sich an den Widerständen auf. Wenn das Verhältnis der Spannungsteilerwiderstände gleich groß ist, dann haben beide Punkte gleiches Potential. Besteht zwischen diesen beiden Punkten ein Potentialunterschied, so fließt ein Strom von A nach B bzw. umgekehrt. Die Veränderung der Gesamtspannung hat keine Auswirkung auf die Potentialdifferenz zwischen Punkt A und B.

Die Brückengleichung lautet

   R1/R2 = R3/R4
Ist die Brückengleichung (Abgleichbedingung) erfüllt, dann ist die Schaltung abgeglichen. Die Widerstandsverhältnisse sind dann gleich. Das Amperemeter steht auf 0. Wird nur ein einziger der Widerstände verändert, so ist die Brücke zwischen Punkt A und B nicht mehr abgeglichen, die Widerstandsverhältnisse sind nicht mehr gleich und es fließt ein Ausgleichsstrom. Genau das geschieht beim Belasten des Wägesensors.

Für die Anbindung an einen Mikrocontroller ist es günstiger, eie Spannung zu messen und keinen Strom, weil die A/D-Wandlereingänge für die Spannungsmessung konzipiert sind. Mit Hilfe des Ohm'schen Gesetztes läßt sich die Brückengleicung erweitern. Ue ist eine konstante Eingangsspannung, und die resultierende Ausgangsspannung Ua wird gemessen. Wenn die Brücke ausgeglichen ist, dann ist Ua = 0, gibt es dagegen eine Änderung des Wertes eines der Widerstände, kann dies über Ua gemessen werden. Dabei gilt die folgende Gleichung entsprechnd dem Ohm'schen Gesetz:

                  R3            R2
   Ua = Ue * (---------  -  ---------)
               R3 + R4       R1 + R2
Im Fall des Wägesensors werden die vier Brückenwiderstände jeweils durch Dehnungsmessstreifen ersetzt.

Messverstärker HX711

Der HX711 enthält nicht nur die analogen Brückenverstärker, sondern auch einen hochauflösenden 24-Bit-A/D-Wandler mit einem SPI-ähnlichen seriellem Interface zum Mikrocontroller. Für die Auswertung des Wägesensors nahezu ideal. Das folgende Bild zeigt die prinzipielle Beschaltung aus dem Datenblatt:

Es gibt von diversen Anbietern kleine Breakout-Boards mit der kompletten Beschaltung des HX711 zu kaufen, man muss also nicht selber löten. Neben EBay und Amazon bieten Sparkfun, Adfruit, EXP-Tech und andere solche Breakout-Boards an, die fast alle die gleiche Schaltung aufweisen - welche sich recht stark am Datenblatt orientiert. Manche der erhältlichen Boards weichen jedoch davon ab. Auch neigen einige Plantinen zu einer größeren Toleranz der Messwerte, haben eine höhere Temperaturempfindlichkeit oder weisen größere Messfehler auf, wenn das Board zuvor abgeschaltet bzw. im Power-Down-Modus gewesen ist. Das folgende Bild zeigt eine typische Beschaltung des HX711 und links unten ein Foto des Breakout-Boards von Sparkfun stellvertretend für alle anderen.

Das HX711-Board akzeptiert fünf Leitungen aus der Wägezelle. Die Lötpunkte auf dem Breakout-Board sind schon mit den typischen Kabelfarben der Wägezellen beschriftet; RED (rot), BLK (schwarz), WHT (weiss), GRN (grün) und YLW (gelb). Diese Farben entsprechen der herkömmlichen Farbcodierung der Wägezellen, wobei der rote, schwarze, grüne und weiße Draht von dem Dehnungsmessstreifen stammen und die gelbe Litze eine optionale Masseleitung ist, die nicht mit den Dehnungsmessstreifen verbunden ist, aber Verbindung zum Metallkörper der Wägezelle hat. Manchmal gibt es anstelle einer gelben Leitung einen etwas stärkeren schwarzen Draht, eine Folie oder nicht isolierte Drähte, um die Signalleitungen abzuschirmen. Die vier Drähte, die aus der Wheatstone-Brücke auf der Wägezelle kommen, sind in der Regel:

Manche Wägezellen können leichte Variationen in der Farbcodierung der Leitungen haben, beispielsweise blau statt grün, gelb statt schwarz oder weiß usw. - insbesondere wenn es nur vier Drähte gibt, also die Abschirmung fehlt. Liefert der HX711 entgegengesetzte Messwerte (z. B. sinkender Wert, wenn das Gewicht erhöht wird), müssen nur die Leitungen O+ und O- vertauscht werden.

Auf der Controllerseite werden die Signale VDD (Stromversorgung des Digitalteils), VCC (Stromversorgung des Analogteils), DAT (Daten), CLK (Takt) und GND (Masse) angeschlossen. VCC, die analoge Spannungsversorgung und VDD, die digitale Versorgungsspannung, können in vielen Fällen miteinander verbunden werden. Nur, wenn Ihr Mikrocontroller mit 3.3 V versorgt wird, dann muss VCC mit 5 V und VDD mit 3.3 V verbunden werden. Bei manchen Boards sind die Anschlüsse VCC und VDD schon auf dem Board durch eine Leiterbahn verbunden (hier müsste man bei 3.3 V Controllerspannung die Leiterbahn unterbrechen), bei anderen Boards sind VCC und VDD getrennt und müssen ggf. verbunden werden.

Über einen Jumper am RATE-Eingang des HX711 kann die Datenrate eingestellt werden. Ist der Anschluss mit GND verbunden, beträgt die Datenrate 10 Messungen pro Sekunde, ist der RATE-Pin über einen Pullup-Widerstand mit VCC verbunden, beträgt die Datenrate 80 Messungen pro Sekunde. Das Signal ist dann aber wesentlich stärker mit Rauschen überlagert und somit nicht ganz so genau.

Waagen-Mechanik

Zum Wiegen eines Kastens wird eine Träger-Plattform benötigt, die den Wägesensor enthält. Diese Plattform muss für einen sicheren Aufbau etwa so gross wie die Grundfläche des Kastens sein, also ca. 50 cm x 60 cm groß sein. Die Nennlast liegt bei 100 - 150 kg. Beim Aufbau muss die Wägezelle möglichst mittig unter der Plattform montiert werden. Die Trägerplattform besteht aus zwei identischen H-förmigen Rahmen aus Vierkantrohr, die über die Wägezelle miteinander verbunden sind.

Diese Rahmenkonstruktion kommt dann einfach zwischen Kasten und Unterbau. Gegebenenfalls bringt man noch Puffer an den Enden der Schenkel an, um eine zu starke Verschränkung der H-Rahmen zu vermeiden. Die Wägezelle wird, wie gsagt, zwischen den beiden Rahmen in der Mitte angebracht.

Zur Verkabelung bietet es sich an, die Verbindungen steckbar zu machen. Für diesen Zweck können RJ45-Buchsen und Netzwerkkabel verwendet. Hier stehen nicht nur genügend Leitungen zur Verfügung, sondern es lassen sich für die Verdrahtung handelsübliche Patch-Kabel aus der Netzwerktechnik verwenden. Deren Qualität übertrifft die für das Wäge-Signal nötigen Parameter bei weitem. Die Kabel sind abgeschirmt, in verschiedenen Längen und Farben erhältlich und preiswert. Als "Mehrfachsteckerleiste" für die RJ45-Buchsen wurde eine Platine entworfen, auf der fünf Signalleitungen zur Verfügung stehen (siehe Links am Ende der Seite):

PinSignal
1VCC
3VDD
5DAT
7SCLK
8GND

Software für den Arduino

Bei Sparkfun bzw. Github stehen neben einer HX711-Bibliothek auch Kalibrierungs- und Beispielprogramme für den Arduino bereit (siehe Links unten), die man sich herunterladen kann. Hier sollen deshalb nur die verwendeten Programme besprochen werden, nicht jedoch die recht gut dokumentierte und übersichtliche Bibliothek.

Tara und Skalierung

Ist alles fertig aufgebaut und steht der Kasten sicher auf der Waagekonstruktion, stehen noch das Ermitteln des Taragewichts und die Kalibrierung an. Mit dem Taragewicht ist das das Gewicht der Wägekonstruktion und des Kastens gemeint. Das lässt sich bei einem "bewohnten" Kasten nur schwer feststellen. Wenn man Glück hat, kann man mit einem leeren Kasten einen Versuchsaufbau zum Messen des Tara aufstellen und von dem ermittelten Wert das Tara der anderen Kästen ableiten. Letztendlich geht es aber nicht um den Absolutwert, sondern um die Zu- oder Abnahme des Gewichts. Man kann mit der Waage recht gut sehen, wann die Bienen morgens ausfliegen und wie sich die Honigernte über die Wochen vermehrt. Auch hier gibt es Schwankungen, das Gewicht kann auch mal etwas sinken, wenn z. B. dem frischen Nektar das Wasser entzogen wird. Für das Ermitteln des Tara kann man das ganz normale Mess-Programm verwenden. Oder man verzichtet ganz auf die Ermittlung eines genauen Tara-Gewichts.

Durch die Skalierung werden die Messwerte des HX711 in brauchbare Einheiten umgerechnet, beispielsweise in Gramm. Dazu muss ein Kalibrierungsfaktor ermittelt werden, der dann im Messprogramm verwendet wird. Dazu wird ein Extra-Programm verwendet, das beim Arduino interaktiv über den seriellen Monitor der Arduino-IDE kommuniziert. Vor der Kalibrierung muss die Wägekonstruktion mehrmals stark belastet und wieder entlastet werden, damit sich die Mechanik setzen kann. Bei manchen Wägezellen tritt auch eine gewisse Trägheit bei hohen, kurzzeitigen Lastwechseln auf, die in der Praxis selten vorkommen. Man sollte also nach dem Belasten der Konstruktion genügend lange warten, bevor man mit der Kalibrierung beginnt. Gegebenenfalls muss man nach einiger Zeit des Betriebs noch einmal nachkalibrieren.

Das Kalibrierungs-Programm

Bei Sparkfun bzw. Github gibt es zwar ein Kalibrierungsprogramm, jedo bezieht sich das auf amerikanische Gewichtseinheiten. Deshalb wird hier das Programm von Thorsten Gurzan (https://beelogger.de) verwendet. Das Programm zur Kalibrierung ist interaktiv und kommuniziert über den seriellen Monitor. Der Ablauf wird im folgenden geschildert. Wer sich über die etwas umständliche Eingabe mit Zahl und 'Enter' wundern sollte: das liegt am Verhalten des seriellen Monitors. Da das Programm aber selten eingesetzt wird, macht das nichts weiter aus. Nun zum Ablauf:

  1. Das Programm gibt den Text "Waage ohne Gewicht – Kalibrierung mit '1' und 'Enter' starten!" aus. Nach der Eingabe wird der aktuelle Messwert der Brücke (= Taragewicht) ermittelt.
  2. Nun folgt die Ausgabe "Waage mit genau 1 kg belasten – Kalibrierung mit '2' und 'Enter' starten!" Anhand der Gewichtszunahme wird die Skalierung ermittelt. Das Referenzgewicht von 1 kg kann man mit einer Küchenwaage etc. ermitteln. Wichtig ist, dass es wirklich genau 1 kg sind, sonst sind später alle Messwerte falsch.
  3. Es erfolgt die Ausgabe "Kalibriere" und danach "Pruefe Gewicht:" Bei erfolgreicher Kalibrierung sollte der angezeigte Wert fast genau 1000 Gramm betragen. Sollte dies nicht der Fall sein, muss die Kalibrierung wiederholt werden.
  4. Abschließend werden Taragewicht und Skalierung ausgegeben. Diese Werte sind im Programmcode der Messprogramms zu hinterlegen.
Das Kalibrier-Programm erwartet den Anschluß des HX711 an den Pins 2 (DATA) und 3 (CLK). Ist die Wägezelle an anderen Pins des Arduino angeschlossen, muss der Code entsprechend angepasst werden (Aufruf von HX711 scale(2, 3)).

Das Messprogramm

Das Messprogramm kann bis zu acht Waagen abfragen. Die ermittelten Gewichtsdaten werden über die serielle Schnittstelle ausgegeben. Beim Testen kann die Daten mit dem seriellen Monitor der Arduino-IDE ansehen. Im Betrieb ist der USB-Anschluss des Arduino mit dem USB-Anschluss eines Raspberry Pi verbunden (oder dem USB-Anschluss eines beliebigen Linux-PCs). Über die USB-Verbindung werden der Arduino und die HX711-Bausteine auch mit Energie versorgt, wobei jeder HX711 gerade mal ca. 1,5 mA Strom benötigt. Auf Seiten des Raspberry Pi nimmt ein Python-Programm die Daten zur weiteren Verarbeitung entgegen. Das Messprogramm ist für die Arduino-Modelle "Uno" und "Nano" konzipiert. Prinzipiell ist eine Erweiterung auf andere Boards der Arduino-Familie möglich.

Für den Anschluss der acht Waagen ergibt sich dann die folgende Pin-Zuordnung der HX711-Bausteine zum Arduino UNO/NANO. Es werden zuerst die Digital-Ports D2, D3 usw. genommen und dann die Analog-Ports A0, A1 usw., die als Digital-Ports eingesetzt werden. Die Digital-Ports 12 und 13 sind ausgespart wg. der am Port 13 angeschlossenen On-Board-LED.

Waage Nr.DataClock
1D2D3
2D4D5
3D6D7
4D8D9
5D10D11
6A0A1
7A2A3
8A4A5

Datenformat und -ausgabe

Der Arduino ermittelt und sendet die Daten in regelmäßigen Zeitabständen. Das Intervall in Sekunden wird durch die Konstante LOOP_DELAY festgelegt. Die Ausgabe der Daten erfolgt als eine Zeile, die mit '$' beginnt und mit Newline abeschlossen wird. Nach dem '$' kommen die Gewichte (Datentyp: long) in Gramm. Die Anzahl der abzufragenden Waagen wird durch die Konstante NR_WEIGHTS festgelegt (1 bis 8). Diese Konstante bestimmt auch die Dimension der Array für die Daten, Tara-Werte usw. Bei Fehlmessungen oder wenn das Gewicht kleiner als die Konstante WEIGHTMIN ist, wird als Gewicht -1 geliefert. Bei Gewichtswerten, die kleiner 0 sind - was gelegentlich bei Erschütterungen des Kastens und der Waage oder bei heftigen Temperaturschwankungen auftreten kann - wird 0 geliefert. Das Programm hat zwar die Möglichkeit der Temperaturkompensaton vorgesehen; die Implementierung erschien bisher jedoch nicht nötig.

Programm-Konstante, vordefinierte Arrays

Es gibt einige Konstante, die helfen sollen Messfehler oder unplausible Werte auszuschließen. Ob wirklich alle Grenzen benötigt werden und ob die Konstanten noch angepasst werden müssen, kann erst ein Langzeitbetrieb zeigen. So ist neben Minimum und Maximum auch win Wert definiert, der die maximale Differenz zweier aufeinanderfolgender Messungen auf 300 g festlegt (ERROR_WEIGHT). In diesem Fall wird zur Sicherheit die Messung nach einer kurzen Wartezeit wiederholt. Der Fall kann ja auch auftreten, wenn der Deckel des Kastens abgenommen wird. Für die Maximal acht Waagen werden alle notwendigen Werte (Tara, Skalierung, etc.) und die Messergebnisse in globalen Arrays festgehalten. Die Werte dieser Arrays werden teilweise bei der Kalibrierung ermittelt und dann im Programm eingetragen:

// Voreingestellte Kalibrierwerte, vom Benutzer einzustellen 
// mit Kalibrierprogramm f. Kanal 0
long  Taragewicht[NR_WEIGHTS] = {-160942L, -160942L, -160942L, -160942L,
                                 -160942L, -160942L, -160942L, -160942L}; 

// Skalierung ist fix und wird bei Kal. nicht veraendert
float Skalierung[NR_WEIGHTS] = {-29.32, -29.32, -29.32, -29.32, 
                                -29.32, -29.32, -29.32, -29.32};

// Speichern des letzten Messwerts
long  LetztesGewicht[NR_WEIGHTS] =  {WEIGHTMAX, WEIGHTMAX, WEIGHTMAX, WEIGHTMAX, 
                                     WEIGHTMAX, WEIGHTMAX, WEIGHTMAX, WEIGHTMAX};
// aktueller Messwert
long  Gewicht[NR_WEIGHTS] = {0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L};

// welche Waagen sind ansprechbar (dynamisch ueberprueft)?
byte active_scale[NR_WEIGHTS] = {0, 0, 0, 0, 0, 0, 0, 0};

// Waagen-/Pin-Definition UNO, Nano: Reihenfolge: HX711(DATA,CLK)
// Erst Digital-Ports D2, D3 usw., dann Analog-Ports als Digital-Ports
// Digital-Ports 12, 13 sind ausgespart wg. angeschlossener LED
HX711 Scale[NR_WEIGHTS] = {HX711(2,3), HX711(4,5), HX711(6,7), HX711(8,9),
                           HX711(10,11), HX711(A0,A1), HX711(A2,A3), HX711(A4,A5)};
Bei letzten Array (Scale[]) werden mit der Arraydefinition praktischerweise auch gleich die entsprechenden Instanzen der HX711-Klasse aus der Bibliothek erzeugt. Man kann daher über Scale[x] auf die x-te Waage zugreifen (siehe Funktion get_scale_value()). Das Programm enthält zahlreiche eingestreute Debug-Ausgaben. Ist die Konstante DEBUG nicht defininiert, wird auch der in "#ifdef DEBUG ... #endif" eingebettete Code nicht compiliert und es werden so auch keine Ausgaben erzeugt.

Waagen-Detektierung

Damit beim kurzzeitigen Abstecken einer Waage oder dem zeitweisen Betrieb weniger Waagen keine Störungen der Messung auftreten, wird vom Programm versucht, die aktiven Waagen zu detektieren. Dazu werden in der Funktion setup() die internen Pullup-Widerstände an den Dateneingängen des Arduino für die HX711-Bausteine aktiviert. Ist kein HX711 angeschlossen, liefert der Eingang ein HIGH-Signal. Die internen Pullups sind mit 40 kΩ bis 50 kΩ relativ hochohmig, so dass die Kommunikation mit einem angeschlossenen HX711 nicht gestört wird.

Die eigentliche Detektierung erfolgt dann über die Funktion check_scales(). Es wird eine bestimmte Zeit gewartet, bis der Dateneingang auf LOW geht (mit der Bibliotheksmethode Scale[k].is_ready). Bleibt er auf HIGH, ist wohl keine Waage angeschlossen. Das Ergebnis der Prüfung wird im Array active_scale für jede Waage festgehalten (HIGH oder LOW). In der Funktion zum Auslesen der Gewichte, read_scale_values() werden nur noch die Aktiven Waagen angesprochen. Da die Funktion check_scales() nur einmal beim Start des Arduino aufgerufen wird, muss der Arduino bein An- oder Abstecken einer Waage einen Reset erhalten.

Gewicht messen und ausgeben

Das Einlesen der Daten wird von der Funktion read_scale_values() erledigt, die Ihrerseits für jede Waage die Funktion get_scale_value() aufruft, deren erster Parameter eine HX711-Instanz (über das Array Scale[]) ist und deren zweiter Parameter der zuletzt gemessene Wert. Die Funktion read_scale_values() aktualisiert die beiden Arrays LetztesGewicht[] und Gewicht[]. Bei nicht vorhandenen Waagen oder Messfehlern wird das Gewicht auf -1 gesetzt.

Der Inhalt des Arrays Gewicht[] wird in der Funktion output_scale_values() auf der seriellen Schnittstelle in Gramm ausgegeben. Bevor die Werte, getrennt durch ein Leerzeichen, gesendet werden, gibt die Funktion ein Newline und ein '$'-Zeichen als Anfangskennung aus. Das macht die Auswertung im Empfangsprogramm auf dem Raspberry Pi leichter. Siehe Link am Ende der Seite.

Das Empfangsprogramm auf dem Raspberry Pi

Schnittstelle detektieren

Am RasPi-Board sind mehrere USB-Devices angeschlossen, unter anderem ein Sound-Adapter und ein sogenannter Surfstick. Es können aber auch noch andere USB-Geräte angeschlossen sein, z. B. ein Memory-Stick, Maus oder Tastatur. Das Empfangsprogramm, das in Python geschrieben ist, muss nun den Arduino aus den USB-Geräten herausfischen. Erschwerend kommt hinzu, dass der Arduino NANO (oder auch der Mikro) einen FTDI-Chip verwendet, der auf die Schnittstelle /dev/ttyUSBx (x = 0, 1, 2, ...) gebunden wird. Der Arduino UNO hat dagegen einen Atmega, der als USB-Interface programmiert ist und die Schnittstelle /dev/ttyACMx (x = 0, 1, 2, ...) gebunden wird. Man könnte zwar per Udev-Regel verhindern, dass die Nummer der Schnittstelle (das x) sich ändert - je nachdem, was gerade eingesteckt ist. Jedoch die Entscheidung zwischen ttyUSBx und ttyACMx wird damit nicht getroffen.

Darum fragt das Programm das System ab, welche USB-Geräte installiert wurden. Das funktioniert über das Kommando dmesg, das alle Aktionen des Systems auflistet, angefangen beim Bootvorgang bis hin zum späteren Einstecken von USB-Geräten. Steckt man nachträglich einen Arduino an, liefer das Kommando folgende Info:

  ...
[  136.223686] usb 1-1.4: New USB device found, idVendor=2a03, idProduct=0043
[  136.223697] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=220
[  136.223704] usb 1-1.4: Product: Arduino Uno
[  136.223710] usb 1-1.4: Manufacturer: Arduino Srl
[  136.223716] usb 1-1.4: SerialNumber: 85438303233351414212
[  136.245567] cdc_acm 1-1.4:1.0: ttyACM0: USB ACM device
[  136.246334] usbcore: registered new interface driver cdc_acm
[  136.246341] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
  ...
Bei einem älteren Arduono-Clone erhält man beispielsweise (letzte Zeile umbrochen):
   ...
[  269.377812] usb 1-1.4: New USB device found, idVendor=0403, idProduct=6001
[  269.377822] usb 1-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  269.377828] usb 1-1.4: Product: FT232R USB UART
[  269.377834] usb 1-1.4: Manufacturer: FTDI
[  269.377840] usb 1-1.4: SerialNumber: A600f32w
   ...
[  270.428002] usb 1-1.4: Detected FT232RL
[  270.428814] usb 1-1.4: FTDI USB Serial Device converter 
  now attached to ttyUSB0
   ...
Wichtig sind dabei die jeweils rot hervorgehobenen Zeilen. Sie sagen einem, an welchem Device die Arduinos angeschlossen sind. Man muss nur noch die entsprechenden Angaben aus dem Datenwust von dmesg herausfischen. Das kann mittels einer einfachen Pipe (= Hintereinanderschaltung von Programmen) auf Kommandozeilenebene erfolgen. Nun muss noch mit dem Zeileneditor sed die Deviceangabe herausgeschnitten werden und schon weiss das Programm, auf welche Schnittstelle es zugreifen muss. Noch schwieriger würde es, wenn zwei Arduinos angeschlossen wären. Dann müssten man weitere Massnahmen zur Detektierung treffen - was hier zum Glück nicht nötig ist. Von Python aus kann man die Shell-Kommandofolge ganz einfach per Popen als Kindprozess aufrufen. Die Python-Befehlsfolge präsentiert sind dann folgendermaßen:
# Arduino NANO detektieren
cmd = "dmesg | grep ttyUSB | grep FTDI | head -1 | sed -e 's/.* //'"
process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
ArduinoNano = str.strip(process.stdout.read())
if ArduinoNano:
  PORT = '/dev/'+ArduinoNano
else:
  # Arduino UNO detektieren
  cmd = "dmesg | grep ttyACM | head -1 | sed -e 's/.*tty//' -e 's/:.*//'"
  process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
  ArduinoUno = str.strip(process.stdout.read())
  if ArduinoUno:
    PORT = '/dev/'+ArduinoUno
  else:
    exit(1)
In der Variablen PORT steht nun die gewünsche Device-Angabe, z. B. /dev/ttyACM0.

Damit das Progrmm nicht "hängt", falls der Arduino mal nicht reagiert, wird per Signalhandler ein Timeout von 60 Sekunden festgelegt, nach dessen Ablauf das Programm auf jeden Fall endet. Solche "Timeout-Notbremsen" sollte man bei serieller Kommunikation oder ähnlichen Anwendungen auf jeden Fall vorsehen.

Der eigentliche Kern zum Empfangen der Daten ist recht einfach und kurz. Die serielle Schnittstelle wird mit den entsprechenden Parametern geöffnet (es versteht sich von selbst, dass Arduino und RasPi die gleiche Datenrate und das gleiche Datenformat verwenden müssen) und der Empfangspuffer gelöscht. Danach wartet das Programm auf ein '$'-Zeichen, denn Arduino und Raspberry Pi laufen ja nicht synchron und es wird in der Regel beim Empfang mitten im Datentelegramm mit dem Lesen begonnen. Nach dem '$'-Zeichen liest das Python-Programm dann die komplette Zeile ein und gibt sie aus. An dieser Stelle könnte dann auch eine Weiterverarbeitung, etwa das Speichenr der Daten in einer Datenbank erfolgen. Bei der aktuellen Anwendung wird die Ausgabe des Empfangsprogramm von einen übergeordneten Prozess weiterverarbeitet.

Schwarmalarm

Um festzustellen, ob ein Schwarm den Stock verläßt, läuft ein Alarmprogramm, das ebenfalls den Waage-Arduino abfragt. Alle Waagen werden ausgelesen und ein Alarm ausgelöst, falls das Gewicht signifikant abgenommen hat. Das Ermitteln der Gewichtswerte erfolgt mit dem gleichen Python-Code, wie mit dem oben beschriebenen Programm.

Als Alarmausgabe werden zwei Relais unterschiedlich angesteuert. An den GPIO-Leitungen 6 und 13 (Pins 31 und 33 der Stiftleiste) ist eine handelsübliche Relaiskarte angeschlossen (Bezug über Amazon, Ebay etc.). Der Eingang der Karte besitzt einen Optokoppler, der der Relais über einen Schalttransistor ansteuert. daher sind die beiden Eingänge Low-aktiv, d. h. beim Anlegen einer logischen "0" schaltet das Relais. Der Optokoppler erlaubt auch den Anschluß der mit 5 V betriebenen Karte an die 3,3-V-GPIO-Ausgänge. Das folgende Bild zeigt die Schaltung eines der beiden Kanäle).

Derzeit aktiviert die Software im Alarmfall das eine relais für die Dauer einer Minute. Während dieser Minute wird das zweite Relais intermittierend betrieben, um z. B. ein Blinklicht anzusteuern. Die Relais werden im Alarmfall aber immer nur nach frühestens 20 Minuten wieder aktiviert, damit es nicht dauernd Alarm gibt.

Als weitere Maßnahme sendet der Raspberry Pi im Alarmfall eine E-Mail an eine vorgegebenen Adresse (alternativ könnte man auch eine SMS versenden). Auch die E-Mail wird erst frühestens 40 Minuten nach der letzten E-Mail nochmals verschickt. Der E-Mail-Versand ist etwas trickreich. Beim Betrieb innerhalb des einenen WLAN wäre der Versand kein Problem. Ist der Raspberry Pi jedoch über einen Surfstick ans Internet angebunden, hat er nicht nur eine sogenannte private IP-Adresse (meist aus dem Bereich 10.x.x.x), sondern auch keinen geeigneten Domainnamen. Daher würde jeder Internet-Provider die von dort kommenden E-Mails als Spam abweisen. Das Programm verschickt deshalb selbst keine E-Mails, sondern nimmt Kontakt zum Programm "alarm.php" auf, das auf dem Webserver läuft und per HTTP-Protokoll erreichbar ist (ähnlich wie bei der Übermittlung der Messdaten). Das PHP-Programm auf dem Webserver sorgt dann für den eigentlichen E-Mail-Versand.

Das Programm wird über einige Variablen am Anfang des Codes eingestellt. So werden hier das Alarmintervall, das Messintervall, der Schwellenwert für die Gewichtsabnahme (2 kg) etc. eingestellt. Es werden auch immer vier aufeinanderfolgende Messungen untersucht, um Fehlalarme zu vermeiden. Die Messwerte und die Alarmzeiten werden jeweils in Dateien auf dem RasPi gespeichert. Das Programm erzeugt, falls nicht schon vorhanden, ein temporäres Dateisystem unter /var/tmp für diese Steuer-Dateien. So erfolgt kein Schreiben auf SD-Karte und die SD-Karte wird geschont.

Mit zwei Variablen lassen sich ein Testmodus und eine Debug-Ausgabe steuern:

Für die Messung der Gewichte und die Alarmierung muss das Programm waagealarm.py regelmäßig per crontab aktiviert werden. Wichtig ist dabei, dass die Zeitintervalle von crontab dem in der Variablen INTERVALL des Programms übereinstimmen. Sinnvoll ist hier ein Intervall von fünf Minuten. Bei vier Messungen dauert es maximal 20 Minuten, bis ein Alarm erfolgt. Deshalb ist die Programmeinstellung: INTERVALL = 5. Der Eintrag in der Datei /etc/crontab lautet dann:

# alle 5 Minuten nach den Waagen schauen
*/5  *  * * *   root    /home/pi/bin/waagealarm.py >/dev/null 2>&1

Links

Copyright © Hans Neumayr (Imkerei Hilgertshausen) & Prof. J. Plate (Netzmafia.de)
Letzte Aktualisierung: , Webseite: