I2C Communication Issue with SEN5X Sensor on nRF9160 DK -EI0

I'm experiencing an issue with I2C communication between the SEN5X sensor and multiple nRF9160 DK boards. The problem manifests as an  crc error during I2C read operations, specifically a -EIO error, indicating an Input/Output error. This issue occurs on some nRF9160 DK boards but not all, which suggests it might be a hardware or configuration issue.

The output is like this.

*** Booting nRF Connect SDK v3.5.99-ncs1-1 ***
Welcome to IOTPM running on nrf9160dk_nrf9160
Start the Sen55
SEN5X: write: 0xd304
Get the sensor information
SEN5X: write: 0xd014
SEN5X: Error i2c read
crc error: byte 0: found: 0x05, expected 0xc2
crc error: byte 2: found: 0x63, expected 0x7b
crc error: byte 4: found: 0x00, expected 0x02
crc error: byte 6: found: 0x41, expected 0x81
crc error: byte 8: found: 0x80, expected 0x81
crc error: byte 10: found: 0x00, expected 0xaa
crc error: byte 12: found: 0x00, expected 0x49
crc error: byte 14: found: 0x3f, expected 0xfb
crc error: byte 16: found: 0x80, expected 0x81
crc error: byte 18: found: 0x00, expected 0xaa
crc error: byte 20: found: 0x00, expected 0x49
crc error: byte 22: found: 0x3f, expected 0xfb
crc error: byte 24: found: 0x80, expected 0x81
crc error: byte 26: found: 0x00, expected 0xaa
crc error: byte 28: found: 0x00, expected 0x49
crc error: byte 30: found: 0x3f, expected 0xfb
SEN5X: write: 0xd033
SEN5X: Error i2c read
crc error: byte 0: found: 0x05, expected 0xc2
crc error: byte 2: found: 0x63, expected 0x7b
crc error: byte 4: found: 0x00, expected 0x02
crc error: byte 6: found: 0x41, expected 0x81
crc error: byte 8: found: 0x80, expected 0x81
crc error: byte 10: found: 0x00, expected 0xaa
crc error: byte 12: found: 0x00, expected 0x49
crc error: byte 14: found: 0x3f, expected 0xfb
crc error: byte 16: found: 0x80, expected 0x81
crc error: byte 18: found: 0x00, expected 0xaa
crc error: byte 20: found: 0x00, expected 0x49
crc error: byte 22: found: 0x3f, expected 0xfb
crc error: byte 24: found: 0x80, expected 0x81
crc error: byte 26: found: 0x00, expected 0xaa
crc error: byte 28: found: 0x00, expected 0x49
crc error: byte 30: found: 0x3f, expected 0xfb
SEN5X: Device name: 8
SEN5X: Serial number: 8
Connect to the LTE


I have an overlay with the following 

&uart0 {
  status = "okay";
};

&i2c2 {
	status = "ok";
	clock-frequency = <100000>;
	compatible = "nordic,nrf-twim";
	pinctrl-0 = <&i2c2_default>;
	pinctrl-1 = <&i2c2_sleep>;
	sen55: sen55@69{
		// compatible = "nordic,nrf-twim";
		compatible = "i2c-device";
		reg = <0x69>;
		label = "sensirion i2c sen55";
	};
};

&i2c2_default {
	group1 {
		psels = <NRF_PSEL(TWIM_SDA, 0, 30)>, <NRF_PSEL(TWIM_SCL, 0, 31)>;
		bias-pull-up;
	};
};

The errer is coming from the readmany() function below.

#include <zephyr/drivers/i2c.h>
#include <sen5x/sen5x.h>

const struct device * sen5x_dev;

bool sen5x_init(const struct device * dev){
	sen5x_dev=dev;
	if(!device_is_ready(sen5x_dev)){ printk("SEN5X: I2C device not ready\n"); return false;}
	uint32_t i2c_cfg = I2C_SPEED_SET(I2C_SPEED_STANDARD) | I2C_MODE_CONTROLLER;
	int32_t ret=i2c_configure(sen5x_dev, i2c_cfg);
	if(ret){printk("SEN5X: Error configuring I2C\n");return false;}
	return true;
}

void sen5x_write_short(uint16_t command){
	uint8_t data[2];
	data[0]=(command&0xFF00)>>8;
	data[1]=(command&0x00FF)>>0;
	printk("SEN5X: write: 0x%02x%02x\n",data[0],data[1]);
	i2c_write(sen5x_dev,data,2,PM_I2C_ADDRESS);
}

void sen5x_write(uint8_t * data, uint8_t len){
	int32_t ret=i2c_write(sen5x_dev, data, len, PM_I2C_ADDRESS);	
	if(ret){printk("SEN5X: Error i2c write\n");}
}

void sen5x_read(uint8_t * data, uint8_t len){
	int32_t ret=i2c_read(sen5x_dev, data, len, PM_I2C_ADDRESS);
	if(ret){printk("SEN5X: Error i2c read\n");}
}

void sen5x_read_many(uint8_t * many, uint8_t len){
	uint8_t data[100];
	uint8_t mlen=len+(len/2);
	sen5x_read((uint8_t*)data,mlen);
	//printk("SEN5X: many (%i)",mlen);
	//for(uint32_t i=0;i<mlen;i++){printk("%02x",(uint32_t)data[i]);}
	//printk("\n");
	for(uint32_t i=0;i<len/2;i++){
		many[2*i]  =data[3*i];
		many[2*i+1]=data[3*i+1];
		if(data[3*i+2]!=sen5x_crc(&many[2*i],2)){printk("crc error: byte %i: found: 0x%02x, expected 0x%02x\n",(2*i),data[3*i+2],sen5x_crc(&many[2*i],2));}
	}
}

