Melexis MLX90620 and MLX90621, non-contact, 16x4 infrared array temperature sensor device driver.

Dependents:   KL25Z_MLX90620

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