This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Reading external sensor using I2C on nrf9160dk

Hello,

I want to read external accelerometer on nrf9160dk using I2C. But when I connect SDA and SCL pins of sensor to nrf91, there is no output.

The Code is:

#include <nrf9160.h>
#include <zephyr.h>
#include <misc/printk.h>
#include <i2c.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

#define I2C_ACCEL_READ_ADDR   60

struct device * i2c_accel;
u8_t I2C_BUFFER[35];


void init_accelerometer(){
    i2c_accel = device_get_binding("I2C_2");
    if (!i2c_accel) {
		printk("error\r\n");
	} 
    i2c_configure(i2c_accel, I2C_SPEED_SET(I2C_SPEED_FAST));

}


void main(void)
{
        printk("Start I2C comminication\r\n");
        init_accelerometer();

	while (1) {

                i2c_read(i2c_accel, I2C_BUFFER, 29, I2C_ACCEL_READ_ADDR);

                printk("I2C_BUFFER = %s\n", I2C_BUFFER);
	}
}

When I don't connect sensor to nrf91, then continuously it prints "I2C_BUFFER ="

When I connect the sensor, everything stops and when I again remove the pins it prints "I2C_BUFFER ="

What I am doing wrong? How to read these sensors value?

Thank you

Parents
  • Hi,

    Here is some code that you can test to see if you get a response from the sensor. If there is an ACK for the address, it prints the address it found.

    main.c

    #include <nrf9160.h>
    #include <zephyr.h>
    #include <misc/printk.h>
    #include <i2c.h>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    
    
    #include <gpio.h>
    
    #define I2C_ACCEL_WRITE_ADDR 0x32
    #define I2C_ACCEL_READ_ADDR 0x75
    
    struct device * i2c_accel;
    uint8_t WhoAmI = 0u;
    
    
    static struct device  *led_port;
    
    #ifdef CONFIG_SOC_NRF9160
    #define I2C_DEV "I2C_3"
    #else
    #define I2C_DEV "I2C_1"
    #endif
    
    
    void main(void)
    {
    	struct device *i2c_dev;
    	
    	k_sleep(500);
    
    	printk("Starting i2c scanner...\n");
    
    	i2c_dev = device_get_binding(I2C_DEV);
    	if (!i2c_dev) {
    		printk("I2C: Device driver not found.\n");
    		return;
    	}
    	
    	uint8_t error = 0u;
    	
    	i2c_configure(i2c_dev, I2C_SPEED_SET(I2C_SPEED_STANDARD));
    
    
    	printk("Value of NRF_TWIM3_NS->PSEL.SCL: %ld \n",NRF_TWIM3_NS->PSEL.SCL);
    	printk("Value of NRF_TWIM3_NS->PSEL.SDA: %ld \n",NRF_TWIM3_NS->PSEL.SDA);
    	printk("Value of NRF_TWIM3_NS->FREQUENCY: %ld \n",NRF_TWIM3_NS->FREQUENCY);
    	printk("26738688 -> 100k\n");
    	
    	
    	
    	for (u8_t i = 4; i <= 0x77; i++) {
    		struct i2c_msg msgs[1];
    		u8_t dst = 1;
    
    		/* Send the address to read from */
    		msgs[0].buf = &dst;
    		msgs[0].len = 1U;
    		msgs[0].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
    		
    		error = i2c_transfer(i2c_dev, &msgs[0], 1, i);
    		if (error == 0) {
    			printk("0x%2x FOUND\n", i);
    		}
    		else {
    			//printk("error %d \n", error);
    		}
    		
    		
    	}
    	
    
    	
    	
    }

    nrf9160_pca10090ns.overlay

    &i2c3 {
    	status = "ok";
    	compatible = "nordic,nrf-twim";
    	sda-pin = < 12 >;
    	scl-pin = < 11 >;
        clock-frequency = <I2C_BITRATE_STANDARD>;  
    };
    

    prj.conf

    #CONFIG_SERIAL=y
    #CONFIG_UART_INTERRUPT_DRIVEN=y
    CONFIG_I2C=y
    CONFIG_I2C_NRFX=y
    CONFIG_I2C_3=y
    CONFIG_I2C_3_NRF_TWIM=y
    
    CONFIG_NEWLIB_LIBC=y
    
    
    #CONFIG_LOG=y
    #CONFIG_I2C_LOG_LEVEL_DBG=y
    #CONFIG_LOG_BACKEND_UART=y
    #CONFIG_I2C_INIT_PRIORITY=60

  • I tested the above same code again and now the address is 0x69. But when I try to read at this address there is nothing. And the address is 60 so why it is showing 69. I am not getting this.

  • What accelerometer sensor are you using ?

Reply Children
  • I am using ICM20648. Actually I encountered the problem.

    Atmel SAM is interfaced to ICM20648 by using I2C. Now I just want to read this data on nRF91. It means SAM is master and ICM, nRF91 are slaves. But when I ran the code, nRF91 was acting as Master and it read the address of ICM which is 0x69 and it stopped the communication between SAM and ICM.

    So now the question is how to configure nRF91 as slave and read the sensor data received at SAM which is Master?

  • Impossible with the TWI hardware on NRF chips - these want to be bus master or act as a slave.

    Almost impossible (read: very hard) to do in software.

    By extensively using the I²C clock streching feature (and GPIOs in open drain mode), one could implement I²C in software that can read and track another I²C master's transactions.

    A more sensible solution would use the NRF chip as pure slave and have the SAM transfer the data it just read from the accelerometer back to the NRF chip in another bus transaction (maybe even on a second bus).

  • Yes I want to use nRF91 as pure slave. So how to configure it, that is the question. What are the settings required in prj.conf file? 

    nRF91 will be slave and SAM will be Master. SAM will write data on address 60 and nRF91 will read at that address. So how to configure nRF9160 as slave for I2C? 

Related