I2C Library

WiringPi includes a library which can make it easier to use the Raspberry Pi’s on-board I2C interface.

Not all systems have the I2C development libraries and headers installed, and when you build wiringPi, it detects this at build time. If you are using these helper functions and you get link errors, it means that wiringPi is not installed with the I2C helper functions. You need to install the I2C development libraries and re-build.

Under Raspbian:

sudo apt-get install libi2c-dev

then rebuild wiringPi.

Before you can use the I2C, you need to load the kernel modules and you can use the gpio utility to load the I2C drivers into the kernel:

gpio load i2c

If you need a baud rate other than the default 100Kbps, then you can supply this on the command-line:

gpio load i2c 400

will set the baud rate to 400Kbps – ie. 400,000 bps. (K here is times 1000)

To use the I2C library, you need to:

#include <wiringPiI2C.h>

in your program. Programs need to be linked with -lwiringPi as usual.

You can still use the standard system commands to check the I2C devices, and I recommend you do so – e.g. the i2cdetect program. Just remember that on a Rev 1 Raspberry pi it’s device 0, and on a Rev. 2 it’s device 1. e.g.

i2cdetect -y 0 # Rev 1
i2cdetect -y 1 # Rev 2

Functions available

  •  int wiringPiI2CSetup (int devId) ;

This initialises the I2C system with your given device identifier. The ID is the I2C number of the device and you can use the i2cdetect program to find this out. wiringPiI2CSetup() will work out which revision Raspberry Pi you have and open the appropriate device in /dev.

The return value is the standard Linux filehandle, or -1 if any error – in which case, you can consult errno as usual.

E.g. the popular MCP23017 GPIO expander is usually device Id 0x20, so this is the number you would pass into wiringPiI2CSetup().

For all the following functions, if the return value is negative then an error has happened and you should consult errno.

  • int wiringPiI2CRead (int fd) ;

Simple device read. Some devices present data when you read them without having to do any register transactions.

  • int wiringPiI2CWrite (int fd, int data) ;

Simple device write. Some devices accept data this way without needing to access any internal registers.

  • int wiringPiI2CWriteReg8 (int fd, int reg, int data) ;
  • int wiringPiI2CWriteReg16 (int fd, int reg, int data) ;

These write an 8 or 16-bit data value into the device register indicated.

  • int wiringPiI2CReadReg8 (int fd, int reg) ;
  • int wiringPiI2CReadReg16 (int fd, int reg) ;

These read an 8 or 16-bit value from the device register indicated.

 

Comments

