Praktikum Mikrocontrollerperipherie

Prof. Jürgen Plate

Praktikum Mikrocontrollerperipherie

Allgemeines

Username und Passwort

Lage der Praktikumsplätze im Labor

Platz Versuch Schnittstelle Rechner
Fenster 1 PSD-Entfernungssensor analog Arduino
Fenster 1 GPS-Empfänger seriell (9600) Linux-PC
Fenster 2 Ultraschall-Entf. mit Servo seriell (4800) Linux-PC
Fenster 2 7-Segment-Multiplex parallel 12 Bit Arduino
Fenster 3 Kamera + Servos seriell, TCP/IP Arduino
Fenster 3 7-Segment-Multiplex parallel 12 Bit Arduino
Fenster 4 RFID seriell (9600), par. 3 Bit Arduino
Fenster 4 Strommessunganalog Arduino
Fenster 5 Farbmischer parallel PWM, seriell Arduino
Fenster 6 Gassensor analog Arduino
Tür 1 RFID seriell (9600), par. 3 Bit Arduino
Tür 2 Grid-Eye seriell (USB, 19200) Linux-PC
Tür 2 7-Segment-Multiplex parallel 12 Bit Arduino
Tür 3 3-Achsen-Beschleunig. analog, parallel 4 Bit Arduino
Tür 4 Geigerzähler parallel 1 Bit Arduino
Tür 5 Grid-Eye seriell (USB,19200) Linux-PC
Tür 5 7-Segment-Multiplex parallel 12 Bit Arduino
Tür 6 RFID seriell (9600), par. 3 Bit Arduino

Semesterprojekt

Im Wintersemester 2017/18 ist die Aufgabe "Entwicklung eines Datenübrtragungsprotokolls" zu bearbeiten.

Aufgaben zur seriellen Schnittstelle am PC

Diese Aufgaben lösen Sie am jeweiligen Linux-PC um Labor E 204. Die Programmierung ist eins-zu-eins auf den Raspberry Pi übertragbar. Der PC hat lediglich den Vorteil, dass die serielle Schnittstelle mit V.24-Pegeln arbeitet. Der Raspberry Pi müsste erst mit einem Pegelwandler nachgerüstet werden. So dient der PC dient hier gewissermaßen als "RasPi-Simulator". Tips zur Programmierung im C finden Sie auf der Webseite http://www.netzmafia.de/skripten/hardware/PC-Schnittstellen/seriell.html.

Grid Eye - Thermopile-Array-Sensor (2x)

Grid-Eye ist ein Thermopile-Array-Sensor in SMD-Bauform von Panasonic. Der Sensor verfügt über 64 Thermopile-Elemente (PIR - Passive Infrared Array), die in einer 8 x 8-Matrix angeordnet sind. Damit lässt sich eine berührungslose Messung von Temperaturverteilungen realisieren. Die Thermopile-Sensoren des Grid-Eye können im Vergleich zu pyroelektrischen Sensoren auch statische Wärmestrahlung messen. Das Versuchssystem mit den Stone-Board liest den Sensor aus, rechnet sie auf die Temperatur in Celsiusgraden um und verschickt sie anschließend als 2-Byte ASCII-Hex-Wert seriell an die USB-Schnittstelle des PC, wo sie über eine pseudo-serielle Schnittstelle verarbeitet werden können (ttyUSB0).

Es werden jeweils acht Werte einer Sensorzeile als Folge zweistelliger Hexzahlen gesendet und mit einen Newline-Zeichen abgeschlossen. Nach jeweils acht Zeilen folgen zusätzlich zwei Newline-Zeichen. Es ergibt sich daher ein Block von ASCII-Zeichen wie in folgendem Beispiel (Newline ist durch ↵ repräsentiert):

   181818191B1B1818↵
   181818191B1B1818↵
   1818181B1B191818↵
   1818181B1B119818↵
   18181B1B19191818↵
   18181B1B11919818↵
   1818181919191818↵
   1818181818181818↵
   ↵
   ↵
Danach folgt der nächste Block usw.

Einstellung der seriellen Schnittstelle:

Schreiben Sie ein Programm, das die Daten über die Schnittstelle einliest und als Matrix von ASCII-Zeichen, jeweils gefolgt von einem Leerzeichen darstellt. Dabei soll gelten:
TemperaturAnzeige
< 24 ' '
24 .. 26'.'
27 .. 29'+'
30 .. 32'*'
33 .. 35'@'
> 35'#'

Die Ausgabe könnte dann folgendermaßen aussehen:

   . . . . + + . . ↵
   . . . . + + . . ↵
   . . . + + . . . ↵
   . . . + + . . . ↵
   . . + + . . . . ↵
   . . + + . . . . ↵
   . . . . . . . . ↵
   . . . . . . . . ↵

Anmerkungen:

Im Hauptprogramm sollen dann Ein- und Ausgabefunktion in einer Endlosschleife aufgerufen werden. Wenn sich nun eine Person (oder auch nur die Hand) vor dem Sensor bewegt, kann dies deutlich erkannt werden.

GPS-Empfang

Das Global Positioning System (GPS), offiziell NAVSTAR GPS, ist ein globales Satellitennavigationssystem zur Positionsbestimmung. Es wurde seit den 1970er Jahren vom US-Verteidigungsministerium entwickelt. GPS ermöglicht seit Mitte 2000 auch zivilen Nutzern eine Genauigkeit von ca. 10 Metern. Die GPS-Satelliten strahlen codierte Radiosignale aus, die ständig ihre aktuelle Position und die genaue Uhrzeit liefern. Aus den Signallaufzeiten können GPS-Empfänger dann ihre eigene Position und Geschwindigkeit berechnen. Theoretisch reichen dazu die Signale von drei Satelliten aus. Da GPS-Empfänger keine Uhr besitzen, die genau genug ist, um die Laufzeiten der Signale korrekt zu messen, ist das Signal eines vierten Satelliten nötig, mit dem dann auch die genaue Zeit im Empfänger bestimmt werden kann.

Als Standardformat von GPS-Daten dient das RINEX-Format, eine Standard- und Formatdefinition, die einen freien Austausch von GPS-Rohdaten ermöglichen soll. Für den Austausch von GPS-Daten in Echtzeitanwendungen ist das RTCM-Format von Bedeutung. Alle Daten des GPS-Empfänger sind ASCII-Zeichen, die zeilenweise gesendet werden, mit einem "$" beginnen und durch Carriage Return (CR) und Linefeed(LF) abgeschlossen sind. Aufschluß über den Inhalt liefert das NMEA-0183-Referenzhandbuch. Von den verschiedenen Datensätzen interessieren uns nur zwei, die unten mit Beispiel und Beschreibung aufgelistet sind:

Die ASCII-Strings werden über die serielle Schnittstelle am den PC gesendet. Die Einstellung der seriellen Schnittstelle ist:

Schreiben Sie ein C-Programm, das aus dem Datenstrom vom GPS-Empfänger die GGA- und RMC-Zeilen extrahiert und auf dem Bildschirm ausgibt.

Erweitern Sie das C-Programm dahingehend, dass die Position, also die geographische Breite (latitude, Nord/Süd), die gegraphische Länge (longitude; Ost/West) und die Höhe (altitude) sowie die Uhrzeit in vom Menschen lesbaren Format (z.B. Stunde, Minute, Sekunde, ...) ausgegeben werden. Die Umrechnung von UTC in eine Zeitangabe aus Datum und Uhrzeit ist weiter unten beschrieben. Die Angabe von Breite und Länge erfogt in Grad (dd), Minuten (mm) und Minutenbruchteilen (mmmm). Die Umrechnung der Minutenbruchteile in Sekunden ist ganz einfach:

Sekunden = Minutenbruchteile * 60

Beispiel: GPS-Angabe (nautisch) 3723.2475

→ 37° 23', Minutenbruchteil: 0.2475

Sekunden = 0.2475 * 60 = 14.85
→ 37° 23' 14.85"
Das Gradsymbol ° ist grundsätzlich eindeutig. Für Minuten, Sekunden und das Dezimaltrennzeichen werden in der Praxis folgende Symbole verwendet:

Aufgaben zur seriellen und parallelen Schnittstelle am Arduino

Zugangskontrolle mit RFID-Lesestation und Arduino (3x)

Die Lesestation besteht aus einem 125-kHz-RFID-Empfänger, der seriell am Arduino angeschlossen ist und einer Anzeigeplatine mit drei LEDs, die an den digitalen Pins 8, 9 und 10 des Arduino hängt.

LED rot   Pin  8
LED gelb  Pin  9 
LED grün  Pin 12
Der RFID-Empfänger dient dem kontaktlosen Auslesen von sogenannten Transponderkarten (HF-Tags bzw. Read-Only-Transponderkarten). Die Aufbereitung der von der Transponderkarte gelesenen Daten wird von einem Mikrocontroller übernommen und über die RS232-Schnittstelle an den Arduino gesendet. Der RFID-Empfänger besitzt ein LC-Display auf dem die Daten sofort angezeigt werden.
Nach dem Anlegen der Betriebsspannung erscheint der Text "RFID-Modul with U2270B" im Display. LED 1 und LED 2 des Lesers werden kurz eingeschalten und nach ca. zwei Sekunden wieder ausgeschalten. Im Display erscheint der Text "check ...". Wird nun eine Transponderkarte in den Empfangsbereich der Spule gehalten und vom Empfänger erkannt, zeigt dies die LED 1 an. Im Display wird der Text "send..." und der 10-stellige Ident-Code der gelesenen Transponderkarte eine Sekunde lang angezeigt und über die RS232-Schnittstelle mit 9600 Baud (8N1) ausgegeben. Dies erfolgt, solange sich die Karte im Empfangsbereich befindet. Andernfalls wird LED 1 wieder umgeschalten und der Text "check ..." im Display angezeigt.

Schreiben Sie ein C-Programm zur Erfassung von Transponderkarten-IDs:

  1. Im dann zu erstellenden Programm wird auf die Daten einer Transponderkarte gewartet. Die gelbe LED an der Digitalschnittstelle zeigt die Empfangsbereitschaft des Programms an. Sobald eine ID empfangen wurde, wird sie an die serielle Schnittstelle gesendet. Notieren Sie die Nummern der Transponderkarten. Als Quittungssignal wechselt die LED-Anzeige für drei Sekunden von gelb auf grün und danach wieder auf gelb.
  2. Schreiben Sie nun ein C-Programm, das basierend auf den erfassten Transponderkarten eine Zugangskontrolle realisiert. Zuerst wird die serielle Schnittstelle initilisiert und dann auf die Daten einer Transponderkarte gewartet. Die gelbe LED an der Digitalschnittstelle zeigt die Empfangsbereitschaft des Programms an. Sobald eine ID empfangen wurde, vergleicht das Programm eine Liste gültiger Transpondernummern (die unter 1. erfasst wurden) mit der empfangenen und gibt für drei Sekunden den entsprechenden Status über die LEDs an der Parallelschnittstelle aus: Danach wechselt die LED-Anzeige wieder auf gelb.
Beachten Sie beim Einlesen der ID, dass diese im Sekundenabstand wiederholt wird, solange sich die Transponderkarte im Lesebereich befindet. Das Programm darf sie aber nur einmal verarbeiten.

Geigerzähler am Arduino

Der Versuch besteht aus einem Geigerzählerbausatz von Vellemann und einen Optokoppler-Interface für die Parallelschnittstelle (die Arbeitsweise eines Geigerzählers wird in der Vorlesung besprochen). Der folgende Auszug der Schaltung zeigt die relevanten Teile:

Links im Bild sehen Sie eine Teilschaltung des Geigerzählers. An den einen Eingang von IC1 gelangt der sehr kurze Impuls vom Zählrohr, der mittels C14 und R12 verlängert wird. Dieses RC-Glied sowie IC1 und IC2 bilden eine monostabile Kippschaltung, an deren Ausgang ein genügend langer Impuls entsteht. Zwischen dem Kollektor von T3 und Masse war ursprünglich ein Piezo-Signalgeber geschaltet, der durch die grau umrandete neue Schaltung ersetzt wurde. Bei jedem Impuls des Geigerzählers schaltet T3 durch und die Anzeige-LED sowie die LED des Optokopplers leuchten auf. Der Ausgang des Optokopplers zieht darauf hin den Port 8 des Arduino auf Low-Potential. Für die einwandfreie Funktion muss der Kollektorwiderstand des Phototransistors auf High-Potential gezogen werden, was man durch Verbinden mit den 5 V des Arduino erreicht. Der Masseanschluss ist mit GND des Arduino verbunden. Damit kann durch kontinuierliche Abfrage des Port 8 der Zählimpuls erkannt werden.

Für erste Tests liegt ein ca. 50 Jahre alter, extrem geschmackvoller Teller bereit, dessen Glasur aus Uranoxid den Geigerzähler "tickern" lässt.

Neben der absoluten Zahl der detektierten Impulse soll nun die Zählrate berechnet werden. Erweitern Sie das Programm so, dass jede Minute die Anzahl der Impulse/Minute errechnet und diesen Wert zusammen mit der absoluten Zahl der Impulse über die Serielle Schnittstelle ausgegeben wird. Berücksichtigen Sie auch den Fall, dass der Absolutzähler überläuft.

Ultraschallsensor

Ein Ultraschallsensor, bestehen aus Sender und Empfänger arbeitet wie ein Echolot: Der Sender schickt einen kurzen Burst aus und das Sensorsystem wartet auf das Echo. Am Arduino ist ein Ultraschallsensor HC-SR04 angeschlossen, der über zwei digitale Pors gesteuert wird. Über den Trigger-Eingang des Sensors startet man eine Messung und kann dann über den Echo-Ausgang die Laufzeit des Signals bestimmen. Der Ultraschallsensor und das Programmierprinzip ist für den Raspberry Pi unter Ultraschall-Entfernungsmessung mit HC-SR04 ausführlich beschrieben.

Schreiben Sie ein Programm, das die Daten über die Schnittstelle einliest und nach der unten stehenden Formel in eine Entfernungsangabe umrechnet. Dabei soll gelten:

s = Strecke:                    s = v * T
v = Schallgeschwindigkeit:      v = 331,5 + 0,6 * t m/s
T = Laufzeit: Messwert in μs
t = Umgebungstemperatur in °C

Anmerkungen:

Der Sensor ist auf einer drehbaren Platte montiert, die über ein Servo bewegt werden kann. Erweitern Sie das Programm dahingehend, dass die Umgebung des Sensors "gescannt" wird. Dazu fährt das Servo zunächst in die Endstellung (wahlweise rechts oder links). Danach wird in einer Schleife das Servo jeweils um ca. 5 Grad gedreht und ein Messwert aufgenommen, bis die gegenüberliegende Endstellung erreicht ist. Das Servo ist an Port 9 angeschlossen. Hinweis: Einbinden der Servo-Library mittels #include <Servo.h>.

Siebensegmentanzeige am Parallelport (4x)

Ziel des Versuchs ist die Realisierung einer per Multiplex betriebenen Anzeige. Hintergrundinfo finden Sie in der Dokumentation der achtstelligen 7-Segmentanzeige. In der Regel wird der Arduino zur Ansteuerung eingesetzt.

  1. Schreiben Sie eine Funktion void Digit(byte Position, char Value), die den Siebensegmentcode von Value für die Hexziffern "0" bis "9" und "A" bis "F" sowie für die Zeichen "-", " " und "." (Dezimalpunkt) an der durch Position angegebenen Stelle (0 bis 7) ausgibt. Die Funktion muss also den ASCII-Wert in den Siebensegmentcode umsetzen.
  2. Schreiben Sie eine Funktion void Blink(void), mit der die Anzeige für 0,5 s ausgeschaltet und dann wieder eingeschalter wird. Dazu wird das EN-Bit verwendet. Nach den Wiedereinschalten wird ebenfalls 0,5 s gewartet, bevor die Funktion verlassen wird.
  3. Schreiben Sie eine Funktion Send(char[] Value), die den String Value rechtsbündig auf der Anzeige ausgibt. Im String sind die Hexziffern "0" bis "9" und "A" bis "F" sowie Zeichen "-", " " und "." erlaubt. Folgt ein Doppelpunkt auf eine Ziffer, wird bei dieser Ziffer der Dezimalpunkt gesetzt.

Steuern einer Netzwerk-Kamera mit Arduino

Die Netzwerkkamera ist auf einer servogesteuerten Mechanik zum Drehen und Neigen der Kamera montiert ("Pan" and "Tilt"). Die Servo-Ansteuerung erfolgt über den Arduino mit der entsprechenden Bibliothek. Das Kamerabild kann über den Web-Browser (Stream und Snapshot) abgerufen werden:

Schreiben Sie unter Verwendung der o. a. Arduino-Bibliothek ein Programm, das zwei Modi kennt. Im ersten Modus erfolgt die Steuerung der Kamera über vier Tasten für das Neigen ([T1] und [T2]) und Drehen ([T3] und [T4]).


Beim zweiten Modus handelt es sich um einen sogenannten Scan-Modus, der den Raum durch ständiges Drehen und Schwenken der Kamera überwacht. Vom einen in den anderen Modus soll jederzeit per Tastendruck auf [T5] gewechselt werden können.

Hinweise: Die Tasten sind an den Digitalports 3, 4, 5, 6, und 7 angeschlossen und schalten gegen Masse. Da dieser Fall recht häufiger auftritt, wurden im AtMega hierfür passende interne Pullup-Widerstände (ca. 20 kΩ) integriert, die sich bei Bedarf aktivieren lassen:

pinMode(pin, INPUT);      /* Anschluss als Eingang definieren */
digitalWrite(pin, HIGH);  /* Pullup-Widerstand aktivieren */
Ermitteln Sie zunächst durch ein Testprogramm, welche Taste an welchem Port angeschlossen ist.

Für den Betrieb der Servos benötigen Sie die Arduino Servo-Bibliothek https://www.arduino.cc/en/Reference/Servo. Für die Servos sind die Ports 8, 9, 10 und 11 vorgesehen. Da nur zwei Servos benötigt werden, verwenden Sie die Ports 8 und 9.

LED Farbmischer

Am Arduino sind drei Power-LEDs angeschlossen (rot, grün, blau), deren Helligkeit über PWM-Ausgänge steuerbar ist. Die Helligkeit der einzelnen LEDs sowie deren Blinken wird über die serielle Schnittstelle vom PC aus gesteuert.

