node-i2c
node-i2c copied to clipboard
Segmentation Fault Reading MCP3424 A/D Converter
I am getting a 'segmentation fault' with the below code running on a BeagleBone Black (node version v0.8.22) communicating with a MCP3424 digital/analog converter:
var i2c = require('i2c');
var address = 0x6a;
var wire = new i2c(address, {device: '/dev/i2c-1', debug: false});
var semaphore = true;
setInterval(function() {
observeCallback();
}, 1);
function observeCallback() {
if (semaphore === true) {
semaphore = false;
wire.readBytes(0x80, 4, function(err, buffer) {
observe(buffer);
semaphore = true;
});
}
}
function observe(buffer) {
var voltageIn = (buffer[0] << 8) + buffer[1];
voltageIn = voltageIn / 2048;
}
Obviously this is a pared down version of the code. It will generally fail within a single digit number of minutes but sometimes it will take longer.
This code is a key element of a pro-bono project that I am doing for a non-profit so any help would be appreciated!
ThamesWill, In my similar problem, I found that you just have to fully avoid the readBytes method. You need to rewrite the function to only use ReadByte. Such as
function observeCallback() {
if (semaphore === true) {
semaphore = false;
// tell the device to send us the data
wire.writeByte(0x80, function(err){});
// i + 1 bytes to read
i = 3;
// replacement buffer
buff = 0;
read_byte = function(){
wire.readByte(function(err,res){
buff = buff<<8 + res;
}
if(i--){
// more to read
read_byte();
}else{
// done reading, call to closing
observe(buff);
}
}
// prime the loop
read_byte();
}
}
Excellent feedback. I jumped on this and got some initial good news...then some bad news. The good news is that it does not crash! The bad news is that I only ever get the first of four bytes that the ADC generates! I dump each byte as I get them and as I change the voltage in I can see the output change...but only the highest order byte! I suspect that there is something I need to do to get this to work but I am not seeing what from looking at the device data sheet.
Do you have any ideas? Am I doing something boneheaded? Here is the code pretty much exactly as you suggested:
wire.writeByte(0x90, function(err){});
readByte();
function readByte() {
wire.readByte(function(err, res) {
console.log(res);
if(i++ < 3){
readByte();
}
});
}
On another front, I also tried solving my problem using the wire.stream command from the library. Good news and bad news here as well. The good news is that it also does not seem to crash. The bad news is that control never returns from the wire.stream command to my script! I get good readings but it makes it a little hard to move on from getting the readings to doing something with them! I guess I could setup a background process but I don't think this is how it should work!
Here is my code for the wire.stream variant:
var i2c = require('i2c');
var address = 0x6a;
var wire = new i2c(address, {device: '/dev/i2c-1', debug: false});
wire.on('data', function(data) {
observeCallback(data);
});
console.log("-----Starting stream");
wire.stream(0x90, 4, 1);
console.log("-----Started stream ");
function observeCallback(data) {
observe(data.data);
}
function observe(buffer) {
var voltageIn = (buffer[0] << 8) + buffer[1];
voltageIn = voltageIn / 2048;
}
Thanks again for the first recommendation...hopefully I am doing something boneheaded.
Will
It is a shame that this library is not supported. I don't have the right skills to do so myself though at a future point I might take a stab at a rewrite that would produce a library that parallels the Wire interface in Arduino land. Is there any chance that someone out there could help in the meantime?
Hey Thomas, i've written a module for mcp3424, i don't know if you still need it, but you can download it from here: https://github.com/x3itsolutions/mcp3424 I haven't tested so much, please try it and let me know, if you've problems with my module.
Is this issue still relevant on latest @abandonware's fork ?
https://libraries.io/npm/@abandonware%2Fi2c/usage
Relate-to: https://github.com/kelly/node-i2c/issues/97