uint8_t sen5x_crc(const uint8_t * data, uint8_t len){
  uint8_t crc = 0xFF;
  for (uint32_t current_byte = 0; current_byte < len; ++current_byte) {
      crc ^= (data[current_byte]);
      for (uint8_t crc_bit = 8; crc_bit > 0; --crc_bit) {
          if(crc & 0x80)
						crc = (crc << 1) ^ 0x31;
          else         
						crc = (crc << 1);
      }
  }
  return crc;
}

void sen5x_reset(){
	sen5x_write_short(0xD304);
	k_msleep(100);
}

void sen5x_get_serial(char * serial, uint8_t len){
	sen5x_write_short(0xD033);
	for(uint32_t i=0;i<len;i++){ serial[i]=0; }
	k_msleep(500);
	sen5x_read_many(serial,len);
}

void sen5x_get_name(char * name, uint8_t len){
	sen5x_write_short(0xD014);
	for(uint32_t i=0;i<len;i++){ name[i]=0; }
	k_msleep(500);
	sen5x_read_many(name,len);
}

void sen5x_get_version(struct sen5x_version * pmv){
	sen5x_write_short(0xD100);
	k_msleep(500);
	sen5x_read_many((uint8_t*)pmv,8);	
}

void sen5x_start(){
	sen5x_write_short(0x0021);
	k_msleep(500);
}

void sen5x_stop(){
	sen5x_write_short(0x0104);
	k_msleep(50);
}

void sen5x_get_measurement(struct sen5x_measurement * pmm){
	sen5x_write_short(0x03C4);
	k_msleep(20);
	uint8_t data[16];
	sen5x_read_many(&data[0],16);
	pmm->mass_concentration_pm1p0=data[0]<<8|data[1];
	pmm->mass_concentration_pm2p5=data[2]<<8|data[3];
	pmm->mass_concentration_pm4p0=data[4]<<8|data[5];
	pmm->mass_concentration_pm10p0=data[6]<<8|data[7];
	pmm->ambient_humidity=data[8]<<8|data[9];
	pmm->ambient_temperature=data[10]<<8|data[11];
	pmm->voc_index=data[12]<<8|data[13];
	pmm->nox_index=data[14]<<8|data[15];
}

void sen5x_print_measurement(struct sen5x_measurement * pmm){
	printk("Mass concentration pm1p0: %.2f ug/m3\n", (pmm->mass_concentration_pm1p0 / 10.0f));
	printk("Mass concentration pm2p5: %.2f ug/m3\n", (pmm->mass_concentration_pm2p5 / 10.0f));
	printk("Mass concentration pm4p0: %.2f ug/m3\n", (pmm->mass_concentration_pm4p0 / 10.0f));
	printk("Mass concentration pm10p0: %.2f ug/m3\n", (pmm->mass_concentration_pm10p0 / 10.0f));
	printk("Ambient humidity: %.2f %%RH\n", (pmm->ambient_humidity / 100.0f));
	printk("Ambient temperature: %.3f C\n", (pmm->ambient_temperature / 200.0f));
	printk("Voc index: %.2f\n", (pmm->voc_index / 10.0f));
	printk("Nox index: %.2f\n", (pmm->nox_index / 10.0f));
}

void sen5x_get_info(struct sen5x_info * info){
	sen5x_get_name(info->name,32);
	sen5x_get_serial(info->serial,32);
}

void sen5x_print_info(struct sen5x_info * info){
	printk("SEN5X: Device name: %s\n", info->name);
	printk("SEN5X: Serial number: %s\n", info->serial);	
}

void sen5x_print_details(){
	char name[32];
	sen5x_get_name(name,32);
	printk("SEN5X: Device name: %s\n",name);

	char serial[32];
	sen5x_get_serial(serial,sizeof(serial));
	printk("SEN5X: Serial number: %s\n", serial);

	struct sen5x_version pmv;
	sen5x_get_version(&pmv);
	printk("SEN5X: FW: %u.%u.%u\n", pmv.firmware_major,pmv.firmware_minor, pmv.firmware_debug);
	printk("SEN5X: HW: %u.%u\n", pmv.hardware_major,pmv.hardware_minor);
	printk("SEN5X: PR: %u.%u\n", pmv.protocol_major,pmv.protocol_minor);
}

Parents
  • Hello, 

    The sensor sen5x and its libraries/software is not know to Nordic Semiconductor. You will have to reach out to the author of the library.

    In order for us to provide any help with this you will need to provide some more debug information from your board. Have you ensured that the I2C is configured correctly and that there is any activity on the lines i.e. using logic analyzer or similar?

    Kind regards,
    Øyvind

Reply
  • Hello, 

    The sensor sen5x and its libraries/software is not know to Nordic Semiconductor. You will have to reach out to the author of the library.

    In order for us to provide any help with this you will need to provide some more debug information from your board. Have you ensured that the I2C is configured correctly and that there is any activity on the lines i.e. using logic analyzer or similar?

    Kind regards,
    Øyvind

Children
Related