Skip to content

Commit 29d0173

Browse files
Jeppe Odgaardcfriedt
authored andcommitted
drivers: sensor: omron: add d6f driver
Add support for Omron D6F mass flow rate sensor series. The sensor series outputs an analogue voltage which is read using an ADC. Signed-off-by: Jeppe Odgaard <[email protected]>
1 parent 5001535 commit 29d0173

File tree

10 files changed

+202
-0
lines changed

10 files changed

+202
-0
lines changed

drivers/sensor/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ add_subdirectory(microchip)
2222
add_subdirectory(nordic)
2323
add_subdirectory(nuvoton)
2424
add_subdirectory(nxp)
25+
add_subdirectory(omron)
2526
add_subdirectory(pixart)
2627
add_subdirectory(pni)
2728
add_subdirectory(realtek)

drivers/sensor/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ source "drivers/sensor/microchip/Kconfig"
108108
source "drivers/sensor/nordic/Kconfig"
109109
source "drivers/sensor/nuvoton/Kconfig"
110110
source "drivers/sensor/nxp/Kconfig"
111+
source "drivers/sensor/omron/Kconfig"
111112
source "drivers/sensor/pixart/Kconfig"
112113
source "drivers/sensor/pni/Kconfig"
113114
source "drivers/sensor/realtek/Kconfig"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright (c) 2025 Prevas A/S
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
# zephyr-keep-sorted-start
5+
add_subdirectory_ifdef(CONFIG_D6F d6f)
6+
# zephyr-keep-sorted-stop

drivers/sensor/omron/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright (c) 2025 Prevas A/S
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
# zephyr-keep-sorted-start
5+
source "drivers/sensor/omron/d6f/Kconfig"
6+
# zephyr-keep-sorted-stop
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Copyright (c) 2025 Prevas A/S
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
zephyr_library()
5+
zephyr_library_sources(d6f.c)

drivers/sensor/omron/d6f/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright (c) 2025 Prevas A/S
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config D6F
5+
bool "D6F mass flow rate sensor"
6+
default y
7+
depends on DT_HAS_OMRON_D6F_P0001_ENABLED || DT_HAS_OMRON_D6F_P0010_ENABLED
8+
select ADC
9+
select FPU if CPU_HAS_FPU
10+
help
11+
Enable Omron D6F mass flow rate sensor driver. The sensor series
12+
outputs an analogue voltage which is read using an ADC.

