传感器简介
MLX90620是全校准16X4像素的IR阵列,集成于工业标准四引脚TO-39封装里。同一封装里包含两个芯片MLX90670(集成信号处理的IR阵列)和24AA02(256x8EEPROM)芯片。MLX90620包含64个IR像素点,每个像素都对应有低噪声斩波放大器和高速ADC。芯片中的PTAT(与绝对温度成正比)传感器用来测量环境温度。IR和PTAT的输出都存在内部的RAM,并可以通过IIC通信获取。
MLX_90620.c
1 /** 2 * @file MLX_90620.c 3 * @brief 4 * @version 0.1 5 * @date 2019-06-28 6 * 7 * @copyright Copyright (c) 2019 Chipintelli Technology Co., Ltd. 8 * 9 */ 10 /*----------------------------------------------------------------------------- 11 include 12 --------------------------- --------------------------------------------------*/ 13 #include <math.h> 14 #include "string.h" 15 #include "ci_sensor.h" 16 #include "MLX_90620.h" 17 #include "ci110x_i2c.h" 18 #include "ci_log.h" 19 #include "ci110x_scu.h" 20 #include "ci_misc.h" 21 22 /*----------------------------------------------------------------------------- 23 define 24 -----------------------------------------------------------------------------*/ 25 #define MLX90620_RESULT(x,y) (x + y * 4) 26 27 #define MLX620_EE_SIZE_BYTES 256 //def MLX620_EE_SIZE_BYTES Device EEPROM memory size expressed in bytes. 28 #define MLX620_EE_IROffsetAi00 0x00 //def MLX620_EE_IROffsetAi00 IR pixels individual offset coefficients - Ai. 29 #define MLX620_EE_IROffsetBi00 0x40 //def MLX620_EE_IROffsetBi00 Individual Ta dependence (slope) of IR pixels offset - Bi. 30 #define MLX620_EE_IRSens00 0x80 //def MLX620_EE_IRSens00 Individual sensitivity coefficients. 31 #define MLX620_EE_MLX_Reserved1 0xC0 //def MLX620_EE_MLX_Reserved1 Melexis reserved part 1. 32 #define MLX620_EE_CyclopsA 0xD4 //def MLX620_EE_CyclopsA Compensation pixel (Cyclop)individual offset. 33 #define MLX620_EE_CyclopsB 0xD5 //def MLX620_EE_CyclopsB Individual Ta dependence (slope) of compensation pixel (Cyclop) offset. 34 #define MLX620_EE_CyclopsAlpha 0xD6 //def MLX620_EE_CyclopsAlpha Sensitivity coefficient of the compensation pixel (16-bit). 35 #define MLX620_EE_TGC 0xD8 //def MLX620_EE_TGC Thermal Gradient Coefficient. 36 #define MLX620_EE_IROffsetBScale 0xD9 //def MLX620_EE_IROffsetBScale Scaling coefficient for slope of IR pixels offset. 37 #define MLX620_EE_PtatVtho 0xDA //def MLX620_EE_PtatVtho VTH0 of absolute temperature sensor (16-bit). 38 #define MLX620_EE_PtatKT1 0xDC //def MLX620_EE_PtatKT1 KT1 of absolute temperature sensor (16-bit). 39 #define MLX620_EE_PtatKT2 0xDE //def MLX620_EE_PtatKT2 KT2 of absolute temperature sensor (16-bit). 40 #define MLX620_EE_IRCommonSens 0xE0 //def MLX620_EE_IRCommonSens Common sensitivity coefficient of IR pixels (16-bit). 41 #define MLX620_EE_IRCommonSensScale 0xE2 //def MLX620_EE_IRCommonSensScale Scaling coefficient for common sensitivity. 42 #define MLX620_EE_IRSensScale 0xE3 //def MLX620_EE_IRSensScale Scaling coefficient for individual sensitivity. 43 #define MLX620_EE_Ke 0xE4 //def MLX620_EE_Ke Emissivity (16-bit). 44 #define MLX620_EE_KsTa 0xE6 //def MLX620_EE_KsTa KsTa (16-bit). 45 #define MLX620_EE_MLX_Reserved2 0xE8 //def MLX620_EE_MLX_Reserved2 Melexis reserved part 2. 46 #define MLX620_EE_ConfReg 0xF5 //def MLX620_EE_ConfReg Configuration register (16-bit). 47 #define MLX620_EE_OscTrim 0xF7 //def MLX620_EE_OscTrim Oscillator trim register (16-bit). 48 #define MLX620_EE_ChipID 0xF8 //def MLX620_EE_ChipID Chip ID (64-bit). 49 //--------------------------------------------------------------------------------------------------------------------------- 50 #define MLX620_IR_ROWS 4 51 #define MLX620_IR_COLUMNS 16 52 #define MLX620_IR_SENSORS (MLX620_IR_ROWS * MLX620_IR_COLUMNS) 53 #define MLX620_IR_SENSOR_IDX(row, col)((col) * MLX620_IR_COLUMNS + (row)) 54 //--------------------------------------------------------------------------------------------------------------------------- 55 #define MLX620_RAM_SIZE_WORDS 0xFF 56 #define MLX620_RAM_SIZE_BYTES (MLX620_RAM_SIZE_WORDS * 2) 57 #define MLX620_RAM_IR_BEG 0x0U 58 #define MLX620_RAM_IR_END 0x3F 59 #define MLX620_RAM_PTAT 0x90 60 #define MLX620_RAM_TGC 0x91 61 #define MLX620_RAM_CONFIG 0x92 62 #define MLX620_RAM_TRIM 0x93 63 //---------------------------------------------------------------------------------------------------------------------------- 64 #define MLX620_ADDR 0x60 65 #define MLX620_EEPROM_ADDR 0x50 66 #define MLX620_CMD_START 0x801 67 #define MLX620_CMD_READ 2 68 #define MLX620_CMD_WRITE_CONFIG 3 69 #define MLX620_CMD_WRITE_TRIM 4 70 #define MLX620_CONFIG_FPS_IR_MASK(fps) (((fps) & 0x0F) << 0) 71 #define MLX620_CONFIG_MEAS_STEP_CONT_MASK (1 << 6) 72 #define MLX620_CONFIG_SLEEP_REQUEST_MASK (1 << 7) 73 #define MLX620_CONFIG_TA_MEAS_RUNNING_MASK (1 << 8) 74 #define MLX620_CONFIG_IR_MEAS_RUNNING_MASK (1 << 9) 75 #define MLX620_CONFIG_POR_BROUT_BIT_MASK (1 << 10) 76 #define MLX620_CONFIG_FMPLUS_ENABLE_MASK (1 << 11) 77 #define MLX620_CONFIG_FPS_PTAT_MASK(fps) (((fps) & 0x03) << 12) 78 #define MLX620_CONFIG_ADC_REFERENCE_MASK (1 << 14) 79 80 /*----------------------------------------------------------------------------- 81 extern 82 -----------------------------------------------------------------------------*/ 83 84 /*----------------------------------------------------------------------------- 85 struct / enum / union 86 -----------------------------------------------------------------------------*/ 87 88 /*----------------------------------------------------------------------------- 89 global 90 -----------------------------------------------------------------------------*/ 91 uint8_t mlx620_rom_buff[MLX620_EE_SIZE_BYTES]; 92 uint16_t mlx620_ram_buff[MLX620_RAM_SIZE_WORDS]; 93 int8_t mlx620_ai[MLX620_IR_SENSORS]; 94 double mlx620_bi[MLX620_IR_SENSORS]; 95 double mlx620_alphai[MLX620_IR_SENSORS]; 96 double mlx620_dvtho; 97 double mlx620_dkt1; 98 double mlx620_dkt2; 99 double mlx620_dlastta; 100 double mlx620_tgc; 101 double mlx620_cyclops_alpha; 102 double mlx620_cyclopsA; 103 double mlx620_cyclopsB; 104 double mlx620_ke; 105 double mlx620_cyclops_data; 106 double ir_tempK[MLX620_IR_SENSORS]; 107 double ir_tempK_reference[MLX620_IR_SENSORS]; 108 double ir_tempK_err[MLX620_IR_SENSORS] = {0}; 109 110 /*----------------------------------------------------------------------------- 111 declare 112 -----------------------------------------------------------------------------*/ 113 114 /*----------------------------------------------------------------------------- 115 function 116 -----------------------------------------------------------------------------*/ 117 118 /** 119 * @brief 延时 毫秒 120 * 121 * @param ms 122 */ 123 static void delay_ms(int ms) 124 { 125 int i=0; 126 while(ms--) 127 { 128 for(i=0;i<0x1A80;i++); 129 } 130 } 131 132 /** 133 * @brief IIC读取一个字节 134 * 135 * @param slave_addr 136 * @param reg 137 * @param val 138 * @return int8_t 139 */ 140 int8_t mlx90620_read_byte(uint8_t slave_addr,uint8_t reg,uint8_t *val) 141 { 142 char buf[256] = {0}; 143 struct i2c_client client = {0}; 144 client.flags = 1; 145 client.addr = slave_addr; 146 strcpy(client.name,"mlx90620"); 147 buf[0] = reg; 148 i2c_master_recv(IIC1,&client,buf,1); 149 *val = buf[0]; 150 delay_ms(5); 151 return RETURN_OK; 152 } 153 154 /** 155 * @brief IIC写一个字节 156 * 157 * @param slave_addr 158 * @param reg 159 * @param val 160 * @return int8_t 161 */ 162 int8_t mlx90620_write_byte(uint8_t slave_addr,uint8_t reg,uint8_t val) 163 { 164 char buf[256] = {0}; 165 struct i2c_client client = {0}; 166 client.flags = 0; 167 client.addr = slave_addr; 168 strcpy(client.name,"mlx90620"); 169 buf[0] = reg; 170 buf[1] = val; 171 i2c_master_send(IIC1,&client,buf,2); 172 delay_ms(5); 173 return RETURN_OK; 174 } 175 176 /** 177 * @brief IIC读多个数据 178 * 179 * @param slave_addr 180 * @param reg 181 * @param data 182 * @param send_len 183 * @param rev_len 184 * @return int8_t 185 */ 186 int8_t mlx90620_read_block(uint8_t slave_addr,uint8_t reg,uint8_t *data, 187 uint32_t send_len,uint32_t rev_len) 188 { 189 char buf[300] = {0}; 190 struct i2c_client client = {0}; 191 client.flags = 1; 192 client.addr = slave_addr; 193 strcpy(client.name,"mlx90620"); 194 buf[0] = reg; 195 memcpy(&buf[1],data,send_len); 196 i2c_master_recv_mlx(IIC1,&client,buf,send_len + 1,rev_len); 197 memcpy(data,buf,rev_len); 198 delay_ms(5); 199 return RETURN_OK; 200 } 201 202 /** 203 * @brief IIC写多个数据 204 * 205 * @param slave_addr 206 * @param reg 207 * @param data 208 * @param len 209 * @return int8_t 210 */ 211 int8_t mlx90620_write_block(uint8_t slave_addr,uint8_t reg,uint8_t *data,uint32_t len) 212 { 213 char buf[256] = {0}; 214 struct i2c_client client = {0}; 215 client.flags = 0; 216 client.addr = slave_addr; 217 strcpy(client.name,"mlx90620"); 218 buf[0] = reg; 219 strncpy(&buf[1],(char const*)data,len); 220 i2c_master_send(IIC1,&client,buf,len + 1); 221 delay_ms(5); 222 return RETURN_OK; 223 } 224 225 /** 226 * @brief 读取Trim 227 * 228 * @param data 229 * @return int8_t 230 */ 231 int8_t mlx90620_read_trim(uint8_t *data) 232 { 233 data[0] = MLX620_RAM_TRIM; 234 data[1] = 0x00; 235 data[2] = 0x01; 236 mlx90620_read_block(MLX620_ADDR,MLX620_CMD_READ,data,3,2); 237 return RETURN_OK; 238 } 239 240 /** 241 * @brief 配置Trim 242 * 243 * @param data 244 * @return int8_t 245 */ 246 int8_t mlx90620_write_trim(uint16_t data) 247 { 248 uint8_t buf[] = { 249 (uint8_t)((data & 0xFF) - 0xAA), 250 (uint8_t)(data & 0xFF), 251 (uint8_t)((data >> 8) - 0xAA), 252 (uint8_t)(data >> 8) 253 }; 254 mlx90620_write_block(MLX620_ADDR,MLX620_CMD_WRITE_TRIM, 255 buf,sizeof(buf)); 256 return RETURN_OK; 257 } 258 259 /** 260 * @brief 读取config 261 * 262 * @param data 263 * @return int8_t 264 */ 265 int8_t mlx90620_read_config(uint8_t *data) 266 { 267 data[0] = MLX620_RAM_CONFIG; 268 data[1] = 0x00; 269 data[2] = 0x01; 270 mlx90620_read_block(MLX620_ADDR,MLX620_CMD_READ,data,3,2); 271 return RETURN_OK; 272 } 273 274 /** 275 * @brief 配置config 276 * 277 * @param data 278 * @return int8_t 279 */ 280 int8_t mlx90620_write_config(uint16_t data) 281 { 282 uint8_t buf[] = { 283 (uint8_t)((data & 0xFF) - 0x55), 284 (uint8_t)(data & 0xFF), 285 (uint8_t)((data >> 8) - 0x55), 286 (uint8_t)(data >> 8) 287 }; 288 mlx90620_write_block(MLX620_ADDR,MLX620_CMD_WRITE_CONFIG, 289 buf,sizeof(buf)); 290 return RETURN_OK; 291 } 292 293 /** 294 * @brief 读取EEPROM数据 295 * 296 * @param addr 297 * @param len 298 * @param data 299 * @return int8_t 300 */ 301 int8_t mlx90620_read_eeprom(uint8_t addr,uint8_t len,uint8_t* data) 302 { 303 return mlx90620_read_block(MLX620_EEPROM_ADDR,addr,data,0,len); 304 } 305 306 /** 307 * @brief 读取RAM数据 308 * 309 * @param addr 310 * @param step 311 * @param len 312 * @param buf 313 * @return int8_t 314 */ 315 int8_t mlx90620_read_ram(uint8_t addr,uint8_t step,uint32_t len,uint8_t *buf) 316 { 317 uint8_t data[300] = {0}; 318 data[0] = addr; 319 data[1] = step; 320 data[2] = len; 321 mlx90620_read_block(MLX620_ADDR,MLX620_CMD_READ,data,3,2 * len); 322 memcpy(buf,data,2* len); 323 return RETURN_OK; 324 } 325 326 /** 327 * @brief 计算TO 328 * 329 * @param idxIr 330 * @param data 331 * @return double 332 */ 333 double mlx620_calc_tokelvin(int idxIr, int16_t data) 334 { 335 if (fabs(mlx620_alphai[idxIr]) < 1e-10) 336 { 337 return 0; 338 } 339 double dt = mlx620_dlastta + 273.15; //convert to Kelvin 340 dt *= dt; 341 dt *= dt; //power of 4 342 double d = (data - (mlx620_ai[idxIr] + mlx620_bi[idxIr] * (mlx620_dlastta - 25)) 343 - mlx620_cyclops_data) /(mlx620_ke * mlx620_alphai[idxIr]) + dt; 344 if (d < 0) 345 { 346 return 0; 347 } 348 double dTo = pow(d, 0.25) - 273.15; //4th square 349 return dTo; 350 } 351 352 /** 353 * @brief 偏移量抵消计算 354 * 355 * @param pFrame 356 * @param start 357 * @param step 358 * @param count 359 * @param pIR 360 */ 361 void mlx620_compensate_ir(int16_t* pFrame, int start, int step, int count, double *pIR) 362 { 363 //compensates full RAM buffer 364 365 if (step == 0) 366 { 367 step = 1; 368 } 369 int end = start + count * step; 370 // check which part of the the IR array is read -> compensate To 371 if (start < MLX620_RAM_IR_BEG + MLX620_IR_SENSORS && end > MLX620_RAM_IR_BEG) 372 { 373 int irStart = (MLX620_RAM_IR_BEG - start) / step; 374 if (irStart < 0) 375 { 376 irStart = 0; 377 } 378 int irEnd = (MLX620_RAM_IR_BEG + MLX620_IR_SENSORS - start) / step; 379 if (irEnd > count) 380 { 381 irEnd = count; 382 } 383 int caddr = start + irStart * step; 384 irEnd -= irStart; 385 for (int i = 0; i < irEnd; ++i) 386 { 387 pIR[i] = mlx620_calc_tokelvin(caddr - MLX620_RAM_IR_BEG, pFrame[i]); 388 caddr += step; 389 } 390 } 391 } 392 393 /** 394 * @brief 计算ta摄氏温度 395 * 396 * @param ptat 397 * @return uint32_t 398 */ 399 uint32_t mlx620_calc_ta(int16_t ptat) 400 { 401 if (fabs(mlx620_dkt2) < 1e-10 || fabs(mlx620_dvtho) < 1e-10) 402 { 403 return 1; 404 } 405 double d = (mlx620_dkt1*mlx620_dkt1 - 4 * mlx620_dkt2 * (1 - ptat / mlx620_dvtho)); 406 if (d < 0) 407 { 408 return 1; 409 } 410 mlx620_dlastta = ((-mlx620_dkt1 + sqrt(d)) / (2 * mlx620_dkt2)) + 25; 411 return 0; 412 } 413 414 /** 415 * @brief 得到绝对温度TA 416 * 417 * @param ptat 418 * @return double 419 */ 420 double mlx620_get_takelvin (int16_t ptat) 421 { 422 mlx620_calc_ta(ptat); 423 return mlx620_dlastta; 424 } 425 426 /** 427 * @brief 计算一些参数 428 * 429 */ 430 void mlx620_calc_common_params(void) 431 { 432 uint16_t val16; 433 uint8_t val8; 434 int8_t s_val8; 435 uint8_t *ptr8; 436 double dOffsetBScale; 437 double dScaleComAlpha = 1; 438 double dScaleAlpha = 1; 439 double dCommonAlpha; 440 441 ptr8 = mlx620_rom_buff; 442 443 // Vth(25) 16 signed 444 memcpy(&val16, ptr8 + MLX620_EE_PtatVtho, sizeof(val16)); 445 mlx620_dvtho = (double)((int16_t)val16); 446 447 // kT1 16 bit signed * 2^10 448 memcpy(&val16, ptr8 + MLX620_EE_PtatKT1, sizeof(val16)); 449 mlx620_dkt1 = (double)((int16_t)val16) / (1 << 10); 450 451 // kT2 16 bit signed * 2^20 452 memcpy(&val16, ptr8 + MLX620_EE_PtatKT2, sizeof(val16)); 453 mlx620_dkt2 = (double)((int16_t)val16) / (1 << 20); 454 455 // Thermal Gradient Gompensation coefficient - mlx620_tgc 456 memcpy(&s_val8, ptr8 + MLX620_EE_TGC, sizeof(s_val8)); 457 mlx620_tgc = s_val8 / 32.0; 458 459 // Cyclops alpha 460 memcpy(&val16, ptr8 + MLX620_EE_CyclopsAlpha, sizeof(val16)); 461 mlx620_cyclops_alpha = val16; 462 463 memcpy(&val8, ptr8 + MLX620_EE_IROffsetBScale, sizeof(val8)); 464 dOffsetBScale = pow(2, val8); 465 466 // cyclops A & B 467 memcpy(&s_val8, ptr8 + MLX620_EE_CyclopsA, sizeof(s_val8)); 468 mlx620_cyclopsA = s_val8; 469 470 memcpy(&s_val8, ptr8 + MLX620_EE_CyclopsB, sizeof(s_val8)); 471 mlx620_cyclopsB = s_val8 / dOffsetBScale; 472 473 memcpy(&val8, ptr8 + MLX620_EE_IRCommonSensScale, sizeof(val8)); 474 dScaleComAlpha = pow(2, val8); 475 476 memcpy(&val8, ptr8 + MLX620_EE_IRSensScale, sizeof(val8)); 477 dScaleAlpha = pow(2, val8); 478 479 memcpy(&val16, ptr8 + MLX620_EE_Ke, sizeof(val16)); 480 mlx620_ke = (double)val16 / 32768.0; 481 482 memcpy(&val16, ptr8 + MLX620_EE_IRCommonSens, sizeof(val16)); 483 dCommonAlpha = (double)val16 / dScaleComAlpha; 484 485 // Ai, Bi and mlx620_alphai 486 for (int i = 0; i < MLX620_IR_SENSORS; ++i) 487 { 488 memcpy(&val8, ptr8 + (MLX620_EE_IROffsetAi00 + i), sizeof(val8)); 489 mlx620_ai[i] = (int8_t)val8; 490 491 memcpy(&val8, ptr8 + (MLX620_EE_IROffsetBi00 + i), sizeof(val8)); 492 mlx620_bi[i] = (double)((int8_t)val8) / dOffsetBScale; 493 494 memcpy(&val8, ptr8 + (MLX620_EE_IRSens00 + i), sizeof(val8)); 495 mlx620_alphai[i] = (double)val8 / dScaleAlpha + dCommonAlpha; 496 } 497 } 498 499 /** 500 * @brief 计算TGC 501 * 502 * @param tgc 503 */ 504 void mlx620_calc_tgc(int16_t tgc) 505 { 506 mlx620_cyclops_data = mlx620_tgc * (tgc - (mlx620_cyclopsA + mlx620_cyclopsB * (mlx620_dlastta - 25))); 507 } 508 509 /** 510 * @brief 计算温度 511 * 512 * @param pIRtempK 513 * @param Ta 514 * @return uint8_t 515 */ 516 uint8_t mlx90620_measure_temperature(double *pIRtempK, double *Ta) 517 { 518 int16_t ptat, tgc; 519 mlx90620_read_ram(MLX620_RAM_PTAT, 0, 1, (uint8_t*)&ptat); 520 *Ta = mlx620_get_takelvin (ptat); 521 mlx90620_read_ram(MLX620_RAM_TGC, 0, 1, (uint8_t*)&tgc); 522 mlx620_calc_tgc(tgc); 523 mlx90620_read_ram(MLX620_RAM_IR_BEG, 1, MLX620_IR_SENSORS, (uint8_t*)mlx620_ram_buff); 524 mlx620_compensate_ir((int16_t*)mlx620_ram_buff, MLX620_RAM_IR_BEG, 1, MLX620_IR_SENSORS, pIRtempK); 525 return RETURN_OK; 526 } 527 528 /** 529 * @brief 初始化 530 * 531 */ 532 void mlx90620_init(void) 533 { 534 uint16_t trimReg = 0; 535 uint16_t confReg = 0; 536 537 mlx90620_read_eeprom(0x00,0xFF,mlx620_rom_buff); 538 trimReg = mlx620_rom_buff[0xF7]; 539 confReg = (mlx620_rom_buff[0xF6] << 8) | (mlx620_rom_buff[0xF5]); 540 mprintf("trimReg = 0x%x confReg = 0x%x ",trimReg,confReg); 541 if((0 == trimReg) || (0xFF == trimReg)) 542 { 543 mlx90620_write_trim(85); 544 } 545 else 546 { 547 mlx90620_write_trim(trimReg); 548 } 549 if((0 == confReg) || (0xFF == confReg)) 550 { 551 mlx90620_write_config(0x745E); 552 } 553 else 554 { 555 mlx90620_write_config(confReg); 556 } 557 while(!((confReg >> 10) & 0x1)) 558 { 559 mlx90620_read_trim((uint8_t*)&trimReg); 560 mlx90620_read_config((uint8_t*)&confReg); 561 mprintf("trimReg = 0x%x confReg = 0x%x ",trimReg,confReg); 562 } 563 mprintf("MLX90620 init success "); 564 mlx620_calc_common_params(); 565 } 566 567 /** 568 * @brief 打开 mlx90620 569 * 570 * @param APDS-9960 init 571 * @retval RETURN_OK 572 * @retval RETURN_ERR 573 */ 574 int32_t mlx90620_open(void) 575 { 576 NVIC_EnableIRQ(IIC1_IRQn); 577 Scu_SetDeviceGate((unsigned int)IIC1,ENABLE); 578 Scu_Setdevice_Reset((unsigned int)IIC1); 579 Scu_Setdevice_ResetRelease((unsigned int)IIC1); 580 Scu_SetIOReuse(I2C1_SCL_PAD,FIRST_FUNCTION); 581 Scu_SetIOReuse(I2C1_SDA_PAD,FIRST_FUNCTION); 582 583 I2C_InitStruct InitStruct = {0}; 584 InitStruct.I2C_IO_BASE = (unsigned int)IIC1; 585 InitStruct.I2C_CLOCK_SPEED = 100; 586 InitStruct.I2C_INPUT_CLK = 50000000; 587 InitStruct.TIMEOUT = 0X5FFFFF; 588 i2c_init(IIC1,&InitStruct); 589 double Ta = 0; 590 mlx90620_init(); 591 mlx90620_measure_temperature(ir_tempK_reference, &Ta); 592 return RETURN_OK; 593 } 594 595 /** 596 * @brief 读测量数据 597 * 598 * @param data 599 * @return int32_t 600 */ 601 int32_t mlx90620_read(sensor_data_t *data) 602 { 603 uint16_t confReg = 0; 604 double Ta = 0; 605 while(!((confReg >> 10) & 0x1)) 606 { 607 mlx90620_read_config((uint8_t*)&confReg);; 608 } 609 mlx90620_measure_temperature(ir_tempK, &Ta); 610 sensor_data_inform(SENSOR_TYPE_INFRARED_ARRAY); 611 for(int i = 0;i < MLX620_IR_SENSORS;i++) 612 { 613 data->infrared_array[i] = (ir_tempK[i] - ir_tempK_reference[i]) + Ta; 614 } 615 return RETURN_OK; 616 } 617 618 /** 619 * @brief mlx90620 ops 620 * 621 */ 622 sensor_ops_t mlx90620_ops = 623 { 624 mlx90620_open, 625 mlx90620_read, 626 }; 627 628 /*----------------------------------------------------------------------------- 629 end of the file 630 -----------------------------------------------------------------------------*/
MLX_90620.h
1 /** 2 * @file MLX_90620.h 3 * @brief MLX_90620传感器的头文件 4 * @version 0.1 5 * @date 2019-07-02 6 * 7 * @copyright Copyright (c) 2019 Chipintelli Technology Co., Ltd. 8 * 9 */ 10 11 #ifndef __MLX_90620_H__ 12 #define __MLX_90620_H__ 13 14 /** 15 * @ingroup third_device_driver 16 * @defgroup MLX90620 17 * @brief MLX90620传感器驱动 18 * @{ 19 */ 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 /*----------------------------------------------------------------------------- 26 include 27 -----------------------------------------------------------------------------*/ 28 29 /*----------------------------------------------------------------------------- 30 define 31 -----------------------------------------------------------------------------*/ 32 33 /*----------------------------------------------------------------------------- 34 extern 35 -----------------------------------------------------------------------------*/ 36 extern sensor_ops_t mlx90620_ops; 37 38 /*----------------------------------------------------------------------------- 39 struct / enum / union 40 -----------------------------------------------------------------------------*/ 41 42 /*----------------------------------------------------------------------------- 43 global 44 -----------------------------------------------------------------------------*/ 45 46 /*----------------------------------------------------------------------------- 47 function declare 48 -----------------------------------------------------------------------------*/ 49 50 #ifdef __cplusplus 51 } 52 #endif 53 54 /** 55 * @} 56 */ 57 58 #endif 59 60 /*----------------------------------------------------------------------------- 61 end of the file 62 -----------------------------------------------------------------------------*/