Best way to read from a sensor that doesn't have interrupt pin and requires some time before the measurement is ready

前端 未结 2 368
粉色の甜心
粉色の甜心 2020-12-06 22:42

I\'m trying to interface a pressure sensor (MS5803-14BA) with my board (NUCLEO-STM32L073RZ).

According to the datasheet (page 3), the pressure sensor requires some m

2条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-06 23:08

    First of all thank you for your suggestions. I tried to analyze every single possible solution you proposed.

    The solution proposed by Peter seemed very interesting but I have to say that, after having gone through the datasheet several times, I don't believe that is feasible. My consideration is based on the following facts.

    Using a scope I see that the acknowledge is received right after sending the command for doing conversion. See following image concerning the temperature conversion:

    It seems quite clear to me the acknowledge bit right after the command. After that the SDA line (yellow) goes high, therefore I don't see how it is possible that I can exploit that for detecting when the conversion is ready.

    Concerning the solution when using SPI, yes, the SDO remains low during the conversion, but I cannot use it: I need to stick with I2C. Furthermore, I have other sensors attached to that SPI bus and I agree with what Gabriel Staples says.

    After my consideration I went for the solution proposed by Gabriel Staples (considering that, in order to read pressure value, I also need to read and convert temperature).

    My current solution is based on a state machine with 6 states. In my solution, I distinguish between the wait time for the pressure conversion and the wait time for the temperature conversion with the idea the I could try to see how much the pressure reading degrades if I use a less precise temperature reading.

    Here is my current solution. The following function is called inside the main while:

    void MS5803_update()
    {
      static uint32_t tStart; // us; start time
    
      switch (sensor_state)
      {
        case MS5803_REQUEST_TEMPERATURE:
        {
            MS5803_send_command(MS5803_CMD_ADC_CONV + TEMPERATURE + baro.resolution);
            tStart = HAL_GetTick();
            sensor_state = MS5803_WAIT_RAW_TEMPERATURE;
            break;
        }
    
        case MS5803_WAIT_RAW_TEMPERATURE:
        {
            uint32_t tNow = HAL_GetTick();
            if (tNow - tStart >= conversion_time)
            {
                sensor_state = MS5803_CONVERTING_TEMPERATURE;
            }
            break;
        }
    
        case MS5803_CONVERTING_TEMPERATURE:
        {
            MS5803_send_command(MS5803_CMD_ADC_READ);
            uint8_t raw_value[3]; // Read 24 bit
            MS5803_read_value(raw_value,3);
            temperature_raw = ((uint32_t)raw_value[0] << 16) + ((uint32_t)raw_value[1] << 8) + raw_value[2];
            sensor_state = MS5803_REQUEST_PRESSURE;
            break;
        }
    
        case MS5803_REQUEST_PRESSURE:
        {
            MS5803_send_command(MS5803_CMD_ADC_CONV + PRESSURE + baro.resolution);
            tStart = HAL_GetTick();
            sensor_state = MS5803_WAIT_RAW_PRESSURE;
            break;
        }
    
        case MS5803_WAIT_RAW_PRESSURE:
        {
            uint32_t tNow = HAL_GetTick();
            if (tNow - tStart >= conversion_time)
            {
                sensor_state = MS5803_CONVERTING_PRESSURE;
            }
            break;
        }
    
        case MS5803_CONVERTING_PRESSURE:
        {
            MS5803_send_command(MS5803_CMD_ADC_READ);
            uint8_t raw_value[3]; // Read 24 bit
            MS5803_read_value(raw_value,3);
            pressure_raw = ((uint32_t)raw_value[0] << 16) + ((uint32_t)raw_value[1] << 8) + raw_value[2];
    
            // Now I have both temperature and pressure raw and I can convert them
            MS5803_updateMeasurements();
    
            // Reset the state machine to perform a new measurement
            sensor_state = MS5803_REQUEST_TEMPERATURE;
            break;
        }
      }
    }
    

    I don't pretend that my solution is better. I just post it in order to have an opinion from you guys. Note: I'm still working on it. Therefore I cannot guarantee is bug-free!

    For PeterJ_01: I could agree that this is not strictly a teaching portal, but I believe that everybody around here asks questions to learn something new or to improve theirselves. Therefore, if you believe that the solution using the ack is better, it would be great if you could show us a draft of your idea. For me it would be something new to learn.

    Any further comment is appreciated.

提交回复
热议问题