ev3dev / ev3dev

ev3dev meta - bug tracking, wiki and releases
http://www.ev3dev.org
GNU General Public License v2.0
630 stars 85 forks source link

Need help with EV3 Sensor Multiplexer using several LEGO EV3 Infrared #1098

Open cho934 opened 6 years ago

cho934 commented 6 years ago

What are you trying to do?

Hello, I want to connect several LEGO EV3 Infrared on the EV3 Sensor Multiplexer.

I follow the following page : http://docs.ev3dev.org/projects/lego-linux-drivers/en/ev3dev-jessie/muxs.html#ev3-sensor-multiplexer-for-ev3-or-nxt

First I'm trying to execute some console commands to initialize the ir sensors correctly and understand how it works. Second, my goal is to do it directly in the C++ program.

What did you expect to happen?

Each IR sensors connected to the MUX must be configured as lego-ev3-ir. I have to do it manually. try this without success echo lego-ev3-ir > /sys/class/lego-port/port11/set_device Then I tried to use value0 of sensor4 (which seem to have the correct address), but values don't change. Moreover the sensor4 is not recognized to IR-PROX

What are the correct command line to execute ? I didn't find the correct sequence of the commands. Could you help me ?

What hardware and software are you using (including version numbers)?

robot@ev3dev:~$ ev3dev-sysinfo -m

System info (from ev3dev-sysinfo)


Image file:         ev3dev-jessie-ev3-generic-2017-09-14
Kernel version:     4.4.87-22-ev3dev-ev3
Board:              LEGO MINDSTORMS EV3 Programmable Brick
Revision:           0006
Brickman:           0.8.1
ev3devKit:          0.4.3
dlech commented 6 years ago

Did you put the MUX ports in ev3-uart mode first?

cho934 commented 6 years ago

The Mux is connected to port n°3 on the brick for example. So by default the mux mode is "auto" and the status is "nxt-i2c".

I can change the mode of this port to "ev3-uart".

But please could you explain me how can I configure each device I connect to the MUX ? must be all the same ? because nothing appears in /sys/class/lego-sensor/ and the setdevice command is only available on the /sys/class/lego-port...

cho934 commented 6 years ago

I modified port n°3 with the mode "auto". Then new ports in3:i2c8:mux(1-4) appeared (port 12 to 15). I tried to change the setdevice with lego-ev3-ir on the port connected with the IR sensor. but it didn't work. nothing is recognized to a lego-ev3-ir

So what is exactly the sequence to use several IR sensors using the MUX ?

dlech commented 6 years ago

Like I said, you need to set the mode of the MUX ports (port 12 to 15 as you said) to ev3-uart. The MUX ports don't have an auto mode, so you have to set the mode for them manually before you can use set_device.

cho934 commented 6 years ago

Ok, but the available modes of each mux port are only "i2c" or "analog", so I'm confused, cannot change to "ev3-uart" :(

dlech commented 6 years ago

Oops, I was thinking that this was the mindsensors.com MUX. I see now that it is the HiTechnic one. You can't use EV3 sensors with this MUX. You can only use NXT sensors.

cho934 commented 6 years ago

ok. I tested with the EV3 MUX sensor, it's working, but it's very annoying to find the correct port using the console. One more question: What is the difference between the following address sensors ? in2:i2c80 in2:i2c81 in2:i2c82 in2:i2c80:mux1 in2:i2c81:mux2 in2:i2c82:mux3 ?

Now I'm looking for a simple solution using my C++ program. Could you provide some help please ?

dlech commented 6 years ago

The mux responds to 3 different I2C addresses, so the mux itself if basically 3 different "sensors". These are the first three addresses you have listed.According to the docs, theses "sensors" don't do anything.

The last 3 addresses are for the ports on the mux, so these are the addresses for the sensors you have attached to the mux. In other words, these 3 are the addresses you are interested in.

ev3dev-lang-cpp has a lego_port class that you can use to manipulate the ports. So, for example, create a lego_port object with address of in2:i2c80:mux1, then set the port to ev3-uart mode and set_device to the sensor you are using. You will probably need some sort of delay after this before trying to create the sensor object since it takes the kernel some time to probe the driver for the sensor after set_device returns.

cho934 commented 6 years ago

Perfect ! Thank you. Here is the code.

lego_port p = lego_port("in2:i2c80:mux1");

p.set_mode("ev3-uart"); p.set_set_device("lego-ev3-ir"); usleep(500000);

ir1_ = infrared_sensor("in2:i2c80:mux1");

if (ir1_.connected()) { ir1_.proximity(); }else{ logger().error() << "ir1_ not Connected !!" << logs::end; }

I'm trying to not change the device all the time and save time (the time to probe the driver) if the driver is already set. I tried to use the get_attr_string() from the device object, but even if I add this function for lego_port class, the result stop the program if error (tested for instance if "in2:i2c80:mux1:lego-ev3-ir/modalias" == "lego:ev3-uart-sensor")

What is the best way to do it ?