2021-04-19 06:37:37

by Dmitry Osipenko

[permalink] [raw]
Subject: BUG: iio: mpu3050: Wrong temperature scale

Hello,

Svyatoslav and me found that the MPU3050 IIO driver reports temperature
that is x10 larger than it should be on Asus Transformer TF201 and Acer
A500 tablet devices running mainline kernel. The driver uses
(x+23000)/280 formula for the conversion of raw temperature value, which
gives 82C for x=0, thus apparently formula is wrong because x=50000
should give us ~25C.

I tried to search for the datasheet with the formula, but couldn't find it.

Linus, will you be able to check whether the formula used by the driver
is correct? Thanks in advance.


2021-04-19 11:26:09

by Linus Walleij

[permalink] [raw]
Subject: Re: BUG: iio: mpu3050: Wrong temperature scale

On Mon, Apr 19, 2021 at 8:06 AM Dmitry Osipenko <[email protected]> wrote:

> The driver uses
> (x+23000)/280 formula for the conversion of raw temperature value, which
> gives 82C for x=0, thus apparently formula is wrong because x=50000
> should give us ~25C.
>
> I tried to search for the datasheet with the formula, but couldn't find it.

There is no public datasheet. I have never seen a non-public datasheet
either.

As the initial submission of the driver says:

"This driver is based on information from the rough input driver
in drivers/input/misc/mpu3050.c and the scratch misc driver
posted by Nathan Royer in 2011. Some years have passed but this
is finally a fully-fledged driver for this gyroscope. It was
developed and tested on the Qualcomm APQ8060 Dragonboard."

Nathans submission:
https://lore.kernel.org/lkml/[email protected]/
(you find the threads at the bottom)

This submission came from inside Invensense so it is the closest
authoritative source we have.

> Linus, will you be able to check whether the formula used by the driver
> is correct? Thanks in advance.

Sadly the code is the documentation when it comes to Invensense stuff,
I am CC:ing Nathans Invensense address in the vain hope he is still
working there and could help, also CC to Jean-Baptiste who was
there last year and maybe can help out.

I don't anymore remember exactly how I found this equation,
but it wasn't from any datasheet. I vaguely remember browsing
through some Android userspace sensor code.

What I tend to do is dig around in old mobile
phone Android trees, and there you sometimes find this information
in different GPL code drops. I bet I got it from browsing some of
those.

Here is an example (Tegra):
https://android.googlesource.com/kernel/tegra/+/dba2740d025c8e7e7e3c61d84a4f964d2c1c0ac9/drivers/misc/inv_mpu

Worst case what one *can* do is to calibrate the scale, like put
the device in a controlled environment of some two reasonably
far apart temperatures and measure, assuming it is at least
linear. Some professionals use controlled environment
chambers for this. But I hope there is a better way.

Yours,
Linus Walleij

2021-04-20 21:28:09

by Dmitry Osipenko

[permalink] [raw]
Subject: Re: BUG: iio: mpu3050: Wrong temperature scale

19.04.2021 13:07, Linus Walleij пишет:
> On Mon, Apr 19, 2021 at 8:06 AM Dmitry Osipenko <[email protected]> wrote:
>
>> The driver uses
>> (x+23000)/280 formula for the conversion of raw temperature value, which
>> gives 82C for x=0, thus apparently formula is wrong because x=50000
>> should give us ~25C.
>>
>> I tried to search for the datasheet with the formula, but couldn't find it.
>
> There is no public datasheet. I have never seen a non-public datasheet
> either.
>
> As the initial submission of the driver says:
>
> "This driver is based on information from the rough input driver
> in drivers/input/misc/mpu3050.c and the scratch misc driver
> posted by Nathan Royer in 2011. Some years have passed but this
> is finally a fully-fledged driver for this gyroscope. It was
> developed and tested on the Qualcomm APQ8060 Dragonboard."
>
> Nathans submission:
> https://lore.kernel.org/lkml/[email protected]/
> (you find the threads at the bottom)
>
> This submission came from inside Invensense so it is the closest
> authoritative source we have.
>
>> Linus, will you be able to check whether the formula used by the driver
>> is correct? Thanks in advance.
>
> Sadly the code is the documentation when it comes to Invensense stuff,
> I am CC:ing Nathans Invensense address in the vain hope he is still
> working there and could help, also CC to Jean-Baptiste who was
> there last year and maybe can help out.
>
> I don't anymore remember exactly how I found this equation,
> but it wasn't from any datasheet. I vaguely remember browsing
> through some Android userspace sensor code.
>
> What I tend to do is dig around in old mobile
> phone Android trees, and there you sometimes find this information
> in different GPL code drops. I bet I got it from browsing some of
> those.
>
> Here is an example (Tegra):
> https://android.googlesource.com/kernel/tegra/+/dba2740d025c8e7e7e3c61d84a4f964d2c1c0ac9/drivers/misc/inv_mpu
>
> Worst case what one *can* do is to calibrate the scale, like put
> the device in a controlled environment of some two reasonably
> far apart temperatures and measure, assuming it is at least
> linear. Some professionals use controlled environment
> chambers for this. But I hope there is a better way.

Linus, thank you very much for the answer! I found a non-kernel example
which uses a similar equation [1], but in a different form. The main
difference is that the Arduino code interprets a raw temperature value
as a signed integer, while upstream assumes it's unsigned.

[1]
https://github.com/blaisejarrett/Arduino-Lib.MPU3050/blob/master/MPU3050lib.cpp#L111


Still, even if assume that the raw temperature is a signed s16 value, it
gives us ~35C in a result, which should be off by ~10C.

Certainly a manual calibration is an option, but we will try to wait for
the answer from Nathans and Jean-Baptiste before going that route.

2021-04-21 12:09:18

by Linus Walleij

[permalink] [raw]
Subject: Re: BUG: iio: mpu3050: Wrong temperature scale

On Tue, Apr 20, 2021 at 11:26 PM Dmitry Osipenko <[email protected]> wrote:

> I found a non-kernel example
> which uses a similar equation [1], but in a different form. The main
> difference is that the Arduino code interprets a raw temperature value
> as a signed integer, while upstream assumes it's unsigned.
>
> [1]
> https://github.com/blaisejarrett/Arduino-Lib.MPU3050/blob/master/MPU3050lib.cpp#L111

Oh that's nice. Room temperature as mentioned is 20 deg C
I think?

The divide by 280 part seems coherent in all examples.

> Still, even if assume that the raw temperature is a signed s16 value, it
> gives us ~35C in a result, which should be off by ~10C.
>
> Certainly a manual calibration is an option, but we will try to wait for
> the answer from Nathans and Jean-Baptiste before going that route.

The method I have seen used is:
- Collect many bags of silica gel, those little packages of "dryer" that
come in shoe boxes.
- Put the device with all these in two layers of plastic bags and pull out
cables, glue or strap many layers around the bags to make it really tight
where the cables come out.
- Submerge this into a mixture of ice and water which is known to be
a calibration point for 0 degrees C, wait for some hour or so to
stabilize, add some ice if it all melts.

Now measures should be 0 deg C so any deviance will be the constant
offset that need be added for the sensor.

I guess the OTP (one time programmable memory) also contains
device-unique calibration, maybe also for the temperature sensor,
but IIUC that is read in automatically by the hardware since no
drivers seem to look into that.

Yours,
Linus Walleij

2021-04-22 01:20:52

by Andy Shevchenko

[permalink] [raw]
Subject: Re: BUG: iio: mpu3050: Wrong temperature scale

On Wed, Apr 21, 2021 at 1:14 PM Linus Walleij <[email protected]> wrote:
>
> On Tue, Apr 20, 2021 at 11:26 PM Dmitry Osipenko <[email protected]> wrote:
>
> > I found a non-kernel example
> > which uses a similar equation [1], but in a different form. The main
> > difference is that the Arduino code interprets a raw temperature value
> > as a signed integer, while upstream assumes it's unsigned.
> >
> > [1]
> > https://github.com/blaisejarrett/Arduino-Lib.MPU3050/blob/master/MPU3050lib.cpp#L111
>
> Oh that's nice. Room temperature as mentioned is 20 deg C
> I think?
>
> The divide by 280 part seems coherent in all examples.
>
> > Still, even if assume that the raw temperature is a signed s16 value, it
> > gives us ~35C in a result, which should be off by ~10C.