drivers/sensor/omron/d6f/d6f.c

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
* Copyright (c) 2025 Prevas A/S
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include <math.h>
7+
#include <stdint.h>
8+
9+
#include <zephyr/drivers/adc.h>
10+
#include <zephyr/drivers/sensor.h>
11+
#include <zephyr/device.h>
12+
#include <zephyr/devicetree.h>
13+
#include <zephyr/logging/log.h>
14+
15+
LOG_MODULE_REGISTER(d6f, CONFIG_SENSOR_LOG_LEVEL);
16+
17+
struct d6f_config {
18+
const struct adc_dt_spec *adc;
19+
struct adc_sequence sequence;
20+
const float *polynomial_coefficients;
21+
uint8_t polynomial_degree;
22+
};
23+
24+
struct d6f_data {
25+
uint32_t adc_sample;
26+
};
27+
28+
static int d6f_sample_fetch(const struct device *dev, enum sensor_channel chan)
29+
{
30+
const struct d6f_config *config = dev->config;
31+
32+
switch (chan) {
33+
case SENSOR_CHAN_ALL:
34+
case SENSOR_CHAN_FLOW_RATE:
35+
return adc_read_dt(config->adc, &config->sequence);
36+
default:
37+
return -ENOTSUP;
38+
}
39+
}
40+
41+
static int d6f_flow_rate(const struct d6f_config *config, struct d6f_data *data,
42+
struct sensor_value *val)
43+
{
44+
float flow_rate = config->polynomial_coefficients[0];
45+
int32_t uv = data->adc_sample;
46+
float v;
47+
int rc;
48+
49+
rc = adc_raw_to_microvolts_dt(config->adc, &uv);
50+
if (rc != 0) {
51+
return rc;
52+
}
53+
v = uv / 1000000.f;
54+
55+
for (uint8_t i = 1; i <= config->polynomial_degree; ++i) {
56+
flow_rate += config->polynomial_coefficients[i] * powf(v, i);
57+
}
58+
59+
rc = sensor_value_from_float(val, flow_rate);
60+
if (rc != 0) {
61+
return rc;
62+
}
63+
64+
return 0;
65+
}
66+
67+
static int d6f_channel_get(const struct device *dev, enum sensor_channel chan,
68+
struct sensor_value *val)
69+
{
70+
const struct d6f_config *config = dev->config;
71+
struct d6f_data *data = dev->data;
72+
73+
switch (chan) {
74+
case SENSOR_CHAN_FLOW_RATE:
75+
return d6f_flow_rate(config, data, val);
76+
default:
77+
return -ENOTSUP;
78+
}
79+
80+
return 0;
81+
}
82+
83+
static int d6f_init(const struct device *dev)
84+
{
85+
const struct d6f_config *config = dev->config;
86+
int rc;
87+
88+
LOG_DBG("Initializing %s", dev->name);
89+
90+
if (!adc_is_ready_dt(config->adc)) {
91+
LOG_ERR("%s not ready", dev->name);
92+
return -ENODEV;
93+
}
94+
95+
rc = adc_channel_setup_dt(config->adc);
96+
if (rc != 0) {
97+
LOG_ERR("%s setup failed: %d", config->adc->dev->name, rc);
98+
return -ENODEV;
99+
}
100+
101+
return 0;
102+
}
103+
104+
static DEVICE_API(sensor, d6f_driver_api) = {
105+
.sample_fetch = d6f_sample_fetch,
106+
.channel_get = d6f_channel_get,
107+
};
108+
109+
#define D6F_INIT(n, c, p) \
110+
static struct d6f_data d6f_data_##c##_##n; \
111+
static const struct adc_dt_spec d6f_adc_##c##_##n = ADC_DT_SPEC_INST_GET(n); \
112+
static const struct d6f_config d6f_config_##c##_##n = { \
113+
.adc = &d6f_adc_##c##_##n, \
114+
.sequence = \
115+
{ \
116+
.options = NULL, \
117+
.channels = BIT(d6f_adc_##c##_##n.channel_id), \
118+
.buffer = &d6f_data_##c##_##n.adc_sample, \
119+
.buffer_size = sizeof(d6f_data_##c##_##n.adc_sample), \
120+
.resolution = d6f_adc_##c##_##n.resolution, \
121+
.oversampling = d6f_adc_##c##_##n.oversampling, \
122+
.calibrate = false, \
123+
}, \
124+
.polynomial_coefficients = (p), \
125+
.polynomial_degree = (ARRAY_SIZE(p) - 1), \
126+
}; \
127+
\
128+
SENSOR_DEVICE_DT_INST_DEFINE(n, d6f_init, NULL, &d6f_data_##c##_##n, \
129+
&d6f_config_##c##_##n, POST_KERNEL, \
130+
CONFIG_SENSOR_INIT_PRIORITY, &d6f_driver_api);
131+
132+
#undef DT_DRV_COMPAT
133+
#define DT_DRV_COMPAT omron_d6f_p0001
134+
static __maybe_unused const float d6f_p0001_polynomial_coefficients[] = {-0.024864, 0.049944};
135+
DT_INST_FOREACH_STATUS_OKAY_VARGS(D6F_INIT, DT_DRV_COMPAT, d6f_p0001_polynomial_coefficients)
136+
137+
#undef DT_DRV_COMPAT
138+
#define DT_DRV_COMPAT omron_d6f_p0010
139+
static __maybe_unused const float d6f_p0010_polynomial_coefficients[] = {
140+
-0.269996, 1.060657, -1.601495, 1.374705, 1.374705, -0.564312, 0.094003};
141+
DT_INST_FOREACH_STATUS_OKAY_VARGS(D6F_INIT, DT_DRV_COMPAT, d6f_p0010_polynomial_coefficients)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright (c) 2025, Prevas A/S
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
title: Omron D6F mass flow rate sensor.
5+
6+
include: sensor-device.yaml
7+
8+
properties:
9+
io-channels:
10+
type: phandle-array
11+
required: true
12+
description: |
13+
ADC used to measure the mass flow rate:
14+
<&adc_node channel>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2025, Prevas A/S
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
title: Omron D6F-P0001A1 0.1 L/min flow rate sensor.
5+
6+
compatible: "omron,d6f-p0001"
7+
8+
include: omron,d6f-analog.yaml
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2025, Prevas A/S
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
title: Omron D6F-P0010 1 L/min flow rate sensor.
5+
6+
compatible: "omron,d6f-p0010"
7+
8+
include: omron,d6f-analog.yaml

0 commit comments

Comments
 (0)