Closed southernwindle closed 5 years ago
Can you share the code of what you have tried so far?
from ev3dev2.port import LegoPort
imu = LegoPort(address='ev3-ports:in2:i2c17')
imu.mode = 'uart'
imu.set_device('ms-absolute-imu')
abs = Sensor('ev3-ports:in2:i2c17')
the set_device and sensor always returns an error, I do not have access to the ev3 at this current time so I cannot send the error.
Try adding a delay after setting the device before creating the sensor object. It takes some time for it to get set up in the kernel.
I have tried that, it doesn't appear to work even after 5 minutes (I tried doing it through SSH too)
one second should be more than enough
I just noticed that you are putting the port in uart
mode. This is an I2C sensor, so it should be nxt-i2c
.
And actually this sensor should be automatically detected, so you shouldn't have to mess with the port at all
Does the sensor show up in the Device Browser on the brick?
Yes
The default address is 1, so abs = Sensor(address='ev3-ports:in2:i2c1')
should be all you need (you can double-check the address against the one you see on the EV3).
Alright, I got it working. Is there any way to read out each different value at the same time without having to change its mode?
also is there any documentation for this specifically
It looks like there is an ALL
mode to read everything at once.
You will probably have to read bin_data
and use struct.unpack(...)
for this mode because I'm pretty sure that the number of valueX
attributes is limited to 8 (0 to 7). The description of the data can be found in the users guide for the sensor: http://www.mindsensors.com/pdfs/AbsoluteIMU-User-Guide.pdf
Totally untested, but hopefully close...
import struct
...
(x_tilt, y_tilt, z_tilt, x_accel, y_accel, z_accel, compass, x_mag, y_mag, z_mag,
x_gyro, y_gyro, z_gyro) = struct.unpack('bbb<h<h<h<h<h<h<h<h<h<h', abs.bin_data)
It is also possible to use x
in the format string to skip over any values that your aren't using.
https://docs.python.org/3.5/library/struct.html#struct-format-strings
self.gyroSensor.bin_data('<b16xh4x')
outputs: (0,0)
and I know this isn't right... in fact even if I don't skip any of the values (self.gyroSensor.bin_data('<bbbbbbbbbbbbbbbbbbbbbbb'
), everything I extract out of this gives 0,0,0,0,0,0,.. which doesn't feel right. Basically the bin_data seems to give 0 all the time... perhaps it requires some initialization...
This code works assuming that the gyro is plugged into in2, it can easily be changed to work for any other port
absport = LegoPort(address='ev3-ports:in2')
absport.mode = 'nxt-i2c'
abs = Sensor('ev3-ports:in2:i2c17')
This should setup the sensor and allow it to be accessed, the Sensor class needs to be imported from sensor.lego
to use the gyro you must set the mode you want and then call the value
To find the mode/value you can find information here: http://docs.ev3dev.org/projects/lego-linux-drivers/en/ev3dev-stretch/sensor_data.html#ms-absolute-imu If I wanted the X-axis angle (tilt) I would use this code:
abs.mode = "TILT"
print(abs.value(0))
Thanks @1StormDragon! That works perfectly. I hope that helps you too @omartin2010
I'm essentially doing what you're describing above - I'm ok running it in "tilt mode" but whenever I try running it in "ALL" mode, which is what I need for my application, then I get all zeros from the bin_data. Flip it to "TILT" mode, and I get my readings... any clue?
in fact, after thinking things a bit, I suspect there being something to do with the driver. The TILT, GYRO, etc. modes can all be read independently so it's got to have something to do with the driver level at the OS (since the same problem can be seen from the OS :
robot@ev3dev:/sys/class/lego-sensor/sensor0$ echo 'TILT' > mode
robot@ev3dev:/sys/class/lego-sensor/sensor0$ cat value0
157
robot@ev3dev:/sys/class/lego-sensor/sensor0$ echo 'ALL' > mode
robot@ev3dev:/sys/class/lego-sensor/sensor0$ cat value0
0
robot@ev3dev:/sys/class/lego-sensor/sensor0$
Any pointer to the driver in the code I could take a look at? Or idea of what else to look for?
Any pointer to the driver in the code I could take a look at
self.gyroSensor.bin_data('<b16xh4x')
This is wrong. '<b16xh4x'
is an argument to struct.unpack()
, not bin_data
.
robot@ev3dev-ev3:/sys/class/lego-sensor/sensor3$ hd bin_data
00000000 d0 d1 ca 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020
It looks like only the first few data values are non-zero, so maybe it is not possible to read everything at once?
Possible workaround is to set the mode and read one value you need, the change the mode and read another value. It will be slightly slower, but it should work just fine.
Agreed it looks wrong, but bin_data('fmt')
takes fmt
as an argument (at least according to here). I've also tried the struct.unpack()
route, and got zeroes.
robot@ev3dev:/sys/class/lego-sensor/sensor1$ hd bin_data
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000020
robot@ev3dev:/sys/class/lego-sensor/sensor1$ cat mode
ALL
robot@ev3dev:/sys/class/lego-sensor/sensor1$ cd ../sensor4
robot@ev3dev:/sys/class/lego-sensor/sensor4$ hd bin_data
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000020
and if I change the mode...
robot@ev3dev:/sys/class/lego-sensor/sensor1$ echo 'TILT' > mode
robot@ev3dev:/sys/class/lego-sensor/sensor1$ hd bin_data
00000000 a0 80 03 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020
robot@ev3dev:/sys/class/lego-sensor/sensor1$
tadam. That's why I'm thinking it has nothing to do with Python in this case...
robot@ev3dev-ev3:/sys/class/lego-sensor/sensor3$ echo ALL > mode
robot@ev3dev-ev3:/sys/class/lego-sensor/sensor3$ hd bin_data
00000000 db 79 db be 02 cb ff 88 02 af 00 ac ff ea 00 11 |.y..............|
00000010 fa 19 fa 13 00 e6 ff 00 00 00 00 00 00 00 00 00 |................|
00000020
Oops, I forgot to set the mode to ALL
. Look like it is "works for me". :confused:
The fact you are getting all 0s is strange because the driver doesn't actually do anything when you set the mode other than changing the register index and size of data that is being read. The TILT
mode and the ALL
mode both read from the same starting register, but read a different number of bytes.
Although I just realized that you are probably using BrickPi3, not EV3, so that is probably the issue.
I am indeed using BrickPi3. Not sure how that can cause an issue. And 2 stacked boards... and 2 sensors. So I'll try removing one of the boards and go with a single sensor. Although both sensor read from "TILT" without any problem (although I'm not super impressed with the precision... my phone's level is way more precise). But that's a very different problem. What do you have to set, again, under /sys/class/lego-ports/port0/ so that this becomes a /sys/class/lego-sensor/.. ? I forget if/how this can be done directly at the command line versus in Python.
For starters, since we have determined this is not a python problem, lets open a new issue at https://github.com/ev3dev/ev3dev/issues and continue the discussion there.
Thanks, done (see here)
Hello, I'm newbie with EV3DEV and I'm trying to make my absolute sensor working on my ev3. The sensor is recognized by the brick but i have a problem with loading the "sensor.lego" module. Here is the error message in vscode :
Traceback (most recent call last):
File "/home/robot/vscode-hello-python-master/test mindstorm.py", line 5, in
Kernel 4.14.117-ev3dev-2.3.5-ev3
Can you help me please ?
I am attempting to connect an AbsoluteIMU-ACG from mindsensors.com though ev3dev2-python
I have tried a few options but have not been able to figure it out, How would I get this connected and measure the values of it? Thanks.