nrf9160dk cannot bind sensor

Hello, guys!

    I'm currently just starting to work on the nrf9160dk board. I want to try to explore the communication of nrf9160 with external acceleration sensor. First, I learned the official routine lis2dh; then I want to try to use I2C to communicate nrf9160 and mma845x. Unfortunately, I encountered a lot of difficulties. I carried out the program on the basis of the lis2dh routine, added a new sensor driver, and finally the  device can not be bound.

    The procedure is as follows:

#define DT_DRV_COMPAT fsl_mma845x


const static int32_t read_sensor(const struct device *sensor,
			   enum sensor_channel channel)
{
	struct sensor_value val[3];
	int32_t ret = 0;

	ret = sensor_sample_fetch(sensor);
	if (ret < 0 && ret != -EBADMSG) {
		printf("Sensor sample update error\n");
		goto end;
	}

	ret = sensor_channel_get(sensor, channel, val);
	if (ret < 0) {
		printf("Cannot read sensor channels\n");
		goto end;
	}

	printf("( x y z ) = ( %f  %f  %f )\n", sensor_value_to_double(&val[0]),
					       sensor_value_to_double(&val[1]),
					       sensor_value_to_double(&val[2]));

end:
	return ret;
}


void main(void)
{	

	const struct device *accelerometer = device_get_binding(
						DT_LABEL(DT_INST(0, fsl_mma845x)));
	
	if (accelerometer == NULL) {
		printf("Could not get %s device\n",
				DT_LABEL(DT_INST(0, fsl_mma845x)));
		return;
	}

	while (1) {
		printf("Accelerometer data:\n");
		if (read_sensor(accelerometer, SENSOR_CHAN_ACCEL_XYZ) < 0) {
			printf("Failed to read accelerometer data\n");
		}

		k_sleep(K_MSEC(2000));
	}
}

&i2c2 {
	compatible = "nordic,nrf-twim";
	status = "okay";
	sda-pin = <11>;
	scl-pin = <12>;
    clock-frequency = <I2C_BITRATE_FAST>;
    
    mma845x@1d {
        compatible = "fsl,mma845x";        
        reg = <0x1d>;
        label = "MMA854x";
    };    
};
CONFIG_STDOUT_CONSOLE=y
CONFIG_I2C=y
CONFIG_SENSOR=y
CONFIG_CBPRINTF_FP_SUPPORT=y
CONFIG_LOG=y

    Change sensor driver based on lis2dh,add new sensors as follows:

1.Create a binding in zephyr\dts\bindings\sensor\<compatible string>.yaml
    E.g. copy zephyr\dts\bindings\sensor\adi,adxl362.yaml, change the name and modify it according to your sensor
2. Create the driver in zephyr\drivers\sensor
    E.g. copy zephyr\drivers\sensor\adxl362, change the name and modify it according to your sensor
3. In \zephyr\drivers\sensor\CMakeLists.txt add the following line    

    eg:add_subdirectory_ifdef(CONFIG_MMA845X mma845x)

4. In \zephyr\drivers\sensor\Kconfig add the following line   

    source "drivers/sensor/<sensor directory>/Kconfig"    

    eg:source "drivers/sensor/lis2dh/Kconfig"

5. Create a sample in zephyr\samples\sensor, to test if it works as expected

   I would like to ask what should I do and how can I improve the program?

   Thank you so much for your time and effort! Really appreciate it.

Sincerely,

Jessie.

  • The steps you provided explains how to add the sensor driver to NCS itself.

    In this ticket I go through some other approaches:  Problem of Including custom driver folder in to a project.

    Creating and adding the driver directly to your project using the API zephyr/include/zephyr/drivers/i2c.h may be easier to achieve. Let me know if you want to use this approach or if you want to add it to NCS, and I'll assist.

    Check out this I2C scanner example or the sample \zephyr\tests\drivers\i2c\i2c_api. These are nice places to start if you want to learn how to use the I2C API.

    Best regards,

    Simon

  • Hello, I have studied and studied all the information you gave. I feel that my abilities are limited. Can you give a specific example of a sensor? ? There's an example of a brand new sensor that I'd like to learn to mimic the write driver. Thank you very much. In addition, there is another problem that bothers me. I modified it directly on the official routine program, changed xxx_REG_WAI and XXX_CHIP_ID and found that the binding can be successful, but when I added it to the new sensor folder, an error occurred. . Can you elaborate on why this happens? ?

  • jessie wang said:
    Hello, I have studied and studied all the information you gave. I feel that my abilities are limited. Can you give a specific example of a sensor? ? There's an example of a brand new sensor that I'd like to learn to mimic the write driver. Thank you very much.

    I think I would split this into two steps. In this way you need only to focus on the sensor itself in 1 and get it up and running, and then you can add it to Zephyr (and maybe create a PR)

    1. Add the senor drivers directly to your project

    • First run the I2C scanner example and try to see if you can communicate with the sensor
      • I took a look at the mma8451 datasheet and it it seems like the address is 0x1D (0x1C when addr pin is connected to GND), so it should respond when that is sent
    • Create the file mma845x.c and mma845x.h and make the accessible from main.c by following 2.2.1 Include header and source files to your project
      • Inside the mma845x.c/h files you create functions like writeRegister, getOrientation, setRange, getRange and so on (Like in this C++ MMA8451 API)..
      • In the above functions you use the i2c API (similar to how it's used in the i2c_scanner sample and \zephyr\tests\drivers\i2c\i2c_api)

    2. Add the sensor driver to zephyr/drivers/sensor

    Let me know when you have completed 1, and I can help you with this. You actually don't need to do this, you can just let the sensor be a part of your project.

    jessie wang said:
    I modified it directly on the official routine program, changed xxx_REG_WAI and XXX_CHIP_ID and found that the binding can be successful, but when I added it to the new sensor folder, an error occurred. . Can you elaborate on why this happens? ?

    I'm not sure. However, I would recommend you to get ahold of a logic analyzer, then you can clearly see what is on the line, and it is easier to figure out why stuff doesn't work

    Best regards,

    Simon

Related