Jeedella / Plantenna_2_Node

This repo contains smart sustainable sensor node
4 stars 2 forks source link

NODE: I2C interface with sensors #16

Open joepboumans opened 2 years ago

joepboumans commented 2 years ago

The nodes interact with the sensors using I2C. These sensors are:

First I'm going to implement and test the MS5637.

joepboumans commented 2 years ago

The MS5637 has only five basic commands:

  1. Reset
  2. Read PROM (112 bit of calibration words)
  3. D1 conversion
  4. D2 conversion
  5. Read ADC result (24 bit pressure / temperature)

The communication message begins with the start condition and ends with the stop condition. The MS5637 address is 1110110x where write: x=0, read: x=1.

image

After the ADC read function the device will return the 24 bit result. After the PROM read the device will return the 16 bit result. The MS5637 uses a 4 bit CRC, this will be ignored for now. In the future this can be added for extra protection against errors.

joepboumans commented 2 years ago

image image

To read the data form either D1 (Pressure) or D2 (Temp) the communication works in the following order. The I2C sends the conversion to start. It then waits for 24 SCL cycles for the result and can then read it. Not waiting 24 SCL cycles will mess up the conversion and the result will be wrong. image

joepboumans commented 2 years ago

The SCL can be at 400kHz for the MS5637.

joepboumans commented 2 years ago

I have had some trouble getting the i2c device driver to work. But it seems to work now. This guide was used to enable the i2c. I did not yet test the twis interaction and will also test that. The main take away is that to enable the driver the device tree needs to be overwritten by a .overlay file. This has to have the same name as the board you are using (In our case nrf52dk_nrf52832).
In here we can define the i2c device by:

&i2c1{
    compatible="nordic,nrf-twim";
    status = "okay";
    sda-pin = < 30 >;
    scl-pin = < 31 >;
    clock-frequency = <I2C_BITRATE_STANDARD>;
    twis_device1:MS5367@EC {
        label = "Sensor";
        reg = <0xEC>;
    };
};

The MS5367 is created as a sub-module of the i2c1 device and inherits the functions the i2c module has. These are the i2c_write/read functions. Now the MS5367 needs to be made in the code. To start off we need to bind the device and the sub-module together. For this a label is used that refers to the device in the device tree (DT) . Then a device is made to store it in.

#define MY_TWIM DT_NODELABEL(i2c1)
const struct device *nrfx_twis_dev1;

Where then this can be binded together using:

nrfx_twis_dev1 = device_get_binding(DT_LABEL(MY_TWIM));

And poof the i2c device is made. Now it can be initialized with the correct parameters. In our case these are:

i2c_configure(nrfx_twis_dev1, I2C_SPEED_SET(I2C_SPEED_FAST) | I2C_MODE_MASTER);

And now the i2c device is up and running.