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

  • Hello,

    I am trying to configure I2C_3 as slave on nrf9160. But I couldn't found any driver for that. There is i2c_nrfx_twim.c for master. But there is no such driver for slave. In i2c.h and nrf9160.h files there are definitions and registers for slave. But how to use them. I am not understanding how to do configuration. Please guide me for this.

    Thanks

  • Jagruti said:
    but it shows error.

    Try using UARTE3_SPIM3_SPIS3_TWIM3_TWIS3_IRQn instead.


    Jagruti said:
    Is it necessary to declare the interrupt vector for the TWIS?

     Yes, try to use the same approach as in the link.

  • Thank you so much. Your solution is working.

    But there is other problem. I receive some data then it shows "*** buffer overflow detected ***: terminated". When I run same program on nRF52840 with NRFX TWIS drivers there is no problem.

    How can I avoid RX buffer overflow?

    Output:

    ***** Booting Zephyr OS build v1.14.99-ncs3-snapshot2-2647-gd6e67554cfeb *****
    Starting TWIS program!
    Data = ,,,,,,,0,
    Data = ,,,,,,,0,
    Data = ,,,,,,,0,
    Data = ,,,,,,,0,
    *** buffer overflow detected ***: terminated
    exit

  • My crystal ball says: Don't use msg buffer on the stack with fire-and-forget (read event based) TWIS functions.

  • I did not understand what you are trying to say. Can you please explain. I am still getting the same error. 

  • If you are getting NRFX_TWIS_EVT_READ_REQ event, you need to call nrfx_twis_tx_prepare(). And try to change

    nrfx_twis_rx_prepare(&m_twis, I2C_BUFFER, size); 

    to

    nrfx_twis_rx_prepare(&m_twis, I2C_BUFFER, sizeof(I2C_BUFFER)); 

Reply Children
No Data
Related