ddemidov / ev3dev-lang-cpp

C++ language bindings for http://ev3dev.org
MIT License
73 stars 38 forks source link

How to get the MicroInfinity CruizCore XG1300L gyroscope working #34

Open LeeJenkins opened 7 years ago

LeeJenkins commented 7 years ago

I'm trying to use an XG1300L gyroscope attached to my EV3, but I'm not able to get it working in my C++ program. I'm looking for help getting it to connect. I assume I've just missed a simple step, but I cannot figure out where I've gone wrong.

I'm following the example code in the ev3dev-mapping code by bmegli. Specifically, I looked at how he used the gyro in the dead-reconing module. It doesn't look like he's doing anything beyond declaring the sensor.

32    const char *GYRO_PORT="i2c-legoev35:i2c1";
...
85    ev3dev::i2c_sensor gyro(GYRO_PORT, {"mi-xg1300l"});

Later the code checks gyro->connected() before sending a command. Easy, right? Well, maybe not. It looks like bmegli may have modified the i2c_sensor class to get it working.

I certainly haven't been able to get it to work. Here's my code:

void gyroTest() {
    std::cout << "make instance of migyro" << std::endl;
    ev3dev::i2c_sensor mnfinity_gyro( "i2c-legoev35:i2c1", {"mi-xg1300l"} );
    if( !mnfinity_gyro.connected() ) {
        std::cout << "migyro.connected(): FALSE" << std::endl;
        return;
    }
    std::cout << "migyro.connected(): TRUE" << std::endl;
    return;
}

When I run the program, it always prints FALSE. This doesn't look like rocket surgery, so I must be passing an incorrect argument value. But I cannot find any other example code and I don't know if I need to get bmegli's patch. Someone who has used this sensor will surely be able to point me in the right direction.

As a sanity check, I booted the EV3 with the LEGO firmware and then ran a sample program from the Microinfinity web site that uses the LEGO Mindstorms block-programming environment. The program was able to display readings from the sensor, so I know the hardware is good and attached properly.

Here's my ev3dev sysinfo:

robot@ev3dev:~$ ev3dev-sysinfo -m
<!-- Copy everything between these lines -->
**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
```
<!-- Copy everything between these lines -->
robot@ev3dev:~$
ddemidov commented 7 years ago

Can you see the device in /sys/class/lego-sensor from command line? (ls /sys/class/lego-sensor). If this is the only connected sensor, it should be named sensor0. Can you check its address and driver_name attributes?

cat /sys/class/lego-sensor/sensor*/address
cat /sys/class/lego-sensor/sensor*/driver_name
LeeJenkins commented 7 years ago

I unplugged all the other sensors so only the XG1300L was attached.

robot@ev3dev:~$ ls -ls /sys/class/lego-sensor/sensor*
ls: cannot access /sys/class/lego-sensor/sensor*: No such file or directory

Also, when I go to the Device Browser in Brickman there are no sensors listed.

Do I need to install support for this sensor?

WasabiFan commented 7 years ago

If this sensor isn't auto-detected you'll need to configure the port to tell it what driver to use. It looks like this one is an I2C-based sensor designed for the NXT so you'd probably use the nxt-i2c mode (I don't know if that's exactly right). I think we've previously discussed how to do that in C++.

ddemidov commented 7 years ago

http://python-ev3dev.readthedocs.io/en/stable/other.html#lego-port

This links python docs, but should be helpful anyway.

LeeJenkins commented 7 years ago

@WasabiFan I had the same thought. I used a lego_port device to set the mode like this:

ev3dev::lego_port in1 ( ev3dev::INPUT_1 );
in1.set_mode ( "nxt-i2c" );

I verified that the mode does actually change. And the port object reports that it is connected. But even so, when I create an i2c_sensor, it reports itself not connected.

According to the sensor docs, it looks like "nxt-i2c" is the correct mode. I also noticed that the footnotes for the sensor say it doesn't follow the LEGO guidelines for I2c registers and cannot be automatically detected. The docs go on to say that in order to register the i2c device you execute the following command:

echo mi-xg1300l 0x01 > /sys/class/lego-port/portN/set_device

But when I run the command (on ports in my case), bash reports an error:

-bash: echo: Write error: Operation not supported

So I'm still doing it wrong. Somehow.

LeeJenkins commented 7 years ago

@ddemidov I read through the port documentation and saw that it mentioned using set_device to specify the sensor type. So I tried this:

in1.set_set_device ( "mi-xg1300l" );

But when I call the function, it throws an exception with the same message (Operation not supported) that I saw when I tried to echo a string to the set_device file in /sys/class/lego_port. I don't know enough (basically zero) about the port interface in /sys to understand why I'm seeing that message.

ddemidov commented 7 years ago

I am sorry, I have zero experience with non-standard sensors. May be @dlech could help.

ddemidov commented 7 years ago

Did you give the sensor enough time after setting the mode and device? This looks to be related: https://github.com/ev3dev/ev3dev/issues/1000#issuecomment-339992590

LeeJenkins commented 7 years ago

@ddemidov and @WasabiFan Thanks to both of you for the support. I've reposted this issue to the main ev3dev forum because it seems to be a sensor issue and not a C++ issue.