MLX90632 Driver Library  a258525c
Universal MCU library for the 90632
mlx90632_extended_meas.c
Go to the documentation of this file.
1 
27 #include <stdint.h>
28 #include <math.h>
29 #include <errno.h>
30 
31 #include "mlx90632.h"
32 #include "mlx90632_depends.h"
33 
34 #define POW10 10000000000LL
35 
36 #ifndef VERSION
37 #define VERSION "test"
38 #endif
39 
40 #ifndef STATIC
41 #define STATIC static
42 #endif
43 
54 STATIC int32_t mlx90632_read_temp_ambient_raw_extended(int16_t *ambient_new_raw, int16_t *ambient_old_raw)
55 {
56  int32_t ret;
57  uint16_t read_tmp;
58 
59  ret = mlx90632_i2c_read(MLX90632_RAM_3(17), &read_tmp);
60  if (ret < 0)
61  return ret;
62  *ambient_new_raw = (int16_t)read_tmp;
63 
64  ret = mlx90632_i2c_read(MLX90632_RAM_3(18), &read_tmp);
65  if (ret < 0)
66  return ret;
67  *ambient_old_raw = (int16_t)read_tmp;
68 
69  return ret;
70 }
71 
83 STATIC int32_t mlx90632_read_temp_object_raw_extended(int16_t *object_new_raw)
84 {
85  int32_t ret;
86  uint16_t read_tmp;
87  int32_t read;
88 
89  ret = mlx90632_i2c_read(MLX90632_RAM_1(17), &read_tmp);
90  if (ret < 0)
91  return ret;
92 
93  read = (int16_t)read_tmp;
94 
95  ret = mlx90632_i2c_read(MLX90632_RAM_2(17), &read_tmp);
96  if (ret < 0)
97  return ret;
98 
99  read = read - (int16_t)read_tmp;
100 
101  ret = mlx90632_i2c_read(MLX90632_RAM_1(18), &read_tmp);
102  if (ret < 0)
103  return ret;
104 
105  read = read - (int16_t)read_tmp;
106 
107  ret = mlx90632_i2c_read(MLX90632_RAM_2(18), &read_tmp);
108  if (ret < 0)
109  return ret;
110 
111  read = (read + (int16_t)read_tmp) / 2;
112 
113  ret = mlx90632_i2c_read(MLX90632_RAM_1(19), &read_tmp);
114  if (ret < 0)
115  return ret;
116 
117  read = read + (int16_t)read_tmp;
118 
119  ret = mlx90632_i2c_read(MLX90632_RAM_2(19), &read_tmp);
120  if (ret < 0)
121  return ret;
122 
123  read = read + (int16_t)read_tmp;
124 
125  if (read > 32767 || read < -32768)
126  return -EINVAL;
127 
128  *object_new_raw = (int16_t)read;
129 
130  return ret;
131 }
132 
133 int32_t mlx90632_read_temp_raw_extended(int16_t *ambient_new_raw, int16_t *ambient_old_raw, int16_t *object_new_raw)
134 {
135  int32_t ret, start_measurement_ret;
136  int tries = 3;
137 
138  // trigger and wait for measurement to complete
139  while (tries-- > 0)
140  {
141  start_measurement_ret = mlx90632_start_measurement();
142  if (start_measurement_ret < 0)
143  return start_measurement_ret;
144 
145  if (start_measurement_ret == 19)
146  break;
147  }
148 
149  if (tries < 0)
150  {
151  // data not ready
152  return -ETIMEDOUT;
153  }
154 
156  ret = mlx90632_read_temp_ambient_raw_extended(ambient_new_raw, ambient_old_raw);
157  if (ret < 0)
158  return ret;
159 
161  ret = mlx90632_read_temp_object_raw_extended(object_new_raw);
162 
163  return ret;
164 }
165 
166 int32_t mlx90632_read_temp_raw_extended_burst(int16_t *ambient_new_raw, int16_t *ambient_old_raw, int16_t *object_new_raw)
167 {
168  int32_t ret, start_measurement_ret;
169 
170  // trigger and wait for measurement to complete
171  start_measurement_ret = mlx90632_start_measurement_burst();
172  if (start_measurement_ret < 0)
173  return start_measurement_ret;
174 
176  ret = mlx90632_read_temp_ambient_raw_extended(ambient_new_raw, ambient_old_raw);
177  if (ret < 0)
178  return ret;
179 
181  ret = mlx90632_read_temp_object_raw_extended(object_new_raw);
182 
183  return ret;
184 }
185 
186 double mlx90632_preprocess_temp_ambient_extended(int16_t ambient_new_raw, int16_t ambient_old_raw, int16_t Gb)
187 {
188  double VR_Ta, kGb;
189 
190  kGb = ((double)Gb) / 1024.0;
191 
192  VR_Ta = ambient_old_raw + kGb * (ambient_new_raw / (MLX90632_REF_3));
193  return ((ambient_new_raw / (MLX90632_REF_3)) / VR_Ta) * 524288.0;
194 }
195 
196 double mlx90632_preprocess_temp_object_extended(int16_t object_new_raw, int16_t ambient_new_raw,
197  int16_t ambient_old_raw, int16_t Ka)
198 {
199  double VR_IR, kKa;
200 
201  kKa = ((double)Ka) / 1024.0;
202 
203  VR_IR = ambient_old_raw + kKa * (ambient_new_raw / (MLX90632_REF_3));
204  return ((object_new_raw / (MLX90632_REF_12)) / VR_IR) * 524288.0;
205 }
206 
207 double mlx90632_calc_temp_ambient_extended(int16_t ambient_new_raw, int16_t ambient_old_raw, int32_t P_T,
208  int32_t P_R, int32_t P_G, int32_t P_O, int16_t Gb)
209 {
210  double Asub, Bsub, Ablock, Bblock, Cblock, AMB;
211 
212  AMB = mlx90632_preprocess_temp_ambient_extended(ambient_new_raw, ambient_old_raw, Gb);
213 
214  Asub = ((double)P_T) / (double)17592186044416.0;
215  Bsub = AMB - ((double)P_R / (double)256.0);
216  Ablock = Asub * (Bsub * Bsub);
217  Bblock = (Bsub / (double)P_G) * (double)1048576.0;
218  Cblock = (double)P_O / (double)256.0;
219 
220  return Bblock + Ablock + Cblock;
221 }
222 
244 static double mlx90632_calc_temp_object_iteration_extended(double prev_object_temp, int32_t object, double TAdut, double TaTr4,
245  int32_t Ga, int32_t Fa, int32_t Fb, int16_t Ha, int16_t Hb,
246  double emissivity)
247 {
248  double calcedGa, calcedGb, calcedFa, first_sqrt;
249  // temp variables
250  double KsTAtmp, Alpha_corr;
251  double Ha_customer, Hb_customer;
252 
253  Ha_customer = Ha / ((double)16384.0);
254  Hb_customer = Hb / ((double)1024.0);
255  calcedGa = ((double)Ga * (prev_object_temp - 25)) / ((double)68719476736.0);
256  KsTAtmp = (double)Fb * (TAdut - 25);
257  calcedGb = KsTAtmp / ((double)68719476736.0);
258  Alpha_corr = (((double)(Fa * POW10)) * Ha_customer * (double)(1.0 + calcedGa + calcedGb)) /
259  ((double)70368744177664.0);
260  calcedFa = object / (emissivity * (Alpha_corr / POW10));
261 
262  first_sqrt = sqrt(calcedFa + TaTr4);
263 
264  return sqrt(first_sqrt) - 273.15 - Hb_customer;
265 }
266 
267 double mlx90632_calc_temp_object_extended(int32_t object, int32_t ambient, double reflected,
268  int32_t Ea, int32_t Eb, int32_t Ga, int32_t Fa, int32_t Fb,
269  int16_t Ha, int16_t Hb)
270 {
271  double kEa, kEb, TAdut;
272  double temp = 25.0;
273  double tmp_emi = mlx90632_get_emissivity();
274  double TaTr4;
275  double ta4;
276  int8_t i;
277 
278  kEa = ((double)Ea) / ((double)65536.0);
279  kEb = ((double)Eb) / ((double)256.0);
280  TAdut = (((double)ambient) - kEb) / kEa + 25;
281 
282  TaTr4 = reflected + 273.15;
283  TaTr4 = TaTr4 * TaTr4;
284  TaTr4 = TaTr4 * TaTr4;
285  ta4 = TAdut + 273.15;
286  ta4 = ta4 * ta4;
287  ta4 = ta4 * ta4;
288  TaTr4 = TaTr4 - (TaTr4 - ta4) / tmp_emi;
289 
290  //iterate through calculations
291  for (i = 0; i < 5; ++i)
292  {
293  temp = mlx90632_calc_temp_object_iteration_extended(temp, object, TAdut, TaTr4, Ga, Fa / 2, Fb, Ha, Hb, tmp_emi);
294  }
295 
296  return temp;
297 }
298 
299 int32_t mlx90632_set_meas_type(uint8_t type)
300 {
301  int32_t ret;
302  uint16_t reg_ctrl;
303 
305  return -EINVAL;
306 
307  ret = mlx90632_addressed_reset();
308  if (ret < 0)
309  return ret;
310 
311  ret = mlx90632_i2c_read(MLX90632_REG_CTRL, &reg_ctrl);
312  if (ret < 0)
313  return ret;
314 
315  reg_ctrl = reg_ctrl & (~MLX90632_CFG_MTYP_MASK & ~MLX90632_CFG_PWR_MASK);
317 
318  ret = mlx90632_i2c_write(MLX90632_REG_CTRL, reg_ctrl);
319  if (ret < 0)
320  return ret;
321 
322  ret = mlx90632_i2c_read(MLX90632_REG_CTRL, &reg_ctrl);
323  if (ret < 0)
324  return ret;
325 
326  reg_ctrl = reg_ctrl & ~MLX90632_CFG_PWR_MASK;
328  {
329  reg_ctrl |= MLX90632_PWR_STATUS_SLEEP_STEP;
330  }
331  else
332  {
333  reg_ctrl |= MLX90632_PWR_STATUS_CONTINUOUS;
334  }
335 
336  ret = mlx90632_i2c_write(MLX90632_REG_CTRL, reg_ctrl);
337 
338  return ret;
339 }
340 
342 {
343  int32_t ret;
344  uint16_t reg_ctrl;
345  uint16_t reg_temp;
346 
347  ret = mlx90632_i2c_read(MLX90632_REG_CTRL, &reg_temp);
348  if (ret < 0)
349  return ret;
350 
351  reg_ctrl = MLX90632_MTYP(reg_temp);
352 
353  if ((reg_ctrl != MLX90632_MTYP_MEDICAL) & (reg_ctrl != MLX90632_MTYP_EXTENDED))
354  return -EINVAL;
355 
356  reg_temp = MLX90632_CFG_PWR(reg_temp);
357 
358  if (reg_temp == MLX90632_PWR_STATUS_SLEEP_STEP)
359  return MLX90632_BURST_MEASUREMENT_TYPE(reg_ctrl);
360 
361  if (reg_temp != MLX90632_PWR_STATUS_CONTINUOUS)
362  return -EINVAL;
363 
364  return reg_ctrl;
365 }
#define MLX90632_RAM_3(meas_num)
Definition: mlx90632.h:178
#define MLX90632_MEASUREMENT_TYPE_STATUS(mtyp_type)
Extract the measurement type from MTYP.
Definition: mlx90632.h:201
#define MLX90632_RAM_1(meas_num)
Definition: mlx90632.h:176
int32_t mlx90632_i2c_read(int16_t register_address, uint16_t *value)
Read the register_address value from the mlx90632.
#define MLX90632_MTYP_MEDICAL_BURST
Definition: mlx90632.h:197
#define MLX90632_CFG_MTYP_MASK
Meas select Mask.
Definition: mlx90632.h:146
#define MLX90632_REF_3
ResCtrlRef value of Channel 3.
Definition: mlx90632.h:191
#define MLX90632_MEASUREMENT_BURST_STATUS(mtyp_type)
Extract the measurement burst/continuous type from MTYP.
Definition: mlx90632.h:202
#define MLX90632_MTYP(reg_val)
Extract MTYP from Control register.
Definition: mlx90632.h:162
int32_t mlx90632_start_measurement_burst(void)
Trigger start of burst measurement for mlx90632.
Definition: mlx90632.c:553
int32_t mlx90632_set_meas_type(uint8_t type)
Switch the measurement type of the MLX90632.
#define MLX90632_RAM_2(meas_num)
Definition: mlx90632.h:177
#define MLX90632_PWR_STATUS_SLEEP_STEP
Pwrmode sleep step.
Definition: mlx90632.h:155
#define MLX90632_MTYP_MEDICAL
Definition: mlx90632.h:195
STATIC int32_t mlx90632_read_temp_object_raw_extended(int16_t *object_new_raw)
Read object raw values for the extended range based on mlx90632_start_measurement return value...
#define MLX90632_MTYP_EXTENDED
Definition: mlx90632.h:196
#define STATIC
#define MLX90632_MTYP_EXTENDED_BURST
Definition: mlx90632.h:198
int32_t mlx90632_i2c_write(int16_t register_address, uint16_t value)
Write value to register_address of the mlx90632.
int32_t mlx90632_get_meas_type(void)
Get the current measurement type set in the MLX90632.
#define MLX90632_BURST_MEASUREMENT_TYPE(meas_type)
The MSBit is only used in the software to indicate burst type measurement.
Definition: mlx90632.h:199
static double mlx90632_calc_temp_object_iteration_extended(double prev_object_temp, int32_t object, double TAdut, double TaTr4, int32_t Ga, int32_t Fa, int32_t Fb, int16_t Ha, int16_t Hb, double emissivity)
Iterative calculation of object temperature.
#define MLX90632_PWR_STATUS_HALT
Pwrmode hold.
Definition: mlx90632.h:154
#define MLX90632_MTYP_STATUS(ctrl_val)
Definition: mlx90632.h:159
MLX90632 driver with virtual i2c communication.
#define MLX90632_CFG_PWR(ctrl_val)
Extract the PowerMode bits.
Definition: mlx90632.h:144
#define POW10
STATIC int32_t mlx90632_read_temp_ambient_raw_extended(int16_t *ambient_new_raw, int16_t *ambient_old_raw)
Read ambient raw old and new values for the extended range based on mlx90632_start_measurement return...
MLX90632 driver dependencies.
#define MLX90632_REF_12
ResCtrlRef value of Channel 1 or Channel 2.
Definition: mlx90632.h:190
double mlx90632_calc_temp_object_extended(int32_t object, int32_t ambient, double reflected, int32_t Ea, int32_t Eb, int32_t Ga, int32_t Fa, int32_t Fb, int16_t Ha, int16_t Hb)
Calculation of object temperature for the extended range.
double mlx90632_preprocess_temp_object_extended(int16_t object_new_raw, int16_t ambient_new_raw, int16_t ambient_old_raw, int16_t Ka)
Calculation of raw object output for the extended range.
int32_t mlx90632_read_temp_raw_extended(int16_t *ambient_new_raw, int16_t *ambient_old_raw, int16_t *object_new_raw)
Read raw ambient and object temperature for extended range.
int32_t mlx90632_addressed_reset(void)
Trigger system reset for mlx90632.
Definition: mlx90632.c:475
#define MLX90632_PWR_STATUS_CONTINUOUS
Pwrmode continuous.
Definition: mlx90632.h:157
double mlx90632_get_emissivity(void)
Read value of emissivity.
Definition: mlx90632.c:377
#define EINVAL
From linux errno.h.
Definition: mlx90632.h:49
#define MLX90632_CFG_PWR_MASK
PowerMode Mask.
Definition: mlx90632.h:143
#define MLX90632_REG_CTRL
Control Register address.
Definition: mlx90632.h:140
int32_t mlx90632_read_temp_raw_extended_burst(int16_t *ambient_new_raw, int16_t *ambient_old_raw, int16_t *object_new_raw)
Read raw ambient and object temperature for extended range sleeping step mode.
double mlx90632_preprocess_temp_ambient_extended(int16_t ambient_new_raw, int16_t ambient_old_raw, int16_t Gb)
Calculation of raw ambient output for the extended range.
double mlx90632_calc_temp_ambient_extended(int16_t ambient_new_raw, int16_t ambient_old_raw, int32_t P_T, int32_t P_R, int32_t P_G, int32_t P_O, int16_t Gb)
Calculation of ambient temperature for the extended range.
static double emissivity
Definition: mlx90632.c:371
#define ETIMEDOUT
From linux errno.h.
Definition: mlx90632.h:46
int mlx90632_start_measurement(void)
Trigger start measurement for mlx90632.
Definition: mlx90632.c:47