Melexis MLX90620 and MLX90621, non-contact, 16x4 infrared array temperature sensor device driver.
MLX90620.h
- Committer:
- loopsva
- Date:
- 2016-07-26
- Revision:
- 2:82782c73251e
- Parent:
- 1:fd536ebc7eaf
File content as of revision 2:82782c73251e:
#ifndef MLX90620_H #define MLX90620_H #include "mbed.h" #define MLX_EEPADDR 0xa0 //eep i2c address #define MLX_RAMADDR 0xc0 //ram i2c address //EEPROM offsets #define MLX620_PTATSENS 0x90 //PTAT sensor reading for MLX90620, 16b #define MLX621_PTATSENS 0x40 //PTAT sensor reading for MLX90621, 16b #define MLX620_TGCSENS 0x91 //TGC sensor reading for MLX90620, 16b #define MLX621_TGCSENS 0x41 //TGC sensor reading for MLX90621, 16b #define MLX_CONFIG 0x92 //config register, 16b #define MLX_TRIM 0x93 //oscillator trim, lsb>6b of 16b #define MLX621_EE_ID_BASE 0xf8 //8 bytes, ID info #define MLX620_EETRIM 0xf7 //1 byte, oscillator trim value #define MLX621_CONFIG_LO 0xf5 //Config reg, lo byte #define MLX621_CONFIG_HI 0xf6 //Config reg, hi byte #define MLX_TOINDEX 0xd4 //0xD4 and 0xE0 (0xD4 + 0x0C), 6 bytes + 6 bytes #define MLX_TAINDEX 0xda //0xDA, 6 bytes #define MLX621_KT1SCALE_BITS 0xf0 //Kt1_scale bits 7:4 #define MLX621_KT2SCALE_BITS 0x0f //Kt2_scale bits 3:0 #define MLX621_KS_SCALE 0xc0 //KS scaling register #define MLX621_KS4_EE 0xc4 //Ks4_ee register #define MLX621_A_COMMON_LO 0xd0 //Acommon register, lo byte #define MLX621_A_COMMON_HI 0xd1 //Acommon register, hi byte #define MLX621_KT12_SCALE 0xd2 //Kt1_Kt2__scale register #define MLX621_ACP_LO 0xd3 //ACP register, lo byte #define MLX621_ACP_HI 0xd4 //ACP register, hi byte #define MLX621_BCP 0xd5 //BCP register #define MLX621_ALPHACP_LO 0xd6 //AlphaCP register, lo byte #define MLX621_ALPHACP_HI 0xd7 //AlphaCP register, hi byte #define MLX621_TGC 0xd8 //TGC reg #define MLX621_DELTA_ABI_SCALE 0xd9 //deltaAi_deltaBi_scale register #define MLX621_VTH25_LO 0xda //Vth(25) register lo byte #define MLX621_VTH25_HI 0xdb //Vth(25) register hi byte #define MLX621_KT1_LO 0xdc //Kt1 register lo byte #define MLX621_KT1_HI 0xdd //Kt1 register lo byte #define MLX621_KT2_LO 0xde //Kt2 register lo byte #define MLX621_KT2_HI 0xdf //Kt2 register lo byte #define MLX621_THETA0_LO 0xe0 //theta 0 register, lo byte #define MLX621_THETA0_HI 0xe1 //theta 0 register, hi byte #define MLX621_THETA0_SCALE 0xe2 //theta 0 scale register #define MLX621_DELTA_TH_SCALE 0xe3 //delta theta scale register #define MLX621_A_EMMIS_LO 0xe4 //emissivity register, lo byte #define MLX621_A_EMMIS_HI 0xe5 //emissivity register, hi byte #define MLX621_KSTA_LO 0xe6 //KsTa register, lo byte #define MLX621_KSTA_HI 0xe7 //KsTa register, hi byte #define MLX621_DELTA_AI_LO 0x3f //deltaAi register, lo byte #define MLX621_DELTA_AI_HI 0x00 //deltaAi register, hi byte #define MLX621_DAISCALE_BITS 0xf0 //deltaAi_scale bits 7:4 #define MLX621_DBISCALE_BITS 0x0f //deltaBi_scale bits 3:0 #define MLX621_KS_SCALE_BITS 0x0f //KS scaling bits (3:0) #define MLX621_BIIJ_EEP_LO 0x00 //Bi(ij)eeprom lo byte ******NEED ADDRESS****** #define MLX621_BIIJ_EEP_HI 0x00 //Bi(ij)eeprom lo byte #define MLX_TGCX_REG MLX_TOINDEX + 4 #define MLX_THETA0_REG_LO MLX_TOINDEX + 12 #define MLX_THETA0_REG_HI MLX_TOINDEX + 13 #define MLX_THETA0_SCALE_REG MLX_TOINDEX + 14 #define MLX_DELTA_TH_SCALE_REG MLX_TOINDEX + 15 #define MLX_EPSILON_REG_LO MLX_TOINDEX + 16 #define MLX_EPSILON_REG_HI MLX_TOINDEX + 17 //CONFIG register bit equates #define MLX_BRNOUTFLAG 0x0400 //brownout flag, 0 = brownout occured #define MLX_IRMEASFLAG 0x0200 //IR measurement, 1 = measurement in progress #define MLX_TAMEASFLAG 0x0100 //TA measurement, 1 = measurement in progress #define MLX621_EEP_ENA 0x1000 //mlx621 enable EEPROM access #define MLX621_RESOLUTION 0x0030 //mlx621 resolution bits 5 & 4 //config register equates #define MLX621_CONF_LO_REF_ENA 0x4000 //default #define MLX621_CONF_HI_REF_ENA 0x0000 #define MLX621_CONF_EEP_DIS 0x1000 #define MLX621_CONF_EEP_ENA 0x0000 //seems like default #define MLX621_CONF_I2C_1MB 0x0000 //default #define MLX621_CONF_I2C_400K 0x0800 #define MLX621_CONF_MD_1 0x0400 //default MD must write a "1" when uploading Config Reg #define MLX621_CONF_POR 0x0000 //POR or Brownout occured #define MLX621_CONF_IR_BUSY 0x0200 //IR measurement running #define MLX621_CONF_IR_IDLE 0x0000 //IR measurement -not- running #define MLX621_CONF_MODE_SLEEP 0x0080 //sleep mode #define MLX621_CONF_MODE_NORM 0x0000 //default, normal mode #define MLX621_CONF_MODE_STEP 0x0040 //step mode #define MLX621_CONF_MODE_CONT 0x0000 //default, continious mode #define MLX621_CONF_ADC_MASK 0x0030 //ADC mask bits #define MLX621_CONF_ADC18 0x0030 //default, ADC in 18 bit mode #define MLX621_CONF_ADC17 0x0020 //ADC in 17 bit mode #define MLX621_CONF_ADC16 0x0010 //ADC in 16 bit mode #define MLX621_CONF_ADC15 0x0000 //ADC in 15 bit mode #define MLX621_CONF_REF_MASK 0x000f //refresh mask bits #define MLX621_CONF_REF_HALF 0x000f //refresh rate 0.5Hz #define MLX621_CONF_REF_1 0x000e //default, refresh rate 1Hz #define MLX621_CONF_REF_2 0x000d //refresh rate 2Hz #define MLX621_CONF_REF_4 0x000c //refresh rate 4Hz #define MLX621_CONF_REF_8 0x000b //refresh rate 8Hz #define MLX621_CONF_REF_16 0x000a //refresh rate 16Hz #define MLX621_CONF_REF_32 0x0009 //refresh rate 32Hz #define MLX621_CONF_REF_64 0x0008 //refresh rate 64Hz #define MLX621_CONF_REF_128 0x0007 //refresh rate 128Hz #define MLX621_CONF_REF_256 0x0006 //refresh rate 256Hz #define MLX621_CONF_REF_512 0x0005 //refresh rate 512Hz #define MLX621_CONF_REF_512a 0x0004 //refresh rate 512Hz #define MLX621_CONF_REF_512b 0x0003 //refresh rate 512Hz #define MLX621_CONF_REF_512c 0x0002 //refresh rate 512Hz #define MLX621_CONF_REF_512d 0x0001 //refresh rate 512Hz #define MLX621_CONF_REF_512e 0x0000 //refresh rate 512Hz /** Software routines to access the Melexis MLX90620 and MLX90621 64 pixel (4 X 16) infrared sensor array * The MLX9062x's internal RAM has different i2c behavior than it's internal EEPROM * As a result, the MLX9062x's RAM uses more primitive mbed i2c commands than does the EEPROM. * */ /* MLX9062x controller class */ class MLX9062x { public: /** * Select device MLX90620 or MLX90621 * **/ enum MLXdevice { mlx90620, //device is an MLX90620 mlx90621, //device is an MLX90620 }; /** * Public data structure for MLX9062x data values. * **/ typedef struct { uint16_t Config; /*!< MLX9062x configuration register*/ uint16_t OscTrim; /*!< MLX9062x oscillator trim register*/ uint16_t PtatD; /*!< MLX9062x PTAT data register*/ int16_t VCP; /*!< MLX90621 VCP data register*/ int mlxDevice; /*!< MLX90620 or MLX90621 device type flag*/ uint32_t mlx621IDhi; /*!< MLX90621 only, device ID hi 32 bits*/ uint32_t mlx621IDlo; /*!< MLX90621 only, device ID lo 32 bits*/ char MLXEEbuf[256]; /*!< MLX9062x EEPROM data buffer, 0x00 - 0xff*/ char MLXRamBuf[128]; /*!< MLX9062x RAM data buffer, 0x00 - 0x7f*/ char MLXRamCmmd[8]; /*!< MLX9062x i2c command i/o buffer*/ double DieTemp; /*!< MLX9062x die temperature*/ } mlx_struct; /** Create a MLX90620 object using the specified I2C object * * Original Constructor * * @param sda pin for I2C object * @param scl pin for I2C object * @param name of MLX90620 object */ MLX9062x(PinName sda, PinName scl, const char* name); /** Create a MLX9062x object using the specified I2C object * * New Constructor with ability to select between a MLX90620 and MLX90621 * * @param sda pin for I2C object * @param scl pin for I2C object * @param MLXdevice select between mlx90620 and mlx90621 device * @param name of MLX9062x object */ MLX9062x(PinName sda, PinName scl, MLXdevice MLXtype, const char* name); /** Copy the contents of the MLX9062x EEPROM into local buffer * * Loads all 256 bytes from EEPROM into local buffer inside mlx_struct * * Note: Only done at initialization. MUST be the first thing you do in MAIN. * * @param pointer to struct mlx_struct * * @returns '1' if i2c error, '0' if ok. */ int LoadEEPROM(mlx_struct& Pntr); /** Initialize the MLX9062x's Oscillator Trim Register * * 7 lsb bits from 16 bit value, * * Data is derived from values received from the EEPROM * * Register is only set once during initialization * * @param pointer to struct mlx_struct * * @returns '1' if i2c error, '0' if ok. */ int SetOscTrimReg(mlx_struct& Pntr); /** Get the MLX9062x's Oscillator Trim Register * * 7 lsb bits from 16 bit value, Read from MLX RAM * * @param pointer to struct mlx_struct * * @returns OTR - Oscillator Trim Register value */ uint16_t GetOscTrimReg(mlx_struct& Pntr); /** Set the MLX9062x's Configuration Register * * 16 bit value set by code at initialization * * Register is set only during initialization. Inital setup: * * 1. ADC low reference * * 2. Ta Ref Rate 8Hz * * 3. I2C FM+ mode enabled * * 4. MD / Brownout bit set * * 5. Normal Operation (non-Sleep) mode * * 6. Step(Melexis reserved) mode. (removed from later datasheets, but used in this code) * * 7. IR refresh rate 4Hz * * @param pointer to struct mlx_struct * * @returns '1' if i2c error, '0' if ok. */ int SetConfigReg(mlx_struct& Pntr); /** Get the MLX9062x's Configuration Register * * 16 bit value, Read from MLX RAM * * Periodic check for Ta ready, IR Array ready and brownout conditions * * @param pointer to struct mlx_struct * * @returns CR - Configuration Register value */ uint16_t GetConfigReg(mlx_struct& Pntr); /** Get the MLX9062x's PTAT register. Register read at every Ta cycle * * 16 bit value, PTAT sensor, Read from MLX RAM * * Returns the Proportional To Ambient Temperature Register value * * @param pointer to struct mlx_struct * * @returns PTAT Register value */ uint16_t GetPTATReg(mlx_struct& Pntr); /** Get the MLX9062x's TGC register * * 16 bit value, TGC, Read from MLX RAM * * Returns the Temperature Gradient Coefficient Register value * * @param pointer to struct mlx_struct * * @returns TGC - Temperature Gradient Coefficient Register value */ int16_t GetTGCReg(mlx_struct& Pntr); /** Get the MLX9062x's IR pixel array and dump into local buffer * * Loads IR Pixel array into buffer (0x7F bytes, 0x3f Pixels), Read from MLX RAM * * @param pointer to struct mlx_struct * * @returns NONE */ void LoadMLXRam(mlx_struct& Pntr); /** Start a Ta and IR array conversion update cycle * * MLX9062x starts aquiring data, takes about 250mS /w 4Hz refresh rate * * Also calls GetPTATReg() and GetTGCReg() * * @param pointer to struct mlx_struct * * @returns '1' if i2c error, '0' if ok. */ int StartMeasurement(mlx_struct& Pntr); /** Get the MLX9062x's die temperature in degC * * Returns MLX9062x die temperature * * Needs to be performed before every array update calculation * * @param pointer to struct mlx_struct * * @returns die temperature of MLX9062x in degC */ double GetDieTemp(mlx_struct& Pntr); /** Calculate initial MLX9062x offsets. Performed only at initialization * * Sets the MLX9062x with die correcting factors at initialization * * @param pointer to struct mlx_struct * * @returns NONE */ void CalcTa_To(mlx_struct& Pntr); /** Calculate temperature of any pixel within the array (0 - 63) * * After an IR array dump into local buffer * * @param set int(0-63) of pixel to convert, * @param pointer to struct mlx_struct * * @returns pixel temperature of selected pixel in degC */ double CalcPixel(mlx_struct& Pntr, int Pixel); private: I2C _i2c; int mlxDev; int16_t Vth25; int8_t AcpX; int8_t BcpX; double Kt1_f; double Kt2_f; double Ta; int8_t TGCX; uint8_t BiScaleX; uint16_t theta0X; uint8_t theta0ScaleX; uint8_t deltaThetaScaleX; uint16_t elipsonX; int8_t AiPix; int8_t BiPix; uint8_t d_Th_Pix; int16_t VirPix; double TempPxlX; int16_t ConfigReg54; int16_t ScaleCR54; int16_t AiScale621; int16_t AlphaCP; int16_t ACP_ee; float aCP; float bCP; float Tgc621; double VcpCPOffComp; void DumpRawRegs(mlx_struct& Pntr); void DSSetup(mlx_struct& Pntr, int Pixel); void DumpPixRegs(mlx_struct& Pntr, int Pixel); int16_t Kt1; int16_t Kt2; int16_t TGCReg; int8_t TempTCG; int8_t Ks4_ee; double Ks4; int16_t KsTa; double KsTaF; double TaK4; double ThPix; double ThetaCP; double ThetaCompPix; double VirComp; int16_t Th_0; int8_t Th_0_sc; int8_t d_Th_sc; int16_t Acommon; int16_t Emiss; uint16_t deltaAi621; uint16_t deltaAiScale621; int16_t BiScale621; float Ai_ij; int16_t Bi_ijEEP; float Bi_ij; float VirOffComp; float VircpTgcComp; float VirTGCComp; float VirPix_tgc_comp; double SxGuts; double Sx; double TempPxl; }; #endif