No data on registers "D1" and "D2" of the height / pressure sensor MS5637

We are having some problems reading registers D1 (0x40 ~ 0x4A) and D2 (0x50 ~ 0x5A) of the MS5637 measurement specifications. Every time an I2C call arrives in this register, they always return 0. This is strange since we can just read the PROM.

Our setup is as follows: We have a custom PCB that houses a BLE121LR (with an embedded TI microcontroller) that is connected to an MS5637 and some other sensors.

Our procedure so far: 1. Write Reset at 0x1E 2. Read PROM at 0xA0 ~ 0xA5 3. Read D1 and D2 at 0x40 and 0x50 β†’ this always returns 0 in any OSR.

I hope someone here can spot our bug and help us get up and running the MS5637.

I've attached our executable code (BGscript), hope it helps. Before each command, I commented on its functionality:

#=======================================================================================
# MS5637 BaroWITHer
# address:    1110110x (write : x=0, read : x=1) EC ED
# RESET:      0x1E
# PROM READ:  0xA0 to 0xAE
# READ ADC:   0x00
#=======================================================================================

## RESET COMMAND
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\x1E")(MSResetwritten)

## WRITE TO PROM A0
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\xA0")(MSPromwritten)
## READ TO PROM A0
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 2)(i2c_result, data_len, prom(0:2))

## WRITE TO PROM A1
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\xA1")(MSPromwritten)
## READ TO PROM A1
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 2)(i2c_result, data_len, prom(2:2))

## WRITE TO PROM A2
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\xA2")(MSPromwritten)
## READ TO PROM A2
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 2)(i2c_result, data_len, prom(4:2))

## WRITE TO PROM A3
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\xA3")(MSPromwritten)
## READ TO PROM A3
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 2)(i2c_result, data_len, prom(6:2))

## WRITE TO PROM A4
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\xA4")(MSPromwritten)
## READ TO PROM A4
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 2)(i2c_result, data_len, prom(8:2))

## WRITE TO PROM A5
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\xA5")(MSPromwritten)
## READ TO PROM A5
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 2)(i2c_result, data_len, prom(10:2))

## WRITE THE PROM VALUES TO BLE SERVICE prom_handle
#  call attributes_write(handle, offset, value_len, value_data)(result)
call attributes_write(prom_handle, 0, 12, prom(0:12))

#-----------------------------
# D1 & D2
#-----------------------------
## READ D1 WITH OSR=256
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\x40")(MSD1D2written)
## READ D1
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 3)(i2c_result, data_len, dvalues(0:3))

## READ D2 WITH OSR=256
#call hardware_i2c_write(address, stop, data_len, data_data)(written)
call hardware_i2c_write($EC, 1, 1, "\x50")(MSD1D2written)
## READ D2
#call hardware_i2c_read(address, stop, length)(result, data_len, data_data)
call hardware_i2c_read($ED, 1, 3)(i2c_result, data_len, dvalues(3:3))

## WRITE THE D1 & D2 VALUES TO BLE SERVICE d2_handle
#  call attributes_write(handle, offset, value_len, value_data)(result)
call attributes_write(d_handle, 0, 6, dvalues(0:6))

      

+3


source to share


3 answers


After much experimentation, I am answering my own question in the hope that it might help others.

Following are the steps to read D1 and D2 values ​​from MS5637 via I2C:



  • Write to register D (for D1 it is 0x40 (HEX))
  • Write to register ADC (0x00)
  • Read ADC (ADC will return value D1)
  • If you are working with bluetooth like in my case: write a value for bluetooth service. in BG script this is done with: "call attributes_write"
+2


source


so you need to be careful when using BGScript read / write commands (FYI: I have an old example on how to do this here: http://www.sureshjoshi.com/embedded/ble112-how-to-use-i2c/ )

How to read:

If you want to read from a register, you need to call hardware_i2c_write using the 7-bit device address shifted from the left and then write the register address you are interested in to the device without setting the stop sign (0).

The slave device will put data into I2C lines, to receive it, call hardware_i2c_read with the same device address, set the stop flag to 1 (so the device knows what you did with it) and read 1 byte of data (which will contain information about the register bits ).

And write:

The first byte is the register you want to write and the second is the data you want to write. Please make sure you avoid the second byte of data with "\ x"



The above assumes you have a device that uses an Address -> Register -> Value structure .... Look at your datasheet ( http://www.meas-spec.com/downloads/MS5637-02BA03.pdf ) it looks like this is address -> Value. It's strange.

It is important to remember that the "address" part of the read / write commands is always the same! Internally LSB becomes 1 or 0 depending on the command itself.

const MS5637_I2C_ADDRESS = $88

## RESET COMMAND
call hardware_i2c_write(MS5637_I2C_ADDRESS, 1, 1, "\x1E")(MSResetwritten)

      

Also, for your D1 / D2 puzzle, try setting the stop bit on initial write to 0 so that your device knows it is still waiting for commands (to be honest, although I2C is a spec, each device has its own fancy implementations) :

## READ D1
call hardware_i2c_write(MS5637_I2C_ADDRESS, 0, 1, "\x40")(MSD1D2written)
call hardware_i2c_read(MS5637_I2C_ADDRESS, 1, 3)(i2c_result, data_len, dvalues(0:3))

      

+1


source


Another thing you need to do is DELAY a little between writing to 0x40 and 0x00. If you are not late and the 0x40 command has not completed yet, you will get a 0 back or an invalid value. The corresponding delays are as follows:

> switch (cmd & 0x0f) {
>     case MS5637_CMD_ADC_256 : wait_us(900); break;
>     case MS5637_CMD_ADC_512 : wait_ms(3); break;
>     case MS5637_CMD_ADC_1024: wait_ms(4); break;
>     case MS5637_CMD_ADC_2048: wait_ms(6); break;
>     case MS5637_CMD_ADC_4096: wait_ms(10); break; }

      

0


source







All Articles