6 years, 6 months ago.

NRF51 DK I2C not working

Hello all,

I am having problems testing the I2c on the NRF51 DK. It should be really simple, but i have now spent 2 days trying to get it working. Has anyone managed to get I2C working on their DK? I have attached two different i2c sensors and not got a response from my code, and hooked up an oscilloscope and wasn't able to see usable i2c data or clock signals. Anyone know if there is a problem with NRF51 DK and I2C?

The code i am using is a simple I2C scanner.

I2C Scanner

#include "mbed.h" //Required for mbed coding
I2C i2c(p30 , p7 ); 
int main() {
    printf("\nI2C Scanner");
    while(1) {
        int error, address;
        int nDevices;
         nDevices = 0;
          for(address = 1; address < 127; address++ ) 
            error = i2c.write(address); 
            if (error == 1)
              printf("I2C device found at address 0x%X %d \n\r", address, error); //Returns 7-bit addres
          if (nDevices == 0)
            printf("No I2C devices found\n\r");
          wait(2);           // wait 2 seconds for next scan

3 Answers

6 years, 5 months ago.

Please, I have the same issue: the nRF51 is giving us a false acknowledge (even disconnecting the i2c wires that goes to the sda and scl pins), how did you solved? Which kind of modiffications you did to wire.cpp?

Waiting for answers!

Thank you very much.

Hi Cesar,

The code i got working can be found:


Hope that helps,

posted by James Cannan 30 Jun 2016
6 years, 6 months ago.

I'm not sure on using pins p30 and p7. If you are using the Arduino connector, try this...

#define SDA                 D14
#define SCL                 D15

I2C i2c(SDA, SCL);

Also, you need to increment the address by 2 each time. The LSB is the read/write bit in mbed

    for(address = 2; address < 255; address +=2 )

Unless you are using a data buffer, leave in i2c.start(); and i2c.stop();

I have found i2c discrepancies between mbed platforms with how they handle low-level i2c commands.. Try the higher level command:

    char i2cbuff[2];
    // ...inside your loop
    i2cbuff[0] = 0;
    // no i2c.start(); needed
    error = i2c.write(address, i2cbuff, 1, false);
    // no i2c.stop(); needed
    // ...continuing inside your loop

Many thanks for the suggestions. Have you tested this on a nrf51 dk? The SDA and SCL on pins p30 and p7 are shown on the nrf51 pinout diagram, and are already assigned to D14 and D15. I updated the code to include your for loop and added the higher level commands, with i2c.start and stop commented out (also tried un-commenting them with no luck) but now every address seems to get an acknowledgement which is not correct.

posted by James Cannan 09 Jun 2016

I managed to get things working in the end. I completely scrapped trying to use the mbed basic functions. I could not figure out what the issue was. I instead rewrote the wire.cpp file from https://mbed.arm.com/teams/RedBearLab/code/I2C_Demo/ and then i could at least detect a i2c sensor.

posted by James Cannan 09 Jun 2016
6 years, 6 months ago.

Hi, Your use of the i2c write needs modifying, under i2c the last bit i.e. bit zero must be a '1' and read function is reset to '0' This is because the i2c.write(data) is just pure data and not the address.

You are using

 i2c.write(data); //You must use start and stop before and after and also you need to SET bit zero to 1 i.e Address|0x01


 error=i2c.write(address|0x01);// error==1 for ack and error==0 for nack

I have an example here https://developer.mbed.org/users/martinsimpson/code/ic2_test_bus/

Hope this helps.

Thanks for the suggestion. I will give that a go at some point and see it that helps.

posted by James Cannan 13 Jun 2016