DSRoute Home Blog

EasyMuxer RobotC


Dieser Post ist auch auf Englisch verfügbar 🇺🇸

Über

Der EV3 Sensor-Multiplexer von Mindsensors ist eine relativ teure, aber relativ zuverlässige Komponente für größere Mindstorms-Projekte.
Da die allgemeine Dokumentation zu RobotC nicht besonders gut ist und der Multiplexer hauptsächlich für die Verwendung in der offiziellen EV3-Programmiersoftware entwickelt zu sein scheint (und die offizielle Dokumentation recht "interessant" aussieht), kann es schwierig sein, die Verwendung dieser Komponente zu verstehen.
Das Ziel dieses Posts ist es, einen kleinen, aber verständlichen Leitfaden zur Verwendung dieses Bauteils in RobotC bereitzustellen.

Außerdem sind die Codebeispiele absichtlich einfach und verständlich gehalten, da sie auch zugänglich für jüngere Schüler sein sollen.


Einrichten der Entwicklungsumgebung

Um zu beginnen, öffne das Fenster "Setup Motors and Sensors" in RobotC und gib an, dass der Anschluss, an dem der Multiplexer angeschlossen ist, vom Typ "General I2C" ist.
Das sollte zu einer solchen Zeile führen:

#pragma config(Sensor, S1, , sensorEV3_GenericI2C)

Nun müssen wir die erforderlichen Treiber einbinden, um die Drittanbieter-Hardware verwenden zu können. Glücklicherweise hat Xander Soldaat bereits den Großteil der Arbeit für uns erledigt und die RobotC Driversuite geschrieben.
Klone das Git-Repository oder lade einfach das Zip-Archiv von hier herunter.
Entpacke alles und speichere es an einem angebrachten Ort.

Nun geh in der RobotC-IDE zu
View -> Preferences -> Detailed Preferences -> Compiler -> Include-Directories
(oder so) und füge das Unterverzeichnis include der gerade heruntergeladenen Driversuite hinzu. Es enthält einige erforderliche Bibliotheken.

Füge dann die ev3smux-Bibliothek im Code wie folgt ein:

#include "mindsensors-ev3smux.h"

Initiieren eines Multiplexers

Der langweilige Teil ist erledigt! Jetzt geht es ans Programmieren:

Um einen Multiplexer zu deklarieren und für die Initialisierung vorzubereiten, benötigst du im Grunde 2 Zeilen:


tMSEV3 muxer1[3];
tEV3SensorTypeMode muxer1Modes[3] = {
	colorMeasureColor,
	colorMeasureColor,
	colorMeasureColor
};
		

Die verfügbaren Modi sind:

Weitere Details findest du in der Header-Datei.

Nun, um den Sensor tatsächlich zu initialisieren, benötigst du Folgendes in deinem task main:


initSensor(&muxer1[0], msensor_S1_1, muxer1Modes[0]);
initSensor(&muxer1[1], msensor_S1_2, muxer1Modes[1]);
initSensor(&muxer1[2], msensor_S1_3, muxer1Modes[2]);
		

Der Großteil davon erklärt sich von selbst. Ich habe keine Referenz für das zweite Argument gefunden, aber da der Name auch recht selbsterklärend ist, bin ich hier nicht tiefer eingestiegen.

HINWEIS: Später werde ich eine Wrapper-Funktion für diese Initialisierung und andere Dinge einführen, um sie einfacher und "idiotensicher" zu machen und dem "natural language" Stil von RobotC zu entsprechen.


Benutzung des multiplexers

So: Wir haben unseren ersten Multiplexer erfolgreich eingerichtet und initialisiert. Super! Jetzt ist es an der Zeit, ihn zu verwenden.

Aber das ist nicht so einfach, wie es klingt (aber immernoch einfach ;D), denn der Multiplexer muss manuell dazu aufgefordert werden, neue Sensordaten zu erfassen. Sobald du dieses Konzept jedoch verstanden hast, wird der Rest trivial.

Um den Multiplexer dazu zu bringen, seine Sensorwerte zu aktualisieren, verwende einfach:


readSensor(&muxer1[0]);
readSensor(&muxer1[1]);
readSensor(&muxer1[2]);
		

Dies liefert außerdem einen booleschen Wert zurück, der angibt, ob die Operation erfolgreich war. Verwende das gerne in deinem Code weiter.

Damit enthält dein Multiplexer nun die neuesten Messwerte der Sensoren. Um tatsächlich auf die Werte zuzugreifen, stellt der Multiplexer verschiedene Attribute für jede mögliche abrufbare Größe zur Verfügung.

Je nachdem, welche Art von Sensor du angeschlossen und welchen Modus du ausgewählt hast, stehen dir folgende Optionen zur Verfügung:

Auch hier findest du weitere Details in der Header-Datei. Dort kannst du auch sehen, dass noch weitere Attribute wie die Rohdaten des I2C verfügbar sind, falls du daran interessiert bist.

Nehmen wir nun an, du hast wie in den vorherigen Beispielen 3 Farbsensoren angeschlossen. Um ihre Messwerte zu erhalten, würdest du Folgendes tun:


short color0 = muxer1[0].color;
short color1 = muxer1[1].color;
short color2 = muxer1[2].color;
		

Ehrlich gesagt weiß ich nicht genau, welcher Rückgabewert hier welcher Farbe entspricht, aber es ist wahrscheinlich etwas, das mit den Standardfarben von RobotC übereinstimmt. Du kannst es gerne ausprobieren und mir Bescheid geben!

Das ist die grundlegende Funktionalität des Multiplexers. Xander hat auch ein etwas fortgeschritteneres Beispiel in seinem Repository. Schau es dir dort an oder direkt hier.


Vereinfachung der Benutzung mit easymuxer.h

Wenn du bereits ein grundlegendes Verständnis für grundlegende Programmierkonzepte hast, mögen die obigen Beispiele trivial erscheinen. Aber für diejenigen unter uns, die noch nie etwas von OOP, Pointern oder Header-Dateien gehört haben, kann das schon abschreckend sein. Das kenne ich nur zu gut aus eigener Erfahrung.
Aus diesem Grund habe ich einen sehr einfachen, aber natürlichen "Wrapper" für den alltäglichen Einsatz des Sensor-Multiplexers entwickelt: easymuxer.

Der Zweck der Bibliothek besteht darin, einen noch einfacheren Ansatz für den Multiplexer zu bieten, der nur wenige Zeilen Setup und eine einzelne Zeile zum Auslesen der Werte erfordert.

Um die Bibliothek zu verwenden, musst du immer noch die mindsensors Header-Datei wie oben gezeigt einbinden. Zusätzlich dazu musst du easymuxer.h einbinden.
Entweder legst du es im Include-Verzeichnis der robotcdriversuite ab oder du gehst zurück zum Einstellungsfenster von vorhin und gibst dem Compiler den Pfad dazu an, wo es zu finden ist.

Füge es wie folgt ein:

#include "easymuxer.h"

Die Deklaration eines Multiplexers bleibt genau gleich,


tMSEV3 muxer1[3];
tEV3SensorTypeMode muxer1Modes[3] = {
	colorMeasureColor,
	colorMeasureColor,
	colorMeasureColor
};
		

aber die Initialisierung ist jetzt viel einfacher. Verwende einfach:


initMuxerWithModes(muxer1, muxer1Modes);
		

innerhalb des "Setup"-Teils deiner task main.

Das Abrufen der Sensordaten ist auch viel einfacher. easymuxer.h bietet Funktionen zum direkten Auslesen von Daten von Sensoren auf deinem Multiplexer. In unserem Fall, mit 3 Farbsensoren, würdest du einfach folgendes benötigen:


short color0 = getMuxColor(muxer1, 0);
short color1 = getMuxColor(muxer1, 1);
short color2 = getMuxColor(muxer1, 2);
		

Diese Funktionen lassen die Sensoren intern neue Werte messen, daher ist es nicht notwendig, ihnen vor jedem Auslesen manuell zu sagen, dass sie dies tun sollen. Juhu!

Die verfügbaren Funktionen sind:

Diese sollten die grundlegenden Anwendungsfälle abdecken.

Ein einfaches Beispiel für die Verwendung dieser Bibliothek könnte so aussehen (unten zum Download):


#pragma config(Sensor, S1, , sensorEV3_GenericI2C)

#include "mindsensors-ev3smux.h"
#include "easymuxer.h"

tMSEV3 muxer1[3];
tEV3SensorTypeMode muxer1Modes[3] = {
	colorMeasureColor, colorMeasureColor, colorMeasureColor
};

void example() {
	int color0 = getMuxColor(muxer1, 0);
	int color1 = getMuxColor(muxer1, 1);
	int color2 = getMuxColor(muxer1, 2);

	displayTextLine(1*0 + 1, "Color: %d", color0);
	displayTextLine(1*1 + 1, "Color: %d", color1);
	displayTextLine(1*2 + 1, "Color: %d", color2);
}

task main() {
  displayCenteredTextLine(0, "Mindsensors");
  displayCenteredBigTextLine(1, "EV3 SMUX");
  displayCenteredTextLine(3, "Test 1");
  sleep(2000);
  eraseDisplay();

  initMuxerWithModes(muxer1, muxer1Modes);

  while (true) {
	example();
  	sleep(100);
  }
}
		

Download section: