Reading a Sensirion SGP30 sensor with nRF52840 via I2C/TWI

After working with arduino's and microprocessors like the ESP8266 and ESP32, I recently started toying around with a nRF52840 dev kit.
After going through some tutorials, I wanted to see if I can get a SGP30 air quality sensor to work (https://www.mouser.com/datasheet/2/682/Sensirion_Gas_Sensors_Datasheet_SGP30-2320451.pdf) 

I have visual studio running with the nRF connect integration / SDK. I used the following sketch to scan for I2C devices:

/*
 * Copyright (c) 2018 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
 */

#include <zephyr.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <drivers/i2c.h>
#include <device.h>

#define TEST_BUF_SIZE 128

void main(void)
{
	printk("The I2C scanner started\n");
    const struct device *i2c_dev;
	int error;

    i2c_dev = device_get_binding("I2C_1");
    if (!i2c_dev) {
        printk("Binding failed.");
        return;
    }

	/* Demonstration of runtime configuration */
    i2c_configure(i2c_dev, I2C_SPEED_SET(I2C_SPEED_STANDARD));
    printk("Value of NRF_TWIM2->PSEL.SCL : %d \n",NRF_TWIM1->PSEL.SCL);
	printk("Value of NRF_TWIM2->PSEL.SDA : %d \n",NRF_TWIM1->PSEL.SDA);
	printk("Value of NRF_TWIM2->FREQUENCY: %d \n",NRF_TWIM1->FREQUENCY);
	printk("26738688 -> 100k\n");

    for (uint8_t i = 4; i <= 0x7F; i++) {
		struct i2c_msg msgs[1];
		uint8_t dst = 1;

		msgs[0].buf = &dst;
		msgs[0].len = 1U;
		msgs[0].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
		
		// printk("Testing %2x", i);

		error = i2c_transfer(i2c_dev, &msgs[0], 1, i);
		if (error == 0) {
			printk("0x%2x FOUND\n", i);
		}
		else {
			// printk("error %d \n", error);
		}
		
	}
}

Which worked, the SGP30 was found on address 0x58.

With the nRF connect SDK, a driver is supplied for the SGP40, but unfortunately not for the SGP30. 

I found a github repository from Sensirion where they have some code for Nordic nRF series: https://github.com/Sensirion/embedded-common/tree/master/i2c/sample-implementations/Nordic_nRF5_series , however, I am not sure how I should use it. I also found the NRF40 drivers that are included with the SDK, and thought that I might be able to replace it with the code from their repository, but it doesn't look like the SGP40 driver code at all.

So now I am a bit lost where I should go from here, any ideas?

Parents
  • Hi,

    With the nRF connect SDK, a driver is supplied for the SGP40, but unfortunately not for the SGP30. 

    Are the sensors very different? It should not be that much work to copy and modify the existing driver to work with a similar device. Look at the SGP40 driver implementation in Zephyr and compare the commands/features with the datasheet of the SGP30 sensor and make the necessary changes.

    I found a github repository from Sensirion where they have some code for Nordic nRF series: https://github.com/Sensirion/embedded-common/tree/master/i2c/sample-implementations/Nordic_nRF5_series , however, I am not sure how I should use it.

    It looks like this is using driver APIs from nRF5 SDK and not from nRF Connect SDK. It may be possible to use this driver with nRF Connect SDK, but you will need to rewrite the HAL layer by using the I2C API from Zephyr (or nrfx_twim). How to actually use that driver is a question you need to direct to Sensirion.

    Best regards,
    Jørgen

  • Thanks, I looked into the SGP40 driver files an think I can use them as a base to build driver files for the SGP30, using the SGP30 data sheets. 

    I am however running into a problem with the SGP40 sample. I believe I was able to compile it earlier on without any modifications, but when I now try to compile it, it gets stuck at these lines:

    #if !DT_HAS_COMPAT_STATUS_OKAY(sensirion_sgp40)
    #error "No sensirion,sgp40 compatible node found in the device tree"
    #endif
    I have the SGP40 drivers enabled in kconfig, but am not sure what I should do to add the SGP40 to the device tree.
    I also have tried to add this to the overlay file:
    &i2c1 {
        sgp40@59 {
            compatible = "sensirion,sgp40";
            reg = <0x59>;
            label = "sensirion_sgp40";
        };
    };
    
    Bu to no avail.
    I'm probably overlooking something simple, but I just don't know what it is. I first would like to be able to compile the SGP40 sample before starting on the SGP30
Reply
  • Thanks, I looked into the SGP40 driver files an think I can use them as a base to build driver files for the SGP30, using the SGP30 data sheets. 

    I am however running into a problem with the SGP40 sample. I believe I was able to compile it earlier on without any modifications, but when I now try to compile it, it gets stuck at these lines:

    #if !DT_HAS_COMPAT_STATUS_OKAY(sensirion_sgp40)
    #error "No sensirion,sgp40 compatible node found in the device tree"
    #endif
    I have the SGP40 drivers enabled in kconfig, but am not sure what I should do to add the SGP40 to the device tree.
    I also have tried to add this to the overlay file:
    &i2c1 {
        sgp40@59 {
            compatible = "sensirion,sgp40";
            reg = <0x59>;
            label = "sensirion_sgp40";
        };
    };
    
    Bu to no avail.
    I'm probably overlooking something simple, but I just don't know what it is. I first would like to be able to compile the SGP40 sample before starting on the SGP30
Children
No Data
Related