mlx90640.cpp
Go to the documentation of this file.
2 
4  this->fps = fps;
5  switch (this->fps) {
6  case 1:
7  this->setRefreshRate(MLX_I2C_ADDR, 0b001);
8  break;
9  case 2:
10  this->setRefreshRate(MLX_I2C_ADDR, 0b010);
11  break;
12  case 4:
13  this->setRefreshRate(MLX_I2C_ADDR, 0b011);
14  break;
15  case 8:
16  this->setRefreshRate(MLX_I2C_ADDR, 0b100);
17  break;
18  case 16:
19  this->setRefreshRate(MLX_I2C_ADDR, 0b101);
20  break;
21  case 32:
22  this->setRefreshRate(MLX_I2C_ADDR, 0b110);
23  break;
24  case 64:
25  this->setRefreshRate(MLX_I2C_ADDR, 0b111);
26  break;
27  default:
28  ROS_ERROR("I2C unsupported frame rate!");
29  exit(1);
30  }
31 
33  this->dumpEE(MLX_I2C_ADDR, this->eeMLX90640);
34  this->extractParameters(this->eeMLX90640, &this->sensorParams);
35 }
36 
37 void MLX90640::see() {
38  this->getFrameData(MLX_I2C_ADDR, this->frame);
39  this->eTa = this->getTa(frame, &this->sensorParams);
40  this->calculateTo(frame, &this->sensorParams, this->emissivity, this->eTa,
41  this->mlx90640To);
42  this->badPixelsCorrection((&this->sensorParams)->brokenPixels,
43  this->mlx90640To, 1, &this->sensorParams);
44  this->badPixelsCorrection((&this->sensorParams)->outlierPixels,
45  this->mlx90640To, 1, &this->sensorParams);
46  this->minTemp = 100.0;
47  this->maxTemp = 0.0;
48 
49  for (int i = 0; i < 768; i++) {
50  if (this->minTemp > this->mlx90640To[i]) {
51  this->minTemp = this->mlx90640To[i];
52  }
53  if (this->maxTemp < this->mlx90640To[i]) {
54  this->maxTemp = this->mlx90640To[i];
55  }
56  }
57 }
58 
59 void MLX90640::copyRawImage(float *pointer) {
60  for (int i = 0; i < 768; i++) {
61  pointer[i] = this->mlx90640To[i];
62  }
63 }
64 
65 float MLX90640::getMin() { return this->minTemp; }
66 
67 float MLX90640::getMax() { return this->maxTemp; }
68 
69 int MLX90640::dumpEE(uint8_t slaveAddr, uint16_t *eeData) {
70  return this->i2cDriver.read(slaveAddr, 0x2400, 832, eeData);
71 }
72 
73 int MLX90640::synchFrame(uint8_t slaveAddr) {
74  uint16_t dataReady = 0;
75  uint16_t statusRegister;
76  int error = 1;
77 
78  error = this->i2cDriver.write(slaveAddr, 0x8000, 0x0030);
79  if (error == -1) {
80  return error;
81  }
82 
83  while (dataReady == 0) {
84  error = this->i2cDriver.read(slaveAddr, 0x8000, 1, &statusRegister);
85  if (error != 0) {
86  return error;
87  }
88  dataReady = statusRegister & 0x0008;
89  }
90 
91  return 0;
92 }
93 
94 int MLX90640::triggerMeasurement(uint8_t slaveAddr) {
95  int error = 1;
96  uint16_t ctrlReg;
97 
98  error = this->i2cDriver.read(slaveAddr, 0x800D, 1, &ctrlReg);
99  if (error != 0) {
100  return error;
101  }
102 
103  ctrlReg |= 0x8000;
104  error = this->i2cDriver.write(slaveAddr, 0x800D, ctrlReg);
105  if (error != 0) {
106  return error;
107  }
108 
109  error = this->i2cDriver.generalReset();
110  if (error != 0) {
111  return error;
112  }
113 
114  error = this->i2cDriver.read(slaveAddr, 0x800D, 1, &ctrlReg);
115  if (error != 0) {
116  return error;
117  }
118  if ((ctrlReg & 0x8000) != 0) {
119  return -9;
120  }
121 
122  return 0;
123 }
124 
125 int MLX90640::getFrameData(uint8_t slaveAddr, uint16_t *frameData) {
126  uint16_t dataReady = 0;
127  uint16_t controlRegister1;
128  uint16_t statusRegister;
129  int error = 1;
130  uint16_t data[64];
131  uint8_t cnt = 0;
132 
133  while (dataReady == 0) {
134  error = this->i2cDriver.read(slaveAddr, 0x8000, 1, &statusRegister);
135  if (error != 0) {
136  return error;
137  }
138  dataReady = statusRegister & 0x0008;
139  }
140 
141  error = this->i2cDriver.write(slaveAddr, 0x8000, 0x0030);
142  if (error == -1) {
143  return error;
144  }
145 
146  error = this->i2cDriver.read(slaveAddr, 0x0400, 768, frameData);
147  if (error != 0) {
148  return error;
149  }
150 
151  error = this->i2cDriver.read(slaveAddr, 0x0700, 64, data);
152  if (error != 0) {
153  return error;
154  }
155 
156  error = this->i2cDriver.read(slaveAddr, 0x800D, 1, &controlRegister1);
157  frameData[832] = controlRegister1;
158  frameData[833] = statusRegister & 0x0001;
159  if (error != 0) {
160  return error;
161  }
162 
163  error = this->validateAuxData(data);
164  if (error == 0) {
165  for (cnt = 0; cnt < 64; cnt++) {
166  frameData[cnt + 768] = data[cnt];
167  }
168  }
169 
170  error = this->validateFrameData(frameData);
171  if (error != 0) {
172  return error;
173  }
174 
175  return frameData[833];
176 }
177 
178 int MLX90640::extractParameters(uint16_t *eeData, thermalParams *mlx90640) {
179  int error = 0;
180 
181  this->extractVDDParameters(eeData, mlx90640);
182  this->extractPTATParameters(eeData, mlx90640);
183  this->extractGainParameters(eeData, mlx90640);
184  this->extractTgcParameters(eeData, mlx90640);
185  this->extractResolutionParameters(eeData, mlx90640);
186  this->extractKsTaParameters(eeData, mlx90640);
187  this->extractKsToParameters(eeData, mlx90640);
188  this->extractCPParameters(eeData, mlx90640);
189  this->extractAlphaParameters(eeData, mlx90640);
190  this->extractOffsetParameters(eeData, mlx90640);
191  this->extractKtaPixelParameters(eeData, mlx90640);
192  this->extractKvPixelParameters(eeData, mlx90640);
193  this->extractCILCParameters(eeData, mlx90640);
194  error = this->extractDeviatingPixels(eeData, mlx90640);
195 
196  return error;
197 }
198 
199 float MLX90640::getVdd(uint16_t *frameData, const thermalParams *params) {
200  float vdd;
201  float resolutionCorrection;
202 
203  int resolutionRAM;
204 
205  vdd = frameData[810];
206  if (vdd > 32767) {
207  vdd = vdd - 65536;
208  }
209  resolutionRAM = (frameData[832] & 0x0C00) >> 10;
210  resolutionCorrection =
211  pow(2, (double)params->resolutionEE) / pow(2, (double)resolutionRAM);
212  vdd = (resolutionCorrection * vdd - params->vdd25) / params->kVdd + 3.3;
213 
214  return vdd;
215 }
216 
217 float MLX90640::getTa(uint16_t *frameData, const thermalParams *params) {
218  float ptat;
219  float ptatArt;
220  float vdd;
221  float ta;
222 
223  vdd = this->getVdd(frameData, params);
224  ptat = frameData[800];
225  if (ptat > 32767) {
226  ptat = ptat - 65536;
227  }
228 
229  ptatArt = frameData[768];
230  if (ptatArt > 32767) {
231  ptatArt = ptatArt - 65536;
232  }
233  ptatArt = (ptat / (ptat * params->alphaPTAT + ptatArt)) * pow(2, (double)18);
234 
235  ta = (ptatArt / (1 + params->KvPTAT * (vdd - 3.3)) - params->vPTAT25);
236  ta = ta / params->KtPTAT + 25;
237 
238  return ta;
239 }
240 
241 void MLX90640::getImage(uint16_t *frameData, const thermalParams *params,
242  float *result) {
243  float vdd;
244  float ta;
245  float gain;
246  float irDataCP[2];
247  float irData;
248  float alphaCompensated;
249  uint8_t mode;
250  int8_t ilPattern;
251  int8_t chessPattern;
252  int8_t pattern;
253  int8_t conversionPattern;
254  float image;
255  uint16_t subPage;
256  float ktaScale;
257  float kvScale;
258  float kta;
259  float kv;
260 
261  subPage = frameData[833];
262  vdd = this->getVdd(frameData, params);
263  ta = this->getTa(frameData, params);
264 
265  ktaScale = pow(2, (double)params->ktaScale);
266  kvScale = pow(2, (double)params->kvScale);
267 
268  gain = frameData[778];
269  if (gain > 32767) {
270  gain = gain - 65536;
271  }
272  gain = params->gainEE / gain;
273 
274  mode = (frameData[832] & 0x1000) >> 5;
275 
276  irDataCP[0] = frameData[776];
277  irDataCP[1] = frameData[808];
278  for (int i = 0; i < 2; i++) {
279  if (irDataCP[i] > 32767) {
280  irDataCP[i] = irDataCP[i] - 65536;
281  }
282  irDataCP[i] = irDataCP[i] * gain;
283  }
284  irDataCP[0] = irDataCP[0] - params->cpOffset[0] *
285  (1 + params->cpKta * (ta - 25)) *
286  (1 + params->cpKv * (vdd - 3.3));
287  if (mode == params->calibrationModeEE) {
288  irDataCP[1] = irDataCP[1] - params->cpOffset[1] *
289  (1 + params->cpKta * (ta - 25)) *
290  (1 + params->cpKv * (vdd - 3.3));
291  } else {
292  irDataCP[1] = irDataCP[1] - (params->cpOffset[1] + params->ilChessC[0]) *
293  (1 + params->cpKta * (ta - 25)) *
294  (1 + params->cpKv * (vdd - 3.3));
295  }
296 
297  for (int pixelNumber = 0; pixelNumber < 768; pixelNumber++) {
298  ilPattern = pixelNumber / 32 - (pixelNumber / 64) * 2;
299  chessPattern = ilPattern ^ (pixelNumber - (pixelNumber / 2) * 2);
300  conversionPattern = ((pixelNumber + 2) / 4 - (pixelNumber + 3) / 4 +
301  (pixelNumber + 1) / 4 - pixelNumber / 4) *
302  (1 - 2 * ilPattern);
303 
304  if (mode == 0) {
305  pattern = ilPattern;
306  } else {
307  pattern = chessPattern;
308  }
309 
310  if (pattern == frameData[833]) {
311  irData = frameData[pixelNumber];
312  if (irData > 32767) {
313  irData = irData - 65536;
314  }
315  irData = irData * gain;
316 
317  kta = params->kta[pixelNumber] / ktaScale;
318  kv = params->kv[pixelNumber] / kvScale;
319  irData = irData - params->offset[pixelNumber] * (1 + kta * (ta - 25)) *
320  (1 + kv * (vdd - 3.3));
321 
322  if (mode != params->calibrationModeEE) {
323  irData = irData + params->ilChessC[2] * (2 * ilPattern - 1) -
324  params->ilChessC[1] * conversionPattern;
325  }
326 
327  irData = irData - params->tgc * irDataCP[subPage];
328 
329  alphaCompensated = params->alpha[pixelNumber];
330 
331  image = irData * alphaCompensated;
332 
333  result[pixelNumber] = image;
334  }
335  }
336 }
337 
338 void MLX90640::calculateTo(uint16_t *frameData, const thermalParams *params,
339  float emissivity, float tr, float *result) {
340  float vdd;
341  float ta;
342  float ta4;
343  float tr4;
344  float taTr;
345  float gain;
346  float irDataCP[2];
347  float irData;
348  float alphaCompensated;
349  uint8_t mode;
350  int8_t ilPattern;
351  int8_t chessPattern;
352  int8_t pattern;
353  int8_t conversionPattern;
354  float Sx;
355  float To;
356  float alphaCorrR[4];
357  int8_t range;
358  uint16_t subPage;
359  float ktaScale;
360  float kvScale;
361  float alphaScale;
362  float kta;
363  float kv;
364 
365  subPage = frameData[833];
366  vdd = this->getVdd(frameData, params);
367  ta = this->getTa(frameData, params);
368 
369  ta4 = (ta + 273.15);
370  ta4 = ta4 * ta4;
371  ta4 = ta4 * ta4;
372  tr4 = (tr + 273.15);
373  tr4 = tr4 * tr4;
374  tr4 = tr4 * tr4;
375  taTr = tr4 - (tr4 - ta4) / emissivity;
376 
377  ktaScale = pow(2, (double)params->ktaScale);
378  kvScale = pow(2, (double)params->kvScale);
379  alphaScale = pow(2, (double)params->alphaScale);
380 
381  alphaCorrR[0] = 1 / (1 + params->ksTo[0] * 40);
382  alphaCorrR[1] = 1;
383  alphaCorrR[2] = (1 + params->ksTo[1] * params->ct[2]);
384  alphaCorrR[3] =
385  alphaCorrR[2] * (1 + params->ksTo[2] * (params->ct[3] - params->ct[2]));
386 
387  gain = frameData[778];
388  if (gain > 32767) {
389  gain = gain - 65536;
390  }
391  gain = params->gainEE / gain;
392 
393  mode = (frameData[832] & 0x1000) >> 5;
394 
395  irDataCP[0] = frameData[776];
396  irDataCP[1] = frameData[808];
397  for (int i = 0; i < 2; i++) {
398  if (irDataCP[i] > 32767) {
399  irDataCP[i] = irDataCP[i] - 65536;
400  }
401  irDataCP[i] = irDataCP[i] * gain;
402  }
403  irDataCP[0] = irDataCP[0] - params->cpOffset[0] *
404  (1 + params->cpKta * (ta - 25)) *
405  (1 + params->cpKv * (vdd - 3.3));
406  if (mode == params->calibrationModeEE) {
407  irDataCP[1] = irDataCP[1] - params->cpOffset[1] *
408  (1 + params->cpKta * (ta - 25)) *
409  (1 + params->cpKv * (vdd - 3.3));
410  } else {
411  irDataCP[1] = irDataCP[1] - (params->cpOffset[1] + params->ilChessC[0]) *
412  (1 + params->cpKta * (ta - 25)) *
413  (1 + params->cpKv * (vdd - 3.3));
414  }
415 
416  for (int pixelNumber = 0; pixelNumber < 768; pixelNumber++) {
417  ilPattern = pixelNumber / 32 - (pixelNumber / 64) * 2;
418  chessPattern = ilPattern ^ (pixelNumber - (pixelNumber / 2) * 2);
419  conversionPattern = ((pixelNumber + 2) / 4 - (pixelNumber + 3) / 4 +
420  (pixelNumber + 1) / 4 - pixelNumber / 4) *
421  (1 - 2 * ilPattern);
422 
423  if (mode == 0) {
424  pattern = ilPattern;
425  } else {
426  pattern = chessPattern;
427  }
428 
429  if (pattern == frameData[833]) {
430  irData = frameData[pixelNumber];
431  if (irData > 32767) {
432  irData = irData - 65536;
433  }
434  irData = irData * gain;
435 
436  kta = params->kta[pixelNumber] / ktaScale;
437  kv = params->kv[pixelNumber] / kvScale;
438  irData = irData - params->offset[pixelNumber] * (1 + kta * (ta - 25)) *
439  (1 + kv * (vdd - 3.3));
440 
441  if (mode != params->calibrationModeEE) {
442  irData = irData + params->ilChessC[2] * (2 * ilPattern - 1) -
443  params->ilChessC[1] * conversionPattern;
444  }
445 
446  irData = irData - params->tgc * irDataCP[subPage];
447  irData = irData / emissivity;
448 
449  alphaCompensated = SCALEALPHA * alphaScale / params->alpha[pixelNumber];
450  alphaCompensated = alphaCompensated * (1 + params->KsTa * (ta - 25));
451 
452  Sx = alphaCompensated * alphaCompensated * alphaCompensated *
453  (irData + alphaCompensated * taTr);
454  Sx = sqrt(sqrt(Sx)) * params->ksTo[1];
455 
456  To = sqrt(sqrt(
457  irData /
458  (alphaCompensated * (1 - params->ksTo[1] * 273.15) + Sx) +
459  taTr)) -
460  273.15;
461 
462  if (To < params->ct[1]) {
463  range = 0;
464  } else if (To < params->ct[2]) {
465  range = 1;
466  } else if (To < params->ct[3]) {
467  range = 2;
468  } else {
469  range = 3;
470  }
471 
472  To = sqrt(sqrt(
473  irData / (alphaCompensated * alphaCorrR[range] *
474  (1 + params->ksTo[range] * (To - params->ct[range]))) +
475  taTr)) -
476  273.15;
477  result[pixelNumber] = To;
478  }
479  }
480 }
481 
482 int MLX90640::setResolution(uint8_t slaveAddr, uint8_t resolution) {
483  uint16_t controlRegister1;
484  int value;
485  int error;
486 
487  value = (resolution & 0x03) << 10;
488  error = this->i2cDriver.read(slaveAddr, 0x800D, 1, &controlRegister1);
489  if (error == 0) {
490  value = (controlRegister1 & 0xF3FF) | value;
491  error = this->i2cDriver.write(slaveAddr, 0x800D, value);
492  }
493 
494  return error;
495 }
496 
497 int MLX90640::getCurResolution(uint8_t slaveAddr) {
498  uint16_t controlRegister1;
499  int resolutionRAM;
500  int error;
501 
502  error = this->i2cDriver.read(slaveAddr, 0x800D, 1, &controlRegister1);
503  if (error != 0) {
504  return error;
505  }
506  resolutionRAM = (controlRegister1 & 0x0C00) >> 10;
507 
508  return resolutionRAM;
509 }
510 
511 int MLX90640::setRefreshRate(uint8_t slaveAddr, uint8_t refreshRate) {
512  uint16_t controlRegister1;
513  int value;
514  int error;
515 
516  value = (refreshRate & 0x07) << 7;
517  if (error == 0) {
518  value = (controlRegister1 & 0xFC7F) | value;
519  error = this->i2cDriver.write(slaveAddr, 0x800D, value);
520  }
521 
522  return error;
523 }
524 
525 int MLX90640::getRefreshRate(uint8_t slaveAddr) {
526  uint16_t controlRegister1;
527  int refreshRate;
528  int error;
529 
530  error = this->i2cDriver.read(slaveAddr, 0x800D, 1, &controlRegister1);
531  if (error != 0) {
532  return error;
533  }
534  refreshRate = (controlRegister1 & 0x0380) >> 7;
535 
536  return refreshRate;
537 }
538 
539 int MLX90640::getSubPageNumber(uint16_t *frameData) { return frameData[833]; }
540 
541 int MLX90640::getCurMode(uint8_t slaveAddr) {
542  uint16_t controlRegister1;
543  int modeRAM;
544  int error;
545 
546  error = this->i2cDriver.read(slaveAddr, 0x800D, 1, &controlRegister1);
547  if (error != 0) {
548  return error;
549  }
550  modeRAM = (controlRegister1 & 0x1000) >> 12;
551 
552  return modeRAM;
553 }
554 
555 int MLX90640::setInterleavedMode(uint8_t slaveAddr) {
556  uint16_t controlRegister1;
557  int value;
558  int error;
559 
560  error = this->i2cDriver.read(slaveAddr, 0x800D, 1, &controlRegister1);
561  if (error == 0) {
562  value = (controlRegister1 & 0xEFFF);
563  error = this->i2cDriver.write(slaveAddr, 0x800D, value);
564  }
565 
566  return error;
567 }
568 
569 int MLX90640::setChessMode(uint8_t slaveAddr) {
570  uint16_t controlRegister1;
571  int value;
572  int error;
573 
574  error = this->i2cDriver.read(slaveAddr, 0x800D, 1, &controlRegister1);
575  if (error == 0) {
576  value = (controlRegister1 | 0x1000);
577  error = this->i2cDriver.write(slaveAddr, 0x800D, value);
578  }
579 
580  return error;
581 }
582 
583 void MLX90640::badPixelsCorrection(uint16_t *pixels, float *to, int mode,
584  thermalParams *params) {
585  float ap[4];
586  uint8_t pix;
587  uint8_t line;
588  uint8_t column;
589 
590  pix = 0;
591  while (pixels[pix] != 0xFFFF) {
592  line = pixels[pix] >> 5;
593  column = pixels[pix] - (line << 5);
594 
595  if (mode == 1) {
596  if (line == 0) {
597  if (column == 0) {
598  to[pixels[pix]] = to[33];
599  } else if (column == 31) {
600  to[pixels[pix]] = to[62];
601  } else {
602  to[pixels[pix]] = (to[pixels[pix] + 31] + to[pixels[pix] + 33]) / 2.0;
603  }
604  } else if (line == 23) {
605  if (column == 0) {
606  to[pixels[pix]] = to[705];
607  } else if (column == 31) {
608  to[pixels[pix]] = to[734];
609  } else {
610  to[pixels[pix]] = (to[pixels[pix] - 33] + to[pixels[pix] - 31]) / 2.0;
611  }
612  } else if (column == 0) {
613  to[pixels[pix]] = (to[pixels[pix] - 31] + to[pixels[pix] + 33]) / 2.0;
614  } else if (column == 31) {
615  to[pixels[pix]] = (to[pixels[pix] - 33] + to[pixels[pix] + 31]) / 2.0;
616  } else {
617  ap[0] = to[pixels[pix] - 33];
618  ap[1] = to[pixels[pix] - 31];
619  ap[2] = to[pixels[pix] + 31];
620  ap[3] = to[pixels[pix] + 33];
621  to[pixels[pix]] = this->getMedian(ap, 4);
622  }
623  } else {
624  if (column == 0) {
625  to[pixels[pix]] = to[pixels[pix] + 1];
626  } else if (column == 1 || column == 30) {
627  to[pixels[pix]] = (to[pixels[pix] - 1] + to[pixels[pix] + 1]) / 2.0;
628  } else if (column == 31) {
629  to[pixels[pix]] = to[pixels[pix] - 1];
630  } else {
631  if (this->isPixelBad(pixels[pix] - 2, params) == 0 &&
632  this->isPixelBad(pixels[pix] + 2, params) == 0) {
633  ap[0] = to[pixels[pix] + 1] - to[pixels[pix] + 2];
634  ap[1] = to[pixels[pix] - 1] - to[pixels[pix] - 2];
635  if (fabs(ap[0]) > fabs(ap[1])) {
636  to[pixels[pix]] = to[pixels[pix] - 1] + ap[1];
637  } else {
638  to[pixels[pix]] = to[pixels[pix] + 1] + ap[0];
639  }
640  } else {
641  to[pixels[pix]] = (to[pixels[pix] - 1] + to[pixels[pix] + 1]) / 2.0;
642  }
643  }
644  }
645  pix = pix + 1;
646  }
647 }
648 
649 void MLX90640::extractVDDParameters(uint16_t *eeData, thermalParams *mlx90640) {
650  int16_t kVdd;
651  int16_t vdd25;
652 
653  kVdd = eeData[51];
654 
655  kVdd = (eeData[51] & 0xFF00) >> 8;
656  if (kVdd > 127) {
657  kVdd = kVdd - 256;
658  }
659  kVdd = 32 * kVdd;
660  vdd25 = eeData[51] & 0x00FF;
661  vdd25 = ((vdd25 - 256) << 5) - 8192;
662 
663  mlx90640->kVdd = kVdd;
664  mlx90640->vdd25 = vdd25;
665 }
666 
667 void MLX90640::extractPTATParameters(uint16_t *eeData,
668  thermalParams *mlx90640) {
669  float KvPTAT;
670  float KtPTAT;
671  int16_t vPTAT25;
672  float alphaPTAT;
673 
674  KvPTAT = (eeData[50] & 0xFC00) >> 10;
675  if (KvPTAT > 31) {
676  KvPTAT = KvPTAT - 64;
677  }
678  KvPTAT = KvPTAT / 4096;
679 
680  KtPTAT = eeData[50] & 0x03FF;
681  if (KtPTAT > 511) {
682  KtPTAT = KtPTAT - 1024;
683  }
684  KtPTAT = KtPTAT / 8;
685 
686  vPTAT25 = eeData[49];
687 
688  alphaPTAT = (eeData[16] & 0xF000) / pow(2, (double)14) + 8.0f;
689 
690  mlx90640->KvPTAT = KvPTAT;
691  mlx90640->KtPTAT = KtPTAT;
692  mlx90640->vPTAT25 = vPTAT25;
693  mlx90640->alphaPTAT = alphaPTAT;
694 }
695 
696 void MLX90640::extractGainParameters(uint16_t *eeData,
697  thermalParams *mlx90640) {
698  int16_t gainEE;
699 
700  gainEE = eeData[48];
701  if (gainEE > 32767) {
702  gainEE = gainEE - 65536;
703  }
704 
705  mlx90640->gainEE = gainEE;
706 }
707 
708 void MLX90640::extractTgcParameters(uint16_t *eeData, thermalParams *mlx90640) {
709  float tgc;
710  tgc = eeData[60] & 0x00FF;
711  if (tgc > 127) {
712  tgc = tgc - 256;
713  }
714  tgc = tgc / 32.0f;
715 
716  mlx90640->tgc = tgc;
717 }
718 
720  thermalParams *mlx90640) {
721  uint8_t resolutionEE;
722  resolutionEE = (eeData[56] & 0x3000) >> 12;
723 
724  mlx90640->resolutionEE = resolutionEE;
725 }
726 
727 void MLX90640::extractKsTaParameters(uint16_t *eeData,
728  thermalParams *mlx90640) {
729  float KsTa;
730  KsTa = (eeData[60] & 0xFF00) >> 8;
731  if (KsTa > 127) {
732  KsTa = KsTa - 256;
733  }
734  KsTa = KsTa / 8192.0f;
735 
736  mlx90640->KsTa = KsTa;
737 }
738 
739 void MLX90640::extractKsToParameters(uint16_t *eeData,
740  thermalParams *mlx90640) {
741  int32_t KsToScale;
742  int8_t step;
743 
744  step = ((eeData[63] & 0x3000) >> 12) * 10;
745 
746  mlx90640->ct[0] = -40;
747  mlx90640->ct[1] = 0;
748  mlx90640->ct[2] = (eeData[63] & 0x00F0) >> 4;
749  mlx90640->ct[3] = (eeData[63] & 0x0F00) >> 8;
750 
751  mlx90640->ct[2] = mlx90640->ct[2] * step;
752  mlx90640->ct[3] = mlx90640->ct[2] + mlx90640->ct[3] * step;
753  mlx90640->ct[4] = 400;
754 
755  KsToScale = (eeData[63] & 0x000F) + 8;
756  KsToScale = 1 << KsToScale;
757 
758  mlx90640->ksTo[0] = eeData[61] & 0x00FF;
759  mlx90640->ksTo[1] = (eeData[61] & 0xFF00) >> 8;
760  mlx90640->ksTo[2] = eeData[62] & 0x00FF;
761  mlx90640->ksTo[3] = (eeData[62] & 0xFF00) >> 8;
762 
763  for (int i = 0; i < 4; i++) {
764  if (mlx90640->ksTo[i] > 127) {
765  mlx90640->ksTo[i] = mlx90640->ksTo[i] - 256;
766  }
767  mlx90640->ksTo[i] = mlx90640->ksTo[i] / KsToScale;
768  }
769 
770  mlx90640->ksTo[4] = -0.0002;
771 }
772 
773 void MLX90640::extractAlphaParameters(uint16_t *eeData,
774  thermalParams *mlx90640) {
775  int accRow[24];
776  int accColumn[32];
777  int p = 0;
778  int alphaRef;
779  uint8_t alphaScale;
780  uint8_t accRowScale;
781  uint8_t accColumnScale;
782  uint8_t accRemScale;
783  float alphaTemp[768];
784  float temp;
785 
786  accRemScale = eeData[32] & 0x000F;
787  accColumnScale = (eeData[32] & 0x00F0) >> 4;
788  accRowScale = (eeData[32] & 0x0F00) >> 8;
789  alphaScale = ((eeData[32] & 0xF000) >> 12) + 30;
790  alphaRef = eeData[33];
791 
792  for (int i = 0; i < 6; i++) {
793  p = i * 4;
794  accRow[p + 0] = (eeData[34 + i] & 0x000F);
795  accRow[p + 1] = (eeData[34 + i] & 0x00F0) >> 4;
796  accRow[p + 2] = (eeData[34 + i] & 0x0F00) >> 8;
797  accRow[p + 3] = (eeData[34 + i] & 0xF000) >> 12;
798  }
799 
800  for (int i = 0; i < 24; i++) {
801  if (accRow[i] > 7) {
802  accRow[i] = accRow[i] - 16;
803  }
804  }
805 
806  for (int i = 0; i < 8; i++) {
807  p = i * 4;
808  accColumn[p + 0] = (eeData[40 + i] & 0x000F);
809  accColumn[p + 1] = (eeData[40 + i] & 0x00F0) >> 4;
810  accColumn[p + 2] = (eeData[40 + i] & 0x0F00) >> 8;
811  accColumn[p + 3] = (eeData[40 + i] & 0xF000) >> 12;
812  }
813 
814  for (int i = 0; i < 32; i++) {
815  if (accColumn[i] > 7) {
816  accColumn[i] = accColumn[i] - 16;
817  }
818  }
819 
820  for (int i = 0; i < 24; i++) {
821  for (int j = 0; j < 32; j++) {
822  p = 32 * i + j;
823  alphaTemp[p] = (eeData[64 + p] & 0x03F0) >> 4;
824  if (alphaTemp[p] > 31) {
825  alphaTemp[p] = alphaTemp[p] - 64;
826  }
827  alphaTemp[p] = alphaTemp[p] * (1 << accRemScale);
828  alphaTemp[p] = (alphaRef + (accRow[i] << accRowScale) +
829  (accColumn[j] << accColumnScale) + alphaTemp[p]);
830  alphaTemp[p] = alphaTemp[p] / pow(2, (double)alphaScale);
831  alphaTemp[p] =
832  alphaTemp[p] -
833  mlx90640->tgc * (mlx90640->cpAlpha[0] + mlx90640->cpAlpha[1]) / 2;
834  alphaTemp[p] = SCALEALPHA / alphaTemp[p];
835  }
836  }
837 
838  temp = alphaTemp[0];
839  for (int i = 1; i < 768; i++) {
840  if (alphaTemp[i] > temp) {
841  temp = alphaTemp[i];
842  }
843  }
844 
845  alphaScale = 0;
846  while (temp < 32767.4) {
847  temp = temp * 2;
848  alphaScale = alphaScale + 1;
849  }
850 
851  for (int i = 0; i < 768; i++) {
852  temp = alphaTemp[i] * pow(2, (double)alphaScale);
853  mlx90640->alpha[i] = (temp + 0.5);
854  }
855 
856  mlx90640->alphaScale = alphaScale;
857 }
858 
859 void MLX90640::extractOffsetParameters(uint16_t *eeData,
860  thermalParams *mlx90640) {
861  int occRow[24];
862  int occColumn[32];
863  int p = 0;
864  int16_t offsetRef;
865  uint8_t occRowScale;
866  uint8_t occColumnScale;
867  uint8_t occRemScale;
868 
869  occRemScale = (eeData[16] & 0x000F);
870  occColumnScale = (eeData[16] & 0x00F0) >> 4;
871  occRowScale = (eeData[16] & 0x0F00) >> 8;
872  offsetRef = eeData[17];
873  if (offsetRef > 32767) {
874  offsetRef = offsetRef - 65536;
875  }
876 
877  for (int i = 0; i < 6; i++) {
878  p = i * 4;
879  occRow[p + 0] = (eeData[18 + i] & 0x000F);
880  occRow[p + 1] = (eeData[18 + i] & 0x00F0) >> 4;
881  occRow[p + 2] = (eeData[18 + i] & 0x0F00) >> 8;
882  occRow[p + 3] = (eeData[18 + i] & 0xF000) >> 12;
883  }
884 
885  for (int i = 0; i < 24; i++) {
886  if (occRow[i] > 7) {
887  occRow[i] = occRow[i] - 16;
888  }
889  }
890 
891  for (int i = 0; i < 8; i++) {
892  p = i * 4;
893  occColumn[p + 0] = (eeData[24 + i] & 0x000F);
894  occColumn[p + 1] = (eeData[24 + i] & 0x00F0) >> 4;
895  occColumn[p + 2] = (eeData[24 + i] & 0x0F00) >> 8;
896  occColumn[p + 3] = (eeData[24 + i] & 0xF000) >> 12;
897  }
898 
899  for (int i = 0; i < 32; i++) {
900  if (occColumn[i] > 7) {
901  occColumn[i] = occColumn[i] - 16;
902  }
903  }
904 
905  for (int i = 0; i < 24; i++) {
906  for (int j = 0; j < 32; j++) {
907  p = 32 * i + j;
908  mlx90640->offset[p] = (eeData[64 + p] & 0xFC00) >> 10;
909  if (mlx90640->offset[p] > 31) {
910  mlx90640->offset[p] = mlx90640->offset[p] - 64;
911  }
912  mlx90640->offset[p] = mlx90640->offset[p] * (1 << occRemScale);
913  mlx90640->offset[p] =
914  (offsetRef + (occRow[i] << occRowScale) +
915  (occColumn[j] << occColumnScale) + mlx90640->offset[p]);
916  }
917  }
918 }
919 
921  thermalParams *mlx90640) {
922  int p = 0;
923  int8_t KtaRC[4];
924  int8_t KtaRoCo;
925  int8_t KtaRoCe;
926  int8_t KtaReCo;
927  int8_t KtaReCe;
928  uint8_t ktaScale1;
929  uint8_t ktaScale2;
930  uint8_t split;
931  float ktaTemp[768];
932  float temp;
933 
934  KtaRoCo = (eeData[54] & 0xFF00) >> 8;
935  if (KtaRoCo > 127) {
936  KtaRoCo = KtaRoCo - 256;
937  }
938  KtaRC[0] = KtaRoCo;
939 
940  KtaReCo = (eeData[54] & 0x00FF);
941  if (KtaReCo > 127) {
942  KtaReCo = KtaReCo - 256;
943  }
944  KtaRC[2] = KtaReCo;
945 
946  KtaRoCe = (eeData[55] & 0xFF00) >> 8;
947  if (KtaRoCe > 127) {
948  KtaRoCe = KtaRoCe - 256;
949  }
950  KtaRC[1] = KtaRoCe;
951 
952  KtaReCe = (eeData[55] & 0x00FF);
953  if (KtaReCe > 127) {
954  KtaReCe = KtaReCe - 256;
955  }
956  KtaRC[3] = KtaReCe;
957 
958  ktaScale1 = ((eeData[56] & 0x00F0) >> 4) + 8;
959  ktaScale2 = (eeData[56] & 0x000F);
960 
961  for (int i = 0; i < 24; i++) {
962  for (int j = 0; j < 32; j++) {
963  p = 32 * i + j;
964  split = 2 * (p / 32 - (p / 64) * 2) + p % 2;
965  ktaTemp[p] = (eeData[64 + p] & 0x000E) >> 1;
966  if (ktaTemp[p] > 3) {
967  ktaTemp[p] = ktaTemp[p] - 8;
968  }
969  ktaTemp[p] = ktaTemp[p] * (1 << ktaScale2);
970  ktaTemp[p] = KtaRC[split] + ktaTemp[p];
971  ktaTemp[p] = ktaTemp[p] / pow(2, (double)ktaScale1);
972  // ktaTemp[p] = ktaTemp[p] * mlx90640->offset[p];
973  }
974  }
975 
976  temp = fabs(ktaTemp[0]);
977  for (int i = 1; i < 768; i++) {
978  if (fabs(ktaTemp[i]) > temp) {
979  temp = fabs(ktaTemp[i]);
980  }
981  }
982 
983  ktaScale1 = 0;
984  while (temp < 63.4) {
985  temp = temp * 2;
986  ktaScale1 = ktaScale1 + 1;
987  }
988 
989  for (int i = 0; i < 768; i++) {
990  temp = ktaTemp[i] * pow(2, (double)ktaScale1);
991  if (temp < 0) {
992  mlx90640->kta[i] = (temp - 0.5);
993  } else {
994  mlx90640->kta[i] = (temp + 0.5);
995  }
996  }
997 
998  mlx90640->ktaScale = ktaScale1;
999 }
1000 
1002  thermalParams *mlx90640) {
1003  int p = 0;
1004  int8_t KvT[4];
1005  int8_t KvRoCo;
1006  int8_t KvRoCe;
1007  int8_t KvReCo;
1008  int8_t KvReCe;
1009  uint8_t kvScale;
1010  uint8_t split;
1011  float kvTemp[768];
1012  float temp;
1013 
1014  KvRoCo = (eeData[52] & 0xF000) >> 12;
1015  if (KvRoCo > 7) {
1016  KvRoCo = KvRoCo - 16;
1017  }
1018  KvT[0] = KvRoCo;
1019 
1020  KvReCo = (eeData[52] & 0x0F00) >> 8;
1021  if (KvReCo > 7) {
1022  KvReCo = KvReCo - 16;
1023  }
1024  KvT[2] = KvReCo;
1025 
1026  KvRoCe = (eeData[52] & 0x00F0) >> 4;
1027  if (KvRoCe > 7) {
1028  KvRoCe = KvRoCe - 16;
1029  }
1030  KvT[1] = KvRoCe;
1031 
1032  KvReCe = (eeData[52] & 0x000F);
1033  if (KvReCe > 7) {
1034  KvReCe = KvReCe - 16;
1035  }
1036  KvT[3] = KvReCe;
1037 
1038  kvScale = (eeData[56] & 0x0F00) >> 8;
1039 
1040  for (int i = 0; i < 24; i++) {
1041  for (int j = 0; j < 32; j++) {
1042  p = 32 * i + j;
1043  split = 2 * (p / 32 - (p / 64) * 2) + p % 2;
1044  kvTemp[p] = KvT[split];
1045  kvTemp[p] = kvTemp[p] / pow(2, (double)kvScale);
1046  // kvTemp[p] = kvTemp[p] * mlx90640->offset[p];
1047  }
1048  }
1049 
1050  temp = fabs(kvTemp[0]);
1051  for (int i = 1; i < 768; i++) {
1052  if (fabs(kvTemp[i]) > temp) {
1053  temp = fabs(kvTemp[i]);
1054  }
1055  }
1056 
1057  kvScale = 0;
1058  while (temp < 63.4) {
1059  temp = temp * 2;
1060  kvScale = kvScale + 1;
1061  }
1062 
1063  for (int i = 0; i < 768; i++) {
1064  temp = kvTemp[i] * pow(2, (double)kvScale);
1065  if (temp < 0) {
1066  mlx90640->kv[i] = (temp - 0.5);
1067  } else {
1068  mlx90640->kv[i] = (temp + 0.5);
1069  }
1070  }
1071 
1072  mlx90640->kvScale = kvScale;
1073 }
1074 
1075 void MLX90640::extractCPParameters(uint16_t *eeData, thermalParams *mlx90640) {
1076  float alphaSP[2];
1077  int16_t offsetSP[2];
1078  float cpKv;
1079  float cpKta;
1080  uint8_t alphaScale;
1081  uint8_t ktaScale1;
1082  uint8_t kvScale;
1083 
1084  alphaScale = ((eeData[32] & 0xF000) >> 12) + 27;
1085 
1086  offsetSP[0] = (eeData[58] & 0x03FF);
1087  if (offsetSP[0] > 511) {
1088  offsetSP[0] = offsetSP[0] - 1024;
1089  }
1090 
1091  offsetSP[1] = (eeData[58] & 0xFC00) >> 10;
1092  if (offsetSP[1] > 31) {
1093  offsetSP[1] = offsetSP[1] - 64;
1094  }
1095  offsetSP[1] = offsetSP[1] + offsetSP[0];
1096 
1097  alphaSP[0] = (eeData[57] & 0x03FF);
1098  if (alphaSP[0] > 511) {
1099  alphaSP[0] = alphaSP[0] - 1024;
1100  }
1101  alphaSP[0] = alphaSP[0] / pow(2, (double)alphaScale);
1102 
1103  alphaSP[1] = (eeData[57] & 0xFC00) >> 10;
1104  if (alphaSP[1] > 31) {
1105  alphaSP[1] = alphaSP[1] - 64;
1106  }
1107  alphaSP[1] = (1 + alphaSP[1] / 128) * alphaSP[0];
1108 
1109  cpKta = (eeData[59] & 0x00FF);
1110  if (cpKta > 127) {
1111  cpKta = cpKta - 256;
1112  }
1113  ktaScale1 = ((eeData[56] & 0x00F0) >> 4) + 8;
1114  mlx90640->cpKta = cpKta / pow(2, (double)ktaScale1);
1115 
1116  cpKv = (eeData[59] & 0xFF00) >> 8;
1117  if (cpKv > 127) {
1118  cpKv = cpKv - 256;
1119  }
1120  kvScale = (eeData[56] & 0x0F00) >> 8;
1121  mlx90640->cpKv = cpKv / pow(2, (double)kvScale);
1122 
1123  mlx90640->cpAlpha[0] = alphaSP[0];
1124  mlx90640->cpAlpha[1] = alphaSP[1];
1125  mlx90640->cpOffset[0] = offsetSP[0];
1126  mlx90640->cpOffset[1] = offsetSP[1];
1127 }
1128 
1129 void MLX90640::extractCILCParameters(uint16_t *eeData,
1130  thermalParams *mlx90640) {
1131  float ilChessC[3];
1132  uint8_t calibrationModeEE;
1133 
1134  calibrationModeEE = (eeData[10] & 0x0800) >> 4;
1135  calibrationModeEE = calibrationModeEE ^ 0x80;
1136 
1137  ilChessC[0] = (eeData[53] & 0x003F);
1138  if (ilChessC[0] > 31) {
1139  ilChessC[0] = ilChessC[0] - 64;
1140  }
1141  ilChessC[0] = ilChessC[0] / 16.0f;
1142 
1143  ilChessC[1] = (eeData[53] & 0x07C0) >> 6;
1144  if (ilChessC[1] > 15) {
1145  ilChessC[1] = ilChessC[1] - 32;
1146  }
1147  ilChessC[1] = ilChessC[1] / 2.0f;
1148 
1149  ilChessC[2] = (eeData[53] & 0xF800) >> 11;
1150  if (ilChessC[2] > 15) {
1151  ilChessC[2] = ilChessC[2] - 32;
1152  }
1153  ilChessC[2] = ilChessC[2] / 8.0f;
1154 
1155  mlx90640->calibrationModeEE = calibrationModeEE;
1156  mlx90640->ilChessC[0] = ilChessC[0];
1157  mlx90640->ilChessC[1] = ilChessC[1];
1158  mlx90640->ilChessC[2] = ilChessC[2];
1159 }
1160 
1162  thermalParams *mlx90640) {
1163  uint16_t pixCnt = 0;
1164  uint16_t brokenPixCnt = 0;
1165  uint16_t outlierPixCnt = 0;
1166  int warn = 0;
1167  int i;
1168 
1169  for (pixCnt = 0; pixCnt < 5; pixCnt++) {
1170  mlx90640->brokenPixels[pixCnt] = 0xFFFF;
1171  mlx90640->outlierPixels[pixCnt] = 0xFFFF;
1172  }
1173 
1174  pixCnt = 0;
1175  while (pixCnt < 768 && brokenPixCnt < 5 && outlierPixCnt < 5) {
1176  if (eeData[pixCnt + 64] == 0) {
1177  mlx90640->brokenPixels[brokenPixCnt] = pixCnt;
1178  brokenPixCnt = brokenPixCnt + 1;
1179  } else if ((eeData[pixCnt + 64] & 0x0001) != 0) {
1180  mlx90640->outlierPixels[outlierPixCnt] = pixCnt;
1181  outlierPixCnt = outlierPixCnt + 1;
1182  }
1183 
1184  pixCnt = pixCnt + 1;
1185  }
1186 
1187  if (brokenPixCnt > 4) {
1188  warn = -3;
1189  } else if (outlierPixCnt > 4) {
1190  warn = -4;
1191  } else if ((brokenPixCnt + outlierPixCnt) > 4) {
1192  warn = -5;
1193  } else {
1194  for (pixCnt = 0; pixCnt < brokenPixCnt; pixCnt++) {
1195  for (i = pixCnt + 1; i < brokenPixCnt; i++) {
1196  warn = this->checkAdjacentPixels(mlx90640->brokenPixels[pixCnt],
1197  mlx90640->brokenPixels[i]);
1198  if (warn != 0) {
1199  return warn;
1200  }
1201  }
1202  }
1203 
1204  for (pixCnt = 0; pixCnt < outlierPixCnt; pixCnt++) {
1205  for (i = pixCnt + 1; i < outlierPixCnt; i++) {
1206  warn = this->checkAdjacentPixels(mlx90640->outlierPixels[pixCnt],
1207  mlx90640->outlierPixels[i]);
1208  if (warn != 0) {
1209  return warn;
1210  }
1211  }
1212  }
1213 
1214  for (pixCnt = 0; pixCnt < brokenPixCnt; pixCnt++) {
1215  for (i = 0; i < outlierPixCnt; i++) {
1216  warn = this->checkAdjacentPixels(mlx90640->brokenPixels[pixCnt],
1217  mlx90640->outlierPixels[i]);
1218  if (warn != 0) {
1219  return warn;
1220  }
1221  }
1222  }
1223  }
1224 
1225  return warn;
1226 }
1227 
1228 int MLX90640::checkAdjacentPixels(uint16_t pix1, uint16_t pix2) {
1229  int pixPosDif;
1230 
1231  pixPosDif = pix1 - pix2;
1232  if (pixPosDif > -34 && pixPosDif < -30) {
1233  return -6;
1234  }
1235  if (pixPosDif > -2 && pixPosDif < 2) {
1236  return -6;
1237  }
1238  if (pixPosDif > 30 && pixPosDif < 34) {
1239  return -6;
1240  }
1241 
1242  return 0;
1243 }
1244 
1245 float MLX90640::getMedian(float *values, int n) {
1246  float temp;
1247 
1248  for (int i = 0; i < n - 1; i++) {
1249  for (int j = i + 1; j < n; j++) {
1250  if (values[j] < values[i]) {
1251  temp = values[i];
1252  values[i] = values[j];
1253  values[j] = temp;
1254  }
1255  }
1256  }
1257 
1258  if (n % 2 == 0) {
1259  return ((values[n / 2] + values[n / 2 - 1]) / 2.0);
1260 
1261  } else {
1262  return values[n / 2];
1263  }
1264 }
1265 
1266 int MLX90640::isPixelBad(uint16_t pixel, thermalParams *params) {
1267  for (int i = 0; i < 5; i++) {
1268  if (pixel == params->outlierPixels[i] || pixel == params->brokenPixels[i]) {
1269  return 1;
1270  }
1271  }
1272 
1273  return 0;
1274 }
1275 
1276 int MLX90640::validateFrameData(uint16_t *frameData) {
1277  uint8_t line = 0;
1278  for (int i = 0; i < 768; i += 32) {
1279  if ((frameData[i] == 0x7FFF) && frameData[833]) {
1280  return -8;
1281  }
1282  line = line + 1;
1283  }
1284 
1285  return 0;
1286 }
1287 
1288 int MLX90640::validateAuxData(uint16_t *auxData) {
1289  if (auxData[0] == 0x7FFF)
1290  return -8;
1291 
1292  for (int i = 8; i < 19; i++) {
1293  if (auxData[i] == 0x7FFF) {
1294  return -8;
1295  }
1296  }
1297  for (int i = 20; i < 23; i++) {
1298  if (auxData[i] == 0x7FFF) {
1299  return -8;
1300  }
1301  }
1302  for (int i = 24; i < 33; i++) {
1303  if (auxData[i] == 0x7FFF) {
1304  return -8;
1305  }
1306  }
1307  for (int i = 40; i < 51; i++) {
1308  if (auxData[i] == 0x7FFF) {
1309  return -8;
1310  }
1311  }
1312  for (int i = 52; i < 55; i++) {
1313  if (auxData[i] == 0x7FFF) {
1314  return -8;
1315  }
1316  }
1317  for (int i = 56; i < 64; i++) {
1318  if (auxData[i] == 0x7FFF) {
1319  return -8;
1320  }
1321  }
1322 
1323  return 0;
1324 }
I2CDriver::generalReset
int generalReset(void)
Definition: i2c_driver.cpp:21
MLX90640::extractAlphaParameters
void extractAlphaParameters(uint16_t *eeData, thermalParams *mlx90640)
Definition: mlx90640.cpp:773
thermalParams::offset
int16_t offset[768]
Definition: params.h:25
MLX90640::eeMLX90640
uint16_t eeMLX90640[832]
Definition: mlx90640.h:23
MLX90640::getCurResolution
int getCurResolution(uint8_t slaveAddr)
Definition: mlx90640.cpp:497
MLX90640::extractParameters
int extractParameters(uint16_t *eeData, thermalParams *mlx90640)
Definition: mlx90640.cpp:178
MLX90640::validateAuxData
int validateAuxData(uint16_t *auxData)
Definition: mlx90640.cpp:1288
MLX90640::emissivity
float emissivity
Definition: mlx90640.h:24
thermalParams::kvScale
uint8_t kvScale
Definition: params.h:29
MLX90640::eTa
float eTa
Definition: mlx90640.h:28
MLX90640::extractOffsetParameters
void extractOffsetParameters(uint16_t *eeData, thermalParams *mlx90640)
Definition: mlx90640.cpp:859
MLX90640::validateFrameData
int validateFrameData(uint16_t *frameData)
Definition: mlx90640.cpp:1276
MLX90640::getVdd
float getVdd(uint16_t *frameData, const thermalParams *params)
Definition: mlx90640.cpp:199
MLX90640::setChessMode
int setChessMode(uint8_t slaveAddr)
Definition: mlx90640.cpp:569
MLX90640::triggerMeasurement
int triggerMeasurement(uint8_t slaveAddr)
Definition: mlx90640.cpp:94
thermalParams::vPTAT25
uint16_t vPTAT25
Definition: params.h:12
thermalParams::ilChessC
float ilChessC[3]
Definition: params.h:32
MLX90640::getFrameData
int getFrameData(uint8_t slaveAddr, uint16_t *frameData)
Definition: mlx90640.cpp:125
thermalParams::cpKv
float cpKv
Definition: params.h:16
MLX90640::extractResolutionParameters
void extractResolutionParameters(uint16_t *eeData, thermalParams *mlx90640)
Definition: mlx90640.cpp:719
MLX90640::extractKvPixelParameters
void extractKvPixelParameters(uint16_t *eeData, thermalParams *mlx90640)
Definition: mlx90640.cpp:1001
thermalParams::brokenPixels
uint16_t brokenPixels[5]
Definition: params.h:33
thermalParams::tgc
float tgc
Definition: params.h:15
MLX90640::getCurMode
int getCurMode(uint8_t slaveAddr)
Definition: mlx90640.cpp:541
MLX90640::extractGainParameters
void extractGainParameters(uint16_t *eeData, thermalParams *mlx90640)
Definition: mlx90640.cpp:696
thermalParams::ktaScale
uint8_t ktaScale
Definition: params.h:27
MLX90640::setInterleavedMode
int setInterleavedMode(uint8_t slaveAddr)
Definition: mlx90640.cpp:555
MLX90640::calculateTo
void calculateTo(uint16_t *frameData, const thermalParams *params, float emissivity, float tr, float *result)
Definition: mlx90640.cpp:338
thermalParams::KtPTAT
float KtPTAT
Definition: params.h:11
MLX90640::getTa
float getTa(uint16_t *frameData, const thermalParams *params)
Definition: mlx90640.cpp:217
MLX90640::image
float image[768]
Definition: mlx90640.h:26
f
f
MLX90640::copyRawImage
void copyRawImage(float *pointer)
Definition: mlx90640.cpp:59
MLX90640::setResolution
int setResolution(uint8_t slaveAddr, uint8_t resolution)
Definition: mlx90640.cpp:482
MLX90640::extractKsToParameters
void extractKsToParameters(uint16_t *eeData, thermalParams *mlx90640)
Definition: mlx90640.cpp:739
thermalParams::vdd25
int16_t vdd25
Definition: params.h:9
I2CDriver::write
int write(uint8_t slaveAddr, uint16_t writeAddress, uint16_t data)
Definition: i2c_driver.cpp:64
thermalParams::kv
int8_t kv[768]
Definition: params.h:28
thermalParams::calibrationModeEE
uint8_t calibrationModeEE
Definition: params.h:19
thermalParams::alpha
uint16_t alpha[768]
Definition: params.h:23
MLX90640::getMax
float getMax()
Definition: mlx90640.cpp:67
thermalParams::cpKta
float cpKta
Definition: params.h:17
MLX90640::frame
uint16_t frame[834]
Definition: mlx90640.h:25
MLX90640::fps
int fps
Definition: mlx90640.h:21
MLX90640::extractCILCParameters
void extractCILCParameters(uint16_t *eeData, thermalParams *mlx90640)
Definition: mlx90640.cpp:1129
MLX90640::maxTemp
float maxTemp
Definition: mlx90640.h:20
thermalParams::alphaScale
uint8_t alphaScale
Definition: params.h:24
MLX90640::pixels
uint32_t pixels[SENSOR_W *SENSOR_H]
Definition: mlx90640.h:17
MLX90640::MLX90640
MLX90640(int fps)
Definition: mlx90640.cpp:3
MLX90640::getRefreshRate
int getRefreshRate(uint8_t slaveAddr)
Definition: mlx90640.cpp:525
MLX90640::minTemp
float minTemp
Definition: mlx90640.h:19
thermalParams::cpAlpha
float cpAlpha[2]
Definition: params.h:30
thermalParams::kta
int8_t kta[768]
Definition: params.h:26
MLX90640::getMin
float getMin()
Definition: mlx90640.cpp:65
thermalParams::outlierPixels
uint16_t outlierPixels[5]
Definition: params.h:34
MLX90640::extractVDDParameters
void extractVDDParameters(uint16_t *eeData, thermalParams *mlx90640)
Definition: mlx90640.cpp:649
MLX90640::getImage
void getImage(uint16_t *frameData, const thermalParams *params, float *result)
Definition: mlx90640.cpp:241
thermalParams::kVdd
int16_t kVdd
Definition: params.h:8
MLX90640::extractPTATParameters
void extractPTATParameters(uint16_t *eeData, thermalParams *mlx90640)
Definition: mlx90640.cpp:667
thermalParams::gainEE
int16_t gainEE
Definition: params.h:14
mlx90640.h
MLX90640::extractCPParameters
void extractCPParameters(uint16_t *eeData, thermalParams *mlx90640)
Definition: mlx90640.cpp:1075
MLX90640::getMedian
float getMedian(float *values, int n)
Definition: mlx90640.cpp:1245
MLX90640::mlx90640To
float mlx90640To[768]
Definition: mlx90640.h:27
MLX90640::data
uint16_t data[768 *sizeof(float)]
Definition: mlx90640.h:29
thermalParams
Definition: params.h:7
thermalParams::ct
int16_t ct[5]
Definition: params.h:22
thermalParams::resolutionEE
uint8_t resolutionEE
Definition: params.h:18
thermalParams::KsTa
float KsTa
Definition: params.h:20
ROS_ERROR
#define ROS_ERROR(...)
MLX90640::see
void see()
Definition: mlx90640.cpp:37
MLX90640::synchFrame
int synchFrame(uint8_t slaveAddr)
Definition: mlx90640.cpp:73
thermalParams::cpOffset
int16_t cpOffset[2]
Definition: params.h:31
MLX90640::isPixelBad
int isPixelBad(uint16_t pixel, thermalParams *params)
Definition: mlx90640.cpp:1266
MLX90640::extractKsTaParameters
void extractKsTaParameters(uint16_t *eeData, thermalParams *mlx90640)
Definition: mlx90640.cpp:727
MLX90640::sensorParams
thermalParams sensorParams
Definition: mlx90640.h:31
MLX90640::extractDeviatingPixels
int extractDeviatingPixels(uint16_t *eeData, thermalParams *mlx90640)
Definition: mlx90640.cpp:1161
I2CDriver::read
int read(uint8_t slaveAddr, uint16_t startAddress, uint16_t nMemAddressRead, uint16_t *data)
Definition: i2c_driver.cpp:26
MLX90640::dumpEE
int dumpEE(uint8_t slaveAddr, uint16_t *eeData)
Definition: mlx90640.cpp:69
thermalParams::KvPTAT
float KvPTAT
Definition: params.h:10
thermalParams::alphaPTAT
float alphaPTAT
Definition: params.h:13
thermalParams::ksTo
float ksTo[5]
Definition: params.h:21
SCALEALPHA
#define SCALEALPHA
Definition: params.h:5
MLX90640::extractTgcParameters
void extractTgcParameters(uint16_t *eeData, thermalParams *mlx90640)
Definition: mlx90640.cpp:708
MLX90640::getSubPageNumber
int getSubPageNumber(uint16_t *frameData)
Definition: mlx90640.cpp:539
MLX_I2C_ADDR
#define MLX_I2C_ADDR
Definition: mlx90640.h:10
MLX90640::setRefreshRate
int setRefreshRate(uint8_t slaveAddr, uint8_t refreshRate)
Definition: mlx90640.cpp:511
MLX90640::checkAdjacentPixels
int checkAdjacentPixels(uint16_t pix1, uint16_t pix2)
Definition: mlx90640.cpp:1228
MLX90640::i2cDriver
I2CDriver i2cDriver
Definition: mlx90640.h:16
MLX90640::extractKtaPixelParameters
void extractKtaPixelParameters(uint16_t *eeData, thermalParams *mlx90640)
Definition: mlx90640.cpp:920
MLX90640::badPixelsCorrection
void badPixelsCorrection(uint16_t *pixels, float *to, int mode, thermalParams *params)
Definition: mlx90640.cpp:583


mlx90640_thermal_camera
Author(s):
autogenerated on Sat Sep 16 2023 02:13:29