I2C Library — 121 Comments

  1. Hi Gordon

    I’ve downloaded your WiringPi library and the I2C library as per your web page. I’m using Occidentalis v0.2 from Adafruit, but since downloading the I2C stuff /dev/rtc0 has disappeared.

    Have got an alternative way of using the RTC?

    pi@raspberrypi /dev $ sudo hwclock –debug
    hwclock from util-linux 2.20.1
    hwclock: Open of /dev/rtc failed: No such file or directory
    No usable clock interface found.
    hwclock: Cannot access the Hardware Clock via any known method.
    pi@raspberrypi /dev $

    Thanks

    Jon

  2. Just found that by going through the adafruit install rtc install it’s working again. Hopefully this info will prove useful to others.

    Thanks for all your hard work.

    Jon

    • I’ve no idea why wiringPi is upsetting the clock )-: I wonder if it’s permissions when you load up the I2C kernel modules? (although I’d have thought they’d be already loaded for the clock module to run if it’s I2C)

      Did you run i2cdetect on your Pi after plugging the RTC in?

      -Gordon

  3. Hi

    I was looking into using WiringPi.
    I have questions though. Which I2C is this using?

    I believe, correct me if I’m wrong, that I2C0 and I2C1 are both available on rev B 512MB. I2C1 on P1 and I2C0 on P5.

    Can WiringPi be used for both?
    Or easilly modified to use on both

    Best regards
    Nicolaj

    • It’s designed to use the correct one for the I2C interface on the GPIO connector on Pi you’re on – ie. it knows what board Rev and select the appropriate one.

      If you want to change the device, you’ll need to write your own – but they’re really only simple wrappers round what the kernel provides, so it’s not a big job.

      -Gordon

  4. Hi Gordon,
    this is a super library! thank your so much for your hard work.

    I have implemented the i2c library in my code and tested it (it works).
    BUT my problem is that I want to send data to a Uc which is using 2 PWM pins. The data i want to send will contain an id of the PWM pin and value (0-255) of the duty cycle for that pin.
    Will wiringPiI2CWrite (int fd, int data) support something along => int data[2] = {0x1,0xff};

    to sum it up, is it possible to send all that data in one write?

    Many thanks in advance for reply.

    here si my code:

    #include
    //#include
    #include
    #include
    #include
    #include
    #include
    #include

    unsigned char test[2] ={0};
    int fd,e;
    int dID = 0x32;

    int main(void){
    // data to be sent
    test[0]=0x01;
    test[1]=0xff;

    if((fd=wiringPiI2CSetup(dID))<0)
    printf("error opening i2c channel\n\r");

    if((e= wiringPiI2CWrite(fd,test))<0){
    printf("error writing to slave\n\r");
    }else{

    //printf("writing hex:0x%i size:%i\n\r",test,sizeof(test));
    }

    sleep(1);

    }

    • Your controller might accept standard write()’s to it. It’s worth a try.

      So do the wiringPiI2CSetup() as before, then:

      write (fd, test, 2) ;

      Let me know if that works. I’ve used it recently with one of the popular RTC chips.

      -Gordon

      • thanks for the fast reply,
        I have tried what you said but i get this error:

        comtest.c: In function ‘main’:
        comtest.c:25:2: warning: passing argument 2 of ‘wiringPiI2CWrite’ makes integer from pointer without a cast [enabled by default]
        /usr/local/include/wiringPiI2C.h:33:12: note: expected ‘int’ but argument is of type ‘int *’
        comtest.c:25:2: error: too many arguments to function ‘wiringPiI2CWrite’
        /usr/local/include/wiringPiI2C.h:33:12: note: declared here

        • ah just made a mistake… used wiringPiI2CWrite instead of write()
          ignore the statement above sorry!

          • ok with write() it seems to be doing more than before.
            I am using Attiny2313 and I still quite new at I2C. so far the code on my I2C is like this. Am I reading the i2c right?

            …..
            // identifier bytes
            uint8_t a0[1] = {1}; // pwm1
            uint8_t b0[1] = {2}; // pwm2
            uint8_t b[8] = {0}; // pwm val

            …..

            if(usiTwiDataInReceiveBuffer()) // if there is data in buffer
            {

            // get it
            int c = 0;
            while(usiTwiDataInReceiveBuffer()){
            b[c++] = usiTwiReceiveByte(); // read data from buffer
            }

            if(b[1] == 0x01){ //check command designation

            if(i%2){ // toggle led

            PORTD |= (1 << PD2);//on green

            }else{

            PORTD &= ~(1<<PD2);
            }
            OCR0A = b[0]; // write pwm val to led.

            i++;

            }else if(b[1] == 0x02){

            if(i%2){
            PORTD |= (1 << PD1);//on red
            }else{
            PORTD &= ~(1<<PD1);
            }

            OCR0B = b[0];

            }

          • Not sure to be honest with you – it’s been a long time since I’ve used I2C on the ATmegas – I did write my own driver for it though (master only though) so I’d need to go & look at the ATmega side of things.
            -Gordon

  5. Keith,

    I am rather sure it is not that simple code needed to make an ATTiny 2313 listening as a slave to the master RPi. Googling for “AVR i2c slave library” will lead you to apropriate pages for free download.

    Next challenge could be that RPi is not enabled for clock stretching, so you will have to slow down i2C-speed dramatically ?

    Regards
    Karl

    • Karl
      Thanks, just did a google on all what you said and you are quite right about the clock stretching, I think someone said something about v2 too supporting or the must be a way around it. Will have to look a bit more. I might have to get another micro if I can not find a way around this without sacrificing speed.

      cheerio

      Keith

  6. Hi Gordon

    I have a query, but firstly, thanks for all your work on this. I’ve used wiringPi since getting my first Pi and I think it’s wonderful. I program in C.

    I’m using your I2C helpers with an MCP23017 16-bit port expander, using your example program as a starting point, and it’s all working nicely.

    Now, 16-bit reads and writes work as one would hope, accessing consecutive 8-bit registers. But – if I have understood your code correctly – you write a ‘1’ into the SEQOP bit in the device’s control register which, according to the data sheet, turns sequential addressing off.

    So now I am confused. Are you turning sequential addressing off on the chip because addresses are incremented somewhere in the bowels of lower-level routines on the Pi, thus avoiding double incrementing? Or am I barking up the wrong end of the pole? Again.

    David (exartemarte)

    • So I think there are a few things at issue here…

      AIUI, 16-bit mode is designed to do a 16-bit read over the I2C bus in a single transaction. So e.g. a A/D converter might have a single 16-bit register to hold the conversion value in it – so you can issue a 16-bit read on that register and get the value. The same device might also map the 16 bits as 2 consecutive 8-bit registers so that controllers which can’t do a 16-bit read can still access the data.

      I think that this is what’s happening in your 16-bit reads on the 23017.

      The 23017 has 2 modes – sequential and byte mode. I set the chip up in byte mode (but don’t actually use the byte mode feature). In Byte mode the 23017 allows you to read a register as normal, then perform more reads to the device without specifying the register, and each time you get the same register that you last specified. So you can poll the GPIO port (for example) by just performing read() instructions using the retirned fd – e.g. read (fd, &c, 1); (where c is unsigned char).

      Sequential mode will auto-increment an internal register address pointer after each read, so you can put it into sequential mode, then read register 0, then perform a read of 15 more registers and you’ll get the next 15 registers in a single operation.

      At least that’s my understanding!

      Personally, I’d stick to byte mode and do the full register poll each time I wanted to read the GPIO register on the chip – it’s slightly less efficient, but you know what to expect!

      -Gordon

      • Thanks,Gordon.

        In associating the SEQOP bit with the low-level mechanics of a 16-bit transfer I think was just adding two and two and making five, on the basis of an imperfect understanding of the data sheet. (It happens a lot!) After poring over the data sheet again I can see that they are separate things, and I take your point about using byte mode.

        Thank you for a prompt and helpful response.

        David

  7. Hi Gordon,

    for the Quick2Wire boards – I ran the q2w.c and had following errors…

    q2w.c:(.text+0x18): undefined reference to `wiringPiI2CSetup’
    q2w.c:(.text+0x80): undefined reference to `wiringPiI2CWriteReg8′
    q2w.c:(.text+0x90): undefined reference to `wiringPiI2CWriteReg8′
    q2w.c:(.text+0xa0): undefined reference to `wiringPiI2CWriteReg8′
    q2w.c:(.text+0xb0): undefined reference to `wiringPiI2CWriteReg8′
    q2w.c:(.text+0xc8): undefined reference to `wiringPiI2CWriteReg8′
    collect2: ld returned 1 exit status

    I am using following command

    gcc -o q2w q2w.c -lwiringPi

    kindly advice…

    regards,

    Jishnu.

    • You need to make sure you have the i2c-dev headers installed.. So do this:

      sudo apt-get install libi2c-dev

      then re-make wiringPi:

      cd wiringPi
      ./build clean ; ./build

      If you don’t get any messages at all about I2C, then you need to upgrade:

      git pull ; ./build

      then re-compile your program.

      -Gordon

  8. thanks Gordon… it’s now working.

    BTW is it possible to read value say from tmp36 and convert it into voltage = value * 3.3/ 1024 and then convert into temperature? My reason for asking is that unlike Gertboard / Arduino I am not seeing any port from where I can take analog value in q2w board?

    BTW I am still looking forward for your tutorial for makefile for running arduino codes from command line.. :-).

    With Best Regards,

    Jishnu

    • the TMP36 is an analogue output temperature sensor, so you just need to write some code to read the analog value from the Q2W analog input board (which I’ve no experience of – just the AtoD on the Gertboard)

      (The q2w system has a main board and then there are add-on board – I’ve only seen the GPIO expander, but I know there is also an analog input board too)

      -Gordon

  9. I need some help. I connected to raspi temperature sensor TCN75A via I2C. Programing in C and trying to use a wiringPi library, but I don’t know how exactly should use this. Can someone write me the code of reading the temperature ??

    • Start by using i2cdetect to make sure it’s visible to the operating system.

      After that, it doesn’t look too bad to interface- just read the registers to get the temperature. Looks like it might have 16-bit registers too, but I’m obly glanced at the data sheet.

      -Gordon

      • Thanks for fast reply 🙂 !!
        Detection is ok!
        0 1 2 3 4 5 6 7 8 9 a b c d e f
        00: — — — — — — — — — — — — —
        10: — — — — — — — — — — — — — — — —
        20: — — — — — — — — — — — — — — — —
        30: — — — — — — — — — — — — — — — —
        40: — — — — — — — — 48 — — — — — — —
        50: — — — — — — — — — — — — — — — —
        60: — — — — — — — — — — — — — — — —
        70: — — — — — — — —

        Here you have my function ( I get only 255 and 255).

        unsigned char TCN_ADRESS_W=0x90;
        unsigned char TCN_ADRESS_R=0x91;
        unsigned char TCN_TEMP=0x00;
        unsigned char temp1,temp2;
        int fd,e;

        void read_temperature(void)
        {

        if((fd=wiringPiI2CSetup(TCN_TEMP))<0)
        printf("error opening i2c channel\n\r");

        if((e= wiringPiI2CWrite(fd,TCN_ADRESS_W))<0)
        printf("error writing to slave\n\r");

        if((temp1= wiringPiI2CReadReg8 (e,TCN_ADRESS_R))<0)
        printf("error writing to slave\n\r");

        temp2= wiringPiI2CReadReg8 (e,TCN_ADRESS_R);
        printf("Temperatura =%d",temp1);
        printf("Temperatura =%d",temp2);
        }

        • You need to call wiringPiI2CSetup() with the device ID, not zero.

          So:

          fd = wiringPiI2CSetup (0x48);

          then you need to read the register:

          x = wiringPiI2CReadReg16 (0) ; // Read 16-bits from register 0.

          This may be wrong – you’ll need to read the data sheet to find the right register to read and the values to expect though.

          Basically note that the underlying code is doing all the I2C bus negotiation for you – you don’t need to write the I2C address, etc. just use the file descriptor returned by the Setup() code, but tell the setup code the device ID.

          -Gordon

          • Hello,
            thank you very much for help and some explanations. At the moment working and not working 🙂 . That mean, I get a ok temperature, for example 25 degrees, but some times a get 32792 and I don’t know why. Second, the accuracy (second byte is empty) is not ok in my opinion. I used this sensor many times but in embedded system with microcontrolers and never had a problems.

          • The functions I’ve made are just wrappers round the standard ones provided by the Linux kernel – I’d really need to sit-down and have a look at your device in-detail. It might be that you need to do 2 8-bit reads for example to get the 2nd byte…

            -Gordon

          • One more, I think the biggest problem for me is that I not understand how working yours functions, I have experience but on embedded systems. Now I added a PCF8563 and also have a problem with writing/reading, do you have an code example of using the I2C library to see the mechanism of action ??

  10. Hello Gordon,
    I would like to thank you for your support,now everything work good !! The temperature I’m reading with using read() function (2 single 8 bits). Next my step will be with wireless module via SPI, I hope this time I will have less problems 🙂 , but I’m full of hope I can count on your support !? 🙂 .
    Best Regards. Marcin.

  11. I am trying to use your library to obtain the temperature reading from a “Parallax L3G4200D 3 axis gyroscope” I figured the temperature reading is the simplest reading to obtain from the device to start off with. I am brand new to I2C and I am very confused on how it all works and how to communicate with devices. I am hoping that you might be able to write me some sample code to either read the temperature or at least one of the axis on the device to get me started. They have working sample code here http://learn.parallax.com/kickstart/27911 for the Arduino at the bottom of the page written in “C” using the “Wire.h” library. The documentation they provide does not tell me how to use it at all with a Pi. Thanks in advance for this.

    • O.K I finally got it working thanks for the great libraries. It is now reading the temperature from the sensor on the Gyro but I have a problem you may be able to answer. When a gyro is left on a flat surface with nothing interacting with it at all the outputs from it should all be “0” correct? Mine is jumping around between numbers. For example “X_L = 0” and “X_H = 17219” with a “delay(500)” between refresh the X_H will jump around while X_L stays pretty much at 0 but will occasionally jump very high. This will happen on a flat surface with nothing interacting with it. Do you think this is a problem with the sensor or something code related? If I pick up the Gyro and shake it around all of the numbers start updating like its functioning correctly.

      • It’s a gyro, so it’s measuring rate of change – this may be a signed numbe (positive for one way, neagitive for the other), so the stable number might be hanf way between 0 and max. I’d need to go & stidy the data sheet in detail to work out what it’s supposed to be doing..

        A very quick look at the data sheet suggests the output values are 2’s compliment, so I’d expect a negative or positive number, but for it to be relatively constant when nothing of moving..

        -Gordon

      • No you would expect the gyro reading to change, it is responding to the earths rotation, we use laser ring gyros at work in precision navigation units for this reason.
        Also any reading at or near 0 will jump to 359 deg (or the digital equivalent) due to jitter / noise from time to time.
        It is possible to find true north from this change (as opposed to magnetic north that a compass reads).

  12. Hi Gordon, do you have any example C code for driving the TI ADS1015 A2D converter with the WiringPi I2C library please?

    Thanks

    Penny

    • I don’t – sorry. I’ll have a look at its data sheet later though. Shouldn’t be too hrd to adapt some existing code if there is any though…

      -Gordon

      • Thank you Gordon. I did try and use the Adafruit code for the ADS1015 but it appears to be for the Arduino and I was unable to compile it. When I subsituted the calls to the WiringPi I just get some fixed values, irresepective of the analog values:

        #include
        #include
        #include
        #include
        #include

        /*=========================================================================
        I2C ADDRESS/BITS
        ———————————————————————–*/
        #define ADS1015_ADDRESS (0x48) // 1001 000 (ADDR = GND)
        /*=========================================================================*/

        /*=========================================================================
        CONVERSION DELAY (in mS)
        ———————————————————————–*/
        #define ADS1015_CONVERSIONDELAY (1)
        #define ADS1115_CONVERSIONDELAY (8)
        /*=========================================================================*/

        /*=========================================================================
        POINTER REGISTER
        ———————————————————————–*/
        #define ADS1015_REG_POINTER_MASK (0x03)
        #define ADS1015_REG_POINTER_CONVERT (0x00)
        #define ADS1015_REG_POINTER_CONFIG (0x01)
        #define ADS1015_REG_POINTER_LOWTHRESH (0x02)
        #define ADS1015_REG_POINTER_HITHRESH (0x03)
        /*=========================================================================*/

        /*=========================================================================
        CONFIG REGISTER
        ———————————————————————–*/
        #define ADS1015_REG_CONFIG_OS_MASK (0x8000)
        #define ADS1015_REG_CONFIG_OS_SINGLE (0x8000) // Write: Set to start a single-conversion
        #define ADS1015_REG_CONFIG_OS_BUSY (0x0000) // Read: Bit = 0 when conversion is in progress
        #define ADS1015_REG_CONFIG_OS_NOTBUSY (0x8000) // Read: Bit = 1 when device is not performing a conversion

        #define ADS1015_REG_CONFIG_MUX_MASK (0x7000)
        #define ADS1015_REG_CONFIG_MUX_DIFF_0_1 (0x0000) // Differential P = AIN0, N = AIN1 (default)
        #define ADS1015_REG_CONFIG_MUX_DIFF_0_3 (0x1000) // Differential P = AIN0, N = AIN3
        #define ADS1015_REG_CONFIG_MUX_DIFF_1_3 (0x2000) // Differential P = AIN1, N = AIN3
        #define ADS1015_REG_CONFIG_MUX_DIFF_2_3 (0x3000) // Differential P = AIN2, N = AIN3
        #define ADS1015_REG_CONFIG_MUX_SINGLE_0 (0x4000) // Single-ended AIN0
        #define ADS1015_REG_CONFIG_MUX_SINGLE_1 (0x5000) // Single-ended AIN1
        #define ADS1015_REG_CONFIG_MUX_SINGLE_2 (0x6000) // Single-ended AIN2
        #define ADS1015_REG_CONFIG_MUX_SINGLE_3 (0x7000) // Single-ended AIN3

        #define ADS1015_REG_CONFIG_PGA_MASK (0x0E00)
        #define ADS1015_REG_CONFIG_PGA_6_144V (0x0000) // +/-6.144V range
        #define ADS1015_REG_CONFIG_PGA_4_096V (0x0200) // +/-4.096V range
        #define ADS1015_REG_CONFIG_PGA_2_048V (0x0400) // +/-2.048V range (default)
        #define ADS1015_REG_CONFIG_PGA_1_024V (0x0600) // +/-1.024V range
        #define ADS1015_REG_CONFIG_PGA_0_512V (0x0800) // +/-0.512V range
        #define ADS1015_REG_CONFIG_PGA_0_256V (0x0A00) // +/-0.256V range

        #define ADS1015_REG_CONFIG_MODE_MASK (0x0100)
        #define ADS1015_REG_CONFIG_MODE_CONTIN (0x0000) // Continuous conversion mode
        #define ADS1015_REG_CONFIG_MODE_SINGLE (0x0100) // Power-down single-shot mode (default)

        #define ADS1015_REG_CONFIG_DR_MASK (0x00E0)
        #define ADS1015_REG_CONFIG_DR_128SPS (0x0000) // 128 samples per second
        #define ADS1015_REG_CONFIG_DR_250SPS (0x0020) // 250 samples per second
        #define ADS1015_REG_CONFIG_DR_490SPS (0x0040) // 490 samples per second
        #define ADS1015_REG_CONFIG_DR_920SPS (0x0050) // 920 samples per second
        #define ADS1015_REG_CONFIG_DR_1600SPS (0x0080) // 1600 samples per second (default)
        #define ADS1015_REG_CONFIG_DR_2400SPS (0x00A0) // 2400 samples per second
        #define ADS1015_REG_CONFIG_DR_3300SPS (0x00C0) // 3300 samples per second

        #define ADS1015_REG_CONFIG_CMODE_MASK (0x0010)
        #define ADS1015_REG_CONFIG_CMODE_TRAD (0x0000) // Traditional comparator with hysteresis (default)
        #define ADS1015_REG_CONFIG_CMODE_WINDOW (0x0010) // Window comparator

        #define ADS1015_REG_CONFIG_CPOL_MASK (0x0008)
        #define ADS1015_REG_CONFIG_CPOL_ACTVLOW (0x0000) // ALERT/RDY pin is low when active (default)
        #define ADS1015_REG_CONFIG_CPOL_ACTVHI (0x0008) // ALERT/RDY pin is high when active

        #define ADS1015_REG_CONFIG_CLAT_MASK (0x0004) // Determines if ALERT/RDY pin latches once asserted
        #define ADS1015_REG_CONFIG_CLAT_NONLAT (0x0000) // Non-latching comparator (default)
        #define ADS1015_REG_CONFIG_CLAT_LATCH (0x0004) // Latching comparator

        #define ADS1015_REG_CONFIG_CQUE_MASK (0x0003)
        #define ADS1015_REG_CONFIG_CQUE_1CONV (0x0000) // Assert ALERT/RDY after one conversions
        #define ADS1015_REG_CONFIG_CQUE_2CONV (0x0001) // Assert ALERT/RDY after two conversions
        #define ADS1015_REG_CONFIG_CQUE_4CONV (0x0002) // Assert ALERT/RDY after four conversions
        #define ADS1015_REG_CONFIG_CQUE_NONE (0x0003) // Disable the comparator and put ALERT/RDY in high state (default)

        uint16_t readADC_SingleEnded(int fd, uint8_t channel) {
        if (channel > 3)
        {
        return 0;
        }

        int m_bitShift = 4;

        // Start with default values
        uint16_t config = ADS1015_REG_CONFIG_CQUE_NONE | // Disable the comparator (default val)
        ADS1015_REG_CONFIG_CLAT_NONLAT | // Non-latching (default val)
        ADS1015_REG_CONFIG_CPOL_ACTVLOW | // Alert/Rdy active low (default val)
        ADS1015_REG_CONFIG_CMODE_TRAD | // Traditional comparator (default val)
        ADS1015_REG_CONFIG_DR_1600SPS | // 1600 samples per second (default)
        ADS1015_REG_CONFIG_MODE_SINGLE; // Single-shot mode (default)

        // Set PGA/voltage range
        config |= ADS1015_REG_CONFIG_PGA_6_144V; // +/- 6.144V range (limited to VDD +0.3V max!)

        // Set single-ended input channel
        switch (channel)
        {
        case (0):
        config |= ADS1015_REG_CONFIG_MUX_SINGLE_0;
        break;
        case (1):
        config |= ADS1015_REG_CONFIG_MUX_SINGLE_1;
        break;
        case (2):
        config |= ADS1015_REG_CONFIG_MUX_SINGLE_2;
        break;
        case (3):
        config |= ADS1015_REG_CONFIG_MUX_SINGLE_3;
        break;
        }

        // Set ‘start single-conversion’ bit
        config |= ADS1015_REG_CONFIG_OS_SINGLE;

        // Write config register to the ADC
        wiringPiI2CWriteReg16(fd, ADS1015_REG_POINTER_CONFIG, config);

        // Wait for the conversion to complete
        delay(ADS1015_CONVERSIONDELAY);

        // Read the conversion results
        // Shift 12-bit results right 4 bits for the ADS1015
        return wiringPiI2CReadReg16(fd, ADS1015_REG_POINTER_CONVERT); >> m_bitShift;
        }

        int main(int argc, char** argv)
        {
        int fd=0;

        fd=wiringPiI2CSetup(ADS1015_ADDRESS);

        if (fd>=0)
        {
        int16_t adc0, adc1, adc2, adc3;

        adc0 = readADC_SingleEnded(fd,0);
        adc1 = readADC_SingleEnded(fd,1);
        adc2 = readADC_SingleEnded(fd,2);
        adc3 = readADC_SingleEnded(fd,3);
        printf(“AIN0: %d\n”,adc0);
        printf(“AIN1: %d\n”,adc1);
        printf(“AIN2: %d\n”,adc2);
        printf(“AIN3: %d\n”,adc3);
        }
        else
        {
        printf(“Failed to open I2C : %d\n”,errno);
        }
        return 0;
        }

  13. Hello Gordon,
    I downloaded the I2C library. I want to connect RPI with I2C Lego mindstorms sensors, but I does not work. As far as I understand this mindstorm’s sensors use a bit rate of 9600, I tried to change from 100000 bps to 9600 bps, with no success.

    Is there any way to customize this library in order to make it work at 9600 bps?
    Thank you
    Arturo

    • If you load the i2c modules with the gpio command then you can set the data rate, but only to the nearest 1000.

      gpio load i2c 9

      would set it to 9,000 bits/sec.

      However and I2C rate of 9600 is very low! But I’m no expeisnce with these new lego sensors.

      -Gordon

  14. Hi Gordon,

    thanks for your library.
    I append a small i2c test program. It may be useful for quick test of their i2c devices or as another example for your library.

    With Best Regards,

    tmm

    /*
    * Copyright (c) 2013 tmm GPL
    ***********************************************************************

    gcc -O3 -Wall -I/usr/local/include -Winline -pipe -L/usr/local/lib i2ctst.c -lwiringPi -lpthread -lm -o i2ctst

    */

    #include
    #include
    #include

    #include
    #include

    int GetNum(char *str)
    {
    int a;
    int b;
    b = (sscanf(str, “%i”, &a) == 0);
    if (b != 0) a = -1;
    return a;
    }

    int main(int argc,
    char *argv[])
    {
    int i,n;
    int j=0;
    int fd = -1;
    int adr = -1;
    int dly = -1;
    int reg = -1;
    int ver = 0;
    int dat = -1;
    int err;
    for (i = 1; i =0) fd = wiringPiI2CSetup((adr&0xff)>>1);
    if (ver) printf(“open res=%d for slaveadr %02x\n”, fd, adr);
    break;
    case ‘v’: ver = 1-ver;
    break;
    case ‘p’: dly = GetNum(&argv[i][2]);
    if (dly>=0) delay(dly);
    break;
    case ‘a’: reg = GetNum(&argv[i][2]);
    break;
    case ‘r’: n = GetNum(&argv[i][2]);
    if (fd>=0) {
    if (n==0) dat = wiringPiI2CRead(fd);
    else if (n==1) dat = wiringPiI2CReadReg8(fd, reg & 0xff);
    else if (n==2) dat = wiringPiI2CReadReg16(fd, reg & 0xff);
    printf(“0x%x %d\n”, dat, dat);
    }
    case ‘w’: dat = GetNum(&argv[i][2]);
    if (fd>=0) {
    err = wiringPiI2CWrite(fd, dat & 0xff);
    if (ver) printf(“writing %02x to slavenr %02x result:%d\n”, dat, adr, err);
    }
    break;
    case ‘1’: dat = GetNum(&argv[i][2]);
    if (fd>=0) {
    err = wiringPiI2CWriteReg8(fd, reg, dat & 0xff);
    if (ver) printf(“writing %02x to slavenr %02x result:%d\n”, dat, adr, err);
    }
    break;
    case ‘2’: dat = GetNum(&argv[i][2]);
    if (fd>=0) {
    err = wiringPiI2CWriteReg16(fd, reg, dat & 0xffff);
    if (ver) printf(“writing %02x to slavenr %02x result:%d\n”, dat, adr, err);
    }
    break;
    case ‘h’: printf(
    ” -h this help (and exit)\n”
    ” -v toggles verbosity (default off)\n”
    ” -dXX select device with i2caddress XX\n”
    ” -pXX wait for XX milliseconds\n”
    ” -aXX set register to XX\n”
    ” -rX read device X:0=byte 1=register byte 2=register word\n”
    ” -1XX write 8bit data XX to device and register\n”
    ” -2XX write 16bit data XX to device and register\n”
    ” -wXX write 8bit data XX to device\n”
    ” XX write 8bit data XX to device\n”
    “\n”
    “e.g.: ./i2c -v -d0x40 0x55 -w1000 0xAA -r0 -w1000 0xff # PCF8574\n”
    ” ./i2c -v -d0x44 -a0 -20×1234\n”
    );
    exit(0);
    break;
    }
    }
    else {
    dat = GetNum(&argv[i][0]);
    if (fd>=0) {
    err = wiringPiI2CWrite(fd, dat & 0xff);
    if (ver) printf(“writing %02x to slavenr %02x result:%d\n”, dat, adr, err);
    }
    }
    }

    return 0;
    }

    • It won’t come out too well in this wordpress comments feedback page – why not put it up on github, or somewhere?

      -Gordon

  15. Hello Gordon,
    Really like your library, but I have a problem I’m trying to solve. I have written a small c program to read the temperature from a DS3231 that I use as the Pi’s RTC. I’ve found that wiringPiI2CSetup fails unless I modprobe -r rtc-ds1307 before running the program, then modprobe -a afterwards to get the RTC back. Not ideal. Can you suggest any solution? Thanks in advance. Code follows:
    /* DS3231temp1.c*/
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #define DS3231ADDR 0x68
    #define ADDRTC 0xd0

    int flag,t1,t2,x,y,fd;
    float tempd;
    int CHRONODOT_TEMP_HI = 0x11;
    int CHRONODOT_TEMP_LO = 0x12;

    int main(void){

    if((fd=wiringPiI2CSetup(DS3231ADDR))<0) {
    printf("error opening i2c channel%d\r\n",fd);}
    else{
    printf("setup ok\r\n");}

    x = wiringPiI2CReadReg8 (fd,CHRONODOT_TEMP_HI) ;
    printf("tempint=%4d\r\n",x);

    t1=x <>3);

    if(t2 & 0x1000)
    t2=t2 + 0xe000;

    tempd=0.03125 * (float) t2;
    tempd= tempd * 9 / 5 + 32;

    printf(“Temp=%5.2f°F\r\n”,tempd);

    }

      • Gordon,
        perror() returns “Device or resource busy.” Seems rtc-ds1307 driver (which drives the ds3231 as well) won’t tolerate another program reading the registers. So I’m stuck unless there’s some solution I can’t identify……….
        Any further thoughts?
        Brian

        • It seems like if the kernel is reading it then you can’t – and that’s fair. But since the kernel has a driver for it, then see if the kernel also has a driver for its temperature sensor – lm-sensors?

          -Gordon

  16. Hello Gordon,

    great library, but I don’t know how to setup a working I2C conversation to my 7 Segment driver SAA1064. Which function should I use? I tried wiringPiI2CWriteReg8 and wiringPiI2CWriteReg16, unfortunately i get always “-1”. wiringPiI2CSetup works return is “3”.

    With this shell command: sudo i2cset -y 1 0x38 0x00 0x17 0x06 0x4F 0x5B 0x7F i
    I get something displayed on the four 7 segment displays.

    C code:
    int main (void)
    { int ok;
    ok = wiringPiI2CSetup(0x38);
    printf(“%d \n”,ok);
    //ok = wiringPiI2CWriteReg16(0x0017, 0x064F, 0x5B00);
    ok = wiringPiI2CWriteReg8(0x00, 0x00, 0x0000);
    printf(“%d \n”,ok);
    }

    Andreas

    • OK. try this:


      int fd ;
      fd = wiringPiI2CSetup(0×38);
      wiringPiI2CWriteReg8 (fd, 0x00, 0x0F) ;
      wiringPiI2CWriteReg8 (fd, 0x00, 0xFF) ;
      wiringPiI2CWriteReg8 (fd, 0x01, 0x00) ;
      wiringPiI2CWriteReg8 (fd, 0x02, 0x00) ;
      wiringPiI2CWriteReg8 (fd, 0x03, 0xFF) ;

      and see if that gives you anything…

      The first argument to writeReg8 is the file descriptor returned in the Setup() call.

      -Gordon

      • Thank you for your fast answer.
        Yes it works 🙂
        OK now I have understood the right syntax

        Code:
        int fd;
        fd = wiringPiI2CSetup(0x38);
        printf(“%d \n”,fd);
        wiringPiI2CWriteReg8 (fd, 0x00, 0x27); // Setting Control Byte
        wiringPiI2CWriteReg8 (fd, 0x01, 0x3F); // Setting Digit 1
        wiringPiI2CWriteReg8 (fd, 0x02, 0x5B); // Setting Digit 2
        wiringPiI2CWriteReg8 (fd, 0x03, 0x4F); // Setting Digit 3
        wiringPiI2CWriteReg8 (fd, 0x04, 0x06); // Setting Digit 4
        printf(“%d \n”,fd);

  17. Hi Gordon, I need your help…

    I am trying to use an arduino I2C slave. I want to send it multiple bytes of data. I am very new to this. I looked into the functions you are calling when I call your functions. I have come across i2c_smbus_write_i2c_block_data(const struct i2c_client *client, u8 command, u8 length, const u8 *values) function which seems to be in i2c-core.c , I found it because I noticed your functions call other functions in this. So if I wish to send multiple bytes of data, will this function work, and also what is variable u8? I am unfamiliar with that, and when I try to use this function my issues are coming when I try to pass it an array… I am very unsure here. Any correspondence is greatly appreciated, thank you!

    Shawn

    • You can just use the normal write() system call with the file handle you opened the I2C device with, ot call wiringPiI2CWrite() to write a single byte down to an open device.

      -Gordon

  18. Hello,
    i’m using archlinux, i can use i2cdetect and i2cset with my MCP23008 to enabled LED.
    I build wiringPi but i receive this: “the wiringpi i2c helper librtaries will not be built.”

    So, when i compile C files with this command: “gcc fichier.c -o exec -lwiringPi”
    i receive this nevertheless i declared #include in C file.

    “undefined reference to ‘wiringPiI2CSetup’
    undefined reference to ‘wiringPiI2CWriteReg8’ ”

    I don’t understand.

    If you can help me please.
    Cordially.

    • Arch doesn’t include the neccessary user-land header files (nor provide an easy way to get it), so wiringPi doesn’t vuild with the I2C libraries included there by default.

      Try this:

      cd
      rm -rf wiringPi
      wget -O- http://unicorn.drogon.net/wiringPi-2.3.tgz | tar xfz -
      cd wiringPi
      ./build

      that will install a beta version of wiringPi v2 which should have everything you need for Arch.

      -Gordon

  19. Hi Gordon,

    Many thanks for the work put into his library – super helpful.

    I’m attempting to get an i2c sensor (Omron d6t thermal imaging 4×4 pixel) running on my rev1 pi.

    I have a possible dumb question:
    When running:
    gpio readall
    what does ‘ALTO’ mean in the mode column?

    Many thanks,

    Julian

    • Each pin has a number of modes it can be in – Input or output are generic digital modes – then there are ALTernative modes – up to 6 alternative modes for each pin – ALT0 through ALT5. For I2C mode the internal plumbing connects the pins to the I2C drivers – this is ALT0 mode for that particular pin.

      If you want to know more, seatch for the Broadcom ARM Peripherals manual.

      -Gordon

      • Hi Gordon,

        Aaah ALT0 not ALTO.
        So say I want to run 2 i2c sensors that have the same device ID what commands should I use to set up 2 alternative pins (with added pullup resisters presumably)? Or could I use the same clock-line and just have one more pin??

        Many thanks,

        Julian

        • Yes, alt zero 🙂
          For 2 sensors – basically you can’t. The Pi does have a 2nd I2C bus, but from what I’ve seen it’s not easy to use concurrently with the first one.

          Some I2C devices have their own sub-addressing system – e.g. taking the base address from 0x20 to 0x21, 0x22, etc. with additional address inputs.

          -Gordon

          • Hey again,

            Many thanks for the speedy response.
            Shame about the device id’s though:(
            I’ve written to the manufacturer (Omron) but they’re not too quick with their reply.

            Cheers,

            Julian

  20. Back again:)

    Not sure if this is your area but the sensor (Omron D6T-44L-06) sends 35 packets which is more than the i2c drivers maximum. Do you know how, or indeed if, this can be altered via wiringpi or elsewhere?

    • I can only find a 4-page datasheet which isn’t that helpful, but you can read as much data as you like – you just use the standard system call read() with the file descriptor, or you can call wiringPiI2CRead() as many time as you like.

      -Gordon

      • Thanks Gordon,
        FYI – The best datasheet I’ve found is this one:
        Usage of the D6T-44L / D6T-8L Thermal sensor
        Put that into google is probably better than me posting the massive file name.

        It’s on digikey site.

        • Hi Gordon,

          I have another question that I hope you don’t mind me posting here…

          Omron tech support finally got back to me regarding the sensors address issue.
          The method they recommend for running more than one sensor is to use IC switching. How would this be possible on the Pi?
          Again, many thanks for all your help so far.

          Best wishes,

          Julian

          • Not sure what “IC switching” is. Power supply switching? If they run at 3.3v and take under 15mA then you might be able to power them directly off the GPIO pins – if you have enough spare pins… Or use an expander chip of some sort…

            -Gordon

  21. Hi Gordon,

    First of all, thanks a lot for the library and support.

    I am using this library for interfacing 3-Axis Acceleration sensor Ic (MMA7660),which is based on I2C communication protocol. Device ID 0x4c, verified with $ i2cdetect -y 1
    Here are some important lines from my code….

    if(wiringPisetup() == -1)
    error msg;
    if( (fd=wiringPiI2CSetup(0x4c)) = 0) // oxo7 : mode register, 0x01 : for active mode
    printf(“Mode set as : Active”);

    while(1)
    {
    x = wiringPiI2CReadReg8(fd, 0x00); // 0x00 : for X-axis value
    y = wiringPiI2CReadReg8(fd, 0x01); // 0x01 : for Y-axis value
    z = wiringPiI2CReadReg8(fd, 0x02); // 0x02 : for Z-axis value

    printf(” x=%d, y=%d, z=%d”, x,y,z);
    }

    But while executing it, it is giving me all the three values same which is nothing but the value of X-axis only, i have verified it but tilting the acceleration sensor in all three directions, it changes only X-axis values, and same value for Y & Z .

    Probably it is reading X-axis register (0x00) only, even when we are sending 0x01 & 0x02 for Y & Z respectively.

    if you have any clue or suggestion regarding this problem, please help me out.

    Thanks in Advance.

    • Some verification in the code,
      Actually it is….

      if(wiringPisetup() == -1)
      error msg;
      if( (fd=wiringPiI2CSetup(0x4c)) = 0) /* 0x07 : mode register, 0x01 : for active mode*/
      printf(“Mode set as : Active”);

      while(1)
      {
      x = wiringPiI2CReadReg8(fd, 0x00); /* 0x00 : for X-axis value*/
      y = wiringPiI2CReadReg8(fd, 0x01); /* 0x01 : for Y-axis value*/
      z = wiringPiI2CReadReg8(fd, 0x02); /* 0x02 : for Z-axis value*/

      printf(” x=%d, y=%d, z=%d”, x,y,z);
      }

  22. Sorry, System is not allowing any HTML tags, and removed some code snippet within “less than” “greater than” symbol….

    Here are some important lines from my code….

    if(wiringPisetup() == -1)
    /*Some error msg;*/
    if( (fd=wiringPiI2CSetup(0x4c)) less than 0 )
    /*some error msg;*/

    if( wiringPiI2CWriteReg8(fd, 0x07, 0x01) greater than or equal to 0) /* 0x07 : mode register, 0x01 : for active mode*/
    printf(“Mode set as : Active”);

    while(1)
    {
    x = wiringPiI2CReadReg8(fd, 0x00); /* 0x00 : for X-axis value*/
    y = wiringPiI2CReadReg8(fd, 0x01); /* 0x01 : for Y-axis value*/
    z = wiringPiI2CReadReg8(fd, 0x02); /* 0x02 : for Z-axis value*/

    printf(” x=%d, y=%d, z=%d”, x,y,z);
    }

    • I’d start by using i2cget to verify that the system is returning the right data – then if it is, we can look at the program to see if there is anything untoward there.

      -Gordon

      • hi Gordon,

        As you said i tried i2cget and i2cset.
        still the same problem.
        i am setting mode register 0x07 with 0x01 using i2cset, but while reading it i am getting something other than 0x01.

        $sudo i2cset -y 1 0x4c 0x07 0x01
        $sudo i2cget -y 1 0x4c 0x07
        0x3b

        and the similar values for x(0x00), y(0x01) & z(0x02) registers as well, only few bits changed like 0x3c, 0x3d.

        i heard somewhere about clock streching problem … is that the reason???

        Kunal.

  23. ref. compiling wiringPiI2C-libraries

    i have on my raspberry pi 2 wiringPi-libraries
    – 1) wiringPi-98bcb20
    – 2) wiringPi-25895a8 the newest version, i think

    in the moment i write a program with your wiringPiI2C-library
    and the L3G4200D

    i included

    i compile my programm with :
    gcc -o l3g4200d-wp-1 l3g4200d-wp-1.c -lwiringPi

    then i have following errors
    /tmp/ccFufjMn.o: In function `main’:
    l3g4200d-wp-1.c:(.text+0x248): undefined reference to `wringPiI2CReadReg16′
    l3g4200d-wp-1.c:(.text+0x268): undefined reference to `wringPiI2CWriteReg16′
    l3g4200d-wp-1.c:(.text+0x288): undefined reference to `wringPiI2CWriteReg16′
    l3g4200d-wp-1.c:(.text+0x2a8): undefined reference to `wringPiI2CWriteReg16′
    /tmp/ccFufjMn.o: In function `setupL3G4200D’:
    l3g4200d-wp-1.c:(.text+0x3ac): undefined reference to `wringPiI2CWriteReg16′
    l3g4200d-wp-1.c:(.text+0x3cc): undefined reference to `wringPiI2CWriteReg16′
    /tmp/ccFufjMn.o:l3g4200d-wp-1.c:(.text+0x3ec): more undefined references to `wringPiI2CWriteReg16′ follow
    collect2: ld returned 1 exit status

    i read the posting from jishnu_oman on 21.february 2013 on your
    side

    you wrote when this happend:
    – sudo apt-get install lib2c-dev
    – remake wiringPi
    – ./build clean; ./build
    all done

    but after a new compile: the same errors are idented
    its possible that the error comes from my 2 libraries ???

    excuse my bad english.
    thanks for help, hints and tricks.
    regards stephan

    • Try the latest version of wiringPi – version 2 was released a few days ago. It has all the I2C stuff built in.

      If you have wiringPi already, then:

      cd ~/wiringPi
      git pull origin
      ./build

      should get it. Check with the gpio -v command – it should give you version 2.xx

      -Gordon

  24. hi gordon,
    thanks for your fast response and your help.
    today i make this
    questions:
    should i uninstall my 2 libraries
    the older, and the newest
    and then new install the latest library. ?
    thank you
    regards stephan

    • hi gordon,
      now my tests:

      in my home-folder (pi) i have this folder
      – wiringPi-25895a8
      – in this folder my program l3g4200d-wp-2.c
      i included
      #include
      #include

      – the tests:
      – 1) gpio -v == Version 2.03
      – 2) i try:
      – 3) gpio load i2c == should be ok
      – 4) git pull orgin
      – not ok == missing git client , i think
      – i have download your library with Plan B
      – 5) ./build ok
      – 6) change on /etc/ld.so.conf
      – new line /usr/local/lib
      ok
      – 7) sudo ldconfig ok
      – 8) – then : gpio -v
      – gpio-version 2.03
      – then : gpio load i2c ok
      – the same with sudo gpio load i2c
      ok
      – 9) compile with:
      gcc -o l3g4200d-wp-2 l3g4200d-wp-2.c -lwiringPi

      – the same errors as yesterday:
      /tmp/cc8I9fFm.o: In function `main’:
      l3g4200d-wp-2.c:(.text+0x1d8): undefined reference to `wringPiI2CWriteReg16′
      l3g4200d-wp-2.c:(.text+0x1f8): undefined reference to `wringPiI2CWriteReg16′
      l3g4200d-wp-2.c:(.text+0x218): undefined reference to `wringPiI2CWriteReg16′
      /tmp/cc8I9fFm.o: In function `setupL3G4200D’:
      l3g4200d-wp-2.c:(.text+0x308): undefined reference to `wringPiI2CWriteReg16′
      l3g4200d-wp-2.c:(.text+0x328): undefined reference to `wringPiI2CWriteReg16′
      /tmp/cc8I9fFm.o:l3g4200d-wp-2.c:(.text+0x348): more undefined references to `wringPiI2CWriteReg16′ follow
      collect2: ld returned 1 exit status

      in the moment i dont know what i should do
      thanks for your help
      regards stephan

      • hi gordon
        hiphiphurra
        after lunch i make a look at
        – on c-using the wiringPiI2C-Library – Raspberry Pi Stack Exchange

        and found this:
        ****************************************
        #include
        #include
        #define dID 0x38
        int fd;

        int main (void)
        {
        if((fd=wiringPiI2CSetup(dID))<0);
        return 1;
        wiringPiI2CWrite(fd, 0x01);
        return 0;
        }
        ****************************************
        compile this with gcc wpi2ctest.c -o wpi2ctest -lwiringPi

        and compile is OK
        now i make a clone of this for my l3g4200d-device
        its compile ok
        thank for your help
        regards stephan

      • Not sure why you were getting the undefined references though, but I guess it’s working now (by your next post?)

        -Gordon

      • hi gordon
        thanks for your answer.
        i’m happy that the program can compile.

        excuse but i have another questions about the
        l3g4200d and the i2c-pins on gpio.

        – 1) i2c-pin-connections:
        i have tested:
        raspi (gpio) l3g4200d
        p1 = 3.3v vIn (2.pin)
        p6 = gnd gnd (1.pin)
        p3 = GPIO2 = sda SDA (5.pin)
        p5 = GPIO3 = scl SCL (4.pin)

        testings:
        -1) sudo modprobe i2c-dev
        – /dev -> i2c-1 i2c-0
        -2) sudo i2cdetect -y 1
        i2c-l3g4200d adress: 0x69

        ? are the pins on gpio + with wiringpi
        correct, or gives some differences
        for the connections (Mapping ???)

        thanks for hints and tricks
        regards stephan

        • wiringPi knows what pins to use for I2C. It bases this on the board revision detection, so normally in wiringPi programs you never need to know if its /dev/i2c-0 or -1. With wiringPi v2, you can even use the gpio command to run the i2cdtect program with the right parameters too: gpio i2cd

          So the physical pins are always the same, the underlying BCM_GPIO pins change between board revs, but wiringPi sorts it out for you.

          (Also use the gpio command to load the i2c kernel drivers: gpio load i2c – no need for sudo)

          -Gordon

          • hi gordon,
            thanks for your fast and good response.
            thank you.
            excuse .)
            i’m a little noob….
            if i connected the physical device to the gpio-port.
            raspi l3g4200d
            p1 = 3.3v vIn (2.pin
            p6 = gnd gnd
            p3 = GPIO2 = sda SDA
            P5 = GPIO3 = scl SCL
            can i do this ?

            second excuse:
            i found the original compiler error
            in my programm i wrote
            “wringPiI2CReadReg16(L3G4200D_Address, 0x29);”
            instead of
            “wiringPiI2CReadReg16(L3G4200D_Address, 0x29);”

            thank you verry much for your great help
            regards stephan

          • That connection ought to be fine. Check that the Pi can see it with the command:

            gpio i2cd

            and make sure the output grid shows the device in position 0x29.

            Ah yes – small typo – I never noticed that myself (bit dyslexic though!)

            -Gordon

  25. hi gordon
    thanks for your answer and hints.
    today i make the first tests with hard-and software
    regards stephan

  26. Hello Gordon,
    I wasted one day to know how to access i2c using SM bus. Thanks for your source it made me understand concepts well :).

    I have 1 question, Can two Raspberry pi’s can communicate each other through i2c ? i.e. one master one slave ?

    • As far as I’m aware, the current Pi driver is for master only, so it’s not possible to use I2C to connect 2 Pi’s together. Use Ethernet – faster, reliable and easy to use.

      -Gordon

  27. Hi,

    I’m trying this with the MPR121 capacitive touch sensor. In order to get the status of all the sensors you need to read registers 0x00 and 0x01. The problem is, no matter what I specify for a register it always reads register 0x00. The same problem happens with i2cget. I hooked up a logic analyzer and I can see the bytes: 0xB4, 0x01, 0xB5, result. the result is always the value of register 0x00 though. One thing I noticed is that the result is followed by a NAK on the rpi and an ACK when the Arduino reads it. The Arduino works fine and returns the correct value.

    • Is it possible it’s a clock-stretching issue with the Pi? (Which AUIU doesn’t cater for this condition correctly)

      -Gordon

  28. Hello,
    did anybody had a luck with ADS1015?
    Is it OK to connect this http://learn.adafruit.com/adafruit-4-channel-adc-breakouts?view=all
    to Pi without any pull down resistors?

    I can detect the 0x48.
    wiringPiI2CReadReg16(fd, 0) returns 0
    wiringPiI2CReadReg16(fd, 1) returns 33669
    wiringPiI2CReadReg16(fd, 2) returns 128
    wiringPiI2CReadReg16(fd, 3) returns 65407
    No changes, just constants.
    What do I do wrong?
    Any hint highly appreciated.
    Thanks,
    Jano

    • Gordon,
      I tried adafruit python code and it works fine.
      I do get different numbers from read functions but it seems like sampling is very slow. I see different numbers after a couple of minutes.
      Thanks,
      Jano

    • Not sure about an I2C library for an ultrasonic sensor but I have some nice code for the HCSR04’s – will publish it soon.

      -Gordon

  29. I am always getting a return of -1 whenever I read or write from any register on the MMA8452Q. I have heard that this accelerometer has problems with i2c because it has a repeat start signal. This is my code. I don’t see where the issue is. The device id is always 0x1d.

    #include
    #include
    #include
    #include
    #include
    using namespace std;

    int main()
    {
    cout << "hello world\n";
    int fd = wiringPiI2CSetup(0x1d);
    //status reg
    int e = wiringPiI2CReadReg8(fd,0x00);
    //data config reg
    int d = wiringPiI2CWriteReg8(fd, 0x0e, 0x00) ;
    cout << fd << " " << e << " " << d << "\n";

  30. I am having a problem with the MMA8452Q 3-axis accelerometer always getting a return of -1 with any read/write command. I have heard it has some problems because of the repeat start command. The device id is always 0x1d. This is my code and output.

    Code:
    #include <#include
    #include
    #include
    #include
    #include
    using namespace std;

    int main()
    {
    cout << "hello world\n";
    int fd = wiringPiI2CSetup(0x1d);
    //status reg
    int e = wiringPiI2CReadReg8(fd,0x00);
    //data config reg
    int d = wiringPiI2CWriteReg8(fd, 0x0e, 0x00) ;
    cout << fd << " " << e << " " << d << "\n";
    return 0;
    }

    output:

    4 -1 -1

    I can't figure what is wrong in this code. You have to access specific registers to get any data.

  31. Gordon,
    I am looking to use your library (or the Python port of it) but I am planning to install a DS3231 RTC on P5 ( i2c-0 on second rev board), I saw comments that there were problems using both i2c busses ( I plan to use the other bus to drive port expanders to control 48 relays), is this possible? Or do I need to find another way to access the RTC outside of your library?
    Thanks
    Ben.

    • I’ve not spent any time using the 2nd I2C port on the Pi.. But have read some conflicting reports that it’s not stable/usable.

      However you can use it in wiringPi – instead of calling

      wiringPiI2CSetup ()

      call:

      wiringPiI2CSetupInterface (“/dev/i2c-0”, 0xID)

      -Gordon

  32. Hello Gordon!

    Thanks for a really easy to handle library!

    Im trying to use the I2C library to read data from a 3D Gyro (MPU6050) and would like to read 14 bytes of data from the device’s FIFO in a burst read operation to the Raspberry Pi.

    The transfer would take place every millisecond, based on a interrupt from the device and even at 400kHz on the bus there is not time for individual transfers of the data bytes. Would that be possible to do with the I2C library, and how would you propose for me to do?

    Best Regards,
    Henrik

  33. Hi Gordon,

    Thanks for the excellent library – I’m using it with a c# wrapper in Mono applications (tho that’s not really relevant to what I’m going to ask!) and it’s make my life a whole lot easier.

    My current pet project is trying to use an i2c broadcast radio tuner (it’s the SI 4735), for which I need to both read and write data in lumps of more than 2 bytes and using registers. I’m wondering what the best way to do this is – should I do an initial register read/write and then a series of registerless generic read/writes to get or set the remaining bytes of the i2c slave response or command, or should I add some more methods to the library i2c class?

    Thanks again for the superb library!
    Regards,
    Mike

  34. Hi Gordon,

    first of all thanks for your lib!
    Similar to a question before I am trying to send two values from the Pi. In my case an Arduino is the slave device getting the information. You mentioned using write (fd, test, 2) to send an array instead of wiringPiI2CWrite. Now the arduino receives two bytes but the second one is always zero while the first value is correct.

    Do you have any idea how to solve this or another easy possibility to send two values with the slave being able to distinguish between them?

    The short part of my code is:

    int data[2]={val1[0],val2[0]};
    if (write ( fd,data,2) != 2) {
    /* ERROR HANDLING: i2c transaction failed */
    printf(“Failed to write to the i2c bus.\n”);
    }

    Regards,Martin.

    • your array is an int – elements of 32-bits wide. Assigning the first 2 values will only set the bottom bytes in eahc 32-bit entity. Try making your data array unsigned char.

      And do compile with the -Wall flag. It might pick that up.

      -Gordon

  35. Hi Gordon,

    I’ve installed the wiringpi libraries but something is wrong.

    I can detect my ads1015 adc using i2cdetect -y 1, and I have results. But they are constant. I have always the same results.

    In order to compare the results, I’ve installed the python libraries from AdaFruit. With those libraries the results are ok, and not constant. But when I call my program using wiringpi, I get always the last result that adafruit outputs.

    Am I doing something wrong ?

    Thanks.

      • This is the setup:

        fileHandle = wiringPiI2CSetup( ADS1015_ADC_ID );

        And this is how I do the sensor reading:
        if ( wiringPiI2CWriteReg16( fileHandle, ADS1015_ADDR_CONFIG, configData ) < 0 )
        {
        perror( "Error Writing Configuration word to I2C Bus" );
        exit ( errno );
        }

        delay(50); /* It needs time for conversion to be complete */

        valueTmp = wiringPiI2CReadReg16 ( fileHandle, ADS1015_ADDR_CONV );

        What happens is that if I run my program 10 times, it gives me always the same value, for instance, 2.86000.
        When I run the adafruit module it gives me other value, for instance, 2.87000.
        When I return to my program, It returns the value 2.87000.

        Thanks

      • Hi,

        I just re installed all my raspian OS and installed the components that I would need to run the Wiring Pi, so all is up do date.

        I didn’t install the python code examples.

        I ran the same exact code, but to my surprise, all is on the same state. I mean, with the return value is always the same.

        There must be something wrong on the way I’m loading the I2C modules.
        I really don’t know what to do next…

  36. Hi Gordon, I have a I2C-reading-problem… The first clockpulse in each byte after the first databyte is too short. (Seen on my logic analyzer) It is 1.7us when running at 100000 I2C. The rest are around 5.0 as they should. So I lose a bit for every byte, rather difficult to use… Do you have any idea for a solution/workaround?
    Hope you have, in any case: thank you!
    Nils

  37. wiringPiNewNode: Pin 100 overlaps with existing definition

    I can’t seem to resolve the problem above. Can I can some help please?

    • I suspect you have 2 peripherals that you’ve used the same pinBase number for – ie. 100. Every peripheral you add into wiringPi needs to have a unique pinBase number. Email your code so I can have a look.

      -Gordon