kelly / node-i2c

Node.js native bindings for i2c-dev. Plays well with Raspberry Pi and Beaglebone.
Other
216 stars 91 forks source link

Read / Write to Device at specific Register #24

Closed jvondrus closed 10 years ago

jvondrus commented 10 years ago

Hello,

i2c device are addressed by 2 number: by address, and by internal register. But how to set "register" at your module?

i2c tool for RPi looks like: i2c_get -y D AA RR, where D is device (0 / 1) AA is device address RR is register value Result is 1 single Byte value.

i2c_set -y D AA RR BB, where BB is value (byte) to set at device DD at register RR.

Thank you.

kelly commented 10 years ago

check out the README file https://github.com/kelly/node-i2c

I think you're looking for the writeBytes and readBytes methods. The command can also be called the register.

jvondrus commented 10 years ago

There is no Register field: var address = 0x18; var wire = new i2c(address, {device: '/dev/i2c-1', debug: true}); wire.readByte(function(err, res) { // result is single byte })

So, there is a Device and Address, but where is Register field?

For example, I want to read one byte from device i2c-1 with address 21 at register 56. By exec i2c tool: "i2c_get -y 1 21 56" How to do it by your Node modul? Thank you.

kelly commented 10 years ago

use the readBytes method:

wire.readBytes(56, 1, function(err, res) {
 console.log(res);
});
jvondrus commented 10 years ago

not works :(

My code:

var i2c         = require ('i2c');
var address = 11;
var wire = new i2c(address, {device: '/dev/i2c-1', debug: true});

wire.readBytes(13, 1, function(err, res) {
 console.log(res);
});

Results:

i2c >
string_decoder.js:109
  charStr += buffer.toString(this.encoding, 0, end);
                    ^
RangeError: toString() radix argument must be between 2 and 36
    at Number.toString (native)
    at StringDecoder.write (string_decoder.js:109:21)
    at ReadStream.onData (readline.js:839:39)
    at ReadStream.EventEmitter.emit (events.js:95:17)
    at new i2c (.../node_modules/i2c/lib/i2c.coffee:30:23)
    at Object.<anonymous> (.../test.js:3:12)
    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)
kelly commented 10 years ago

it appears REPL is breaking for some reason on your version of node. I don't know why. Anyways, use 'debug: false'

jvondrus commented 10 years ago

My Node version is v0.10.26. It works, I set 'debug: false', and it start to works. :) Thank you very much.

Now is time for remake my program and test communication speed. RPi i2ctool takes around 30ms for 1 command.

jvondrus commented 10 years ago

I got another issue :(

After 11 bus readings :

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit.
Trace
    at process.EventEmitter.addListener (events.js:160:15)
    at process.on.process.addListener (node.js:769:26)
    at new i2c (.../node_modules/i2c/lib/i2c.coffee:32:15)
    at Object.exports.HandleGetCMD (.../lib/command.js:39:15)
    at Active_Handle_CMD (.../iH42.js:192:9)
    at Active_Loop [as _onTimeout] (.../iH42.js:248:2)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)

Is there some command how to close old handle?

And after some more time:

/usr/iH42/node_modules/i2c/lib/i2c.coffee:57
      wire.setAddress(address);
           ^
TypeError: Failed to set address
    at i2c.setAddress (.../node_modules/i2c/lib/i2c.coffee:57:12)
    at i2c.readBytes (.../node_modules/i2c/lib/i2c.coffee:88:12)
    at Object.exports.HandleGetCMD (.../lib/command.js:39:25)
    at Active_Handle_CMD (.../iH42.js:192:9)
    at Active_Loop [as _onTimeout] (.../iH42.js:248:2)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)

That error will up at random time, i dont know why, calling i2c is still same:

    new i2c(rqstg.address).readBytes (rqstg.register, len, function (err, res)
    { "HANDLE" });
kelly commented 10 years ago

Unfortunately, I don't have the ability to provide support for everyone's project using this library. I'd recommend looking over the other projects using this module https://www.npmjs.org/package/i2c or look in the examples folder.

jvondrus commented 10 years ago

Im not asking for support my project and my code, I want to support for your module. My code looks similar like that example codes.

Im asking for inspect your code, its looks that there are problem with EventEmitter and memory leek, Its looks like problem with unclosed function.

jvondrus commented 10 years ago

I found it :) Problem is at opening "new i2c (address)", there is a limit for opened devices,

All device have to be initialized (opened) before communication. Each device as individual variable:

var dev11 = new i2c (11);
var dev21 = new i2c (21);
...

and then read / write bytes:

dev11.readBytes ...
dev21.readBytes ...
dev11.writeBytes ...
jvondrus commented 10 years ago

Here are my results:

RPi i2ctool takes around 30 ms for 1 commnad, and around 20% CPU use as user and 30% as system (50% total). Your Node.js I2C modul takes under 1ms for 1 commad, and around 4% CPU as user and 2% as system (6% total) :+1: Realy perfect.

My RPi load is now around 0.07 instead 1.5 :)

The right way how to use is is:

// Preload all devices
var dev11 = new i2c (11);
var dev21 = new i2c (21);
...
// Then works with them
dev11.readBytes ...
dev21.readBytes ...
dev11.writeBytes ...

Handle with i2c bus can be called also at loop without delay, without problem. There is a just warning when using more than 11 different device ( ... new i2c(..) modules), and it will collaps around 100 devices (Address setting module cause error).

ActionNerd commented 9 years ago

Adding for reference.

Experienced the same RangeError as above:

i2c > string_decoder.js:129 charStr += buffer.toString(this.encoding, 0, end); ^ RangeError: toString() radix argument must be between 2 and 36 at Number.toString (native) at StringDecoder.write (string_decoder.js:129:21) at ReadStream.onData (readline.js:839:39) at ReadStream.emit (events.js:95:17) at new i2c (/var/imu_test/node_modules/i2c/lib/i2c.coffee:30:23) at Object. (/var/imu_test/app.js:3:12) 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)

Adding 'debug:false' to the new i2c declaration worked to stop the error.

var wire = new i2c(address, {device: '/dev/i2c-1', debug: false});

Not sure if this helps, but saw some folks were having a similar error with repl in the J5 library with issue 271. It was corrected by changing:

if (!Repl.isBlocked) {
    process.stdin.emit("data", 1);
}

to this:

if (!Repl.isBlocked) {
    process.stdin.emit("data", "1");
}

I'm using node v0.10.29. I'll update node at some point this month and see if the error persists. Thanks for the comment above about debug.