11 Replies Latest reply on Mar 31, 2015 7:33 AM by Jacen

    Help for I2C in MRAA

    Jacen

      Hi All,

      I got problems about I2C in Mini Breakout board. I tried to use MRAA library to read one sensor data via I2C.

      Here is my reading code

      unsigned char * I2CReadRegister(mraa_i2c_context i2cDev,unsigned char RegAddr, unsigned short len)

      {

        unsigned char * buf=(unsigned char *)malloc(len);

        memset(buf,0,len);

       

       

        mraa_i2c_address(i2cDev,DEV_ADDR);

        mraa_i2c_write_byte(i2cDev,RegAddr);

        mraa_i2c_address(i2cDev,DEV_ADDR);

        mraa_i2c_read(i2cDev,buf,len);

        return buf;

      }

      Here is my Sensor I2C communication protocol

      Capture.PNG

       

      I do a Test reading like this :

      Data=I2CReadRegister(MyI2CDev,DEV_ID,1);

      Register DEV_ID in this sensor saving an 1 byte Dev ID inside.But every time i could only got 0 return. I don't know why.

      This Sensor definitely no problem cause i could get correct return in intel-Arduino using Wire library

      Can Someone give me an example that how to read data /Write data using MRAA I2C,

       

      Thanks

       

      Jacen

        • 1. Re: Help for I2C in MRAA
          CMata_Intel

          Hi Jacen

           

          If you are working with the mini breakout board, the voltage output of the pins is 1.8V if the sensor needs 5V to read and write you need to use a voltage translator to make it work. Also try to use pull up resistors in your configuration.

          Are you able to use a oscilloscope or a logic analyzer to check the signals that the Edison is sending and the ones from the sensor?

           

          Regards;

          CMata

          • 2. Re: Help for I2C in MRAA
            Jacen

            Hi CMata_Intel

            How to configuration pull up resistors in current program? is there any function i could use?

            I checked the senor needs around 1.8 V.

            Is that means the code looks good so far?

             

            Thanks

            • 3. Re: Help for I2C in MRAA
              Jacen

              Hi CMata_Intel

              I just tried this code in Arduino Intel using Bus I2C6 ,it was still not working. So i personally think there is probably issue in code.

              I checked my MRAA library version that is V0.5.2 , i use most update firmware for my Edison.

               

              I reviewed the source code for both MRAA  and Wire(Intel-Arduino library). i got an question, According to i2c protocol, there are some  communication signal here like ST SR SP.

              i think i could tell which function does which signal in Wire.

              For instance we want to read a byte.

               

              Wire.beginTransmission(address); //ST + Device address

              Wire.write(reg); //Register address

              Wire.endTransmission(false); // if true will send SP singal

              Wire.requestFrom(address, len); //SR + device address  and getting start to receive data from I2C device ,when got enough byte send SP signal

              while(Wire.available() < len); //Hang out until we get the # of bytes we expect

               

               

              for(int x = 0 ; x < len ; x++)

              buffer[x] = Wire.read();  read from buffer 

               

              Burt from the MRAA library I2C example i can't tell

               

                   // first 'select' the register we want to read from

                      mraa_i2c_address(i2c, HMC5883L_I2C_ADDR);

                      mraa_i2c_write_byte(i2c, HMC5883L_DATA_REG);

               

               

                      // then we read from that register incrementing with every read the

                      // chosen register

                      mraa_i2c_address(i2c, HMC5883L_I2C_ADDR);

                      // this call behaves very similarly to the Wire receive() call

                      mraa_i2c_read(i2c, rx_tx_buf, DATA_REG_SIZE);

               

              • 4. Re: Help for I2C in MRAA
                CMata_Intel

                Hi Jacen

                 

                I'm sorry for the delay in my response, do you have updates in this?

                There is an example in Python to use MRAA+I2C, do you need to use C?

                Have you tried to see the signals in an oscilloscope or logic analyzer?

                 

                Regards;

                CMata

                • 5. Re: Help for I2C in MRAA
                  Jacen

                  Hi CMata_Intel

                  Thanks for keeping answer me.

                  the chip i actually used is:https://www.sparkfun.com/products/12756

                  i found this staff have no problem running with Arduino library ,but if using with MRAA library there is no output.

                  I think the MRAA code is right cause i could use this code reading other i2c chip's data.

                   

                  So i don't know why

                   

                  Thanks

                  • 6. Re: Help for I2C in MRAA
                    CMata_Intel

                    Hi Jacen

                     

                    Did you tested with Arduino IDE and worked fine?

                    Could you attach in a file the entire code to test it? I don't have the SparkFun's block you are using to test this but I could see the output of the code you are using

                    mraa_i2c_address(i2c, HMC5883L_I2C_ADDR) ;

                    are you sure about the address you are using here? A lot of issues in I2C are related to the wrong address number.

                     

                    Regards;

                    CMata

                    • 7. Re: Help for I2C in MRAA
                      CMata_Intel

                      Hi Jacen

                       

                      Do you have updates in this? Did you check the address you are using?

                       

                      Regards;

                      CMata

                      • 8. Re: Help for I2C in MRAA
                        nniles

                        I think I had some of the same issues that you're having when I started learning I2C on the Edison.  I was completely unfamiliar with I2C before, so I don't know how specific these issues are to the Edison/MRAA implementation...

                         

                        Like you, I think, I had the impression that I could just call the library functions to read and write bytes to the bus in accordance with the diagrams in the spec.  The problem with that perception is that I2C conversations have some additional bit-level signalling that is presented by the API through different function calls (e.g., read, read_byte, read_byte_data, read_word_data, read_bytes_data).  The functions with the suffix _data are aimed at interacting with registers and produce the appropriate bit-level signals (ACK, NACK, etc.) at the appropriate times in the conversation.

                         

                        From your code, I can't tell exactly what you're trying to do, but if you're just trying to retrieve the contents of an 8-bit register, you might try this:

                         

                        uint8_t bytedata = 0;

                        mraa_i2c_address(i2c, HMC5883L_I2C_ADDR);

                        bytedata = mraa_i2c_read_byte_data(i2c, HMC5883L_DATA_REG);

                         

                        Or change it to mraa_i2c_read_word_data() for a 16-bit register.

                         

                        Good luck!

                        • 9. Re: Help for I2C in MRAA
                          Jacen

                          Hi nniles and CMata_Intel

                          Thanks for keeping tracking this post.

                          Here is my code

                          mraa::I2c * Myi2cDev;
                          Myi2cDev=new mraa::I2c(6);

                           

                           

                          Myi2cDev->address(DEV_ADDR);
                          Myi2cDev->write(MMA8452Q_WHO_AM_I);
                          Myi2cDev->address(DEV_ADDR);
                          buf[0]=Myi2cDev->read();

                           

                           

                          printf("The Data Read is:%X\n",buf[0]);

                           

                          This code is working on a other I2C device , but i dno't know why this one can not working on this MMA8452Q.

                          • 10. Re: Help for I2C in MRAA
                            nniles

                            Jacen,

                             

                            Try this instead:

                             

                            mraa::i2c *Myi2cDev;

                            mraa_result_t retval;

                            Myi2cDev = new mraa::i2c ( 6 );

                             

                            retval = Myi2cDev->address ( DEV_ADDR );

                            // you should always check these, just in case

                            if ( retval == MRAA_SUCCESS ) {

                            buf[0] = Myi2cDev->readReg ( MMA8452Q_WHO_AM_I );

                            printf ( "The data read is: 0x%0X\n", buf[0] );

                            }

                            else

                            printf ( "Error writing to i2c bus.\n" );

                             

                            Since you are trying to read a register, the proper bus signalling for this task is produced by the readReg (c++, or read_byte_data in c) MRAA call. 

                             

                            The combination of i2c::write() followed by i2c::read() is missing some kind of handshake, and the device never replies (at least that was my experience, I am working with the LSM9DS0 IMU/TAM).

                             

                            Thanks,

                            • 11. Re: Help for I2C in MRAA
                              Jacen

                              Hi nniles,

                              I found your code could not run on my MRAA, because mine version is old which is 0.4.4. So i update my Mraa in Edison and my computer(for compile using).


                              Then i could use function readReg(), yes it works. i could the response.


                              But it makes me confuse

                              if i use this style code like:

                              Myi2cDev->address(DEV_ADDR);
                              Myi2cDev->writeByte(MMA8452Q_WHO_AM_I);
                              Myi2cDev->address(DEV_ADDR);
                              buf[0]=Myi2cDev->readByte();

                              i still can not get the repose even in new MRAA(version 0.6.1)

                              same thing happened when using this code

                              Myi2cDev->address(DEV_ADDR);
                              buf[0]=Myi2cDev->readByte();

                               

                              but if i use you code like this:

                              Myi2cDev->address ( DEV_ADDR );

                              Myi2cDev->readReg ( MMA8452Q_WHO_AM_I );

                              It is working.

                               

                              I don't know when i use ReadByte when i use ReadReg what different for them?

                              And If there still has different for write() and writeReg()?