Nach einem Aufruf von analogWrite() erzeugt der entsprechende Pin ein stetiges Rechtecksignal des angegebenen Tastverhältnisses bis zum nächsten Aufruf von analogWrite(). Die Frequenz des PWM-Signals beträgt etwa 490 Hz. Auf den meisten Arduino-Boards steht diese Funktion an den Pins 3, 5, 6, 9, 10 und 11 zur Verfügung. Für den Versuch werden die LEDs sowie die Stromversorgung folgendermaßen verdrahtet:

AnschlussKabel-
Farbe
Arduino-
Pin
GNDbraunGND
ROTrotPB1(9)
GRÜNgrünPB2(10)
BLAUviolettPB3(11)

Die Steuerung erfolgt über die serielle Schnittstelle, indem Kommandos an den Arduino gesendet werden. Jedes Kommando wird mit einem Zeilenende abgeschlossen. Folgende vom Arduino auszuwertende Kommandos sind zu implementieren:

KommandoBedeutung
RxxHelligkeitswert für ROT. Dabei steht "xx" für eine zweistellige Sedezimalzahl zwischen 00 und FF
GxxHelligkeitswert für GRÜN. Dabei steht "xx" für eine zweistellige Sedezimalzahl zwischen 00 und FF
BxxHelligkeitswert für BLAU. Dabei steht "xx" für eine zweistellige Sedetimalzahl zwischen 00 und FF
IxBlinkfrequenz in Hz. Dabei steht "x" für eine Zahl zwischen 0 und 9, wobei die "0" auf Dauerlicht schaltet (kein Blinken).

Aufgaben zur Erfassung analoger Sensordaten mit Arduino

3-Achsen-Beschleunigungssensor am Arduino

Es soll die Lage eines "Flugzeugmodells" anhand eines Beschleunigungssensors über das das analoge Interface bestimmt werden. Der Sensor ADXL 335 liefert eine der Beschleunigung proportionale Spannung die per Programm ausgewertet werden soll.

  1. Schreiben Sie ein Rumpfprogramm, das beim Start die aktuellen Werte für X, Y und Z einliest und als "Nullstellung" speichert. Danach sollen im Halbsekunden-Rhythmus die Werte für X, Y und Z eingelesen und auf dem Bildschirm ausgegeben werden. Bestimmen Sie Grenzwerte für die Neigung des "Fliegers" in X- und Y-Richtung für eine Neigung von etwa 30° in jeweils beiden Richtungen (Sie dürfen schätzen).
  2. Nun kommen die vier LEDs ins Spiel. Auf der Basis der gewonnenen Erkenntnisse steuern Sie nun die jeweilige LED an, wenn der Neigungs-Grenzwert überschritten wird. Ermitteln Sie dazu den Neigungs- und Kipp-Winkel aus dem X-, Y- und Z-Wert bzw. Y- und Z-Wert nach dem Satz des Pythagoras bzw. nach dem Cosinussatz. Beachten Sie dabei, dass alle Winkelfunktionen im Bogenmass arbeiten → Umrechnung im Grad durch Grad = Winkel * 180 / π. Zur Erinnerung:



Strommessung mit dem integrierten Stromsensor INA169

Der INA169 ist ein "High-Side-Strommonitor", was bedeutet, dass Sie einen Widerstand ("Shunt") in die positive Zuleitung zum Verbraucher legen und der INA169 den Spannungsabfall über diesen Widerstand misst. Der Chip gibt einen zum gemessenen Spannungsabfall proportionalen Strom aus. Schaltet man einen Widerstand vom Ausgang des INA169 gegen Masse, erhält man eine zum Messwert proportionale Spannung. Mit etwas Mathematik kann aus dieser Ausgangsspannung der Strom durch den Shunt-Widerstand ermittelt werden. Vorteil eines High-Side-Sensors ist, dass der gemessene Stromkreis und der auswertende Controller eine gemeinsame Masse besitzen.

Der Schaltplan des Breakout-Bords zeigt neben dem INA169-Chip nur den Shunt-Widerstand zwischen den Pins 3 und 4 und den Ausgangswiderstand an Pin 1. Wenn Sie die Werte der Widerstände ändern möchten, können Sie diese ersetzen oder einen weiteren Widerstand parallel schalten.