Actually here [1] it says in chapter 3.1 that room temperature is 35°C.

Range: -30°C .. +85°C
Sensitivity: 280 LSB/°C
Room temperature offset: 35°C = -13200 LSB

[1]: https://www.cdiweb.com/datasheets/invensense/mpu-3000a.pdf

> > Certainly a manual calibration is an option, but we will try to wait for
> > the answer from Nathans and Jean-Baptiste before going that route.
>
> The method I have seen used is:
> - Collect many bags of silica gel, those little packages of "dryer" that
> come in shoe boxes.
> - Put the device with all these in two layers of plastic bags and pull out
> cables, glue or strap many layers around the bags to make it really tight
> where the cables come out.
> - Submerge this into a mixture of ice and water which is known to be
> a calibration point for 0 degrees C, wait for some hour or so to
> stabilize, add some ice if it all melts.
>
> Now measures should be 0 deg C so any deviance will be the constant
> offset that need be added for the sensor.



--
With Best Regards,
Andy Shevchenko

2021-04-22 01:22:43

by Andy Shevchenko

[permalink] [raw]
Subject: Re: BUG: iio: mpu3050: Wrong temperature scale

On Wed, Apr 21, 2021 at 10:05 PM Andy Shevchenko
<[email protected]> wrote:
>
> On Wed, Apr 21, 2021 at 1:14 PM Linus Walleij <[email protected]> wrote:
> >
> > On Tue, Apr 20, 2021 at 11:26 PM Dmitry Osipenko <[email protected]> wrote:
> >
> > > I found a non-kernel example
> > > which uses a similar equation [1], but in a different form. The main
> > > difference is that the Arduino code interprets a raw temperature value
> > > as a signed integer, while upstream assumes it's unsigned.
> > >
> > > [1]
> > > https://github.com/blaisejarrett/Arduino-Lib.MPU3050/blob/master/MPU3050lib.cpp#L111
> >
> > Oh that's nice. Room temperature as mentioned is 20 deg C
> > I think?
> >
> > The divide by 280 part seems coherent in all examples.
> >
> > > Still, even if assume that the raw temperature is a signed s16 value, it
> > > gives us ~35C in a result, which should be off by ~10C.
>
> Actually here [1] it says in chapter 3.1 that room temperature is 35°C.
>
> Range: -30°C .. +85°C
> Sensitivity: 280 LSB/°C
> Room temperature offset: 35°C = -13200 LSB
>
> [1]: https://www.cdiweb.com/datasheets/invensense/mpu-3000a.pdf


So, if I'm reading this and the register description right the value
is in the range
-32768..32767.
-13200 defines 35°C

50000 as mentioned by Dmitry is actually -15536. So, it means that the
more negative a value is the higher temperature is shown.

Since it's linearized scale, now we can see that

(13200 -15536)/280 + 35 gives us 26.66.

Does it make sense?

--
With Best Regards,
Andy Shevchenko

2021-04-22 01:23:14

by Andy Shevchenko

[permalink] [raw]
Subject: Re: BUG: iio: mpu3050: Wrong temperature scale

On Wed, Apr 21, 2021 at 11:00 PM Lars-Peter Clausen <[email protected]> wrote:
> On 4/21/21 9:41 PM, Andy Shevchenko wrote:
> > On Wed, Apr 21, 2021 at 10:05 PM Andy Shevchenko
> > <[email protected]> wrote:
> >> On Wed, Apr 21, 2021 at 1:14 PM Linus Walleij <[email protected]> wrote:
> >>> On Tue, Apr 20, 2021 at 11:26 PM Dmitry Osipenko <[email protected]> wrote:
> >>>
> >>>> I found a non-kernel example
> >>>> which uses a similar equation [1], but in a different form. The main
> >>>> difference is that the Arduino code interprets a raw temperature value
> >>>> as a signed integer, while upstream assumes it's unsigned.
> >>>>
> >>>> [1]
> >>>> https://github.com/blaisejarrett/Arduino-Lib.MPU3050/blob/master/MPU3050lib.cpp#L111
> >>> Oh that's nice. Room temperature as mentioned is 20 deg C
> >>> I think?
> >>>
> >>> The divide by 280 part seems coherent in all examples.
> >>>
> >>>> Still, even if assume that the raw temperature is a signed s16 value, it
> >>>> gives us ~35C in a result, which should be off by ~10C.
> >> Actually here [1] it says in chapter 3.1 that room temperature is 35°C.
> >>
> >> Range: -30°C .. +85°C
> >> Sensitivity: 280 LSB/°C
> >> Room temperature offset: 35°C = -13200 LSB
> >>
> >> [1]: https://www.cdiweb.com/datasheets/invensense/mpu-3000a.pdf
> >
> > So, if I'm reading this and the register description right the value
> > is in the range
> > -32768..32767.
> > -13200 defines 35°C
> >
> > 50000 as mentioned by Dmitry is actually -15536. So, it means that the
> > more negative a value is the higher temperature is shown.
> >
> > Since it's linearized scale, now we can see that
> >
> > (13200 -15536)/280 + 35 gives us 26.66.
> >
> > Does it make sense?
> (13200 + x)/280 + 35 = (23000 + x)/280, which is what is in the driver.
> So the only bit missing is the cast to s16.

