eclipse / upm

UPM is a high level repository that provides software drivers for a wide variety of commonly used sensors and actuators. These software drivers interact with the underlying hardware platform through calls to MRAA APIs.
MIT License
663 stars 411 forks source link

lsm9ds0 problem with javascript #411

Closed teuteuguy closed 8 years ago

teuteuguy commented 8 years ago

I'm trying to use the lsm9ds0 sensor with javascript, but code is not running.

Using the example, code crashes after the init line: `var sensorObj = require('jsupm_lsm9ds0');

// Instantiate an LSM9DS0 using default parameters (bus 1, gyro addr 6b, // xm addr 1d) var sensor = new sensorObj.LSM9DS0();

// Initialize the device with default values sensor.init();

var x = new sensorObj.new_floatp(); var y = new sensorObj.new_floatp(); var z = new sensorObj.new_floatp();`

with

sensor.init(); ^ Error: UPM Runtime Error: writeReg: I2c.writeReg() failed at Object. (/home/root/aws-iot-edison-lsm9ds0/index.js:5:8) at Module._compile (module.js:456:26) at Object.Module._extensions..js (module.js:474:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Function.Module.runMain (module.js:497:10) at startup (node.js:119:16) at node.js:935:3

Any ideas ?

(Edison flashed with latest version of the firmware from the intel edison website, and using the sparkfun 9dof board)

xbolshe commented 8 years ago

As I see sparkfun 9dof board has no lsm9ds0 chip inside, but it has: ITG-3200 - triple-axis digital-output gyroscope ADXL345 - 13-bit resolution, ±16g, triple-axis accelerometer HMC5883L - triple-axis, digital magnetometer

So, it is better to use the following UPM modules: itg3200 adxl345 hmc5883l

BR, xbolshe

teuteuguy commented 8 years ago

Hi xbolshe, Thanks for the response, however, the sparkfun 9dof for intel edison does have the LSM9DS0 ... https://www.sparkfun.com/products/13033

xbolshe commented 8 years ago

Clear that it is not https://www.sparkfun.com/products/10736. Did you set a correct I2C address of LSM9DS0 ? What SDOXM / SDOG values do you use?

BR, xbolshe

teuteuguy commented 8 years ago

xbolshe, could you be a bit more specific as to how you "set a correct I2C address of LSM9DS0" ? Same for SDOXM and SDOG values. Not sure what you mean.

All i've done is the above code.

xbolshe commented 8 years ago

lsm9ds0 uses some default values: bus 1, gyro addr 6b, xm addr 1d Need to check that they are correct.

https://cdn.sparkfun.com/datasheets/Dev/Edison/9dof_block.pdf

i2c

Need to check that address are correct. They are selected by SDOXM and SDOG on the board.

Also need to check that an I2C bus number of Edison board is correct (possible values are 1 or 6).

BR, xbolshe

teuteuguy commented 8 years ago

Thanks for this information.

If I do i2cdetect -y -r 1, I get: 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- 1d -- -- 20: UU UU UU UU -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- 6b -- -- -- -- 70: -- -- -- -- -- -- -- --

Basically, it sees it on 6b and 1d. Do I need to "configure" it in the javascript code ? I'm litterally just trying to use this code: https://github.com/intel-iot-devkit/upm/blob/master/examples/javascript/lsm9ds0.js

Not too sure what I can / should do to tweak it to get it to work.

My error is that the .init function fails on an i2c writeReg fail.

teuteuguy commented 8 years ago

I've done more tests...

I've updated firmware to the very latest code (yocto 3.0). opkg update opkg upgrade opkg install mraa opkg install upm

I've simplified the code to: var sensorObj = require('jsupm_lsm9ds0'); var sensor = new sensorObj.LSM9DS0(); sensor.init();

setInterval(function() {

}, 500);

// exit on ^C process.on('SIGINT', function() { sensor = null; sensorObj.cleanUp(); sensorObj = null; console.log("Exiting."); process.exit(0); });

Now I have a different error ...

module.js:356 Module._extensions[extension](this, filename); ^ Error: libmraa.so.0: cannot open shared object file: No such file or directory at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Module.require (module.js:364:17) at require (module.js:380:17) at Object. (/home/root/aws-iot-edison-lsm9ds0/index.js:1:79) at Module._compile (module.js:456:26) at Object.Module._extensions..js (module.js:474:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Function.Module.runMain (module.js:497:10)

xbolshe commented 8 years ago

Last error is related with MRAA/UPM update. https://github.com/intel-iot-devkit/mraa/issues/502

malikabhi05 commented 8 years ago

You could as a temporary solution create a symlink for that shared object, something like... ln -s /usr/lib/libmraa.so.1 /usr/lib/libmraa.so.0 This would get it working for you, it worked for me (I ran the javascript example from the repo). However, once UPM is tagged with the latest version this error will go away and things should work fine then.

teuteuguy commented 8 years ago

Unfortunately, I get the same error as before if I implement the ln -s you suggest.

Code: var sensorObj = require('jsupm_lsm9ds0'); var sensor = new sensorObj.LSM9DS0(); sensor.init();

setInterval(function() {

}, 500);

// exit on ^C process.on('SIGINT', function() { sensor = null; sensorObj.cleanUp(); sensorObj = null; console.log("Exiting."); process.exit(0); });

Result: index.js:3 sensor.init(); ^ Error: UPM Runtime Error: writeReg: I2c.writeReg() failed at Object. (/home/root/aws-iot-edison-lsm9ds0/index.js:3:8) at Module._compile (module.js:456:26) at Object.Module._extensions..js (module.js:474:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Function.Module.runMain (module.js:497:10) at startup (node.js:119:16) at node.js:935:3

teuteuguy commented 8 years ago

Is there anything I can test using the UPN library with this device ?

Reading / Writing to I2C registers to see if manually it works ?

teuteuguy commented 8 years ago

More investigations.

Not knowing how to get it to work in nodejs, I decided to try the board with the arduino environment on the Intel Edison. Using the sparkfun library for lsm9ds0: https://github.com/sparkfun/SparkFun_LSM9DS0_Arduino_Library

Works like a charm.

So, the board is OK.

Something doesn't work with that sensor, I2C and the UPM library.

Any help would be appreciated ...

arfoll commented 8 years ago

So I'm guessing from your log you provided in mraa that your issue is you've got the 9DOF sensor connect to the arduino expansion board rather than the miniboard - correct? It could also be our miniboard detection is broken in mraa in your case which would be bad :/

This means your board is being initialised as an arduino which does not expose i2c bus 1 therefore mraa is switching you over to bus 6 causing you to obviously not see the sensor - see your log here:

May 10 05:17:11 timsedison libmraa[377]: i2c_init: Selected bus 1
May 10 05:17:11 timsedison libmraa[377]: Invalid i2c bus 1, moving to default i2c bus 6

To fix, modify UPM in https://github.com/intel-iot-devkit/upm/blob/master/src/lsm9ds0/lsm9ds0.cxx#L37 to m_i2cG(1, True) and m_i2cXM(1, True).

@Propanu @pylbert I suggest moving the constructor to check if the user is on an Intel edison board and by default assume the sparkfun board so call mraa_uart_init_raw or provide an alternative constructor to force sparkfun board.

teuteuguy commented 8 years ago

Hi arfoll,

thanks for the input. Not sure I completely understand, however am testing your solution. UPM rebuilding as I write this, but it's taking a long time ... been 30mins already and only 39% done so far. Will update you with result.

That said, while waiting, I'm using the sparkfun board: https://www.sparkfun.com/products/13033

So I'm not sure what you mean, or at least in my understanding, i'm using "the miniboard" you are referring to, no ?

Cheers

teuteuguy commented 8 years ago

/home/root/upm/src/lsm9ds0/lsm9ds0.cxx:37:13: error: 'True' was not declared in this scope m_i2cG(1, True), m_i2cXM(1, True), m_gpioG_INT(0), m_gpioG_DRDY(0),

:(

alext-mkrs commented 8 years ago

I think that may have been a misunderstanding. @teuteuguy, you are using Edison Compute Module + Edison Kit for Arduino, right?

I guess @arfoll may have taken "Sparkfun board" as not a sensor breakout you are talking about, but one of the Sparkfun so called Blocks (red ones here), which may require different approach in terms of pinmuxing and such.

If my understanding is correct, just try replacing in your code this

var sensor = new sensorObj.LSM9DS0();

with this

var sensor = new sensorObj.LSM9DS0(6, 0x6b, 0x1d);

and don't alter/recompile UPM at all.

That will explicitly tell UPM to ask mraa for I2C bus number 6, which is the only one available by default on the Edison Arduino board. Let's see if that helps or changes the situation (please include journalctl -f output as well, if it still doesn't work).

teuteuguy commented 8 years ago

Hi alext-mkrs,

same result: /home/root/aws-iot-edison-lsm9ds0/index.js:3 sensor.init(); ^ Error: UPM Runtime Error: writeReg: I2c.writeReg() failed at Object. (/home/root/aws-iot-edison-lsm9ds0/index.js:3:8) at Module._compile (module.js:456:26) at Object.Module._extensions..js (module.js:474:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Function.Module.runMain (module.js:497:10) at startup (node.js:119:16) at node.js:935:3 -- Logs begin at Sat 2000-01-01 00:00:20 UTC. -- May 11 00:56:03 timsedison libmraa[10232]: i2c_init: Selected bus 6 May 11 00:56:03 timsedison libmraa[10232]: i2c6: read_byte_data: Access error: Remote I/O error May 11 00:56:03 timsedison libmraa[10232]: i2c6: write_byte_data: Access error: Remote I/O error May 11 00:56:23 timsedison libmraa[10241]: libmraa version v1.0.0 initialised by user 'root' with EUID 0 May 11 00:56:23 timsedison libmraa[10241]: edison: Arduino board detected May 11 00:56:23 timsedison libmraa[10241]: libmraa initialised for platform 'Intel Edison' of type 2 May 11 00:56:24 timsedison libmraa[10241]: i2c_init: Selected bus 6 May 11 00:56:24 timsedison libmraa[10241]: i2c_init: Selected bus 6 May 11 00:56:24 timsedison libmraa[10241]: i2c6: read_byte_data: Access error: Remote I/O error May 11 00:56:24 timsedison libmraa[10241]: i2c6: write_byte_data: Access error: Remote I/O error

with code: var sensorObj = require('jsupm_lsm9ds0'); var sensor = new sensorObj.LSM9DS0(6, 0x6b, 0x1d); sensor.init();

setInterval(function() {

}, 500);

// exit on ^C process.on('SIGINT', function() { sensor = null; sensorObj.cleanUp(); sensorObj = null; console.log("Exiting."); process.exit(0); });

teuteuguy commented 8 years ago

Update.

I've managed to recompile UPM library. (note that the True need to be true).

Recompiled, make, make install.

Re-ran my code with var sensor = new sensorObj.LSM9DS0(); instead of the .LSM9DS0(6, 0x6b, 0x1d) proposed modification that did not seem to work.

Result is that it works !!!

Accelerometer: AX: -0.1895270049571991 AY: -0.17921800911426544 AZ: -0.9975939989089966 Gyroscope: GX: -0.8575000166893005 AY: -0.20125000178813934 AZ: 0.026249999180436134 Magnetometer: MX: 0.22247999906539917 MY: -0.13239999115467072 MZ: 0.11727999895811081 Temperature: 41.40625

woop woop.

So now ... the question is, how can this be "fixed" in the official release ?

alext-mkrs commented 8 years ago

Which Edison (not the sensor one) board do you have?

Edit: never mind, I've checked that link you've provided earlier, you are using one of the Sparkfun Blocks, not just a sensor breakout.

Then, like I said, @arfoll's solution is spot on. You mentioned "arduino board" previously and that led me to a different path.

@arfoll, looks like though, our Edison kit for Arduino detection fails here, as it treats the Block as the one, so it could be improved too. I'll look into this sometime this weekend, within that mraa issue opened for this one.

Though I don't have any of the Blocks :smiley:, so @teuteuguy, your help will be needed as well.

Propanu commented 8 years ago

I agree @arfoll's solution is the way to go, however it should be generic:

m_i2cG(bus, true), m_i2cXM(bus, true)

That way you won't be limited to the Sparkfun Block (which is hardwired to bus 1 on the SoC connector) with this driver and you could still use other lsm9ds0 modules on bus 6 with the Arduino base (e.g. this one).

teuteuguy commented 8 years ago

@arfoll, @Propanu: guys, I'm happy to help here. Just send stuff my way and I'll test it out.

:)

arfoll commented 8 years ago

@teuteuguy glad it works. FYI you can easily rebuild just one UPM module, go into build/src/ and run make or just run make help and grep through at all the targets (careful, there are loads :/)

@Propanu I guess the simple solution is to have a seperate constructor/init() for the sparkfun block. The other solution is to let people access i2c-1 on the arduino breakout from mraa, I guess that would be ok too, I only worry this may lead to some confusion and raw mode works well for those kinds of cases. @alext-mkrs what do you think is best?

alext-mkrs commented 8 years ago

Yeah, confusion is what I foresee :smiley: in case we allow i2c-1. I'd go for a parameter for the constructor, which would use the the _raw I2C init - and that that would be perfectly under user control what to use. Unless there's a way to autodetect a SparkFun Block, if so this could be automatic and not a parameter.

Propanu commented 8 years ago

Best I can do with automatic detection would be if I2C bus is 1 and platform is Edison Arduino and I tend to prefer this option. Otherwise I'm leaning towards the extra param in the constructor. I highly doubt there's a way to tell you're using the Sparkfun Block via driver only, besides you would need to talk to the device first anyway.

alext-mkrs commented 8 years ago

I'm leaning towards the extra param in the constructor

IMHO that would be the best way to go.

Propanu commented 8 years ago

Added an extra boolean parameter to the constructor to specify whether we want to init the device in raw mode or not. Considered fixed as of UPM 0.7.0. Thanks for all the feedback!