DSRoute Home Blog

EasyMuxer RobotC


This post is also available in german 🇩🇪

About

The EV3 sensor multiplexer by mindsensors is a relatively expensive, but seemingly reliable component for big mindstorms projects.
But because the general documentation regarding RobotC is not particulary good, and since the Multiplexer seems to be mainly designed to be used in the official EV3 programming software (and its official documentation looks "interesting") it can be hard to get a grip on the usage of this part.
The goal of this post is to provide a small but comprehensible guide about the usage of this component in RobotC.

Also, because this is intended to be used by younger students, the code examples are deliberatly kept as easy and understandable as possible.


Setting up your IDE

To start of, open the Motors and Sensors Setup window of RobotC and specify, that the port where your Multiplexer is connected to is of type Generic I2C.
That should result in a line similar to:

#pragma config(Sensor, S1, , sensorEV3_GenericI2C)

at the top of your program.

Now, we need to include the necessary drivers to use the third-party hardware. Luckily, Xander Soldaat already did all the hard work for us and wrote the RobotC Driversuite.
Clone the git repository or just download the zip archive from here.
Extract everything and store it somewhere you remember.

Now, inside the RobotC IDE, go to
View -> Preferences -> Detailed Preferences -> Compiler -> Include Directories
(or something similar) and include the include subfolder of the driversuite you just downloaded. It contains some necessary libraries.

Then, include the ev3smux library in your code like so:

#include "mindsensors-ev3smux.h"

Initiating a multiplexer

That's the boring part done! Now, let's get to coding:

To declare and prepare a multiplexer for initialization, you basically need 2 lines:


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

The available modes are:

See the header file for more details.

Now, to actually initialize the sensor you need something like this in your 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]);
		

Most of that is pretty self-explanatory. I didn't find a reference to what the second argument really is, but since the name is also pretty self-explanatory I did not dig deeper here.

NOTE:I will later introduce a wrapper for this initialization and the other stuff, to make it easier and fool-proof to use and to make it match the "natural language" style of RobotC.


Using the multiplexer

So: We successfully set up and initialized our first multiplexer. Great! Now its time to use it.

But this isn't as simple as it sounds (though its still simple ;D), because the multiplexer needs to be manually told to measure new sensor data. But once you understand that concept, the rest becomes trivial.

To make the multiplexer update its sensor-values, simply use:


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

This returns a boolean, whether or not the operation was successful, so feel free to include that in your code.

With that, your multiplexer now holds the latest readings of the updated sensors. To actually grab the values, the mutliplexer provides different attributes for every possible value to be read.

Depending on what type of sensor you connected and what mode you selected, you can choose from:

Again, see the header file for more details. There you can also see, that it provides even more attributes like the raw I2C data if you are interested in that.

Now, let's say you connected 3 color sensors like I have in the previous examples. To get their readings you would do:


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

I honestly dont know what number corresponds to what color, but its probably something aligned with the default robotC colors. Feel free to test it out and tell me!

That is the basic functionality of the multiplexer. Xander also has a slightly more advanced example in his repository. Check it out there or take a look here.


Simplifying the usage with easymuxer.h

If you already have a basic understanding of present concepts in programming the above examples might seem trivial to you. But for people who never heard about OOP, pointers or header files in their life, this might already be scary, I know that too good from personal experience.
That's why I developed a very basic but natural "wrapper" for the everyday use cases for the sensor-multiplexer: easymuxer.

The library's scope is, to offer an even easier approach to the multiplexer, needing only few lines of setup and a single line for reading the values.

To use the library, you still need to include the mindsensors header file as shown above. In addition to it, you need to include easymuxer.h.
Either put it in the include directory of the driver suite, or go back to the settings window from earlier and tell the compiler where to find it.

Include it like so:

#include "easymuxer.h"

Declaring a multiplexer stays exactly the same,


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

but initializing is alot easier now. Just use:


initMuxerWithModes(muxer1, muxer1Modes);
		

inside the "setup" part of your task main.

Getting the sensor data also is alot easier. easymuxer.h provides functions, to directly read data from a sensor on your multiplexer. In our case, with 3 color sensors, you would just need:


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

These functions internally make the sensors measure new values, so no need to manually tell them to do so before each read. Yay!

The available functions are:

These should cover the basic use cases.

A simple example using this library might look like this (download below):


#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: