ruuvi.drivers.c ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
Loading...
Searching...
No Matches
ruuvi_interface_adc_ntc.c
Go to the documentation of this file.
2
3#if (RI_ADC_NTC_ENABLED || DOXYGEN)
4
10
15
26#ifdef RI_ADC_NTC_CHANNEL
27#define ADC_NTC_USE_CHANNEL RI_ADC_NTC_CHANNEL
28#else
29#define ADC_NTC_USE_CHANNEL 1
30#endif
31
32#ifdef RI_ADC_NTC_DIVIDER
33#define ADC_NTC_USE_DIVIDER RI_ADC_NTC_DIVIDER
34#else
35#define ADC_NTC_USE_DIVIDER 1.00f
36#endif
37
38#ifdef RI_ADC_NTC_VDD
39#define ADC_NTC_USE_VDD RI_ADC_NTC_VDD
40#else
41#define ADC_NTC_USE_VDD 3.60f
42#endif
43
44#ifdef RI_ADC_NTC_BALANCE
45#define ADC_NTC_BALANCE RI_ADC_NTC_BALANCE
46#else
47#define ADC_NTC_BALANCE 10000.00f
48#endif
49
50#ifdef RI_ADC_NTC_DEFAULT_RES
51#define ADC_NTC_DEFAULT_RES RI_ADC_NTC_DEFAULT_RES
52#else
53#define ADC_NTC_DEFAULT_RES 10000.00f
54#endif
55
56#ifdef RI_ADC_NTC_DEFAULT_TEMP
57#define ADC_NTC_DEFAULT_TEMP RI_ADC_NTC_DEFAULT_TEMP
58#else
59#define ADC_NTC_DEFAULT_TEMP 25.00f
60#endif
61
62#ifdef RI_ADC_NTC_DEFAULT_BETA
63#define ADC_NTC_DEFAULT_BETA RI_ADC_NTC_DEFAULT_BETA
64#else
65#define ADC_NTC_DEFAULT_BETA 3974.0f
66#endif
67
68#define ADC_NTC_DATA_COUNTER 1
69#define ADC_NTC_DEFAULT_BITFIELD 0
70#define ADC_NTC_ENABLE_BYTE 1
71#define ADC_K_TO_C_CONST 273.15f
72#define ADC_NTC_DEFAULT_TEMP_K (ADC_NTC_DEFAULT_TEMP + ADC_K_TO_C_CONST)
73
74static ri_adc_pins_config_t adc_ntc_pins_config =
75{
77#ifdef RI_ADC_ADV_CONFIG
78 .p_pin.resistor = RI_ADC_RESISTOR_DISABLED,
79#endif
80};
81
82static ri_adc_channel_config_t adc_ntc_config =
83{
86#ifdef RI_ADC_ADV_CONFIG
87 .gain = RI_ADC_GAIN1_6,
88 .acqtime = RI_ADC_ACQTIME_10US,
89#endif
90};
91
92static ri_adc_get_data_t adc_ntc_options =
93{
95 .divider = ADC_NTC_USE_DIVIDER,
96};
97
98static uint64_t m_tsample;
99static bool m_autorefresh;
101static bool m_is_init;
102static const char m_sensor_name[] = "NTC";
103
111static float ratio_to_temperature (const float * const ratio)
112{
113 float result = RD_FLOAT_INVALID;
114 float Rt;
115 float Rb = (float) ADC_NTC_BALANCE;
116 float beta = (float) ADC_NTC_DEFAULT_BETA;
117 float T0 = (float) ADC_NTC_DEFAULT_TEMP_K;
118 float R0 = (float) RI_ADC_NTC_DEFAULT_RES;
119
120 if ( (NULL != ratio) && (*ratio >= 0.0F) && (*ratio <= 1.0F))
121 {
122 // Calculate NTC resistance.
123 Rt = (Rb * *ratio) / (1.0F - *ratio);
124 // 1/T = 1/T0 + 1/B * ln(R/R0)
125 result = 1.0F / ( (1 / T0) + ( (1 / beta) * log (Rt / R0)));
126 // Convert K->C
127 result -= ADC_K_TO_C_CONST;
128 }
129
130 return result;
131}
132
133static rd_status_t get_data (void)
134{
135 rd_status_t err_code = RD_SUCCESS;
136 float ratio;
137 m_tsample = rd_sensor_timestamp_get();
138
140 &adc_ntc_options,
141 &ratio))
142 {
143 //m_temperture = volts_to_temperature (&volts);
144 m_temperture = ratio_to_temperature (&ratio);
145 }
146 else
147 {
148 err_code = RD_ERROR_INVALID_STATE;
149 }
150
151 return err_code;
152}
153
155{
156 uint8_t mode;
157 rd_status_t err_code = ri_adc_ntc_mode_get (&mode);
158 return err_code | validate_default_input_set (samplerate, mode);
159}
161{
162 uint8_t mode;
163 rd_status_t err_code = ri_adc_ntc_mode_get (&mode);
164 return err_code | validate_default_input_set (resolution, mode);
165}
166
168{
169 uint8_t mode;
170 rd_status_t err_code = ri_adc_ntc_mode_get (&mode);
171 return err_code | validate_default_input_set (scale, mode);
172}
173
174rd_status_t ri_adc_ntc_dsp_set (uint8_t * dsp, uint8_t * parameter)
175{
176 uint8_t mode;
177 rd_status_t err_code = ri_adc_ntc_mode_get (&mode);
178 err_code |= validate_default_input_set (parameter, mode);
179
180 if (RD_SUCCESS == err_code)
181 {
182 if (NULL == dsp)
183 {
184 err_code = RD_ERROR_NULL;
185 }
186 else
187 {
188 if (RD_SENSOR_DSP_LAST != (*dsp))
189 {
190 err_code = RD_ERROR_NOT_SUPPORTED;
191 }
192 }
193 }
194
195 return RD_SUCCESS;
196}
197
198rd_status_t ri_adc_ntc_dsp_get (uint8_t * dsp, uint8_t * parameter)
199{
200 return ( (validate_default_input_get (dsp)) |
201 validate_default_input_get (parameter));
202}
203
205 environmental_sensor, rd_bus_t bus, uint8_t handle)
206{
207 rd_status_t err_code = RD_SUCCESS;
208
209 if (NULL == environmental_sensor)
210 {
211 err_code = RD_ERROR_NULL;
212 }
213 else
214 {
215 if (m_is_init)
216 {
217 err_code = RD_ERROR_INVALID_STATE;
218 }
219 else
220 {
221 rd_sensor_initialize (environmental_sensor);
222 environmental_sensor->name = m_sensor_name;
223 err_code |= ri_adc_init (NULL);
224 adc_ntc_pins_config.p_pin.channel = handle;
226 &adc_ntc_pins_config,
227 &adc_ntc_config);
228
229 if (RD_SUCCESS == err_code)
230 {
231 environmental_sensor->init = ri_adc_ntc_init;
232 environmental_sensor->uninit = ri_adc_ntc_uninit;
233 environmental_sensor->samplerate_set = ri_adc_ntc_samplerate_set;
234 environmental_sensor->samplerate_get = validate_default_input_get;
235 environmental_sensor->resolution_set = ri_adc_ntc_resolution_set;
236 environmental_sensor->resolution_get = validate_default_input_get;
237 environmental_sensor->scale_set = ri_adc_ntc_scale_set;
238 environmental_sensor->scale_get = validate_default_input_get;
239 environmental_sensor->dsp_set = ri_adc_ntc_dsp_set;
240 environmental_sensor->dsp_get = ri_adc_ntc_dsp_get;
241 environmental_sensor->mode_set = ri_adc_ntc_mode_set;
242 environmental_sensor->mode_get = ri_adc_ntc_mode_get;
243 environmental_sensor->data_get = ri_adc_ntc_data_get;
244 environmental_sensor->configuration_set = rd_sensor_configuration_set;
245 environmental_sensor->configuration_get = rd_sensor_configuration_get;
246 environmental_sensor->provides.datas.temperature_c = ADC_NTC_ENABLE_BYTE;
247 m_tsample = RD_UINT64_INVALID;
248 m_is_init = true;
249 }
250 }
251 }
252
253 return err_code;
254}
255
257 rd_bus_t bus, uint8_t handle)
258{
259 rd_status_t err_code = RD_SUCCESS;
260
261 if (NULL == sensor)
262 {
263 err_code = RD_ERROR_NULL;
264 }
265 else
266 {
267 rd_sensor_uninitialize (sensor);
268 m_tsample = RD_UINT64_INVALID;
269 m_is_init = false;
270 m_autorefresh = false;
271 err_code |= ri_adc_stop (ADC_NTC_USE_CHANNEL);
272 }
273
274 return err_code;
275}
276
278{
280
281 if (NULL == mode)
282 {
283 err_code = RD_ERROR_NULL;
284 }
285 else
286 {
287 if ( (RD_SENSOR_CFG_SLEEP == (*mode)) ||
288 (RD_SENSOR_CFG_DEFAULT == (*mode)))
289 {
290 m_autorefresh = false;
291 (*mode) = RD_SENSOR_CFG_SLEEP;
292 err_code = RD_SUCCESS;
293 }
294
295 if (RD_SENSOR_CFG_CONTINUOUS == (*mode))
296 {
297 m_autorefresh = true;
298 err_code = RD_SUCCESS;
299 }
300
301 if (RD_SENSOR_CFG_SINGLE == *mode)
302 {
303 uint8_t current_mode;
304 ri_adc_ntc_mode_get (&current_mode);
305
306 if (RD_SENSOR_CFG_CONTINUOUS == current_mode)
307 {
308 (*mode) = RD_SENSOR_CFG_CONTINUOUS;
309 err_code = RD_ERROR_INVALID_STATE;
310 }
311 else
312 {
313 m_autorefresh = false;
314 (*mode) = RD_SENSOR_CFG_SLEEP;
315 err_code = get_data();
316 }
317 }
318 }
319
320 return err_code;
321}
322
324{
325 rd_status_t err_code = RD_SUCCESS;
326
327 if (NULL == mode)
328 {
329 err_code = RD_ERROR_NULL;
330 }
331 else
332 {
333 if (m_autorefresh)
334 {
335 (*mode) = RD_SENSOR_CFG_CONTINUOUS;
336 }
337
338 if (!m_autorefresh)
339 {
340 (*mode) = RD_SENSOR_CFG_SLEEP;
341 }
342 }
343
344 return err_code;
345}
346
348 p_data)
349{
350 rd_status_t err_code = RD_SUCCESS;
351
352 if (NULL == p_data)
353 {
354 err_code = RD_ERROR_NULL;
355 }
356 else
357 {
358 if (m_autorefresh)
359 {
360 err_code = get_data();
361 }
362
363 if ( (RD_SUCCESS == err_code) &&
364 (RD_UINT64_INVALID != m_tsample))
365 {
366 rd_sensor_data_t d_environmental;
368 float env_values;
369 env_values = m_temperture;
371 d_environmental.data = &env_values;
372 d_environmental.valid = env_fields;
373 d_environmental.fields = env_fields;
375 &d_environmental,
376 p_data->fields);
377 p_data->timestamp_ms = m_tsample;
378 }
379 }
380
381 return err_code;
382}
383
384#endif
#define RD_ERROR_NULL
Null Pointer.
uint32_t rd_status_t
bitfield for representing errors
#define RD_FLOAT_INVALID
Signal that value should not be used.
#define RD_ERROR_NOT_SUPPORTED
Not supported.
#define RD_SUCCESS
Internal Error.
#define RD_UINT64_INVALID
Signal that value should not be used.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
#define RD_SENSOR_DSP_LAST
Return last value from sensor. Parameter: No effect. Use default.
#define RD_SENSOR_CFG_SLEEP
Sensor should go to sleep immediately.
#define RD_SENSOR_CFG_DEFAULT
Default value, always valid for the sensor.
void rd_sensor_uninitialize(rd_sensor_t *const p_sensor)
Mark sensor as uninitialized by calling the generic initialization. Will not clear the name of the se...
rd_status_t rd_sensor_configuration_get(const rd_sensor_t *sensor, rd_sensor_configuration_t *config)
Implementation of ref rd_configuration_fp.
void rd_sensor_initialize(rd_sensor_t *const p_sensor)
Initialize sensor struct with non-null pointers which return RD_ERROR_NOT_INITIALIZED.
rd_status_t validate_default_input_set(uint8_t *const input, const uint8_t mode)
Validate that given setting can be set on a sensor which supports only default value.
void rd_sensor_data_populate(rd_sensor_data_t *const target, const rd_sensor_data_t *const provided, const rd_sensor_data_fields_t requested)
Populate given target data with data provided by sensor as requested.
rd_status_t rd_sensor_configuration_set(const rd_sensor_t *sensor, rd_sensor_configuration_t *config)
Implementation of ref rd_configuration_fp.
#define RD_SENSOR_CFG_CONTINUOUS
Sensor will keep sampling at defined sample rate.
rd_bus_t
Type of bus sensor uses.
uint64_t rd_sensor_timestamp_get(void)
Calls the timestamp function and returns its value.
rd_status_t validate_default_input_get(uint8_t *const input)
Validate and get input when only allowed value is default.
#define RD_SENSOR_CFG_SINGLE
Sensor should go to sleep after single measurement.
Header to enable and disable module compilation.
#define RI_ADC_NTC_DEFAULT_RES
NTC at default temp.
Ruuvi error codes and error check function.
Ruuvi sensor interface Lifecycle: Beta
Interface for controlling ADC onboard MCU.
@ RI_ADC_MODE_SINGLE
Single ended mode.
@ RI_ADC_VREF_EXTERNAL
External voltage reference.
rd_status_t ri_adc_get_data_ratio(uint8_t channel_num, ri_adc_get_data_t *p_config, float *p_data)
Get ADC data in volts.
@ RI_ADC_GND
GND of device.
rd_status_t ri_adc_stop(uint8_t channel_num)
Stop use ADC channel.
rd_status_t ri_adc_configure(uint8_t channel_num, ri_adc_pins_config_t *p_pins, ri_adc_channel_config_t *p_config)
Configure ADC channel.
rd_status_t ri_adc_init(ri_adc_config_t *p_config)
Initialization of ADC.
rd_status_t ri_adc_ntc_dsp_set(uint8_t *dsp, uint8_t *parameter)
rd_sensor_dsp_fp
rd_status_t ri_adc_ntc_mode_set(uint8_t *mode)
rd_sensor_setup_fp
#define ADC_NTC_USE_CHANNEL
float m_temperture
Last measured temperature.
rd_status_t ri_adc_ntc_data_get(rd_sensor_data_t *const p_data)
rd_sensor_data_fp
rd_status_t ri_adc_ntc_resolution_set(uint8_t *resolution)
rd_sensor_setup_fp
rd_status_t ri_adc_ntc_uninit(rd_sensor_t *sensor, rd_bus_t bus, uint8_t handle)
rd_sensor_init_fp
#define ADC_NTC_DATA_COUNTER
rd_status_t ri_adc_ntc_dsp_get(uint8_t *dsp, uint8_t *parameter)
rd_sensor_dsp_fp
#define ADC_NTC_USE_DIVIDER
rd_status_t ri_adc_ntc_init(rd_sensor_t *environmental_sensor, rd_bus_t bus, uint8_t handle)
rd_sensor_init_fp
#define ADC_K_TO_C_CONST
#define ADC_NTC_DEFAULT_BITFIELD
#define ADC_NTC_DEFAULT_BETA
rd_status_t ri_adc_ntc_scale_set(uint8_t *scale)
rd_sensor_setup_fp
rd_status_t ri_adc_ntc_samplerate_set(uint8_t *samplerate)
rd_sensor_setup_fp
#define ADC_NTC_ENABLE_BYTE
#define ADC_NTC_BALANCE
#define ADC_NTC_USE_VDD
rd_status_t ri_adc_ntc_mode_get(uint8_t *mode)
rd_sensor_setup_fp
#define ADC_NTC_DEFAULT_TEMP_K
unsigned int temperature_c
Temperature, celcius.
Generic sensor data struct.
float * data
Data of sensor. Must contain as many elements as fields has bits set.
uint64_t timestamp_ms
Timestamp of the event, rd_sensor_timestamp_get.
rd_sensor_data_fields_t valid
Listing of valid data in this sample.
rd_sensor_data_fields_t fields
Description of datafields which may be contained in this sample.
Interface to sensor. Some sensors can implement additional functions. The additional functions are de...
rd_sensor_data_fp data_get
rd_sensor_data_fp
rd_configuration_fp configuration_set
rd_configuration_fp
rd_sensor_setup_fp samplerate_get
rd_sensor_setup_fp
rd_sensor_setup_fp resolution_get
rd_sensor_setup_fp
rd_sensor_init_fp uninit
rd_sensor_init_fp
rd_configuration_fp configuration_get
rd_configuration_fp
rd_sensor_dsp_fp dsp_get
rd_sensor_dsp_fp
rd_sensor_data_fields_t provides
Description of data fields the sensor is able to provide.
rd_sensor_dsp_fp dsp_set
rd_sensor_dsp_fp
rd_sensor_setup_fp mode_set
rd_sensor_setup_fp
const char * name
Sensor human-readable name. Should be at most 8 bytes long.
rd_sensor_setup_fp mode_get
rd_sensor_setup_fp
rd_sensor_setup_fp samplerate_set
rd_sensor_setup_fp
rd_sensor_init_fp init
rd_sensor_init_fp
rd_sensor_setup_fp scale_set
rd_sensor_setup_fp
rd_sensor_setup_fp resolution_set
rd_sensor_setup_fp
rd_sensor_setup_fp scale_get
rd_sensor_setup_fp
Union to access sensor data.
uint32_t bitfield
Bitfield used to access sensor data.
rd_sensor_data_bitfield_t datas
Structured data field.