6 Replies Latest reply on Jan 9, 2015 3:33 PM by VictorR

    How to write binary data to I2C using JavaScript? (MRAA)

    VictorR

      I am looking for example how to write binary data to an I2C device from JavaScript.

       

      The MRAA library supports I2C but examples are provided only in C; the JavaScript documentation covers only the simple functions like blinking with a LED.

       

      Here is the code I am trying to make working:

      var mraa = require("mraa");

      var i2C = new mraa.I2c(0);

      i2C.address(0x70);

       

      writeBuffer(new Buffer([0x21]));   // Works fine

      writeBuffer(new Buffer([0xEF]));   // Problem!

       

      function writeBuffer(buffer)

      {

          var strBuf = buffer.toString('ascii');

          i2C.write(strBuf);

      }

       

      With a bus sniffer I see that value 0x21 is written as expected, but the value 0xEF loses its most significant byte and is written as 0x6F. Well, that's how the "ascii" format works according to the Node.js documentation.

       

      If I use buffer.toString('binary") instead of 'ascii', the string looks Ok, but the i2C.write function writes then two bytes instead of one: C3,AF instead of EF. Probably somewhere in the code that binds JavaScript to native library the string is converted to UTF-8. MRAA sources contain some script for generating JavaScript definitions from the C code, but being Windows developer and having no experience with cmake I did not manage to execute the script.

       

      Could you please point me to some example on how to write binary data to I2C bus from JavaScript on Intel Galileo Gen2?

       

      PS: I think my question is not specific to Galileo and applies to Edison too.

        • 1. Re: How to write binary data to I2C using JavaScript? (MRAA)
          CMata_Intel

          Hi VictorR

           

          The examples that I have found for MRAA using Javascript are in this link. Unfortunately, not related to I2C.

          Take a look at the code in this other thread. At the end of the thread there is a working script but for a specific sensor. I think you could use it to check some things.

          Also, what do you have connected to your board? Do you have the latest MRAA version in your board?

           

          Regards;

          CMata

          • 2. Re: How to write binary data to I2C using JavaScript? (MRAA)
            VictorR

            Hi CMata!

             

            The code from the SPI thread does not help me a lot; fortunately for the author of that topic all the characters in that example do fit in 7 bits and implicit encoding to UTF-8 does not manipulate string bytes.

             

            I am trying to communicate with Adafruit LED matrix 8x8 that is currently not supported directly my MRAA or UPM. The matrix API is very simple and I can write the library myself, the only problem is I do not know how to write arbitrary bytes to I2C bus from JavaScript. Here is the test to reproduce my problem

             

            var mraa = require("mraa"); //require mraa 
            var i2C = new mraa.I2c(0); 
            i2C.address(0x70); 
            
            i2C.write(String.fromCharCode(0x21));  // Ok. Writes one byte 0x21 as expected 
            i2C.write(String.fromCharCode(0xEF)); // Error! Writes two bytes 0xC3, 0xAF because of implicit conversion to UTF-8 
            

             

            So i2C.write(string) function is not suitable for writing binary data.

             

            In C++ headers of the MRAA there are two write functions:

            mraa_result_t write(char* data, size_t length)

            mraa_result_t write(uint8_t data)

             

            Unfortunately I do not know how to call the second function form the JavaScript. The documentation says "The API itself is very similar to the python one but with a js syntax" but does not provide hints on how exactly parameters are mapped in JS. There is a Python example where the write function si called with a hex constant passed as a parameter, but when I do the same in JavaScript from XDK, I get the following error:

             

            i2C.write(0xEF);
            

             

            ERROR: /node_app_slot/main.js:6                                                                                                                                                                                                                                       

            ERROR: i2C.write(0xEF);                                                                                                                                                                                                                                               

            ERROR:    ^                                                                                                                                                                                                                                                         

            ERROR: Error: Illegal arguments for function write.                                                                                                                                                                                                                   

            at Object.<anonymous> (/node_app_slot/main.js:6:5)                                                                                                                                                                                                                             at Module._compile (module.js:456:26)                                                                                                                                                                                                                             

            at Object.Module._extensions..js (module.js:474:10)

            ...

             

            I suppose the JavaScript wrapper is automatically generated from the C++ header. Is there any documentation on how exactly the functions and their parameters are translated from C++ to JavaScript?

            • 3. Re: How to write binary data to I2C using JavaScript? (MRAA)
              CMata_Intel

              Hi VictorR

               

              Have you tried with these examples (bmp85 & rgblcd)

              The bmp85.js is very recent and is using writeReg, take a look at it and let me know if those are helpful for you.

               

              Regards;

              CMata

              • 4. Re: How to write binary data to I2C using JavaScript? (MRAA)
                VictorR

                Hi CMata

                 

                The functions writeReg and writeByte from bmp85.js are exactly what I need!

                 

                When I try to execute example from bmp85.js on Galileo Gen2 from Intel XDK IoT Edition version 0128 I get the following error:

                 

                ERROR: x.writeReg(char('0xf4'), char('0x2e'))                                                                                                                                                                                                                               

                ERROR:   ^                                                                                                                                                                                                                                                                  

                ERROR: Error: in method 'I2c_writeReg', argument 2 of type 'char'                                                                                                                                                                                                           

                    at Object.<anonymous> (/node_app_slot/main.js:36:3)                                                                                                                                                                                                                     

                    at Module._compile (module.js:456:26)                                                                                                                                                                                                                                   

                    at Object.Module._extensions..js (module.js:474:10)                                                                                                                                                                                                                     

                    at Module.load (module.js:356:32)                                                                                                                                                                                                                                       

                    at Function.Module._load (module.js:312:12)                                                                                                                                                                                                                             

                    at Function.Module.runMain (module.js:497:10)                                                                                                                                                                                                                           

                    at startup (node.js:119:16)                                                                                                                                                                                                                                             

                    at node.js:906:3  

                 

                Should I somehow update MRAA to the latest version first?

                 

                General question: MRAA and is UPM libraries are not referenced in package.json files that are generated by XDK templates. Still, JavaScript code running on Galileo automagically loads them with the "require" command. How does it work?

                • 5. Re: How to write binary data to I2C using JavaScript? (MRAA)
                  CMata_Intel

                  Hi VictorR

                   

                  In order to update MRAA to the latest version you will need the following:

                  root@edison:~#  echo "src mraa-upm http://iotdk.intel.com/repos/1.1/intelgalactic" > /etc/opkg/mraa-upm.conf
                  root@edison:~# opkg update
                  root@edison:~# opkg install libmraa0 
                  

                   

                  I think that the xdk already has a MRAA and UPM version, maybe are not included in the packaje.json, I haven't seen this file yet. Let me check this and I'll post you back. Also let me know the outcome of upgrading MRAA.

                   

                  Best Regards;

                  CMata

                  • 6. Re: How to write binary data to I2C using JavaScript? (MRAA)
                    VictorR

                    Thank you! Updating MRAA following your instructions solved the problem!

                     

                    Now I am able to control Adafruit LED matrix 8x8 over I2C from the JavaScript.

                     

                    LedMatrix.jpg

                    Here is the code example:

                     

                    /*
                    Simple library for controlling Adafruit LED 1.2" 8x8 Matrix
                    https://learn.adafruit.com/adafruit-led-backpack/1-2-8x8-matrix
                    
                    Wiring:
                    GND -> Galileo GND
                    VCC -> Galileo 5V
                    SDA -> Galileo analog pin 4
                    SCL -> Galileo analog pin 5
                    */
                    
                    var mraa = require("mraa"); //require mraa
                    var i2C = new mraa.I2c(0);
                    
                    // helper function to go from hex val to dec
                    function char(x) { return parseInt(x, 16); }
                    
                    // Must be called once before using other functions
                    function init() {
                        console.log("Initializing LED matrix controller");
                        i2C.address(0x70);
                        i2C.writeByte(char('0x21'));    // Turn on oscillator
                        i2C.writeByte(char('0xef'));    // Brightness 15
                        i2C.writeByte(char('0x81'));    // No blinking
                    }
                    
                    /* Writes the Buffer of 8 bytes in the display's memory
                        Attention: matrix columns are mapped to the bits as following:
                        7 0 1 2 3 4 5 6
                    */
                    function writeBuffer(buffer)
                    {
                        // Add write command (zero byte) at the head of buffer
                        var rawBuffer = new Buffer(buffer.length * 2 + 1);
                       
                        rawBuffer[0] = 0x00; // Write command
                       
                        for (var i = 0; i < buffer.length; i++)
                        {
                            rawBuffer[i*2 + 1] = buffer[i];
                            rawBuffer[i*2 + 2] = 0;
                        }
                        i2C.write(rawBuffer);
                    }
                    
                    // Clears the matrix
                    function clear() {
                        console.log("LED: clear");
                        var allZeroes =
                        writeBuffer(new Buffer([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]));
                       
                    }
                       
                    // Shows a smiling face
                    function smile() {
                        console.log("LED: smile");
                        var smiley = new Buffer([0x1E, 0x21, 0xCA, 0xD0, 0xD0, 0xCA, 0x21, 0x1E]);
                        writeBuffer(smiley);
                    }
                       
                    init();
                    
                    clear();
                    smile();  
                    

                     

                    I should probably make a pull request to MRAA JavaScript examples repository.