fivdi / i2c-bus

I2C serial bus access with Node.js
MIT License
348 stars 57 forks source link

What am I doing wrong with this code. #1

Closed MrYsLab closed 9 years ago

MrYsLab commented 9 years ago

I am trying to write 2 bytes to the beaglebone black via the johnny-five plugin beaglebone-io. I am getting an error I don't understand. Converting the array of numbers to an array of strings results in the same error.


// at the top of the file I have:
var i2c = require('i2c-bus'),
    i2c1 = i2c.openSync(1);

// my i2c write function
BeagleBone.prototype.sendI2CWriteRequest = function(address, bytes) {

  console.log("i2c write bytes: address = " + address + " bytes = " + bytes) ;
  console.log("element type = " + typeof bytes[0]);

  i2c1.i2cWriteSync(address, bytes.length, bytes);

  return this;
};

And here is the error output I am getting:

>> i2c write bytes: address = 30 bytes = 0,112
element type = number

buffer.js:246
  switch (encoding && encoding.toLowerCase()) {
                               ^
TypeError: Object 2 has no method 'toLowerCase'
    at Function.Buffer.isEncoding (buffer.js:246:32)
    at assertEncoding (fs.js:112:27)
    at Object.fs.writeSync (fs.js:525:5)
    at Bus.i2cWriteSync (/home/debian/node_modules/i2c-bus/i2c-bus.js:261:13)
    at BeagleBone.sendI2CWriteRequest (/home/debian/node_modules/beaglebone-io/lib/beaglebone.js:367:8)
    at Compass.<anonymous> (/home/debian/node_modules/johnny-five/lib/compass.js:79:13)
    at Array.forEach (native)
    at new Compass (/home/debian/node_modules/johnny-five/lib/compass.js:78:9)
    at Board.<anonymous> (/home/debian/compass.js:14:13)
    at Board.EventEmitter.emit (events.js:95:17)
fivdi commented 9 years ago

Is it because because bytes is an array? i2cWriteSync expects an argument of type Buffer.

fivdi commented 9 years ago

If an i2c-bus method argument is called buffer, then a Buffer object must be passed when the method is called. I should update the documentation and explicitly state what argument types are. Take a look at the sync.js and async.js tests to see examples of calling plain I2C methods.

MrYsLab commented 9 years ago

Thanks. I converted the array to a Buffer, but am having a problem when a single byte is being requested for transmission (at least I think the problem is caused by the single byte write) .

BeagleBone.prototype.sendI2CWriteRequest = function(address, bytes) {

  console.log("i2c write bytes: address = " + address + " bytes = " + bytes + " length = " + bytes.length) ;
  buf = new Buffer(bytes);
  console.log("i2c write bytes: address = " + address + " buf = " + buf + " length = " + buf.length) ;

  i2c1.i2cWriteSync(address, buf.length, buf);

  return this;
};

// output

>> i2c write bytes: address = 30 bytes = 0,112 length = 2
i2c write bytes: address = 30 buf = p length = 2
i2c write bytes: address = 30 bytes = 1,64 length = 2
i2c write bytes: address = 30 buf = @ length = 2
i2c write bytes: address = 30 bytes = 2,0 length = 2
i2c write bytes: address = 30 buf =  length = 2
i2c write bytes: address = 30 bytes = 3 length = 1
i2c write bytes: address = 30 buf =  length = 1

buffer.js:246
  switch (encoding && encoding.toLowerCase()) {
                               ^
TypeError: Object 6 has no method 'toLowerCase'
    at Function.Buffer.isEncoding (buffer.js:246:32)
    at assertEncoding (fs.js:112:27)
    at Object.fs.read (fs.js:441:5)
    at Bus.<anonymous> (/home/debian/node_modules/i2c-bus/i2c-bus.js:240:8)
    at processImmediate [as _immediateCallback] (timers.js:330:15)
fivdi commented 9 years ago

According to the stack trace that error is being thrown in fs.read. It looks like i2cWriteSync completed successfully, and the error is occurring in a subsequent call to i2cRead. In the subsequent call buffers are not being used.

MrYsLab commented 9 years ago

Ooops - I did not fully implement the read. Well now I have and it seems to be working. Thanks for all your help. I am going to review my code and upload to beaglebone-io.

fivdi commented 9 years ago

That's good news :)

rwaldron commented 9 years ago

@MrYsLab be careful, this is leaking the buf binding:

BeagleBone.prototype.sendI2CWriteRequest = function(address, bytes) {

  console.log("i2c write bytes: address = " + address + " bytes = " + bytes + " length = " + bytes.length) ;
  buf = new Buffer(bytes); <--- global leakage!
  console.log("i2c write bytes: address = " + address + " buf = " + buf + " length = " + buf.length) ;

  i2c1.i2cWriteSync(address, buf.length, buf);

  return this;
};
MrYsLab commented 9 years ago

I will fix it. Thanks.

rwaldron commented 9 years ago

No problem :)

MrYsLab commented 9 years ago

@fivdi I've updated the bealgebone-io code and believe it is correct now. I am investigating a problem I am having with the led-matrix-demo. I captured the data being sent to i2c using an arduino, and compared it to the data in the Buffer when writing to I2C on BeagleBone Black. The data is identical, but the results on the 8x8 display were not. I tried using a synchronous write in case I was writing too fast, but there was no change to the display.

After reconnecting the 8x8 to the BBB, I no longer see any LEDs lighting, so I need to recheck my connections.

I will report back once I get things up and running again. Hopefully, all will magically work ;-).

fivdi commented 9 years ago

See here

fivdi commented 9 years ago

@MrYsLab I'm going to close this issue as we've resolved it.