I am developing an application on a Beaglebone Black that needs to do Analog to Digital Conversion but can not use the onboard ADC since an LCD shield has it tied up. I have been trying to get Node-I2c to work but am struggling. Has anyone gotten a Node.js app to talk to a MCP3424 (or to any ADC) via I2C?
As I mentioned in a comment I had installed the i2c library by korevec (Link) but had suffered from self imposed user issues trying to get it to work. It did ultimately work as illustrated by the below code snippet. NOTE that I think, but am not sure, that the voltage conversion is correct! I am still struggling a little with the mechanics of that conversion but was happy to get to this point.
//***************************************************************
// The Chair - voltage - I2C read from an attached ADC
//***************************************************************
// The "korevec/node-i2c" library (available on npm or via github)
var i2c = require('i2c');
// Address of the ADC we want to access
var address = 0x68;
// Combination of channel=1, resolution=12, gain=0, mode=continuous
// 90=12 bits, 94=14, 98=16, and 9C=28 with all else constant
var command = 0x90;
// Instantiate our interface - device may differ by 'puter. Use
// "i2cdetect -r -y 1" to find the right device
var wire = new i2c(address, {device: '/dev/i2c-1', debug: false});
// Setup the listener that will handle data coming from reading
// the ADC. The data structure coming from the idc interface
// contains the address, buffer, command sent, length, and a
// timestamp. ***NOTE*** the below conversion to voltate is
// NOT right yet. I was just happy to get to this point.
wire.on('data', function(data) {
console.log(data);
var buffer = data.data;
var v = voltage(buffer, command);
console.log("Voltage: " + v);
console.log("--------------------");
});
// Read a value from the ADC every five seconds, using the command
// from above, to return four bytes each time it fires.
wire.stream(command, 4, 5000);
function voltage(buffer, command) {
if ((buffer[3] & 0x0c) == 0x0c) {
var dataBytes = 3;
}
else {
dataBytes = 2;
}
var signBit = 0; // Location of sign bit
var signExtend = 0; // Bits to be set if sign is set
var divisor = 0; // Divisor for conversion
switch (command) {
case 0x90: //12
signBit = 0x800;
signExtend = 0xFFFFF000;
divisor = Math.pow(2, 11);
break;
case 0x94: //14
signBit = 0x2000;
signExtend = 0xFFFFC000;
divisor = Math.pow(2, 13);
break;
case 0x98: //16
signBit = 0x8000;
signExtend = 0xFFFF0000;
divisor = Math.pow(2, 15);
break;
case 0x9C: //18
signBit = 0x20000;
signExtend = 0xFFFC0000;
divisor = Math.pow(2, 17);
break;
}
console.log("signBit = " + signBit.toString(16));
console.log("signExtend = " + signExtend.toString(16));
var result = 0;
for (var i = 0; i < dataBytes; ++i) {
result <<= 8;
result |= buffer[i];
}
console.log("result1 = " + result);
// Fill/blank remaining bits
if ((result & signBit) != 0)
result |= signExtend; // Sign bit is set, sign-extend
console.log("result2 = " + result);
console.log("divisor = " + divisor);
return (5 * (result / divisor));
}
If anyone has done the bitwise work to translate the bytes returned from the MCP3424 and wanted to comment on the above it would be welcome.