Wenn der Strom von VIN+ über den Shunt nach VIN- fliesst, ergibt sich ein Spannungsabfall über dem Shunt. Der OP-Amp im INA169-Chips misst die Differenzspannung zwischen VIN+ und VIN-. Der Ausgang des Operationsverstärkers wird durch den internen Transistor verstärkt, der einen Strom am Ausgang des INA169 generiert, der eine Spannung über dem Lastwiderstand zu Folge hat. Der INA169 kann nur Gleichstrom messen, wobei der Pin VIN+ ein höheres Potential als der Pin VIN- aufweisen muss. Für den Messwert ergibt sich:

     I = (Vout * 1000)/(Rs * Rl)
Setzt man die Werte ein, ergibt sich:
     I = (Vout * 1000)/(0,1 * 10000) 
       = (Vout * 1000)/(1000)
       = Vout
Bei der vorgegebenen Dimensionierung entspricht die Ausgangsspannung zahlenmäßig genau dem gemessenen Strom, z. B. erhält man bei einem Strom von 2,7 A am Ausgang 2,7 V.

Das Breakout-Board hat fünf Anschlüsse:

Der INA169 kann keine Spannungsdifferenz größer als 500 mV über Rs messen. Auch steigt der Ausgangsfehler, wenn die Spannung über Rs unter 35 mV absinkt. Will man den Messbereich ändern, können Rs und Rl ersetzt werden. Das Ändern eines der Widerstände ändert die obige Gleichung. Bleibt Rl auf 10 Kiloohm, ergeben sich für Rs die folgenden Bereiche:

Rs [Ohm]Messbereich
10,03,5 mA - 35 mA
1,035 mA - 350 mA
0,1350 mA - 3,5 A

Bei einem Widerstand RS von 0,1 Ohm und 3,5 A muss der Widerstand ca. 1,2 W Verlustleistung verkraften. Sie benötigen also einen Widerstand, der mindestens 2 W verträgt.

Schreiben Sie ein Programm, das die Ausgangsspannung des INA169 misst und entsprechend in einen Stromwert umrechnet. Beim Arduino hat der A/D-Wandler eine Auflösung von 10 Bit und die Referenzspannung des Wandlers beträgt 5 V. Die ermittelten Stromwerte sollen viermal pro Sekunde über die serielle Schnittstelle zum PC gesendet werden. Führen Sie die Messung mit verschiedenen Verbrauchern durch und überprüfen Sie das Messergebnis auf Plausibilität.

Zum Einstellen unterschiedlicher Ströme stehen ein Netzteil und diverse Verbraucher sowie Hochlastwiderstände zur Verfügung. Durch Wechsel der Steckbuchse können verschiedene Verbraucher gewählt und somit verschiedene Ströme eingestellt werden. Messen Sie zunächst den Strom durch die Widerstände (4,7 Ohm) und ermitteln Sie dann die Leistung der anderen Verbraucher durch Strommessung und Berechnung der Leistung.

Ermitteln der Luftgüte mit einem Gassensor

Der Gassensor MQ-135 wird unter anderem in Luftqualitätskontrollanlagen für Gebäude oder Büros eingebaut. Er soll warnen, wenn der "Mief" einen zu hohen Wert erreicht. Seine Eigenschaften sind:

Das Breakout-Board (Watterott 20150232, SainSmart SKU:20-011-961 ) besitzt zusätzlich einen Komparator, der bei Erreichen einer einstellbaren Schaltschwelle einen Digitalausgang auf Low-Pegel schaltet. Zusätzlich leuchtet eine LED auf dem Board auf.

Der Aufbau des MQ-135-Gassensors ist im Bild oben dargestellt. Der Sensor bestehend aus einem Mikro- AL2O3-Keramikrohr, einer empfindlichen Schicht aus Zinndioxid (SnO2) sowie Messelektrode und Heizung. Der MQ-135 hat ein 6-poliges Gehäuse, wobei vier Anschlüsse das Messsignal führen und die anderen beiden für die Heizung verwendet werden. Bei der vorgeschriebenen Heizspannung nimmt der Sensor ca. 150 mA auf und wird 50 bis 60°C heiss.

Die folgende Grafik zeigt die Widerstandsänderung in Abhängigkeit von der Konzentration dieser Gase in der Umgebungsluft in ppm ("Parts per Million" des Gesamtgasvolumens). Die allgemeine Empfindlichkeit ist etwa gleich für alle Gase. Da CO2 das vierthäufigste Gas in der Erdatmosphäre mit ungefähr ca. 397 ppm Konzentration ist, sind alle anderen Gase, die der Sensor detektiert, wesentlich weniger verbreitet als CO2. Das bedeutet, dass der Sensor in normaler Atmosphäre meistens CO2 detektiert. Im globalen Mittel liegt der CO2-Anteil der Luft zwar bei etwa 397 ppm Volumenanteil, er schwankt aber regional, tageszeitabhängig und jahreszeitabhängig stark.

