You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@mynewt.apache.org by Kevin Townsend <ke...@adafruit.com.INVALID> on 2018/07/02 16:24:15 UTC
Re: Sensor API Timing Constraints
To try to frame this in a concrete example, I've pushed out a PR with
the initial TSL2591 driver. It would be worthwhile discussing there how
to handle minimum delays between valid sensor reads:
https://github.com/apache/mynewt-core/pull/1237
On 30/06/18 19:12, Kevin Townsend wrote:
> Hi Amr,
>
> Thanks for the relevant response and pointers. I'll dig deeper into
> the suggested functions, and the BME280 is a really useful sensor so
> any improvements there are useful!
>
> The solution you're proposing is definately valid, but puts all of the
> timing constraint considerations solely on the shoulders of the
> developper and at the application level. That's not unfair (you should
> fully understand your HW!), but I can't help but think that there will
> be situations where the timing can change dynamically and that a small
> addition to the sensor API would be helpful to expose 'minimum sample
> time' as a value. This would be useful in situations where you are
> implementing auto-ranging like with a light sensor or accelerometer,
> where you need to dynamically toggle the range up or down to get a
> valid sample, but the end user may not be aware of these changes.
>
> This is what Android does at a low level with it's own sensor API,
> just as an example:
> https://developer.android.com/reference/android/hardware/Sensor.html#getMinDelay()
>
> There may be some other meta-data in the Android API that is worth
> considering adding, but I think exposing min delay at the sensor
> driver level across all devices may be useful and allows for dynamic
> changes to timing constraints without the user having to be aware of
> all the conditions behind that?
>
> Kevin
>
>
> On 30/06/18 14:43, Amr Bekhit wrote:
>> You could also have a look at the Sensor Listener API and the
>> sensor_set_poll_rate_ms function - if all you need is to read the
>> sensor at a specified interval, that API could be all that you need.
>> On Sat, 30 Jun 2018 at 15:36, Amr Bekhit <am...@gmail.com> wrote:
>>> It just so happens that I've recently completed the driver for the
>>> Bosch BME680 environmental sensor as well as a separate module for the
>>> Bosch BSEC sensor fusion library. I've yet to submit the patches so I
>>> don't know if the method I chose would be accepted but I'd like to
>>> share my own thoughts to the discussion. First let me give a brief
>>> background on the sensor and the BSEC library.
>>>
>>> The BME680 contains sensors for temperature, humidity, pressure and
>>> gas. To take a reading including the gas sensor, you first trigger a
>>> reading (which involves the sensor measuring the first three
>>> parameters and then turning on the gas sensor heater for a period of
>>> time), after which you wait a specified amount of time (approximately
>>> 200ms) and then read the results. The BSEC library requires that the
>>> sensor is read at precise intervals (it contains profiles for 3s and
>>> 300s periods) and the readings are combined together to perform
>>> compensation, background calibration and air quality measurement.
>>> Bosch states that sensor is not really meant to be used standalone but
>>> in conjunction with the BSEC library.
>>>
>>> I decided to have the sensor driver layer only perform the
>>> trigger-wait-read process (so my sensor_read function triggers a
>>> reading, calls os_time_delay to wait, and then reads and returns the
>>> result). Regarding the BSEC library, because this is a bit more higher
>>> level, I packaged that into a separate package that spawns its own
>>> thread that takes care of the timing requirements for reading and
>>> provides another API for reading the processed results. So in summary,
>>> the BSEC library uses the mynewt sensor API to access the BME680, but
>>> my application code uses a separate custom API to access the processed
>>> data. I did it this way, because I didn't feel that the sensor API was
>>> meant to be that high level that it would spawn its own background
>>> threads and so put that in a separate package.
>>>
>>> So in your case, I would have simply implemented the sensor read as
>>> part of the sensor API, but created a separate package that then is
>>> responsible for regularly reading from the sensor and providing a
>>> "always ready" result to the application.
>>>
>>> I guess the "right way" depends on how high level the sensor API is
>>> intended to be - I've taken the assumption that the API aims to cover
>>> simply taking a single measurement from the sensor, rather than
>>> providing a fully processed and always-up-to-date result.
>>>
>>> On Sat, 30 Jun 2018 at 00:02, Kevin Townsend
>>> <ke...@adafruit.com.invalid> wrote:
>>>> I'm working on some sensor drivers for Mynewt 1.4, and have run
>>>> into an
>>>> issue that I'm not sure has a single perfect answer, but should
>>>> perhaps
>>>> be addressed or further discussed.
>>>>
>>>> Most sensors have specific timing constraints, and in certain
>>>> instances
>>>> these can change dynamically. The TSL2561 light sensor, for
>>>> example, can
>>>> have it's integration time set from 13ms to 402ms, depending on the
>>>> level of light sensitivity required. The TSL2591 driver I'm writing
>>>> (since the TSL2561 is EOL) has a variable integration time from
>>>> 100..600ms.
>>>>
>>>> The 'problem' is that there is no concept of minimum time between
>>>> sample
>>>> reads in the sensor API at present (to my knowledge, feel free to
>>>> correct me!), and I'm not sure the best way to insert this delay
>>>> between
>>>> valid reads so that the data we get back can be considered reliable or
>>>> fresh.
>>>>
>>>> If a sensor has a 300ms delay between valid samples, for example,
>>>> we can
>>>> still request data every 10ms but the response is undetermined in the
>>>> sense that each sensor will handle this differently. In the case of
>>>> the
>>>> TSL2561 and TSL2591 the first sample requested will likely be invalid
>>>> since a single valid integration cycle hasn't finished, and then it
>>>> will
>>>> buffer and continue to return values until the NEXT valid sample is
>>>> available. This is visible in the following sequence where the
>>>> first IR
>>>> reading is completely out of range, and some subsequent values are
>>>> actually cached entries that might not reflect current light levels
>>>> since they happen before the next integration time ellapses:
>>>>
>>>> 011023 compat> tsl2591 r 10
>>>> 011799 Full: 30
>>>> 011799 IR: 61309
>>>> 011799 Full: 30
>>>> 011800 IR: 13
>>>> 011801 Full: 30
>>>> 011801 IR: 13
>>>> 011801 Full: 30
>>>> 011801 IR: 13
>>>> 011802 Full: 30
>>>> 011802 IR: 13
>>>> 011802 Full: 30
>>>> 011803 IR: 13
>>>> 011803 Full: 30
>>>> 011803 IR: 13
>>>> 011804 Full: 30
>>>> 011804 IR: 13
>>>> 011804 Full: 30
>>>> 011804 IR: 13
>>>> 011805 Full: 30
>>>> 011805 IR: 13
>>>>
>>>> I'm not sure what the best way to handle this is, though.
>>>>
>>>> Some options are:
>>>>
>>>> * Add a blocking delay in the read task to take into account the
>>>> current minimum delay between valid samples (at the risk of
>>>> causing
>>>> problems on the I2C bus if other devices perform transactions in
>>>> between)
>>>> * Add a concept of 'minimum time' between sample reads at the
>>>> sensor
>>>> API level and enforce this at a higher level, with one of the
>>>> following consequences for read requests that occur before this
>>>> delay: (*Keep in mind that this min value can change dynamically
>>>> based on sensor config or auto-ranging!)
>>>> o Return an appropriate error value
>>>> o Return the previous cached value with the sample still
>>>> marked as
>>>> valid
>>>> o Return the previous cached value with the sample marked as
>>>> invalid
>>>> o Other?
>>>>
>>>> There are other solutions, but I was hoping to get some feedback on
>>>> this
>>>> to hear what other people think of the issue of the current disparity
>>>> between the sensor API and real-world timing constraints of the
>>>> sensors
>>>> themselves. An argument could be made that the end user should know
>>>> and
>>>> work with the constraints of their HW, but it seems like this could
>>>> also
>>>> be handled with some small API additions as well?
>>>>
>