Cool! So, that cast needs a very good comment then :-)

--
With Best Regards,
Andy Shevchenko

2021-04-22 01:23:20

by Andy Shevchenko

[permalink] [raw]
Subject: Re: BUG: iio: mpu3050: Wrong temperature scale

On Wed, Apr 21, 2021 at 11:02 PM Andy Shevchenko
<[email protected]> wrote:
>
> On Wed, Apr 21, 2021 at 11:00 PM Lars-Peter Clausen <[email protected]> wrote:
> > On 4/21/21 9:41 PM, Andy Shevchenko wrote:
> > > On Wed, Apr 21, 2021 at 10:05 PM Andy Shevchenko
> > > <[email protected]> wrote:
> > >> On Wed, Apr 21, 2021 at 1:14 PM Linus Walleij <[email protected]> wrote:
> > >>> On Tue, Apr 20, 2021 at 11:26 PM Dmitry Osipenko <[email protected]> wrote:
> > >>>
> > >>>> I found a non-kernel example
> > >>>> which uses a similar equation [1], but in a different form. The main
> > >>>> difference is that the Arduino code interprets a raw temperature value
> > >>>> as a signed integer, while upstream assumes it's unsigned.
> > >>>>
> > >>>> [1]
> > >>>> https://github.com/blaisejarrett/Arduino-Lib.MPU3050/blob/master/MPU3050lib.cpp#L111
> > >>> Oh that's nice. Room temperature as mentioned is 20 deg C
> > >>> I think?
> > >>>
> > >>> The divide by 280 part seems coherent in all examples.
> > >>>
> > >>>> Still, even if assume that the raw temperature is a signed s16 value, it
> > >>>> gives us ~35C in a result, which should be off by ~10C.
> > >> Actually here [1] it says in chapter 3.1 that room temperature is 35°C.
> > >>
> > >> Range: -30°C .. +85°C
> > >> Sensitivity: 280 LSB/°C
> > >> Room temperature offset: 35°C = -13200 LSB
> > >>
> > >> [1]: https://www.cdiweb.com/datasheets/invensense/mpu-3000a.pdf
> > >
> > > So, if I'm reading this and the register description right the value
> > > is in the range
> > > -32768..32767.
> > > -13200 defines 35°C
> > >
> > > 50000 as mentioned by Dmitry is actually -15536. So, it means that the
> > > more negative a value is the higher temperature is shown.
> > >
> > > Since it's linearized scale, now we can see that
> > >
> > > (13200 -15536)/280 + 35 gives us 26.66.
> > >
> > > Does it make sense?
> > (13200 + x)/280 + 35 = (23000 + x)/280, which is what is in the driver.
> > So the only bit missing is the cast to s16.
>
> Cool! So, that cast needs a very good comment then :-)

