i2c via bonescript under Debian

I see the bonescript has some i2c methods. Are there any examples out there that work under Debian on the Black Bone?

–Mark

I see the bonescript has some i2c methods. Are there any examples out there
that work under Debian on the Black Bone?

Here's one that works on BoneScript 0.2.4 on Debian, but happens to be
calling the I2C methods from a web page:

http://jsfiddle.net/jkridner/PGL92/ [1]

I had something similar for drawing a Flot graph using the
accelerometer, but not sure where I posted it.

Some more running-from-webpage examples:
http://jsfiddle.net/user/jkridner/fiddles/

[1] source
var canvas = document.getElementById("mysketch");
var p = new Processing(canvas, sketchProc);

function sketchProc(pjs) {
    // Sketch global variables
    var radius = 50.0;
    var X, Y;
    var nX, nY;
    var delay = 16;
    var brightness = 0;
    var buttonStatus = 0;
    var sliderStatus = 0;
    var lastSliderValue = 0;
    var BUTTON = 'P8_19';
    var SLIDER = 'P9_36';
    var port = '/dev/i2c-2'
    var address = 0x1c;

    // Get the BoneScript library and begin updating the canvas
    setTargetAddress('192.168.7.2', {
        initialized: run
    });

    function run() {
        var b = require('bonescript');
        b.pinMode(BUTTON, b.INPUT);
        b.i2cOpen(port, address, {}, onI2C);

        // Setup the Processing Canvas
        pjs.setup = function () {
            pjs.size(256, 256);
            pjs.strokeWeight(10);
            pjs.frameRate(15);
            X = pjs.width / 2;
            Y = pjs.height / 2;
            nX = X;
            nY = Y;
        }

        // Main draw loop
        pjs.draw = function () {
            // Calculate some fading values based on the frame count
            radius = 50.0 + (15 - sliderStatus) * pjs.sin(pjs.frameCount / 4);
            brightness = (radius - 40.0) / 20.0;

            // Track circle to new destination
            X += (nX - X) / delay;
            Y += (nY - Y) / delay;

            // Fill canvas grey
            pjs.background(100);

            // Set fill-color to blue or red, based on button status
            if (buttonStatus) pjs.fill(200, 30, 20)
            else pjs.fill(0, 121, 184);

            // Set stroke-color white
            pjs.stroke(255);

            // Draw circle
            pjs.ellipse(X, Y, radius, radius);

            // Update physical values
            readSlider();
        }

        function readSlider() {
            b.analogRead(SLIDER, onAnalogRead);
        }

        // Handle data back from potentiometer
        function onAnalogRead(x) {
            if (!x.err && (x.value >= 0) && (x.value <= 1)) {
                if (Math.abs(x.value - lastSliderValue) > 0.05) {
                    lastSliderValue = x.value;
                    sliderStatus = parseInt(x.value * 10, 10);
                }
            }

            // Fetch button status
            b.digitalRead(BUTTON, onDigitalRead);

        }

        // Handle data back from button
        function onDigitalRead(x) {
            buttonStatus = (x.value == b.LOW) ? 1 : 0;

            // Fetch accelerometer status
            readAccel();
        }

        function onI2C(x) {
            if (x.event == 'return') {
                b.i2cWriteBytes(port, 0x2a, [0x00], onI2C_A);
            }
        }

        function onI2C_A() {
            b.i2cWriteBytes(port, 0x0e, [0x00], onI2C_B);
        }

        function onI2C_B() {
            b.i2cWriteBytes(port, 0x2a, [0x01], pjs.setup);
        }

        // Fetch accelerometer status
        function readAccel() {
            b.i2cReadBytes(port, 1, 6, onReadBytes);
        }

        function onReadBytes(x) {
            console.log(JSON.stringify(x));
            if (x.event == 'callback') {
                var gX = convertToG(x.res[0]);
                var gY = convertToG(x.res[2]);
                var gZ = convertToG(x.res[4]);
                $('#X').html(gX);
                $('#Y').html(gY);
                $('#Z').html(gZ);

                // Update heading of ball
                nX = 128 - (gX / 2) * 256;
                nY = (gY / 2) * 256 + 128;

                //pjs.draw();
            }
        }

        function convertToG(x) {
            if (x >= 128) x = -((x ^ 0xFF) + 1); // Get two's complement
            x = x / 64; // Scale to G
            x = x.toFixed(2); // Limit decimal places
            return (x);
        }
    }
}

Hmm… I’m not getting anywhere with this. I have a TMP101 i2c device wired to P9_19 and P9_20. From the command line this works:

i2cdetect -y -r 1

0 1 2 3 4 5 6 7 8 9 a b c d e f
00: – – – – – – – – – – – – –
10: – – – – – – – – – – – – – – – –
20: – – – – – – – – – – – – – – – –
30: – – – – – – – – – – – – – – – –
40: – – – – – – – – – 49 – – – – – –
50: – – – – UU UU UU UU – – – – – – – –
60: – – – – – – – – – – – – – – – –
70: 70 – – – – – – –

i2cget -y 1 0x49

0x17

i2cget -y 1 0x49

0x1b
I stuck my figure on the device and warmed it up for the second i2cget.

Now with bonescript:

var b = require(‘bonescript’);
var port = ‘/dev/i2c-0’
var TMP102 = 0x48;

b.i2cOpen(port, TMP102, {}, onI2C);

function onI2C(x) {
// console.log(x);
if (x.event == ‘return’) {
b.i2cScan(port, onScan);
b.i2cReadBytes(port, 0, 1, onReadByte);
}
}

function onScan(x) {
console.log('scan data: ’ + x.data);
}

function onReadByte(x) {
console.log('onReadByte: ’ + JSON.stringify(x));
console.log('res: ’ + JSON.stringify(x.res));
}

When I run with /dev/i2c-1 I get:

scan data:
scan data: undefined
onReadByte: {“err”:{},“res”:[240],“event”:“callback”}
res: [240]
onReadByte: {“event”:“return”,“return”:[240]}
res: undefined

That is, scan doesn’t find anything. If I run with /dev/i2c-0

scan data: 52,80
scan data: undefined
onReadByte: {“err”:{},“res”:[240],“event”:“callback”}
res: [240]
onReadByte: {“event”:“return”,“return”:[240]}
res: undefined

Scan finds two devices, but I don’t see how they relate to whats on the bus.

Any ideas?

–Mark

Hmm... I'm not getting anywhere with this. I have a TMP101 i2c device wired
to P9_19 and P9_20. From the command line this works:

# i2cdetect -y -r 1
     0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- 49 -- -- -- -- -- --
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: 70 -- -- -- -- -- -- --
# i2cget -y 1 0x49
0x17
# i2cget -y 1 0x49
0x1b
I stuck my figure on the device and warmed it up for the second i2cget.

Now with bonescript:
var b = require('bonescript');
var port = '/dev/i2c-0'
var TMP102 = 0x48;

b.i2cOpen(port, TMP102, {}, onI2C);

function onI2C(x) {
    // console.log(x);
    if (x.event == 'return') {
        b.i2cScan(port, onScan);
        b.i2cReadBytes(port, 0, 1, onReadByte);
    }
}

function onScan(x) {
    console.log('scan data: ' + x.data);
}

function onReadByte(x) {
    console.log('onReadByte: ' + JSON.stringify(x));
    console.log('res: ' + JSON.stringify(x.res));
}
When I run with /dev/i2c-1 I get:

scan data:
scan data: undefined
onReadByte: {"err":{},"res":[240],"event":"callback"}
res: [240]
onReadByte: {"event":"return","return":[240]}
res: undefined

That is, scan doesn't find anything. If I run with /dev/i2c-0

scan data: 52,80
scan data: undefined
onReadByte: {"err":{},"res":[240],"event":"callback"}
res: [240]
onReadByte: {"event":"return","return":[240]}
res: undefined

Scan finds two devices, but I don't see how they relate to whats on the bus.

Any ideas?

You'll want to use '/dev/i2c-2'.

Check out bonescript/bone.js at master · jadonk/bonescript · GitHub
for the mapping.

The reason I chose to use i2c-2 because the adapters are enumerated
out of order. Otherwise, it won't match the hardware documentation.
(BeagleBoard.org - bone101)

There has been some discussion to fix this in mainline, but I'm not
sure of the current state.

http://lists.infradead.org/pipermail/linux-arm-kernel/2012-August/116775.html

I get that same result using '/dev/i2c-2' as '/dev/i2c-0. Ant other suggestions?

--Mark

Oops, I mean the same as '/dev/i2c-1

--Mark

Hmm... I'm not getting anywhere with this. I have a TMP101 i2c device wired
to P9_19 and P9_20. From the command line this works:

# i2cdetect -y -r 1
     0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- 49 -- -- -- -- -- --
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: 70 -- -- -- -- -- -- --
# i2cget -y 1 0x49
0x17
# i2cget -y 1 0x49
0x1b
I stuck my figure on the device and warmed it up for the second i2cget.

Now with bonescript:
var b = require('bonescript');
var port = '/dev/i2c-0'
var TMP102 = 0x48;

b.i2cOpen(port, TMP102, {}, onI2C);

function onI2C(x) {
    // console.log(x);
    if (x.event == 'return') {
        b.i2cScan(port, onScan);
        b.i2cReadBytes(port, 0, 1, onReadByte);

Issuing both of these at the same time probably isn't what you really
want. I'm not sure if they will interfere. Better to wait until the
scan is complete before trying to issue the read.

    }
}

function onScan(x) {
    console.log('scan data: ' + x.data);

You aren't checking x.err here. Make sure there isn't an error.

}

function onReadByte(x) {
    console.log('onReadByte: ' + JSON.stringify(x));
    console.log('res: ' + JSON.stringify(x.res));
}
When I run with /dev/i2c-1 I get:

scan data:
scan data: undefined

Why is this getting printed twice? I can't quite see what is going on here.

onReadByte: {"err":{},"res":[240],"event":"callback"}
res: [240]
onReadByte: {"event":"return","return":[240]}
res: undefined

That is, scan doesn't find anything. If I run with /dev/i2c-0

scan data: 52,80
scan data: undefined
onReadByte: {"err":{},"res":[240],"event":"callback"}
res: [240]
onReadByte: {"event":"return","return":[240]}
res: undefined

Scan finds two devices, but I don't see how they relate to whats on the bus.

Any ideas?

You'll want to use '/dev/i2c-2'.

I know you say you aren't seeing a difference, but I am seeing
responses based on what is on my I2C-2 bus:

i2c-scan.js:
var b = require('bonescript');
var port = '/dev/i2c-2'

b.i2cOpen(port, null, {}, onI2C);

function onI2C(x) {
    console.log('onI2C: ' + JSON.stringify(x));
    if (x.event == 'return') {
        b.i2cScan(port, onScan);
    }
}

function onScan(x) {
    if (x.event == 'callback') {
        console.log('scan data: ' + JSON.stringify(x));
    }
}

root@beaglebone:/var/lib/cloud9# node i2c-scan.js
onI2C: {"event":"return","value":true}
scan data: {"err":null,"data":[87],"event":"callback"}

root@beaglebone:/var/lib/cloud9# i2cdetect -y -r 1
     0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- 1d -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- UU UU UU UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- 6b -- -- -- --
70: -- -- -- -- -- -- -- --

So, it seems these don't line up. To see if the delta is due to the
wrapper I have in BoneScript or the node-i2c library I pull in, I
tried out this:

debian@beaglebone:/var/lib/cloud9$ cat i2c-scan-native.js
var i2c = require('bonescript/node_modules/i2c');
var wire = new i2c(null, {device: '/dev/i2c-1'});
wire.scan(function(err, data) {
  if(err) console.log('ERROR: ' + JSON.stringify(err));
  console.log(JSON.stringify(data));
});
debian@beaglebone:/var/lib/cloud9$ node i2c-scan-native.js
[87]

That shows that it is the node-i2c library that causes only one of my
devices to show up and at a different reported address.

Updating to the latest version on git didn't seem to make a difference.

Jason:
Running your i2c-scan.js on my bone returns on devices. So, something odd is going on here.

I’m going to put this on the back burner and see what else I can cook up.

–Mark