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

  • ah, it seems I did not.

    I now changed my overlay file to:

    &i2c1 {
    sgp30@58 {
    compatible = "sensirion,sgp30";
    reg = ;
    label = "sensirion_sgp30";
    status = "okay";
    };
    };

    I does give me some red remarks (Only i2c nodes accepted in /soc/peripheral@50000000/i2c@9000/.), but it does now go past the "No sensirion,sgp30 compatible node found in the device tree" it seems.

    I do now however get stuck at the compiler not finding the sgp30.h file.


    In the main.c file, I replaced

    #include <drivers/sensor/sgp40.h>

    with

    #include <drivers/sensor/sgp30.h>

    But when I try to compile the code, I get: 


    c:\Users\Erik\zigbee\test1\sgp30test1\src\main.c:12:10: fatal error: drivers/sensor/sgp30.h: No such file or directory

    I even tired manually copieng the sgp30.h and sgp30.c files to C:\Users\Erik\zigbee\test1\sgp30test1\src\drivers\sensor, but I stil get the same error.


    Maybe I should explain a bit more what I did. I started with the files that where located in C:\Users\Erik\ncs\v1.8.0\zephyr\drivers\sensor\sgp40 and copied them to C:\Users\Erik\ncs\v1.8.0\zephyr\drivers\sensor\sgp30

    I then changed the 4 files in the directory to match the sgp30 datasheet where possible.
    I now have the following files in that dir:

    - CMakeList.txt
    - Kconfig
    - sgp30.h
    - sgp30.c

    I then added the following line to C:\Users\Erik\ncs\v1.8.0\zephyr\drivers\sensor\CMakeLists.txt

    add_subdirectory_ifdef(CONFIG_SGP30 sgp30)

    and the following line to C:\Users\Erik\ncs\v1.8.0\zephyr\drivers\sensor\Kconfig

    source "drivers/sensor/sgp30/Kconfig"

    I then created the sample application for the sgp40/sht40 that is included in the SDK in visual studio code, added the sgp30 to the KConfig (and removed the SGP40)

    I simplified the code to make it as minimal as possible.

    There's probably some step I'm missing in the process, but I just can't figure out what it is. Any ideas?

Reply
  • ah, it seems I did not.

    I now changed my overlay file to:

    &i2c1 {
    sgp30@58 {
    compatible = "sensirion,sgp30";
    reg = ;
    label = "sensirion_sgp30";
    status = "okay";
    };
    };

    I does give me some red remarks (Only i2c nodes accepted in /soc/peripheral@50000000/i2c@9000/.), but it does now go past the "No sensirion,sgp30 compatible node found in the device tree" it seems.

    I do now however get stuck at the compiler not finding the sgp30.h file.


    In the main.c file, I replaced

    #include <drivers/sensor/sgp40.h>

    with

    #include <drivers/sensor/sgp30.h>

    But when I try to compile the code, I get: 


    c:\Users\Erik\zigbee\test1\sgp30test1\src\main.c:12:10: fatal error: drivers/sensor/sgp30.h: No such file or directory

    I even tired manually copieng the sgp30.h and sgp30.c files to C:\Users\Erik\zigbee\test1\sgp30test1\src\drivers\sensor, but I stil get the same error.


    Maybe I should explain a bit more what I did. I started with the files that where located in C:\Users\Erik\ncs\v1.8.0\zephyr\drivers\sensor\sgp40 and copied them to C:\Users\Erik\ncs\v1.8.0\zephyr\drivers\sensor\sgp30

    I then changed the 4 files in the directory to match the sgp30 datasheet where possible.
    I now have the following files in that dir:

    - CMakeList.txt
    - Kconfig
    - sgp30.h
    - sgp30.c

    I then added the following line to C:\Users\Erik\ncs\v1.8.0\zephyr\drivers\sensor\CMakeLists.txt

    add_subdirectory_ifdef(CONFIG_SGP30 sgp30)

    and the following line to C:\Users\Erik\ncs\v1.8.0\zephyr\drivers\sensor\Kconfig

    source "drivers/sensor/sgp30/Kconfig"

    I then created the sample application for the sgp40/sht40 that is included in the SDK in visual studio code, added the sgp30 to the KConfig (and removed the SGP40)

    I simplified the code to make it as minimal as possible.

    There's probably some step I'm missing in the process, but I just can't figure out what it is. Any ideas?

Children
No Data
Related