![]() |
Praktikum MikrocontrollerperipherieProf. Jürgen Plate |
| Platz | Versuch | Schnittstelle | Rechner |
|---|---|---|---|
| Fenster 1 | 7-Segment-Multiplex | parallel 12 Bit | Arduino |
| Fenster 1 | GPS-Empfänger | seriell (9600) | Linux-PC |
| Fenster 2 | Ultraschall-Entf. | seriell (USB, 4800) | Linux-PC |
| Fenster 2 | Geigerzähler | parallel 1 Bit | Arduino |
| Fenster 3 | Kamera + Servos | seriell, TCP/IP | Arduino |
| Fenster 4 | RFID | seriell (9600), par. 3 Bit | Arduino |
| Fenster 5 | Strommessung | analog | Arduino |
| Fenster 5 | 7-Segment-Multiplex | parallel 12 Bit | Arduino |
| Fenster 6 | Touch-Display | seriell (9600) | Linux-PC |
| Fenster 6 | Farbmischer | parallel PWM, seriell | Arduino |
| Fenster 7 | Touch-Display | seriell (9600) | Linux-PC |
| 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 | PSD-Entfernungssensor | analog | Arduino |
| Tür 4 | 3-Achsen-Beschleunig. | analog, parallel 4 Bit | Arduino |
| Tür 4 | Gassensor | analog | 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 |
Im Wintersemester 2016/17 ist die Aufgabe Eieruhr zu bearbeiten.
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.
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. Ein mit Atmel ATmega bestücktes Mikrocontrollerboard steuert das Ultraschall-System an und liefert kontinuierlich über die USB-Schnittstelle (Pseudo-Seriellschnittstelle) jeweils die Laufzeit in Mikrosekunden als ASCII-String, der durch Carriage-Return und Linefeed abgeschlossen wird.
Einstellung der seriellen Schnittstelle:
Schreiben Sie ein Programm, das die Daten über die Schnittstelle einliest und
nach der Formel s = v * t in eine Entfernungsangabe umrechnet.
Dabei soll gelten:
v = Schallgeschwindigkeit (bei 20 Grad): 343.0 m/s
t = Laufzeit: Messwert in Mikrosekunden
Anmerkungen:
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:
| Temperatur | Anzeige |
|---|---|
| < 24 | ' ' |
| 24 .. 26 | '.' |
| 27 .. 29 | '+' |
| 30 .. 32 | '*' |
| 33 .. 35 | '@' |
| > 35 | '#' |
. . . . + + . . ↵ . . . . + + . . ↵ . . . + + . . . ↵ . . . + + . . . ↵ . . + + . . . . ↵ . . + + . . . . ↵ . . . . . . . . ↵ . . . . . . . . ↵
Anmerkungen:
int open_serial(void)
{
/*
* Oeffnet seriellen Port
* Gibt das Filehandle zurueck oder -1 bei Fehler
*
* 19200 bps, 8 Datenbits, 1 Stoppbit, no parity, no handshake
*/
int fd; /* Filedeskriptor */
struct termios options; /* Schnittstellenoptionen */
/* Port oeffnen - read/write, kein "controlling tty", Status von DCD ignorieren */
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd >= 0)
{
/* get the current options */
fcntl(fd, F_SETFL, 0);
if (tcgetattr(fd, &options) != 0) return(-1);
memset(&options, 0, sizeof(options)); /* Structur loeschen */
/* Baudrate setzen */
cfsetispeed(&options, B19200);
cfsetospeed(&options, B19200);
/* setze Optionen */
options.c_cflag &= ~PARENB; /* kein Paritybit */
options.c_cflag &= ~CSTOPB; /* 1 Stoppbit */
options.c_cflag &= ~CSIZE; /* 8 Datenbits */
options.c_cflag |= CS8;
options.c_cflag |= (CLOCAL | CREAD);
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_iflag = IGNPAR; /* Parity-Fehler ignorieren */
options.c_oflag &= ~OPOST; /* setze "raw" Input */
options.c_cc[VMIN] = 0; /* warten auf min. 0 Zeichen */
options.c_cc[VTIME] = 10; /* Timeout 1 Sekunde */
tcflush(fd,TCIOFLUSH); /* Puffer leeren */
if (tcsetattr(fd, TCSAFLUSH, &options) != 0) return(-1);
}
return(fd);
}
printf("\033[2J"); /* Dirty: clear screen */
printf("\033[1;1H"); /* Dirty: cursor home */
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:
Programmiert werden soll die Ansteuerung eines Farbgrafik-LCD mit Touchscreen (EA-KIT 129-6) über die serielle Schnittstelle. Gefordert ist ein Entwurf des Bildschirm-Layouts (128 x 64 Pixel) und die Ausgabe unter Verwendung der oben aufgeführten Programm-Bibliothek display_funct:
26.10.2015 09:50:55 RX: 12226 MB, TX: 578 MB, AK: 67 LD: 0.09, 0.05, 0.01 /dev/sda1 34%Sorgen Sie im Programm dafür, dass die Informationen im 30-Sekunden-Abstand aktualisiert werden (Endlosschleife, sleep-Kommando).
Die Einstellung der seriellen Schnittstelle ist:
Nach manchen Grafik-Befehlen (z. B. Schriftart ändern, Button zeichnen) muss gewartet werden, damit das Display die folgenden Befehle korrekt ausführt (Auch mit Hardware-Handshake).
netstat -i Kernel-Schnittstellentabelle Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg eth0 1500 0 1286226046 0 0 0 606976358 0 0 0 BMRU lo 16436 0 24596559 0 0 0 24596559 0 0 0 LRUSie müssen die Zeile für eth0 herausschneiden (grep) und dann die Felder RX-OK und TX-OK in Shell-Variablen speichern. Das kann mit einer Kommando-Pipe der Form
RX=$(netstat -i | grep eth0 | awk '{print $4;}')
TX=$(netstat -i | grep eth0 | awk '{print $8;}')
Überprüfen Sie das Ergebnis mit dem Befehl echo "RX TX"
RX=$(echo "$RX / 1024" | bc) TX=$(echo "$TX / 1024" | bc)Nun ermitteln Sie noch die Zahl der gerade aktuellen Verbindungen nach dem gleichen Muster:
AK=$(netstat -tu | wc -l)Von diesem Wert muss noch wegen der beiden Kopfzeilen 2 subtrahiert werden. Das ergibt das Folge-Kommando:
AK=$(echo "$AK - 2" | bc)Nun können die drei Werte der Variablen, ausgegeben werden. Zur Kontrolle können Sie die Werte mit echo "$RX $TX $AK" ausgeben.
uptime 09:42:11 up 244 days, 20:07, 3 users, load average: 0.09, 0.05, 0.01Schneiden Sie mittels sed alles einschließlich "load average:" weg und geben Sie nur die Lastinfo aus. Das Kommando lautet dann:
LD=$(uptime | sed -e 's/..*average: //')Auch hier kontrollieren Sie mittels echo $LD .
df Dateisystem 1K-Blöcke Benutzt Verfügbar Ben% Eingehängt auf /dev/sda1 67947448 21653428 42842460 34% / tmpfs 1947648 0 1947648 0% /lib/init/rw udev 1943200 104 1943096 1% /dev tmpfs 1947648 0 1947648 0% /dev/shmIdentifizieren Sie die Zeile, die sich auf die Festplatte bezieht (im Beispiel /dev/sda1, es kann aber auch etwas wie /dev/disk/by-uuid/377b8dd7... sein) und extrahieren Sie diese mit Hilfe des grep-Kommandos. Schneiden Sie mittels awk '{print $1 " " $5}' den Namen der Platte und die Prozentangabe heraus. Das ergibt das Kommando:
PL=$(df | grep "/dev/sda1" | awk '{print $1 " " $5}')
Kontrollieren Sie das Ergebnis mir echo $PL .
Routinen für das serielle Touch-Terminal:
Da es sich um sehr viele, meist einzeilige Befehle handelt, bitte das Headerfile
studieren. Diese Bibliothek ist noch sehr sehr Alpha!
Headerfile display_funct.h
C-Quelle display_funct.c
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 12Der 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.
Schreiben Sie ein C-Programm zur Erfassung von Transponderkarten-IDs:
RX (Empfang) Pin 10 TX (Senden) Pin 11In diesem Fall wird nur der RX-Pin benötigt. Zur Initialisierung wird der folgende Code benötigt:
#include <SoftwareSerial.h>
#define RT 8
#define GE 9
#define GN 12
#define RX 10
#define TX 11
.
.
SoftwareSerial RFID(RX,TX); /* Instanz der SoftwareSerial-Schnittstelle */
.
.
void setup()
{
Serial.begin(19200); /* Verbindung zum PC */
while (!Serial) ; /* Warten auf connect */
RFID.begin(9600); /* Verbindung zum RFID-Leser */
pinMode(GE,OUTPUT); /* LED-Pins */
pinMode(GN,OUTPUT);
pinMode(RT,OUTPUT);
.
.
}
void loop()
{
/* zum Testen */
if (RFID.available())
{ Serial.write(RFID.read()); }
}
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.
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.
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.
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:
| Anschluss | Kabel- Farbe | Arduino- Pin |
|---|---|---|
| GND | braun | GND |
| ROT | rot | PB1(9) |
| GRÜN | grün | PB2(10) |
| BLAU | violett | PB3(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:
| Kommando | Bedeutung |
|---|---|
| Rxx | Helligkeitswert für ROT. Dabei steht "xx" für eine zweistellige Sedezimalzahl zwischen 00 und FF |
| Gxx | Helligkeitswert für GRÜN. Dabei steht "xx" für eine zweistellige Sedezimalzahl zwischen 00 und FF |
| Bxx | Helligkeitswert für BLAU. Dabei steht "xx" für eine zweistellige Sedetimalzahl zwischen 00 und FF |
| Ix | Blinkfrequenz in Hz. Dabei steht "x" für eine Zahl zwischen 0 und 9, wobei die "0" auf Dauerlicht schaltet (kein Blinken). |
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.
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)
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,0 | 3,5 mA - 35 mA | 1,0 | 35 mA - 350 mA |
| 0,1 | 350 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.
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:

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.
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 VUm 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.0Fü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.
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 mainBeachten 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
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:
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.
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.
int echo_on(void); /* Tastaturecho einschalten */
int echo_off(void); /* Tastaturecho ausschalten */
int getch(void); /* Taste einlesen (ohne anschl. Enter, ohne Echo) */
int getch_nw(void) /* Taste einlesen (ohne Warten, ohne Echo) */
/* gibt -1 zurueck, wenn kein Zeichen gelesen wurde */
Headerfile prakt.h (inkl. Quellen)