"will need" (since it's not yet in upstream)


--
With Best Regards,
Andy Shevchenko

2021-04-22 01:24:00

by Lars-Peter Clausen

[permalink] [raw]
Subject: Re: BUG: iio: mpu3050: Wrong temperature scale

On 4/21/21 9:41 PM, Andy Shevchenko wrote:
> On Wed, Apr 21, 2021 at 10:05 PM Andy Shevchenko
> <[email protected]> wrote:
>> On Wed, Apr 21, 2021 at 1:14 PM Linus Walleij <[email protected]> wrote:
>>> On Tue, Apr 20, 2021 at 11:26 PM Dmitry Osipenko <[email protected]> wrote:
>>>
>>>> I found a non-kernel example
>>>> which uses a similar equation [1], but in a different form. The main
>>>> difference is that the Arduino code interprets a raw temperature value
>>>> as a signed integer, while upstream assumes it's unsigned.
>>>>
>>>> [1]
>>>> https://github.com/blaisejarrett/Arduino-Lib.MPU3050/blob/master/MPU3050lib.cpp#L111
>>> Oh that's nice. Room temperature as mentioned is 20 deg C
>>> I think?
>>>
>>> The divide by 280 part seems coherent in all examples.
>>>
>>>> Still, even if assume that the raw temperature is a signed s16 value, it
>>>> gives us ~35C in a result, which should be off by ~10C.
>> Actually here [1] it says in chapter 3.1 that room temperature is 35°C.
>>
>> Range: -30°C .. +85°C
>> Sensitivity: 280 LSB/°C
>> Room temperature offset: 35°C = -13200 LSB
>>
>> [1]: https://www.cdiweb.com/datasheets/invensense/mpu-3000a.pdf
>
> So, if I'm reading this and the register description right the value
> is in the range
> -32768..32767.
> -13200 defines 35°C
>
> 50000 as mentioned by Dmitry is actually -15536. So, it means that the
> more negative a value is the higher temperature is shown.
>
> Since it's linearized scale, now we can see that
>
> (13200 -15536)/280 + 35 gives us 26.66.
>
> Does it make sense?
(13200 + x)/280 + 35 = (23000 + x)/280, which is what is in the driver.
So the only bit missing is the cast to s16.


2021-04-22 01:24:05

by Andy Shevchenko

[permalink] [raw]
Subject: Re: BUG: iio: mpu3050: Wrong temperature scale

On Wed, Apr 21, 2021 at 11:00 PM Lars-Peter Clausen <[email protected]> wrote:
> On 4/21/21 9:41 PM, Andy Shevchenko wrote:
> > On Wed, Apr 21, 2021 at 10:05 PM Andy Shevchenko
> > <[email protected]> wrote:
> >> On Wed, Apr 21, 2021 at 1:14 PM Linus Walleij <[email protected]> wrote:
> >>> On Tue, Apr 20, 2021 at 11:26 PM Dmitry Osipenko <[email protected]> wrote:
> >>>
> >>>> I found a non-kernel example
> >>>> which uses a similar equation [1], but in a different form. The main
> >>>> difference is that the Arduino code interprets a raw temperature value
> >>>> as a signed integer, while upstream assumes it's unsigned.
> >>>>
> >>>> [1]
> >>>> https://github.com/blaisejarrett/Arduino-Lib.MPU3050/blob/master/MPU3050lib.cpp#L111
> >>> Oh that's nice. Room temperature as mentioned is 20 deg C
> >>> I think?
> >>>
> >>> The divide by 280 part seems coherent in all examples.
> >>>
> >>>> Still, even if assume that the raw temperature is a signed s16 value, it
> >>>> gives us ~35C in a result, which should be off by ~10C.
> >> Actually here [1] it says in chapter 3.1 that room temperature is 35°C.
> >>
> >> Range: -30°C .. +85°C
> >> Sensitivity: 280 LSB/°C
> >> Room temperature offset: 35°C = -13200 LSB
> >>
> >> [1]: https://www.cdiweb.com/datasheets/invensense/mpu-3000a.pdf
> >
> > So, if I'm reading this and the register description right the value
> > is in the range
> > -32768..32767.
> > -13200 defines 35°C
> >
> > 50000 as mentioned by Dmitry is actually -15536. So, it means that the
> > more negative a value is the higher temperature is shown.

s/higher/lower/
Sorry for my signness.

> > Since it's linearized scale, now we can see that
> >
> > (13200 -15536)/280 + 35 gives us 26.66.
> >
> > Does it make sense?
> (13200 + x)/280 + 35 = (23000 + x)/280, which is what is in the driver.
> So the only bit missing is the cast to s16.


--
With Best Regards,
Andy Shevchenko

2021-04-22 01:24:55

by Dmitry Osipenko

[permalink] [raw]
Subject: Re: BUG: iio: mpu3050: Wrong temperature scale

21.04.2021 23:04, Andy Shevchenko пишет:
> On Wed, Apr 21, 2021 at 11:02 PM Andy Shevchenko
> <[email protected]> wrote:
>>
>> On Wed, Apr 21, 2021 at 11:00 PM Lars-Peter Clausen <[email protected]> wrote:
>>> On 4/21/21 9:41 PM, Andy Shevchenko wrote:
>>>> On Wed, Apr 21, 2021 at 10:05 PM Andy Shevchenko
>>>> <[email protected]> wrote:
>>>>> On Wed, Apr 21, 2021 at 1:14 PM Linus Walleij <[email protected]> wrote:
>>>>>> On Tue, Apr 20, 2021 at 11:26 PM Dmitry Osipenko <[email protected]> wrote:
>>>>>>
>>>>>>> I found a non-kernel example
>>>>>>> which uses a similar equation [1], but in a different form. The main
>>>>>>> difference is that the Arduino code interprets a raw temperature value
>>>>>>> as a signed integer, while upstream assumes it's unsigned.
>>>>>>>
>>>>>>> [1]
>>>>>>> https://github.com/blaisejarrett/Arduino-Lib.MPU3050/blob/master/MPU3050lib.cpp#L111
>>>>>> Oh that's nice. Room temperature as mentioned is 20 deg C
>>>>>> I think?
>>>>>>
>>>>>> The divide by 280 part seems coherent in all examples.
>>>>>>
>>>>>>> Still, even if assume that the raw temperature is a signed s16 value, it
>>>>>>> gives us ~35C in a result, which should be off by ~10C.
>>>>> Actually here [1] it says in chapter 3.1 that room temperature is 35°C.
>>>>>
>>>>> Range: -30°C .. +85°C
>>>>> Sensitivity: 280 LSB/°C
>>>>> Room temperature offset: 35°C = -13200 LSB
>>>>>
>>>>> [1]: https://www.cdiweb.com/datasheets/invensense/mpu-3000a.pdf
>>>>
>>>> So, if I'm reading this and the register description right the value
>>>> is in the range
>>>> -32768..32767.
>>>> -13200 defines 35°C
>>>>
>>>> 50000 as mentioned by Dmitry is actually -15536. So, it means that the
>>>> more negative a value is the higher temperature is shown.
>>>>
>>>> Since it's linearized scale, now we can see that
>>>>
>>>> (13200 -15536)/280 + 35 gives us 26.66.
>>>>
>>>> Does it make sense?
>>> (13200 + x)/280 + 35 = (23000 + x)/280, which is what is in the driver.
>>> So the only bit missing is the cast to s16.
>>
>> Cool! So, that cast needs a very good comment then :-)
>
> "will need" (since it's not yet in upstream)
>
>

The exact value I'm getting is 52144, which is -13392 and gives us 35C.
I see that the datasheet says it should be a temperature of the sensor
die, so maybe it's a correct value, although it means that it's warm as
much as ARM CPU core, which is questionable to me whether it's a correct
value.

2021-04-22 01:27:58

by Dmitry Osipenko

[permalink] [raw]
Subject: Re: BUG: iio: mpu3050: Wrong temperature scale

22.04.2021 02:02, Linus Walleij пишет:
> On Wed, Apr 21, 2021 at 10:00 PM Lars-Peter Clausen <[email protected]> wrote:
>> On 4/21/21 9:41 PM, Andy Shevchenko wrote:
>>> On Wed, Apr 21, 2021 at 10:05 PM Andy Shevchenko
>>> <[email protected]> wrote:
>>>> On Wed, Apr 21, 2021 at 1:14 PM Linus Walleij <[email protected]> wrote:
>>>>> On Tue, Apr 20, 2021 at 11:26 PM Dmitry Osipenko <[email protected]> wrote:
>>>>>
>>>>>> I found a non-kernel example
>>>>>> which uses a similar equation [1], but in a different form. The main
>>>>>> difference is that the Arduino code interprets a raw temperature value
>>>>>> as a signed integer, while upstream assumes it's unsigned.
>>>>>>
>>>>>> [1]
>>>>>> https://github.com/blaisejarrett/Arduino-Lib.MPU3050/blob/master/MPU3050lib.cpp#L111
>>>>> Oh that's nice. Room temperature as mentioned is 20 deg C
>>>>> I think?
>>>>>
>>>>> The divide by 280 part seems coherent in all examples.
>>>>>
>>>>>> Still, even if assume that the raw temperature is a signed s16 value, it
>>>>>> gives us ~35C in a result, which should be off by ~10C.
>>>> Actually here [1] it says in chapter 3.1 that room temperature is 35°C.
>>>>
>>>> Range: -30°C .. +85°C
>>>> Sensitivity: 280 LSB/°C
>>>> Room temperature offset: 35°C = -13200 LSB
>>>>
>>>> [1]: https://www.cdiweb.com/datasheets/invensense/mpu-3000a.pdf
>
> Oh nice find!
>
>>> So, if I'm reading this and the register description right the value
>>> is in the range
>>> -32768..32767.
>>> -13200 defines 35°C
>>>
>>> 50000 as mentioned by Dmitry is actually -15536. So, it means that the
>>> more negative a value is the higher temperature is shown.
>>>
>>> Since it's linearized scale, now we can see that
>>>
>>> (13200 -15536)/280 + 35 gives us 26.66.
>>>
>>> Does it make sense?
>> (13200 + x)/280 + 35 = (23000 + x)/280, which is what is in the driver.
>> So the only bit missing is the cast to s16.
>
> Yup there is the bug. (I am guilty.)
>
> Dmitry will you test & send a patch?


I'll send the patch. Thank you all for yours help!

2021-04-22 01:29:02

by Linus Walleij

[permalink] [raw]
Subject: Re: BUG: iio: mpu3050: Wrong temperature scale

On Wed, Apr 21, 2021 at 10:00 PM Lars-Peter Clausen <[email protected]> wrote:
> On 4/21/21 9:41 PM, Andy Shevchenko wrote:
> > On Wed, Apr 21, 2021 at 10:05 PM Andy Shevchenko
> > <[email protected]> wrote:
> >> On Wed, Apr 21, 2021 at 1:14 PM Linus Walleij <[email protected]> wrote:
> >>> On Tue, Apr 20, 2021 at 11:26 PM Dmitry Osipenko <[email protected]> wrote:
> >>>
> >>>> I found a non-kernel example
> >>>> which uses a similar equation [1], but in a different form. The main
> >>>> difference is that the Arduino code interprets a raw temperature value
> >>>> as a signed integer, while upstream assumes it's unsigned.
> >>>>
> >>>> [1]
> >>>> https://github.com/blaisejarrett/Arduino-Lib.MPU3050/blob/master/MPU3050lib.cpp#L111
> >>> Oh that's nice. Room temperature as mentioned is 20 deg C
> >>> I think?
> >>>
> >>> The divide by 280 part seems coherent in all examples.
> >>>
> >>>> Still, even if assume that the raw temperature is a signed s16 value, it
> >>>> gives us ~35C in a result, which should be off by ~10C.
> >> Actually here [1] it says in chapter 3.1 that room temperature is 35°C.
> >>
> >> Range: -30°C .. +85°C
> >> Sensitivity: 280 LSB/°C
> >> Room temperature offset: 35°C = -13200 LSB
> >>
> >> [1]: https://www.cdiweb.com/datasheets/invensense/mpu-3000a.pdf

Oh nice find!

> > So, if I'm reading this and the register description right the value
> > is in the range
> > -32768..32767.
> > -13200 defines 35°C
> >
> > 50000 as mentioned by Dmitry is actually -15536. So, it means that the
> > more negative a value is the higher temperature is shown.
> >
> > Since it's linearized scale, now we can see that
> >
> > (13200 -15536)/280 + 35 gives us 26.66.
> >
> > Does it make sense?
> (13200 + x)/280 + 35 = (23000 + x)/280, which is what is in the driver.
> So the only bit missing is the cast to s16.

Yup there is the bug. (I am guilty.)

Dmitry will you test & send a patch?

Yours,
Linus Walleij