Bevor Sie den Sensor verwenden können, muss er kalibriert werden. Dazu wird der Sensor 12 bis 24 Stunden angeschlossen, um ihn einzubrennen. Anschließend wird er der Außenluft ausgesetzt, vorzugsweise bei 20°C und 35% rel. Luftfeuchte. Warten Sie, bis der Messwert sich stabilisiert. Dies ist der Kalibrierungswert RZERO für 397 ppm. Der Burn-In ist für das Praktikum bereits erfolgt. Im Praktikum wird der Digitalausgang nicht verwendet. Das Board ist folgendenmaßen mit dem Arduino verschaltet:

AO  → A0
DO  offen
VCC → 5 V
GND → GND

Die Berechnung des Schadstoffanteils in der Umgebungsluft orientiert sich an der CO2-Linie des Datenblatts. Damit werden aber auch die anderen Schadstoffe erfasst. Am Programmanfang tragen Sie folgende Konstanten ein:

/// Kalibrierungswiderstand (CO2-Wert bei Aussenluft) in kOhm
/// Hier den von Ihnen ermittelten Wert eintragen
#define RZERO 76.63

/// Lastwiderstand auf dem Board in kOhm
#define RLOAD 10.0

/// Parameter fuer die ppm-Berechnung von CO2 (aus dem
/// Datenblatt ermittelt)
#define PA 116.602
#define PB 2.769

/// Warnschwelle fuer die Signalisierung "dicker Luft"
/// Hier den von Ihnen gewuenschten Wert eintragen
#define WARN 450

Der Sensorwiderstand wird aus dem Wert des A/D-Wandlers nach der folgenden Formel berechnet:

/// Sensorwiderstand im kOhm ermitteln
int val = analogRead(_pin);
float RSENS = ((1023.0/(float)val) - 1.0)*RLOAD;

Mit der Steigung und einem Punkt der Linie kann der ppm-Wert nach der Formel ppm = PA * (RSENS/RZERO)-PB berechnet werden. Da das Datenblatt-Diagramm einen logarithmischen Massstab verwendet, ergibt sich eine Expotentialgleichung.

/// Umrechnung des Widerstands in ppm
float PPM = PA * pow((RSENS/RZERO), -PB);

Ermitteln Sie zuerst durch eine längere Messperiode den Kalibrierungswert RZERO und tragen Sie diesen dann im Programm ein. Die Ausgabe der Messwerte soll periodisch im 10-Sekunden-Rhythmus auf der seriellen Konsole erfolgen.

Programmieren Sie danach die Umrechnung in ppm-Anteile. Auch hier soll die Ausgabe der Werte periodisch im 10-Sekunden-Rhythmus auf der seriellen Konsole erfolgen. Definieren Sie eine Warnschwelle (Konstante WARN), ab der eine am Digitalausgang PD2 angeschlossene LED eingeschaltet wird.

Datenblätter MQ135: MQ135a.pdf und MQ135b.pdf.

Entfernungsmessung mit einem PSD-Sensor

Der IR-Sensor GP2Y0A02YK hat eine Eingangsspannung von 5 V. An Pin 1 liegt dann eine positive, analoge Spannung an, die je nach Objektentfernung zwischen 0,4 - 2,8 V liegt. Die Zeit für eine Messung beträgt etwa 40 ms.

Die Spannungsänderung ist nicht linear, wie die folgende Grafik aus dem Datenblatt zeigt:

Um die Messgenauigkeit zu verbessern, wird der Arduino nicht mit der Default-Referenz von 5 V betrieben, sondern der Eingang AREF über einen Schutzwiderstand von 5 kOhm mit der 3,3-V-Versorgungsspannung verbunden. Da der AREF-Eingang intern über einem 32-kOhm-Widerstand abgeschlossen ist, ergibt sich eine effektive Referenzspannung von:

Vref = 3,3 * 32/(32 + 5) = 2,854 V
Um die Referenzspannung auf den AREF-Eingang umzuschalten, muss in der Funktion setup() der folgende Befehl stehen:
analogReference(EXTERNAL);
Wird der analoge Wert (zwischen 0 und 1023) ausgelesen, muss er in eine Spannung umgerechnet werden:
Vin = analogRead(0) * 2.854 / 1023.0
Für einen ersten Test geben Sie den ermittelten Spannungswert auf der seriellen Schnittstelle aus (serielles Terminal in der Arduino-IDE) und vergleichen die Werte mit der Kennlinie. Sie werden eventuell bemerken, dass zwei aufeinanderfolgende Werte voneinander abweichen, obwohl sich an der Entfernung des Objekts nichts geändert hat. Das kann aufgrund von Reflexionen und anderen Einflüssen vorkommen. Lesen Sie daher 5 bis 10 Werte ein und ermitteln Sie davon den Mittelwert. Diesen Wert verwenden Sie dann für die weitere Berechnung.

