Sie sind auf Seite 1von 12

Projekt der Elektrotechnik und

Informationstechnik
3. Projektversuch
Schallsensor
13. Oktober 2009
I
Inhaltsverzeichnis
Inhaltsverzeichnis
1 Einleitung 1
2 Grundlagen 2
2.1 Mindstorms NXT Schallsensor . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.2 LEGO Lampe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3 MATLAB-Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3.1 for-Schleife . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3.2 MATLAB-Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3.3 Debugger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
3 Durchf uhrung 6
3.1 Sensor testen (ca. 30 min) . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.2 Sensor auslesen (ca. 90 min) . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.3 Klatschsensor (ca. 60 min) . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
II
1 Einleitung
1 Einleitung
Mit dem im LEGO Mindstorms NXT Education Set enthaltenen Schallsensor ist es
moglich, Gerausche zu detektieren und gegebenenfalls darauf zu reagieren. In diesem
Versuch sollen Sie den Sensor naher kennenlernen.
Ein wichtiges Hilfsmittel bei der Programmierung von Robotern sind auerdem Schlei-
fen, da die selben Arbeitsschritte oft immer wieder ausgef uhrt m ussen, bis ein Ereignis
eintritt. Ziel des Versuches ist daher auch, die Programmierung der for-Schleife von MAT-
LAB zu vertiefen.
1
2 Grundlagen
2 Grundlagen
Im Folgenden wird der Schallsensor und die Funktionen beschrieben, mit denen der Sensor
aus MATLAB angesteuert werden kann.
2.1 Mindstorms NXT Schallsensor
Abbildung 1: Schallsensor ( c LEGO)
Der Schallsensor im Mindstorms-Kit (siehe Abbildung 1) misst den Schalldruck in seiner
Umgebung. Im Gegensatz zu einem einfachen Mikrofon ist der Sensor nicht dazu geeig-
net, Gerausche oder Sprache aufzunehmen, die spater wieder abgespielt werden konnen.
Der Messwert, den der Sensor an den NXT-Brick liefert, ist eher zu vergleichen mit der
mittleren

Lautstarke, die zum Messzeitpunkt am Sensor vorliegt. Es wird also im Sen-


sor bereits ein Teil der Daten durch eine elektrische Schaltung vorverarbeitet. Dadurch
geht ein groer Teil der Information dar uber, um welches Gerausch es sich tatsachlich
gehandelt hat, verloren.
Der Schallsensor hat zwei Betriebsmodi. Im ersten misst der Sensor den Schalldruck
in dB. Die dB-Skala ist logarithmisch aufgebaut, d.h. verdoppelt sich der Schalldruck, so
erhoht sich der Messwert um 3 dB. Der Messbereich des Schallsensors reicht bis 90 dB
und umfasst einen Frequenzbereich von 20 Hz bis 18 kHz.
Die Empndlichkeit des menschlichen Gehors f ur Tone unterschiedlicher Frequenzen ist
unterschiedlich gro. Tone im Bereich um 3 kHz werden z.B. besonders gut wahrgenom-
men. Der zweite Betriebsmodus des Sensors ist gedacht, um diesen Eekt zu kompen-
sieren. Er gibt die Messwerte in dBA zur uck, einer Variante der logarithmischen Skala,
die in der Technischen Akustik eingesetzt wird, beispielsweise bei der Beurteilung von
Larmbelastigungen.
Um Werte des Sensors auslesen zu konnen, muss nat urlich zuerst eine Bluetooth- oder
USB-Verbindung mit dem NXT-Brick aufgebaut werden, wie Sie es auch schon aus dem
vorangegangenen Versuch kennen. Die daf ur benotigten Funktionen sind COM OpenNXT,
COM SetDefaultNXT und COM CloseNXT.
2
2 Grundlagen
OpenSound Initialisierung des Schallsensors.
OpenSound(SENSORPORT, MODE);
SENSORPORT Anschluss, an dem der Sensor angeschlossen ist. Mogliche Werte:
SENSOR_1, SENSOR_2, SENSOR_3, SENSOR_4 (entsprechen den Ports 1, 2, 3, 4).
MODE String, der den Modus angibt, in dem der Sensor aktiviert werden soll.
Mogliche Werte: DB, DBA
GetSound Auslesen des Sensors.
SOUNDVALUE = GetSound(SENSORPORT);
SENSORPORT Anschluss, an dem der Sensor angeschlossen ist. Mogliche Werte:
SENSOR_1, SENSOR_2, SENSOR_3, SENSOR_4 (entsprechen den Ports 1, 2, 3, 4).
SOUNDVALUE Ein Wert zwischen 0 und 1023 (10 Bit), der den gemessenen Schall-
druck auf einer logarithmischen Skala reprasentiert.
CloseSensor Sensorport abschalten.
CloseSensor(SENSORPORT);
SENSORPORT Anschluss, an dem der Sensor angeschlossen ist. Mogliche Werte:
SENSOR_1, SENSOR_2, SENSOR_3, SENSOR_4 (entsprechen den Ports 1, 2, 3, 4).
2.2 LEGO Lampe
Die im Mindstorms-Kit enthaltenen Gl uhbirnchen werden uber den Adapter zur alteren
Generation von LEGO Technik / LEGO Mindstorms mit dem NXT-Brick verbunden.
Wie Motoren werden sie an die Ports A/B/C angeschlossen.
SwitchLamp Lampe ein-/ausschalten.
SwitchLamp(MOTORPORT, VALUE);
MOTORPORT Anschluss, an dem die Lampe angeschlossen ist. Mogliche Werte:
MOTOR_A, MOTOR_B, MOTOR_C (entsprechen den Ports A, B, C).
VALUE Entweder on oder off.
2.3 MATLAB-Grundlagen
Die wichtigsten Programmstrukturen, die wir in diesem Versuch benotigen, sind die for-
Schleife und die Funktionsdeklaration.
3
2 Grundlagen
2.3.1 for-Schleife
Eine for-Schleife in MATLAB hat beispielsweise folgende Form:
for x = 1:10
x
end
Der Schleifenkopf (erste Zeile) bestimmt dabei die Start- und Stoppbedingungen der
Schleife. In diesem Beispiel ist x die Schleifenvariable. 1:10 ist in MATLAB-Syntax ein
Array mit 10 Elementen, namlich genau den Zahlen 1 bis 10. Wenn die Schleife ausgef uhrt
wird, erhalt x je genau einmal hintereinander den Wert eines der Elemente.
Der Schleifenkorper (der Teil zwischen dem Kopf und der letzten Zeile) wird dann f ur
jeden Wert einmal ausgef uhrt. D.h. im ersten Durchlauf hat x den Wert 1, dann 2, usw.
bis 10. Danach ist die Abarbeitung der Schleife beendet und das Programm fahrt mit
den Befehlen nach der Schleife fort. Da der Schleifenkorper auch aus mehreren Befehlen
bestehen kann, wird das Ende der Schleife mit end gekennzeichnet.
Um das Programm f ur den Mensch, der es programmiert, besser lesbar zu machen, r uckt
man den Schleifenkorper um einen Tabulator nach rechts ein. Dies ist f ur die korrekte
Abarbeitung der Schleife jedoch nicht erforderlich.
In diesem Beispiel ist der Befehl x der Schleifenkorper. Es wird also in jedem Durchlauf
der Wert der Variable x ausgegeben. Da dieser sich mit jedem Durchlauf andert, gibt das
Beispiel nacheinander die Werte 1 bis 10 aus.
2.3.2 MATLAB-Funktionen
Wenn man in MATLAB eine eigene Funktion deklarieren mochte, muss man dies stets in
einer eigenen Datei tun. Die Datei sollte dabei genau so heien wie die Funktion selbst.
Zusatzlich muss im Kopf der Datei speziziert werden, welche Argumente die Funktion
entgegennimmt und welche R uckgabewerte sie hat:
function [a, b, c] = meinefunktion(d, e, f);
<Befehle> ...
Hierbei sind d bis f Argumente, die der Aufrufer an die Funktion ubergibt. a bis c sind
R uckgabewerte der Funktion, die dem Aufrufer ubergeben werden, wenn die Funktion
abgearbeitet ist. In diesem Beispiel konnte der Aufrufer den Befehl
[x, y, z] = meinefunktion(1, 2, 3);
geben. Dadurch wird meinefunktion mit den Werten d = 1, e = 2 und f = 3 abge-
arbeitet. Das Ergebnis der Berechnung wird funktionsintern zwar in den Variablen a bis
c gespeichert, jedoch bestimmt der Aufrufer der Funktion, dass die Ergebnisse in den
Variablen x bis z abgelegt werden, sobald die Funktion fertig ist. F ur den Aufrufer der
Funktion sind die Variablen a bis c nicht sichtbar.
4
2 Grundlagen
Abbildung 2: Debugger-Men uleiste Abbildung 3: Gesetzter Breakpoint in Zeile 9
2.3.3 Debugger
Als Computer noch mit mechanischen Bauelementen arbeiteten, konnte es passieren, dass
sich tatsachlich ein Insekt in die Eingeweide einer solchen Rechenmaschine verirrte und
dort z.B. einen Schalter zur Fehlfunktion brachte. Daher stammt der Ausdruck

Bug
(engl.: Kafer, Insekt) f ur Programmfehler. In heutigen Zeiten handelt es sich jedoch meis-
tens nicht um einen Fehler der Hardware (wie z.B. defekter Hauptspeicher), sondern
meistens um Fehler, die der Programmierer selbst gemacht hat. Da man zunachst die
Codezeile nden muss, in der die Ursache f ur das Fehlverhalten des Programms steckt,
dauert die Suche nach solchen Fehlern meistens langer als die Behebung (und meist auch
langer als erwartet).
Wie in vielen anderen Entwicklungsumgebungen auch gibt es in MATLAB einen Debug-
ger. Mit diesem Werkzeug kann man ein Programm wahrend der Abarbeitung anhalten,
den Inhalt aller Variablen inspizieren, dann schrittweise mit der Abarbeitung fortfahren,
etc. Damit lassen sich Bugs wesentlich schneller nden als durch Betrachten des fehler-
haften Programmverhaltens.
Zum Benutzen des Debuggers muss man lediglich in einer Zeile des Programms einen
Breakpoint, also den Punkt, an dem die Abarbeitung des Programms anhalten soll, set-
zen. Dies geschieht in MATLAB, indem man im Editor auf den Strich rechts neben der
Zeilennummer klickt. Es erscheint dann ein roter Kreis (Abb. 3). Startet man dann das
Programm, wird es vorlaug an dieser Stelle unterbrochen, und die in Abb. 2 gezeigten
Symbole in der Men uleiste werden aktiv. Man kann dann das Programm schrittweise und
interaktiv abarbeiten lassen (Step), weiter ausf uhren lassen bis zum nachsten Breakpoint
oder Programmende (Continue) oder auch den Debugmodus verlassen (Exit). Im Debug-
modus erscheint vor dem Prompt im Befehlsfenster ein

K. Dies bedeutet, dass man die


Variablen, die in der aktuellen Funktion g ultig sind, im Workspace betrachten und sogar
verandern kann, bevor das Programm weiterlauft. Im Befehlsfenster kann man Variablen
plotten lassen und im Prinzip auch beliebige andere Befehle ausf uhren.
5
3 Durchf uhrung
3 Durchf uhrung
Dauer: ca. 180 Minuten
3.1 Sensor testen (ca. 30 min)
1. Schlieen Sie den Brick per USB an den Rechner an, onen Sie eine USB-Verbindung
und setzen Sie die Verbindung als Default.
2. Schlieen Sie den Schallsensor an den ersten Sensorport des Bricks an, und initiali-
sieren Sie den Schallsensor mit Hilfe des Befehls OpenSound. Die Ausgabe der Werte
soll in dB erfolgen.
3. Lesen Sie einen einzelnen Messwert mit Hilfe des Befehls GetSound aus. Vergewissern
Sie sich, dass der Sensor Daten liefert, die den Erwartungen entsprechen (z.B. indem
Sie einmal ein lautes Gerausch erzeugen, wahrend Sie den Sensor auslesen). Beachten
Sie, dass die Ausgabe des Befehls nicht angezeigt wird, wenn Sie ein Semikolon ans
Ende stellen!
4. Schlieen Sie die Verbindung wieder mit COM CloseNXT.
6
3 Durchf uhrung
3.2 Sensor auslesen (ca. 90 min)
Wir wollen nun uber einen langeren Zeitraum Messwerte auslesen. Dazu bedienen wir
uns der for-Schleife von MATLAB. Da die Programmierung von Schleifen auf der Kom-
mandozeile umstandlich werden kann, erstellen wir eine eigene Funktion, die man immer
wieder aufrufen kann.
1. Legen Sie mit Hilfe des MATLAB-Editors eine neue Datei mit dem Namen
soundsensor.m an. Benutzen Sie daf ur den Befehl edit oder das MATLAB-Men u.
2. Legen Sie den Funktionskopf an. Unsere Funktion soundsensor benotigt keine Ar-
gumente und gibt auch keinen Wert zur uck.
3. Zu Beginn der Funktion soll wie in Aufgabe 3.1 die USB-Verbindung geonet
und der Schallsensor initialisiert werden. Geben Sie also die entsprechenden Befehle
in den Editor ein.
4. Der Hauptteil der Funktion soll aus einer for-Schleife bestehen, die die Laufvariable
i von 1 bis 1000 durchzahlt. Platzieren Sie innerhalb der Schleife einen GetSound-
Befehl, so dass dieser 1000 mal ausgef uhrt wird.
5. Am Ende der Funktion soll die USB-Verbindung wieder abgebaut werden. F ugen
Sie also hinter der for-Schleife einen Befehl zum Schlieen der Verbindung an.
Die Funktion besteht jetzt aus drei Teilen: Initialisieren der Verbindung und des
Sensors, Lesen der Daten in einer Schleife, Schlieen der Verbindung. Speichern Sie
die Funktion.
6. Gehen Sie zur uck ins MATLAB-Hauptfenster und f uhren Sie die Funktion mit dem
Befehl soundsensor aus. In der Ausgabe sollten jetzt nacheinander 1000 Messwerte
erscheinen, wie Sie vom Sensor gemessen werden. Falls keine Ausgabe erscheint, stel-
len Sie sicher, dass hinter dem GetSound-Befehl kein Semikolon steht, was die Aus-
gabe unterdr uckt. Korrigieren Sie die Funktion und wiederholen Sie diesen Schritt
falls notig.
Wir wollen nun die Messdaten speichern, damit wir die Daten auf einfache Art und
Weise auswerten konnen. Dazu andern wir die Funktion so, dass Sie die gemessenen Daten
in einem MATLAB-Array zur uckgibt.
7. Gehen Sie zur uck in den Editor.

Andern Sie den Funktionskopf so, dass die Funktion
eine Variable namens values an den Aufrufer der Funktion zur uckgibt.
8. Im ersten Teil der Funktion (vor der Schleife) m ussen wir das Array values initia-
lisieren. Es soll zunachst keine Daten enthalten. F ugen Sie daher den Befehl
values = [];
vor der Schleife in die Funktion ein.
7
3 Durchf uhrung
9. Die Messwerte sollen nun anstatt direkt ausgegeben zu werden in jedem Schlei-
fendurchlauf an das Array values angehangt werden. Realisieren Sie dies, indem
Sie dem Element von values mit dem Index i in der Schleife den gemessenen Wert
zuweisen.
10. Speichern Sie die Funktion, gehen Sie wieder zur uck in das MATLAB-Hauptfenster
und lesen Sie 1000 Messwerte ein, indem Sie den Befehl
v = soundsensor;
eingeben. Der Befehl sollte ohne Ausgabe verlaufen. Nach einigen Sekunden sollte
v ein Array mit 1000 Werten sein.
11. Da die Messdaten nun im Array v gespeichert sind, konnen wir sie auch nach der
eigentlichen Messung verarbeiten. Stellen Sie sie als Beispiel mit dem Befehl plot
grasch dar. Stimmt der Verlauf des Schalldrucks mit dem uberein, was Sie erwartet
haben? Wiederholen Sie die Messung und die Darstellung ein paar mal, um das zu
uberpr ufen. Hinweis: Da die Anzahl der Messpunkte pro Sekunde davon abhangt,
wie leistungsfahig der PC ist, m ussen Sie die Anzahl der Messwerte ggf. erhohen,
um uber einen langeren Zeitraum messen zu konnen.
8
3 Durchf uhrung
3.3 Klatschsensor (ca. 60 min)
In diesem Teil des Versuchs wollen wir ein Programm schreiben, das nicht nur Messdaten
einliest, sondern auch auf Ereignisse reagiert. Dazu verkn upfen wir die Messungen vom
Schallsensor mit der Schaltung einer Lampe. Wenn der Schalldruck einen gewissen Wert
uberschreitet, wird die Lampe ein- bzw. ausgeschaltet. Dadurch bekommen wir einen
einfachen Klatschsensor.
1.

Onen Sie die Datei clapsensor.m. Darin bendet sich bereits folgendes Ger ust:
function clapsensor()
% close all handles and open a new one
COM_CloseNXT(all);
h = COM_OpenNXT;
COM_SetDefaultNXT(h);
% open sound sensor on sensor port 1
OpenSound(SENSOR_1, DB);
% initialize sample array and state of lamp
values = zeros(15, 1);
state = 0;
% initially, turn lamp off
SwitchLamp(MOTOR_A, off);
for i = 1:500
% get a new sample from the sensor
s = GetSound(SENSOR_1);
% throw away oldest sample and add the new one at the end
values = [values(2:end); s];
% ...
% wait 10ms between samples
pause(0.01);
end
% close handle
COM_CloseNXT(h);
end
Die Funktion in dieser Form liest Messwerte vom Sensor ein, halt aber immer nur
die 15 neuesten Messwerte in der Variable values vor. In der Schleife fehlen noch
die Befehle, die die Messwerte verarbeiten.
9
3 Durchf uhrung
Nach jedem Messwert wartet das Programm 10 Millisekunden, um nicht unnotig
viele Messwerte verarbeiten zu m ussen. Da die Verarbeitung des Messwerts durch
den PC aber unterschiedlich lange dauern kann (z.B. wenn andere Prozesse CPU-
Ressourcen verbrauchen), ist diese Vorgehensweise relativ ungenau. Um Messwerte
in gleichmaigen Intervallen zu nehmen, kann man in Matlab auch Timer-Objekte
verwenden. Diese werden in Versuch 5 (Lichtsensor) genauer beschrieben.
Die Lampe wird zu Beginn der Funktion ausgeschaltet. Die zusatzliche Variable
state dient dazu, den Status der Lampe, d.h. ob sie momentan an- (1) oder ausge-
schaltet (0) ist, zu speichern, und wird daher zu Beginn auf 0 gesetzt.
2. F ugen Sie an der Stelle, die mit den drei Punkten gekennzeichnet ist, einen Befehl
ein, der die Messwerte grasch darstellt (z.B. plot oder stem). Speichern Sie, wech-
seln Sie zum MATLAB-Hauptfenster und f uhren Sie die Funktion aus. Sie sollten
sehen, wie die jeweils 15 letzten Messwerte in einem MATLAB-Fenster durchlaufen.
3. Ersetzen Sie jetzt den plot-Befehl durch eine if-Anweisung, die pr uft, ob der aktu-
ellste Messwert einen bestimmten Schwellwert uberschreitet. Welcher Wert sinnvoll
ist, m ussen sie experimentell bestimmen. Falls der Schwellwert uberschritten ist (al-
so ein Klatschen gemessen wurde), soll wiederum gepr uft werden, welchen Zustand
die Lampe aktuell hat, und dann in den jeweils anderen Zustand geschaltet werden.
Hinweis: Sie m ussen dazu zwei if-Anweisungen ineinander verschachteln!
Setzen sie innerhalb der aueren if-Anweisung einen Breakpoint, so dass das Pro-
gramm jedesmal angehalten wird, wenn der Schwellwert uberschritten ist. So konnen
Sie schrittweise (mit

Step) uberpr ufen, ob der Inhalt der if-Anweisung richtig aus-


gef uhrt wird und dann (mit

Continue) das Programm fortsetzen.


4. Um das Verhalten des Klatschsensors zu verbessern, kann man anstelle von groen
Schalldruckwerten auch groe

Anderungen des Schalldrucks als Kriterium verwen-
den. Dies entspricht einer Flankendetektion: Die Lampe schaltet nur dann um, wenn
der Schalldruck um ein gewisses Ma ansteigt. Bestimmen Sie dazu mit Hilfe des
diff-Befehls die

Anderung des Schalldrucks in den letzten 15 Messwerten. Speichern
Sie das Ergebnis in einer eigenen Variable. Modizieren Sie dann die if-Anweisung
so, dass sie das letzte Element dieses Arrays mit einem Schwellwert testet. Verwen-
den Sie auch hier wieder den Debugger, um das Programm zu beobachten.
5. (Zusatzaufgabe) Schlieen Sie noch zwei zusatzliche Lampen an den NXT-Brick an
und verandern Sie die Funktion so, dass sie auf einen, zwei bzw. drei Klatscher
reagiert. Je nach Anzahl der Klatscher soll immer nur eine der drei Lampen an-
bzw. ausgeschaltet werden. Hinweis: Bis jetzt haben Sie immer nur den aktuellsten
Messwert bzw. die aktuellste Messwertdierenz als Schaltkriterium verwendet. Jetzt
benotigen Sie auch die restlichen der 15 Messwerte.
10