Kurze Einführung:
Beim Aufbau von Robotern oder anderen automatisch gesteuerten Maschinen
kommt man schnell an die Grenzen des RCX-Bausteins:
Er hat nur 3 Eingänge und 3 Ausgänge. Das reicht oft nicht aus.
Wenn man viele Touch-Sensoren anschließen will, wo der RCX auch erkennen
soll, welcher Sensor aktiviert (= gedrückt) wurde,
kann man sie mit verschieden großen Widerständen in Reihe schalten.
So etwas nennt man Multiplexer (= Vervielfacher).
Dieses Verfahren kann man nicht für beliebig viele Touch-Sensoren machen, aber
bis zu 4 Sensoren kann der RCX an einem Eingang sicher erkennen.
(In Martin's Bastelstube, Teil III
gibt's dann ein Beispiel mit 6 Schaltern, aber da geht es wirklich an die
physikalischen Grenzen des RCX.)
Beispiel-Schaltung:
Wir bauen einen Multiplexer für 3 Touch-Sensoren an einem Eingang.
Die gesamte Schaltung passt unter eine LEGO-Kontaktplatte im Format 8x2.
Der Eingangswiderstand am RCX-Sensoreingang ist 10 kOhm. Wir sollten also auch
Widerstände in derselben Größenordnung wählen, damit später
die Unterscheidung der einzelnen Touch-Sensoren in Software einfacher und
unempfindlicher gegen Störungen und Messrauschen wird.
Touch-Sensor 1 bekommt einen Reihenwiderstand von 5.1 kOhm.
Touch-Sensor 2 bekommt einen Reihenwiderstand von 10 kOhm.
Touch-Sensor 3 bekommt einen Reihenwiderstand von 20 kOhm.
(Zur Info: Jeder Touch-Sensor hat im geschlossenen Zustand (als Kurzschluss-Schutz)
einen Widerstand von etwa 500-700 Ohm.)
Diese Einteilung, dass die Widerstandswerte sich immer verdoppeln, hat einen speziellen
Zweck – damit kann man später in Software auch dann noch die einzelnen
Touch-Sensoren erkennen, wenn mehrere gleichzeitig gedrückt sind.
Hardware:
Wir trennen auf der Unterseite der Kontaktplatte einen der Blechstreifen in vier
Abschnitte à 2 Noppen (am besten mit einer dünnen Trennscheibe wie in
Martin's Bastelstube, Teil I beschrieben).
Der zweite Blechstreifen bleibt in einem Stück.
Wir legen einen der vier entstandenen kurzen Abschnitte als Ausgang unseres
Multiplexers fest, die anderen sind die Eingänge. Der Ausgang ist idealerweise
an einem Ende des Kontaktplättchens.
Jetzt löten wir von jedem der drei Eingänge eine Verbindung zum Ausgang
über einen Widerstand. Mit Isolierschläuchen stellen wir sicher,
dass keine Kurzschlüsse zwischen den Widerstandsbeinchen entstehen.
Auf verschiedenen Internet-Seiten findet ihr ähnliche Beschreibungen, zum Teil
werden von den Autoren andere Widerstandwerte vorgeschlagen ...
das ist genauso gut möglich, ihr müsst dann eben die Schwellwerte in eurem
Programm auf die veränderten Messwerte anpassen.
Die von mir verwendeten Widerstandswerte schöpfen den Wertebereich des
Sensor-Eingangs weiter aus und geben dadurch eine geringere
Empfindlichkeit gegenüber Störungen und Messrauschen.
Software:
Zuerst müssen wir den Sensor-Eingang in den RAW-Modus schalten. Damit bekommen
wir die höchste Messgenauigkeit (Zahlenwerte zwischen 0 und 1023).
SetSensorType (SENSOR_1, SENSOR_TYPE_TOUCH);
SetSensorMode (SENSOR_1, SENSOR_MODE_RAW);
Wir lassen uns auf dem Display des RCX die Messwerte für den Sensor-Eingang
anzeigen und schreiben auf, welche Messwerte für alle 8 möglichen
Touch-Sensor-Kombinationen angezeigt werden.
SelectDisplay (DISPLAY_SENSOR_1);
Beispieltabelle:
touch_1 |
touch_2 |
touch_3 |
Messwert |
Schwellwert |
0 |
0 |
0 |
1023 |
|
|
SCHWELLWERT_1 = 856 |
0 |
0 |
1 |
690 |
|
|
SCHWELLWERT_2 = 607 |
0 |
1 |
0 |
524 |
|
|
SCHWELLWERT_3 = 474 |
0 |
1 |
1 |
424 |
|
|
SCHWELLWERT_4 = 398 |
1 |
0 |
0 |
372 |
|
|
SCHWELLWERT_5 = 342 |
1 |
0 |
1 |
312 |
|
|
SCHWELLWERT_6 = 294 |
1 |
1 |
0 |
276 |
|
|
SCHWELLWERT_7 = 257 |
1 |
1 |
1 |
239 |
|
Wir berechnen immer die Mitte zwischen zwei Messwerten als Schwellwert
für die Entscheidungen in Software.
Diese Schwellwerte können wir als Makros an den Anfang unseres Programms
schreiben oder direkt unten in den Entscheidungsbaum eintragen.
#define SCHWELLWERT_1 856
#define SCHWELLWERT_2 607
#define SCHWELLWERT_3 474
#define SCHWELLWERT_4 398
#define SCHWELLWERT_5 342
#define SCHWELLWERT_6 294
#define SCHWELLWERT_7 257
In unserem Programm fragen wir den Messwert einmalig ab und vergleichen
den gespeicherten Messwert gegen die vorher berechneten Schwellwerte.
int messwert;
int touch_1;
int touch_2;
int touch_3;
// Messwert einmalig vom Sensor-Eingang lesen
messwert = SENSOR_1;
// Binärer Entscheidungsbaum für alle möglichen Touch-Kombinationen
if (messwert > SCHWELLWERT_4)
{
touch_1 = 0;
if (messwert > SCHWELLWERT_2)
{
touch_2 = 0;
if (messwert > SCHWELLWERT_1)
{
touch_3 = 0;
}
else
{
touch_3 = 1;
}
}
else
{
touch_2 = 1;
if (messwert > SCHWELLWERT_3)
{
touch_3 = 0;
}
else
{
touch_3 = 1;
}
}
}
else
{
touch_1 = 1;
if (messwert > SCHWELLWERT_6)
{
touch_2 = 0;
if (messwert > SCHWELLWERT_5)
{
touch_3 = 0;
}
else
{
touch_3 = 1;
}
}
else
{
touch_2 = 1;
if (messwert > SCHWELLWERT_7)
{
touch_3 = 0;
}
else
{
touch_3 = 1;
}
}
}
Es geht auch anders ... das ist im Code etwas übersichtlicher, aber
braucht mehr Rechenzeit für die weiter unten liegenden Entscheidungen.
int messwert;
int touch_1;
int touch_2;
int touch_3;
// Messwert einmalig vom Sensor-Eingang lesen
messwert = SENSOR_1;
// Linearer Entscheidungsbaum für alle möglichen Touch-Kombinationen
if (messwert > SCHWELLWERT_1)
{
touch_1 = 0;
touch_2 = 0;
touch_3 = 0;
}
else if (messwert > SCHWELLWERT_2)
{
touch_1 = 0;
touch_2 = 0;
touch_3 = 1;
}
else if (messwert > SCHWELLWERT_3)
{
touch_1 = 0;
touch_2 = 1;
touch_3 = 0;
}
else if (messwert > SCHWELLWERT_4)
{
touch_1 = 0;
touch_2 = 1;
touch_3 = 1;
}
else if (messwert > SCHWELLWERT_5)
{
touch_1 = 1;
touch_2 = 0;
touch_3 = 0;
}
else if (messwert > SCHWELLWERT_6)
{
touch_1 = 1;
touch_2 = 0;
touch_3 = 1;
}
else if (messwert > SCHWELLWERT_7)
{
touch_1 = 1;
touch_2 = 1;
touch_3 = 0;
}
else // messwert <= SCHWELLWERT_7
{
touch_1 = 1;
touch_2 = 1;
touch_3 = 1;
}
Damit ihr nicht alles nochmal abtippen müsst, habe ich in der Datei
mux_decoder.nqc
den gesamten NQC-Quellcode zum Herunterladen.
Anwendung:
Jetzt haben wir den Zustand jedes einzelnen Touch-Sensors in den drei
Variablen touch_1, touch_2 und touch_3.
Was ihr (oder euer Roboter) mit der Information anfangt, bleibt euch
überlassen.
Ihr könntet zum Beispiel bei eurem Fußball-Roboter unterscheiden,
welcher Bumper (links / rechts / Mitte) die Wand getroffen hat
und entsprechend verschiedene Ausweichmanöver fahren.
Tschüß, euer Martin S.
|