Danach erfolgt eine Umrechnung der Spannung in die Distanz in Zentimetern, wobei die Kennlinie durch ein Polynom approximiert wird.

D =    16.2537 * Vin * Vin * Vin * Vin 
    - 129.8930 * Vin * Vin * Vin 
    + 382.2680 * Vin * Vin
    - 512.6110 * Vin 
    + 306.4390 
Ermitteln Sie nun nach obiger Formel verschiedene Entfernungen und verifizieren Sie das Ergebnis mit Hilfe eines Maßbandes.

Die Firma Sharp hat in einer Veröffentlichung folgende Annäherungsformel angegeben:

D = (0.008271 + 939.65 * Vin)/(1.0 + -3.398 * Vin + 17.339 * Vin * Vin);
Ermitteln Sie zusätztlich die Entfernung nach dieser Formel und vergleichen Sie die Ergebnisse der beiden Formeln.

Dokumentationen zum Praktikum

Software zum Praktikum (Raspberry Pi bzw. Linux-PC)

Compiler, Editor beim Raspberry Pi bzw. beim Linux-PC

Der Compiler gcc wird auf der Kommandozeile oder im Makefile aufgerufen (siehe unten). Als Editor können entweder shellbasierte Programme (vi etc.) oder der bildschirmorientierte Editor (gedit) verwendet werden. Wer lieger eine integrierte Oberfläche hat, kann Geany verwenden (gelbes Teekannensymbol auf dem Desktop).

Beachten Sie, dass bei allen Programmen die Warnungen eingeschaltet werden sollen. Ein Programm namens "oops" wird mit folgender Befehlszeile übersetzt:

gcc -Wall -o oops oops.c

Zum Erzeugen der Binärdateien, die aus mehreren Quelldateien bestehen, könnte man ein Makefile anlegen. Man kann dann durch das Kommando make das Compilieren und Linken automatisch erledigen. Unter der Annahme, dass Ihre C-Quelle main.c heisst und Sie die Bibliothek oops verwenden wollen, könnte ein einfaches Makefile folgendermaßen aussehen:

all: main

main: main.c oops
 → gcc -Wall -o main oops.o  main.c


oops: oops.c oops.h
 → gcc -Wall -c oops.c

clean:
 → rm -f oops.o main
Beachten Sie, dass make bei den Einrückungen (oben durch " → " markiert) unbedingt Tabulatorzeichen und keine Leerzeichen benötigt. Normalerweise reicht es aber, einfach alle Quelldateien beim gcc-Aufruf anzugeben:
gcc -Wall -o main main.c oops.c

Wartezeiten (Delay-Funktion) beim Raspberry Pi bzw. beim Linux-PC

Die Wartezeit bei Blink(), Print() im Scrollmodus bei der Siebensegment-Aufgabe und Wartezeiten bei den anderen Aufgaben (Geigerzähler) können über die Funktion nanosleep() gesteuert werden:

	struct timespec ts;
   ...
	ts.tv_sec  = 0;
	ts.tv_nsec = ???;
   ...
	nanosleep (&ts, NULL);
Bei Werten im Sekundenbereich kann sleep() verwendet werden. Weitergehende Infos bietet das Kapitel Prozesse und Signale des Programmierskripts. Dort erfahren Sie ggf. auch mehr zur Prozesskommunikation.

Bei Multitasking-Betriebssystemen wie Unix oder Linux, aber auch Windows, ist es immer angeraten, kuzte "Schlafpausen" einzubauen, das sonst die Programme eine überproportional hohe Prozessorlast aufnehmen. Werden Wartezeiten mit den o. g. Funktionen realisiert, ermöglicht das dem Scheduler, auch mal andere Programme "ranzulassen". Siehe dazu:

Headerfiles beim Raspberry Pi bzw. beim Linux-PC

Für alle Programme genügen in der Regel die folgenden Headerfiles:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <termio.h>
#include <termios.h>

Übrigens: Die Linux-Manualpages bieten auch Infos zu jeder Bibliotheksfunktion von C. Einfach man funktionsname eingeben.

Programmbibliotheken

Alle Programme sind nicht nur hier auf www.netzmafia.de abrufbar, sondern auch auf den Praktikums-PCs im Verzeichnis /global zu finden. Bitte die Kommentierung im jeweiligen Headerfile beachten und ggf. die I/O-Adressen anpassen.

Die Quelldateien können Sie per scp-Kommando zum Raspberry Pi übertragen.
Copyright © Hochschule München, FK 04, Prof. Jürgen Plate
Letzte Aktualisierung: