sensors: Redefine SENSOR_CHAN_HUMIDITY in percents, not milli-percents.

Based on the discussion in #5693, the reason why humidity was defined
in milli-percent was likely following Linux which defines it as such
in its sensor subsystem:
http://elixir.free-electrons.com/linux/latest/source/Documentation/ABI/testing/sysfs-bus-iio#L263

However, Linux defines temperature in milli-degrees either, but
Zephyr uses degrees (similarly for most other quantities). Typical
sensor resolution/precision for humidity is also on the order of 1%.

One of the existing drivers, th02.c, already returned values in
percents, and few apps showed it without conversion and/or units,
leading to confusing output to user like "54500".

So, switching units to percents, and update all the drivers and
sample apps.

For few drivers, there was also optimized conversion arithmetics
to avoid u64_t operations. (There're probably more places to
optimize it, and temperature conversion could use such optimization
too, but that's left for another patch.)

Fixes: #5693

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
This commit is contained in:
Paul Sokolovsky 2018-01-25 15:06:17 +02:00 committed by Carles Cufí
commit b7623a85b0
9 changed files with 23 additions and 23 deletions

View file

@ -212,8 +212,6 @@ static int bme280_channel_get(struct device *dev,
*/ */
val->val1 = (data->comp_humidity >> 10); val->val1 = (data->comp_humidity >> 10);
val->val2 = (((data->comp_humidity & 0x3ff) * 1000 * 1000) >> 10); val->val2 = (((data->comp_humidity & 0x3ff) * 1000 * 1000) >> 10);
val->val1 = val->val1 * 1000 + (val->val2 * 1000) / 1000000;
val->val2 = (val->val2 * 1000) % 1000000;
break; break;
default: default:
return -EINVAL; return -EINVAL;

View file

@ -168,7 +168,7 @@ static int dht_channel_get(struct device *dev,
#if defined(CONFIG_DHT_CHIP_DHT11) #if defined(CONFIG_DHT_CHIP_DHT11)
/* use only integral data byte */ /* use only integral data byte */
if (chan == SENSOR_CHAN_HUMIDITY) { if (chan == SENSOR_CHAN_HUMIDITY) {
val->val1 = drv_data->sample[0] * 1000; val->val1 = drv_data->sample[0];
val->val2 = 0; val->val2 = 0;
} else { /* chan == SENSOR_CHAN_TEMP */ } else { /* chan == SENSOR_CHAN_TEMP */
val->val1 = drv_data->sample[2]; val->val1 = drv_data->sample[2];
@ -183,8 +183,8 @@ static int dht_channel_get(struct device *dev,
if (chan == SENSOR_CHAN_HUMIDITY) { if (chan == SENSOR_CHAN_HUMIDITY) {
raw_val = (drv_data->sample[0] << 8) | drv_data->sample[1]; raw_val = (drv_data->sample[0] << 8) | drv_data->sample[1];
val->val1 = raw_val * 100; val->val1 = raw_val / 10;
val->val2 = 0; val->val2 = (raw_val % 10) * 100000;
} else { /* chan == SENSOR_CHAN_TEMP */ } else { /* chan == SENSOR_CHAN_TEMP */
raw_val = (drv_data->sample[2] << 8) | drv_data->sample[3]; raw_val = (drv_data->sample[2] << 8) | drv_data->sample[3];

View file

@ -73,10 +73,12 @@ static int hdc1008_channel_get(struct device *dev,
val->val1 = (s32_t)(tmp >> 16) - 40; val->val1 = (s32_t)(tmp >> 16) - 40;
val->val2 = (1000000 * (tmp & 0xFFFF)) >> 16; val->val2 = (1000000 * (tmp & 0xFFFF)) >> 16;
} else if (chan == SENSOR_CHAN_HUMIDITY) { } else if (chan == SENSOR_CHAN_HUMIDITY) {
/* val = 100000 * sample / 2^16 */ /* val = 100 * sample / 2^16 */
tmp = 100000 * (u64_t)drv_data->rh_sample; u32_t tmp2;
val->val1 = tmp >> 16; tmp2 = 100 * (u32_t)drv_data->rh_sample;
val->val2 = (1000000 * (tmp & 0xFFFF)) >> 16; val->val1 = tmp2 >> 16;
/* x * 1000000 / 65536 == x * 15625 / 1024 */
val->val2 = (15625 * (tmp2 & 0xFFFF)) >> 10;
} else { } else {
return -ENOTSUP; return -ENOTSUP;
} }

View file

@ -43,9 +43,9 @@ static int hts221_channel_get(struct device *dev,
(drv_data->h1_t0_out - drv_data->h0_t0_out) + (drv_data->h1_t0_out - drv_data->h0_t0_out) +
drv_data->h0_rh_x2; drv_data->h0_rh_x2;
/* convert humidity x2 to mili-percent */ /* convert humidity x2 to percent */
val->val1 = conv_val * 500; val->val1 = conv_val / 2;
val->val2 = 0; val->val2 = (conv_val % 2) * 500000;
} }
return 0; return 0;

View file

@ -126,10 +126,11 @@ static int sht3xd_channel_get(struct device *dev,
val->val1 = (s32_t)(tmp / 0xFFFF) - 45; val->val1 = (s32_t)(tmp / 0xFFFF) - 45;
val->val2 = (1000000 * (tmp % 0xFFFF)) / 0xFFFF; val->val2 = (1000000 * (tmp % 0xFFFF)) / 0xFFFF;
} else if (chan == SENSOR_CHAN_HUMIDITY) { } else if (chan == SENSOR_CHAN_HUMIDITY) {
/* val = 100000 * sample / (2^16 -1) */ /* val = 100 * sample / (2^16 -1) */
tmp = 100000 * (u64_t)drv_data->rh_sample; u32_t tmp2 = 100 * (u32_t)drv_data->rh_sample;
val->val1 = tmp / 0xFFFF; val->val1 = tmp2 / 0xFFFF;
val->val2 = (1000000 * (tmp % 0xFFFF)) / 0xFFFF; /* x * 100000 / 65536 == x * 15625 / 1024 */
val->val2 = (tmp2 % 0xFFFF) * 15625 / 1024;
} else { } else {
return -ENOTSUP; return -ENOTSUP;
} }

View file

@ -98,7 +98,7 @@ enum sensor_channel {
* object is close. * object is close.
*/ */
SENSOR_CHAN_PROX, SENSOR_CHAN_PROX,
/** Humidity, in milli percent. */ /** Humidity, in percent. */
SENSOR_CHAN_HUMIDITY, SENSOR_CHAN_HUMIDITY,
/** Illuminance in visible spectrum, in lux. */ /** Illuminance in visible spectrum, in lux. */
SENSOR_CHAN_LIGHT, SENSOR_CHAN_LIGHT,

View file

@ -105,7 +105,7 @@ static void sensor_ipm_callback(void *context, u32_t id, volatile void *data)
break; break;
case SENSOR_CHAN_HUMIDITY: case SENSOR_CHAN_HUMIDITY:
/* resolution of 0.01 percent */ /* resolution of 0.01 percent */
humidity_value = val->val1 / 10; humidity_value = val->val1 * 100 + val->val2 / 10000;
break; break;
case SENSOR_CHAN_PRESS: case SENSOR_CHAN_PRESS:
/* resolution of 0.1 Pa */ /* resolution of 0.1 Pa */

View file

@ -113,8 +113,7 @@ void main(void)
/* display himidity on LCD */ /* display himidity on LCD */
glcd_cursor_pos_set(glcd, 17 - strlen(row), 0); glcd_cursor_pos_set(glcd, 17 - strlen(row), 0);
sprintf(row, "RH:%d%c", val[1].val1/1000, sprintf(row, "RH:%d%%", val[1].val1);
37 /* percent symbol */);
glcd_print(glcd, row, strlen(row)); glcd_print(glcd, row, strlen(row));
/* display pressure on LCD */ /* display pressure on LCD */

View file

@ -39,9 +39,9 @@ void main(void)
/* display temperature */ /* display temperature */
printf("Temperature:%.1f C\n", sensor_value_to_double(&temp)); printf("Temperature:%.1f C\n", sensor_value_to_double(&temp));
/* display humidity (converted from millipercent) */ /* display humidity */
printf("Relative Humidity:%.0f%%\n", printf("Relative Humidity:%.1f%%\n",
sensor_value_to_double(&hum) / 1000); sensor_value_to_double(&hum));
k_sleep(2000); k_sleep(2000);
} }