Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segmentation Fault Reading MCP3424 A/D Converter #13

Open
ghost opened this issue Sep 13, 2013 · 5 comments
Open

Segmentation Fault Reading MCP3424 A/D Converter #13

ghost opened this issue Sep 13, 2013 · 5 comments

Comments

@ghost
Copy link

ghost commented Sep 13, 2013

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!

@critch
Copy link

critch commented Sep 13, 2013

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();
      }
}

@ghost
Copy link
Author

ghost commented Sep 13, 2013

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

@ghost
Copy link
Author

ghost commented Dec 2, 2013

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?

@x3itsolutions
Copy link

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.

@rzr
Copy link

rzr commented Oct 20, 2020

Is this issue still relevant on latest @abandonware's fork ?

https://libraries.io/npm/@abandonware%2Fi2c/usage

Relate-to: #97

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants