Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: MLX90620.cpp
- Revision:
- 1:fd536ebc7eaf
- Parent:
- 0:8c2ddd9801ca
- Child:
- 2:82782c73251e
diff -r 8c2ddd9801ca -r fd536ebc7eaf MLX90620.cpp
--- a/MLX90620.cpp Tue Jun 14 19:17:47 2016 +0000
+++ b/MLX90620.cpp Thu Jul 21 23:09:24 2016 +0000
@@ -4,62 +4,46 @@
#include "mbed.h"
#include "MLX90620.h"
-//these bufferes must reside in main.cpp
-//extern char* MLXEEbuf; //256 uint8_ts, holds contents of EEPROM
-//extern char* MLXRamBuf; //128 uint8_ts, 0x0 - 0x3f 'uint16_t', holds contents of RAM array
-//extern char* MLXRamCmmd; // 8 uint8_ts, MLX90620 i2c command i/o buffer
-/*
-uint16_t Config = 0; //MLX90620 configuration register
-uint16_t OscTrim = 0; //MLX90620 oscillator trim register
-uint16_t PtatD = 0; //MLX90620 PTAT data register
-int16_t VCP = 0; //VCP / TGC
-int16_t Vth25X = 0;
-float TaXX = 0.0;
-
-//For To
-int8_t AcpX = 0;
-int8_t BcpX = 0;
-float Kt1fX = 0.0;
-float Kt2fX = 0.0;
-int8_t TGCX = 0;
-uint8_t BiScaleX = 0;
-uint16_t theta0X = 0;
-uint8_t theta0ScaleX = 0;
-uint8_t deltaThetaScaleX = 0;
-uint16_t elipsonX = 0;
-int8_t AiPixelX = 0; //eeprom address range 0x00 - 0x3f
-int8_t BiPixelX = 0; //eeprom address range 0x40 - 0x7f
-uint8_t dThetaPixelX = 0; //eeprom address range 0x80 - 0xbf
-int16_t VirPixelX = 0;
-double TempPxlX = 0;
-*/
+//for debugging purposes (uncomment)
+//#define MLXTEST_621b 1
//--------------------------------------------------------------------------------------------------------------------------------------//
-// Constructor
+// Original Constructor
-MLX90620::MLX90620(PinName sda, PinName scl, const char* name) : _i2c(sda, scl){
+MLX9062x::MLX9062x(PinName sda, PinName scl, const char* name) : _i2c(sda, scl){
_i2c.frequency(400000); //set up i2c speed
_i2c.stop(); //initialize with a stop
+ mlxDev = mlx90620; //default device is MLX90620
}
//--------------------------------------------------------------------------------------------------------------------------------------//
-//copy contents of EEPROM inside the MLX90620 into a local buffer. Data is used for lookup tables and parameters
+// Additional Constructor for selecting the MLX device
+
+MLX9062x::MLX9062x(PinName sda, PinName scl, MLXdevice MLXtype, const char* name) : _i2c(sda, scl){
+ _i2c.frequency(400000); //set up i2c speed
+ _i2c.stop(); //initialize with a stop
+ mlxDev = MLXtype; //user select device 620 or 621
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+//copy contents of EEPROM inside the MLX9062x into a local buffer. Data is used for lookup tables and parameters
#define MLX_EEP_EASY_LOAD 1
-int MLX90620::LoadEEPROM(mlx_struct& Pntr) {
+int MLX9062x::LoadEEPROM(mlx_struct& Pntr) {
+ Pntr.mlx621IDhi = 0;
+ Pntr.mlx621IDlo = 0;
+ Pntr.mlxDevice = mlxDev; //make strurcture device same as local device
//clear out buffer first
- for(int i = 0; i < 256; i++) { //option to clear out EEPROM buffer first
- Pntr.MLXEEbuf[i] = 0;
- }
+ for(int i = 0; i < 256; i++) Pntr.MLXEEbuf[i] = 0; //clear out entire EEMPROM buffer
//load the entire EEPROM
Pntr.MLXEEbuf[0] = 0; //start at address 0 of EEPROM
if(!_i2c.write(MLX_EEPADDR, Pntr.MLXEEbuf, 1, true)) { //send command, 0 returned is ok
#ifdef MLX_EEP_EASY_LOAD
- _i2c.read((MLX_EEPADDR + 1), Pntr.MLXEEbuf, 256); //**** this command does not work with the KL25Z anv v63 of mbed.lbr !!!! //load contents of EEPROM
+ _i2c.read((MLX_EEPADDR + 1), Pntr.MLXEEbuf, 256);//**** this command does not work with the KL25Z and v63 of mbed.lbr !!!!
#else
_i2c.start();
_i2c.write(MLX_EEPADDR + 1);
@@ -73,57 +57,73 @@
_i2c.stop(); //don't read EEP if write is broken
return(1); //return with error
}
+ if(Pntr.mlxDevice == mlx90621) {
+ Pntr.mlx621IDhi = (Pntr.MLXEEbuf[MLX621_EE_ID_BASE + 7] << 24) | (Pntr.MLXEEbuf[MLX621_EE_ID_BASE + 6] << 16) |
+ (Pntr.MLXEEbuf[MLX621_EE_ID_BASE + 5] << 8) | Pntr.MLXEEbuf[MLX621_EE_ID_BASE + 4];
+ Pntr.mlx621IDlo = (Pntr.MLXEEbuf[MLX621_EE_ID_BASE + 3] << 24) | (Pntr.MLXEEbuf[MLX621_EE_ID_BASE + 2] << 16) |
+ (Pntr.MLXEEbuf[MLX621_EE_ID_BASE + 1] << 8) | Pntr.MLXEEbuf[MLX621_EE_ID_BASE + 0];
+ }
return(0); //return with ok
}
//--------------------------------------------------------------------------------------------------------------------------------------//
-//copy oscillator offset from MLXEEbuf to MLX90620 (MS byte = 0)
+//copy oscillator offset from MLXEEbuf to MLX9062x (MS byte on 620 always = 0)
-int MLX90620::SetOscTrimReg(mlx_struct& Pntr) {
+int MLX9062x::SetOscTrimReg(mlx_struct& Pntr) {
Pntr.MLXRamCmmd[0] = 4; //command
- Pntr.MLXRamCmmd[1] = Pntr.MLXEEbuf[MLX_EETRIM] - 0xaa; //LS byte check
- Pntr.MLXRamCmmd[2] = Pntr.MLXEEbuf[MLX_EETRIM]; //oscillator trim value
+ Pntr.MLXRamCmmd[1] = Pntr.MLXEEbuf[MLX620_EETRIM] - 0xaa; //LS byte check
+ Pntr.MLXRamCmmd[2] = Pntr.MLXEEbuf[MLX620_EETRIM]; //oscillator trim value
Pntr.MLXRamCmmd[3] = 0x100 - 0xaa; //MS byte check
Pntr.MLXRamCmmd[4] = 0; //MS byte = 0
int r = _i2c.write(MLX_RAMADDR, Pntr.MLXRamCmmd, 5, false); //send command
- return(r); //return ok or error
+ //printf("OscTrim-W: %02x %02x %02x %02x %02x\r\n", Pntr.MLXRamCmmd[0], Pntr.MLXRamCmmd[1], Pntr.MLXRamCmmd[2], Pntr.MLXRamCmmd[3], Pntr.MLXRamCmmd[4]);
+ return(r); //return ok or error
}
//--------------------------------------------------------------------------------------------------------------------------------------//
-//get oscillator offset register from MLX90620
+//get oscillator offset register from MLX9062x
-uint16_t MLX90620::GetOscTrimReg(mlx_struct& Pntr) {
+uint16_t MLX9062x::GetOscTrimReg(mlx_struct& Pntr) {
Pntr.MLXRamCmmd[0] = 2; //command
Pntr.MLXRamCmmd[1] = MLX_TRIM; //address of register
Pntr.MLXRamCmmd[2] = 0; //address step
Pntr.MLXRamCmmd[3] = 1; //# of reads
_i2c.write(MLX_RAMADDR, Pntr.MLXRamCmmd, 4, true); //send command
- _i2c.read(MLX_RAMADDR, Pntr.MLXRamCmmd, 2); //get 16 bit register
- Pntr.OscTrim = (Pntr.MLXRamCmmd[1] << 8) + Pntr.MLXRamCmmd[0]; //store register
- return(Pntr.OscTrim); //return value
+ _i2c.read(MLX_RAMADDR, Pntr.MLXRamCmmd, 2, false); //get 16 bit register
+ Pntr.OscTrim = (Pntr.MLXRamCmmd[1] << 8) + Pntr.MLXRamCmmd[0]; //store register
+ //printf("OscTrim-R: %02x %02x\r\n", Pntr.MLXRamCmmd[0], Pntr.MLXRamCmmd[1]);
+ return(Pntr.OscTrim); //return value
}
//--------------------------------------------------------------------------------------------------------------------------------------//
//initialize the configuration register
//******* NOTE: Step measurement mode was removed from new data sheet dated Sept 19 2012
-int MLX90620::SetConfigReg(mlx_struct& Pntr) {
- Pntr.MLXRamCmmd[0] = 3; //command
- //old mode
- //MLXRamCmmd[1] = 0x14c - 0x55; //LS byte check
- //MLXRamCmmd[2] = 0x4c; //LS config value, step meas mode, 4Hz array *******
- Pntr.MLXRamCmmd[1] = 0x10c - 0x55; //LS byte check
- Pntr.MLXRamCmmd[2] = 0x0c; //LS config value, normal mode, 4Hz array *******
- Pntr.MLXRamCmmd[3] = 0x5c - 0x55; //MS byte check
- Pntr.MLXRamCmmd[4] = 0x5c; //MS config value, 8Hz Ta, 400k i2c
+int MLX9062x::SetConfigReg(mlx_struct& Pntr) {
+ Pntr.MLXRamCmmd[0] = 3; //command
+ if(Pntr.mlxDevice == mlx90621) {
+ Pntr.MLXRamCmmd[2] = Pntr.MLXEEbuf[MLX621_CONFIG_LO]; //LS byte
+ Pntr.MLXRamCmmd[4] = Pntr.MLXEEbuf[MLX621_CONFIG_HI]; //MS byte
+ //here you can manipulate the Config Register contents from the default EEPROM values of 0x463e
+ Pntr.MLXRamCmmd[2] = (Pntr.MLXRamCmmd[2] & ~MLX621_CONF_ADC_MASK) | MLX621_CONF_ADC18;
+ Pntr.MLXRamCmmd[4] = Pntr.MLXRamCmmd[4] | (MLX621_CONF_MD_1 >> 8);
+ Pntr.MLXRamCmmd[1] = Pntr.MLXRamCmmd[2] - 0x55; //LS byte check
+ Pntr.MLXRamCmmd[3] = Pntr.MLXRamCmmd[4] - 0x55; //MS byte check
+ } else {
+ Pntr.MLXRamCmmd[1] = 0x10c - 0x55; //LS byte check
+ Pntr.MLXRamCmmd[2] = 0x0c; //LS config value, normal mode, 4Hz array *******
+ Pntr.MLXRamCmmd[3] = 0x5c - 0x55; //MS byte check
+ Pntr.MLXRamCmmd[4] = 0x5c; //MS config value, 8Hz Ta, 400k i2c
+ }
int r = _i2c.write(MLX_RAMADDR, Pntr.MLXRamCmmd, 5, false);
+ //printf("Command-W: %02x %02x %02x %02x %02x\r\n", Pntr.MLXRamCmmd[0], Pntr.MLXRamCmmd[1], Pntr.MLXRamCmmd[2], Pntr.MLXRamCmmd[3], Pntr.MLXRamCmmd[4]);
return(r);
}
//--------------------------------------------------------------------------------------------------------------------------------------//
-//get configuration register from MLX90620
+//get configuration register from MLX9062x
-uint16_t MLX90620::GetConfigReg(mlx_struct& Pntr) {
+uint16_t MLX9062x::GetConfigReg(mlx_struct& Pntr) {
Pntr.MLXRamCmmd[0] = 2; //command
Pntr.MLXRamCmmd[1] = MLX_CONFIG; //address of register
Pntr.MLXRamCmmd[2] = 0; //address step
@@ -135,52 +135,78 @@
}
//--------------------------------------------------------------------------------------------------------------------------------------//
-//get PTAT register from MLX90620
+//get PTAT register from MLX9062x
-uint16_t MLX90620::GetPTATReg(mlx_struct& Pntr) {
+uint16_t MLX9062x::GetPTATReg(mlx_struct& Pntr) {
Pntr.MLXRamCmmd[0] = 2; //command
- Pntr.MLXRamCmmd[1] = MLX_PTATSENS; //address of register
+ Pntr.MLXRamCmmd[1] = MLX620_PTATSENS; //address of register
+ if(Pntr.mlxDevice == mlx90621) Pntr.MLXRamCmmd[1] = MLX621_PTATSENS;
Pntr.MLXRamCmmd[2] = 0; //address step
Pntr.MLXRamCmmd[3] = 1; //# of reads
_i2c.write(MLX_RAMADDR, Pntr.MLXRamCmmd, 4, true);
_i2c.read(MLX_RAMADDR, Pntr.MLXRamCmmd, 2);
Pntr.PtatD = (Pntr.MLXRamCmmd[1] << 8) + Pntr.MLXRamCmmd[0];
+#ifdef MLXTEST_621b
+ if(Pntr.mlxDevice == mlx90620) {
+ Pntr.PtatD = 0x1ac0;
+ } else {
+ if(ConfigReg54 == 0) {
+ Pntr.PtatD = 0x0cfb;
+ } else
+ if(ConfigReg54 == 1) {
+ Pntr.PtatD = 0x19f7;
+ } else
+ if(ConfigReg54 == 2) {
+ Pntr.PtatD = 0x33ef;
+ } else
+ if(ConfigReg54 == 3) {
+ Pntr.PtatD = 0x67de;
+ } else {
+ Pntr.PtatD = 0;
+ }
+ }
+#endif
return(Pntr.PtatD);
}
//--------------------------------------------------------------------------------------------------------------------------------------//
-//get VCP / TGC register from MLX90620
+//get VCP / TGC register from MLX9062x
-int16_t MLX90620::GetTGCReg(mlx_struct& Pntr) {
+int16_t MLX9062x::GetTGCReg(mlx_struct& Pntr) {
Pntr.MLXRamCmmd[0] = 2; //command
- Pntr.MLXRamCmmd[1] = MLX_TGCSENS; //address of register
+ Pntr.MLXRamCmmd[1] = MLX620_TGCSENS; //address of register
+ if(Pntr.mlxDevice == mlx90621) Pntr.MLXRamCmmd[1] = MLX621_TGCSENS;
Pntr.MLXRamCmmd[2] = 0; //address step
Pntr.MLXRamCmmd[3] = 1; //# of reads
_i2c.write(MLX_RAMADDR, Pntr.MLXRamCmmd, 4, true);
_i2c.read(MLX_RAMADDR, Pntr.MLXRamCmmd, 2);
- VCP = (Pntr.MLXRamCmmd[1] << 8) + Pntr.MLXRamCmmd[0];
+ int16_t VCP = (Pntr.MLXRamCmmd[1] << 8) + Pntr.MLXRamCmmd[0];
+#ifdef MLXTEST_621b
+ VCP = 0xffdc;
+#endif
+ Pntr.VCP = VCP;
return(VCP);
}
//--------------------------------------------------------------------------------------------------------------------------------------//
-//get RAM dump from MLX90620
-bool firstDump = false;
+//get RAM dump from MLX9062x
-void MLX90620::LoadMLXRam(mlx_struct& Pntr) {
+void MLX9062x::LoadMLXRam(mlx_struct& Pntr) {
Pntr.MLXRamCmmd[0] = 2; //command
Pntr.MLXRamCmmd[1] = 0; //start address
Pntr.MLXRamCmmd[2] = 1; //address step
Pntr.MLXRamCmmd[3] = 0x40; //# of reads
_i2c.write(MLX_RAMADDR, Pntr.MLXRamCmmd, 4, true);
_i2c.read(MLX_RAMADDR, Pntr.MLXRamBuf, 0x80);
- Pntr.PtatD = MLX90620::GetPTATReg(Pntr);
- VCP = MLX90620::GetTGCReg(Pntr);
+ Pntr.PtatD = MLX9062x::GetPTATReg(Pntr);
+ Pntr.VCP = MLX9062x::GetTGCReg(Pntr);
}
//--------------------------------------------------------------------------------------------------------------------------------------//
-//start measurement MLX90620
+//start measurement MLX9062x
-int MLX90620::StartMeasurement(mlx_struct& Pntr) {
+int MLX9062x::StartMeasurement(mlx_struct& Pntr) {
+ if(Pntr.mlxDevice == mlx90621) return(0); //there is no start_meas in the 90621
Pntr.MLXRamCmmd[0] = 1; //command
Pntr.MLXRamCmmd[1] = 8; //address of config register
int r = _i2c.write(MLX_RAMADDR, Pntr.MLXRamCmmd, 2, false);
@@ -188,88 +214,447 @@
}
//--------------------------------------------------------------------------------------------------------------------------------------//
-// Initial Calculations for Ta and To
+// Only a test to set up values in EEPROM and RAM buffers to debug math.
+//Note: must be performed after reading the EEPROM and RAM data
-float MLX90620::GetDieTemp(mlx_struct& Pntr) {
- Pntr.PtatD = MLX90620::GetPTATReg(Pntr);
- float TaX = (-Kt1fX + sqrt(pow(Kt1fX, 2.0f) - 4.0f * Kt2fX * ((float)(Vth25X - Pntr.PtatD))))/(2.0f * Kt2fX) + 25.0f;
- return(TaX);
+void MLX9062x::DSSetup(mlx_struct& Pntr, int Pixel) {
+#ifdef MLXTEST_621b
+#warning "MLX90620 test mode B"
+ if(Pntr.mlxDevice == mlx90620) {
+ Pntr.MLXEEbuf[0xda] = 0x78;
+ Pntr.MLXEEbuf[0xdb] = 0x1a;
+ Pntr.MLXEEbuf[0xdc] = 0x33;
+ Pntr.MLXEEbuf[0xdd] = 0x5b;
+ Pntr.MLXEEbuf[0xde] = 0xcc;
+ Pntr.MLXEEbuf[0xdf] = 0xed;
+ } else {
+ //7.3.2 for Ta Calculations
+ Pntr.MLXEEbuf[0xda] = 0x20;
+ Pntr.MLXEEbuf[0xdb] = 0x64;
+ Pntr.MLXEEbuf[0xdc] = 0x89;
+ Pntr.MLXEEbuf[0xdd] = 0x55;
+ Pntr.MLXEEbuf[0xde] = 0x7e;
+ Pntr.MLXEEbuf[0xdf] = 0x5e;
+ Pntr.MLXEEbuf[0xd2] = 0x8b;
+
+ //7.3.4 for To Calculations (pixel 11)
+ Pntr.MLXEEbuf[0x00 + Pixel] = 0x21;
+ Pntr.MLXEEbuf[0x40 + Pixel] = 0xbc;
+ Pntr.MLXEEbuf[0x80 + Pixel] = 0xcd;
+
+ Pntr.MLXEEbuf[0xc0] = 0x99;
+ Pntr.MLXEEbuf[0xc4] = 0x9e;
+
+ Pntr.MLXEEbuf[0xd0] = 0x8a;
+ Pntr.MLXEEbuf[0xd1] = 0xff;
+
+ Pntr.MLXEEbuf[0xd3] = 0x9d;
+ Pntr.MLXEEbuf[0xd4] = 0xff;
+ Pntr.MLXEEbuf[0xd5] = 0xa2;
+ Pntr.MLXEEbuf[0xd6] = 0xa8;
+ Pntr.MLXEEbuf[0xd7] = 0x0f;
+ Pntr.MLXEEbuf[0xd8] = 0x18;
+ Pntr.MLXEEbuf[0xd9] = 0x07;
+
+ Pntr.MLXEEbuf[0xe0] = 0xae;
+ Pntr.MLXEEbuf[0xe1] = 0x4e;
+ Pntr.MLXEEbuf[0xe2] = 0x26;
+ Pntr.MLXEEbuf[0xe3] = 0x1f;
+ Pntr.MLXEEbuf[0xe4] = 0x00;
+ Pntr.MLXEEbuf[0xe5] = 0x80;
+ Pntr.MLXEEbuf[0xe6] = 0x0c;
+ Pntr.MLXEEbuf[0xe7] = 0x02;
+
+ VirPix = 0x01b7;
+ }
+#endif
}
//--------------------------------------------------------------------------------------------------------------------------------------//
// Initial Calculations for Ta and To
-void MLX90620::CalcTa_To(mlx_struct& Pntr) {
- //Calculate Ta first
- Vth25X = (Pntr.MLXEEbuf[MLX_TAINDEX + 1] << 8) + Pntr.MLXEEbuf[MLX_TAINDEX + 0];
- int16_t Kt1 = (Pntr.MLXEEbuf[MLX_TAINDEX + 3] << 8) + Pntr.MLXEEbuf[MLX_TAINDEX + 2];
- int16_t Kt2 = (Pntr.MLXEEbuf[MLX_TAINDEX + 5] << 8) + Pntr.MLXEEbuf[MLX_TAINDEX + 4];
- Kt1fX = Kt1 / 1024.0;
- Kt2fX = Kt2 / 1048576.0;
- TaXX = MLX90620::GetDieTemp(Pntr);
+//#define MLXTEST_621 1
+
+double MLX9062x::GetDieTemp(mlx_struct& Pntr) {
+ Pntr.PtatD = MLX9062x::GetPTATReg(Pntr);
+
+ //Note: There seems to be a scaling error in the following routine
+ //MLX621_CONF_ADC18 = +26.891C
+ //MLX621_CONF_ADC17 = +25.934C
+ //MLX621_CONF_ADC16 = +25.467C
+ //MLX621_CONF_ADC15 = +25.187C
+
+ double TaX = (-Kt1_f + sqrt(pow(Kt1_f, 2.0) - 4.0 * Kt2_f * (((Vth25 - (double)Pntr.PtatD)/ScaleCR54))))/(2.0 * Kt2_f) + 25.0;
+ Pntr.DieTemp = TaX;
+ return(TaX);
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Display internal PIXEL registers for debugging math
+
+void MLX9062x::DumpPixRegs(mlx_struct& Pntr, int Pixel) {
+#ifdef MLXTEST_621b
+ if(Pntr.mlxDevice == mlx90620) {
+ /*
+ printf("\r\n\r\npixel = %d\r\n", Pixel);
+ printf("Acp = %d\r\nBcp = %d\r\nBiS = %d\r\n", AcpX, BcpX, BiScaleX);
+ printf("Vcp = %d\r\neps = %d\r\nTGC = %d\r\n", VCP, elipsonX, TGCX);
+ printf("Vcp_off_comp = %f\r\n", Vcp_off_comp);
+ printf("VirPix_off_comp = %f\r\n", VirPix_off_comp);
+ printf("VirPix = %d\r\n", VirPix);
+ printf("AiPix = %d\r\n", AiPix);
+ printf("BiPix = %d\r\n", BiPix);
+ printf("BiScale = %d\r\n", BiScaleX);
+ printf("2^BiScale = %f\r\n", (powf(2.0,BiScaleX)));
+ printf("1 << BiScale = %d\r\n", (1 << BiScaleX));
+ printf("Ta-25.0 = %f\r\n", (Ta - 25.0f));
+ printf("BiPix/2^BiScale = %f\r\n", (BiPix / powf(2.0,BiScaleX)));
+ printf("AiP+BiP/2^BiScale)*(Ta-25= %f\r\n", (AiPix + BiPix / powf(2.0,BiScaleX) * (Ta - 25.0f)));
+ printf("VirPix_off_comp again = %f\r\n", (VirPix - (AiPix + BiPix / powf(2.0,BiScaleX) * (Ta - 25.0f))));
+ printf("VirPix_off_comp2 step = %f\r\n", VirPix_off_comp2);
+ printf("VirPix_tgc_comp = %f\r\n", VirPix_tgc_comp);
+ printf("elipsonf = %f\r\n", elipsonf);
+ printf("VirPix_comp = %f\r\n", VirPix_comp);
+ printf("theta28 = %f << double print problem\r\n", (theta28 * 100000000.0)); //<<< can't print a double
+ printf("TempPxl = %f\r\n", TempPxl);
+*/
+
+ } else {
+ printf("Pixel,%2d\r\n", Pixel);
+
+ //DSSetup(Pntr, Pixel);
+ printf("VirPix,%d,%x\r\n", VirPix, VirPix);
+ printf("VCP,%d\r\n", Pntr.VCP);
+ printf("Ta,%.3f\r\n\r\n", Ta);
+
+ printf("Acommon_mod,%d\r\n", Acommon);
+ printf("AiPix,%d\r\n", AiPix);
+ printf("Ai_ij_f,%.16f\r\n", Ai_ij);
+ printf("BiPix_mod,%d\r\n", BiPix);
+ printf("Bi_ij_f,%.16f\r\n", Bi_ij);
+ printf("VirOffComp,%.16f\r\n", VirOffComp);
+ printf("ACP_ee_mod,%d\r\n", ACP_ee);
+ int8_t bCPx = Pntr.MLXEEbuf[MLX621_BCP];
+ if(bCPx > 127) bCPx -= 256;
+ printf("bCP_ee_mod,%d\r\n", bCPx);
+ printf("bCP,%.16f\r\n", bCP);
+ printf("VcpCPOffComp,%.16f\r\n", VcpCPOffComp);
+ printf("TempTCG_mod,%d\r\n\r\n", TempTCG);
+
+ printf("Tgc621 mod,%.16f\r\n", Tgc621);
+ printf("Emiss mod,%d\r\n", Emiss);
+ printf("VirTGCComp,%.16f\r\n", VirTGCComp);
+ printf("VirComp,%.16f\r\n", VirComp);
- //Calculate To
- AcpX = Pntr.MLXEEbuf[MLX_TOINDEX + 0];
- BcpX = Pntr.MLXEEbuf[MLX_TOINDEX + 1];
-// uint16_t thetaCPX = (EEbuf[MLX_TOINDEX + 3] << 8) + MLXEEbuf[MLX_TOINDEX + 2];
- TGCX = Pntr.MLXEEbuf[MLX_TOINDEX + 4];
- BiScaleX = Pntr.MLXEEbuf[MLX_TOINDEX + 5];
- theta0X = (Pntr.MLXEEbuf[MLX_TOINDEX + 13] << 8) + Pntr.MLXEEbuf[MLX_TOINDEX + 12];
- theta0ScaleX = Pntr.MLXEEbuf[MLX_TOINDEX + 14];
- deltaThetaScaleX = Pntr.MLXEEbuf[MLX_TOINDEX + 15];
- elipsonX = (Pntr.MLXEEbuf[MLX_TOINDEX + 17] << 8) + Pntr.MLXEEbuf[MLX_TOINDEX + 16];
-/*
- printf("Vth(25) = %6d 0x%x\nTa1 = %6d 0x%x\nTa2 = %6d 0x%x\n", Vth25X, Vth25X, Kt1, Kt1, Kt2, Kt2);
- printf("Kt1fX = %f\nKt2fX = %f\nTaXX = %f\n\n", Kt1fX, Kt2fX, TaXX);
- printf("Acp = %6d 0x%x\nBcp = %6d 0x%x\nThCP = %6d 0x%x\n", AcpX, AcpX, BcpX, BcpX, thetaCPX, thetaCPX);
- printf("TGC = %6d 0x%x\nBiS = %6d 0x%x\nTh0 = %6d 0x%x\n", TGCX, TGCX, BiScaleX, BiScaleX, theta0X, theta0X);
- printf("T0s = %6d 0x%x\nDts = %6d 0x%x\nelip = %6d 0x%x\n\n", theta0ScaleX, theta0ScaleX, deltaThetaScaleX, deltaThetaScaleX, elipsonX, elipsonX);
+ printf("KsTa,%d\r\n", KsTa);
+ printf("KsTaF,%.16f\r\n", KsTaF);
+ printf("ThPix,%.16f\r\n", ThPix);
+ printf("ThetaCP,%.16f\r\n", ThetaCP);
+ printf("ThetaCompPix,%.16f\r\n", ThetaCompPix);
+
+ printf("Ks4_ee,%d\r\n", Ks4_ee);
+ printf("Ks4_scale,%d,%x\r\n", Pntr.MLXEEbuf[MLX621_KS_SCALE], Pntr.MLXEEbuf[MLX621_KS_SCALE]);
+ printf("Ks4,%.16f\r\n", Ks4);
+ printf("TaK4,%.2f\r\n", TaK4);
+ printf("Sx,%.16f\r\n", Sx);
+ /*
+
+ printf("BiPix,%d,%x\r\n", Pntr.MLXEEbuf[Pixel + 0x40], Pntr.MLXEEbuf[Pixel + 0x40]);
+ printf("d_Th_Pix,%d,%x\r\n", d_Th_Pix, d_Th_Pix);
+
+ //printf("VirOff_(Ta - 25.0f),%.16f\r\n", (Ta - 25.0f));
+ //printf("VirOff_Bi_ij * (Ta - 25.0f),%.16f\r\n", Bi_ij * (Ta - 25.0f));
+ //printf("VirOff_(Ai_ij + Bi_ij * (Ta - 25.0f)),%.16f\r\n", (Ai_ij + Bi_ij * (Ta - 25.0f)));
+
+ printf("VircpTgcComp,%.16f\r\n", VircpTgcComp);
+ printf("VirTGCComp,%.16f\r\n", VirTGCComp);
+ printf("DELTA_TH_SCALE,%d,%.0f\r\n", Pntr.MLXEEbuf[MLX621_DELTA_TH_SCALE], (double) powf(2.0,Pntr.MLXEEbuf[MLX621_DELTA_TH_SCALE]));
+ printf("THETA0_SCALE,%d,%.0f\r\n", Pntr.MLXEEbuf[MLX621_THETA0_SCALE], (double) powf(2.0,Pntr.MLXEEbuf[MLX621_THETA0_SCALE]));
+ //printf("Alpha_ij_raw,%d,%04x\r\n", (Pntr.MLXEEbuf[MLX621_THETA0_HI] << 8) + Pntr.MLXEEbuf[MLX621_THETA0_LO], (Pntr.MLXEEbuf[MLX621_THETA0_HI] << 8) + Pntr.MLXEEbuf[MLX621_THETA0_LO]);
+ //printf("Alpha_ij_f,%.16f\r\n", Alpha_ij);
+ //printf("VirNorm,%.16f\r\n", VirNorm);
+ printf("VirComp,%.16f\r\n", VirComp);
+ printf("TempPxl,%.16f\r\n", TempPxl);
+
+ //printf("TempPxl_a,%.16f\r\n", powf((Ta + 273.15), 4.0));
+ //printf("TempPxl_b,%.16f\r\n", log10((VirComp + powf((Ta + 273.15), 4.0)) / 4.0));
+ //printf("TempPxl_c,%.16f\r\n", exp((log10((VirComp + powf((Ta + 273.15), 4.0)) / 4.0))));
+ //printf("TempPxl_d,%.16f\r\n", powf((Ta + 273.15), 1.0));
+ //printf("TempPxl_e,%.16f\r\n", Ta + 273.15);
+ //printf("TempPxl_f,%.16f\r\n", Ta + 273.15);
+ printf("Th_0 ,%.16f\r\n", (double)Th_0 / pow(2.0,(double)Th_0_sc));
+ //printf("d_Th_Pix,%d,%x\r\n", d_Th_Pix, d_Th_Pix);
+ //printf("d_Th_Pix_raw,%d,%3.20f\r\n", Pntr.MLXEEbuf[Pixel + 0x80], (double)Pntr.MLXEEbuf[Pixel + 0x80]);
+ //printf("ThDeltaZ,%3.20f\r\n", (double)d_Th_Pix); // !!!!! coverting 205 to 34!!
+ //d_Th_Pix = Pntr.MLXEEbuf[Pixel + 0x80];
+ //printf("ThDelta1,%.16f\r\n", (double)d_Th_Pix);
+ //printf("ThDelta2,%.16f\r\n", (double)Th_0 / pow(2.0,(double)Th_0_sc));
+ //printf("ThDelta3,%.16f\r\n", (double)d_Th_Pix / pow(2.0,(double)d_Th_sc));
+ //printf("ThDelta4,%.16f\r\n", (double)Th_0 / pow(2.0,(double)Th_0_sc) + (double)d_Th_Pix / pow(2.0,(double)d_Th_sc));
+ //printf("ThDelta5,%.16f\r\n", (double)d_Th_Pix / pow(2.0,(double)d_Th_sc));
+
+ //ThPix = (((double)Th_0 / pow(2.0,(double)Th_0_sc) + ((double)d_Th_Pix / pow(2.0,(double)d_Th_sc)))) / ScaleCR54;
+
+ printf("ThPix,%.16f\r\n", ThPix);
+ printf("ThetaCP,%.16f\r\n", ThetaCP);
+ printf("ThetaCompPix,%.16f\r\n", ThetaCompPix);
+ //printf("SxGuts1,%.32f\r\n", pow(ThetaCompPix, 3.0));
+ //printf("SxGuts2,%.32f\r\n", pow(ThetaCompPix, 3.0) * VirComp);
+ //printf("SxGuts3,%.32f\r\n", pow(ThetaCompPix, 4.0));
+ //printf("SxGuts4,%.32f\r\n", pow(ThetaCompPix, 4.0) * TaK4);
+ //printf("SxGuts5,%.32f\r\n", pow(ThetaCompPix, 3.0) * VirComp + (pow(ThetaCompPix, 4.0) * TaK4));
+ printf("SxGuts,%.32f\r\n", SxGuts);
+ printf("Sx,%.16f\r\n", Sx);
*/
+ printf("TempPxl,%.16f\r\n", TempPxl);
+ printf("\r\n");
+ }
+#endif
+}
+
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Display internal registers for debugging math
+
+void MLX9062x::DumpRawRegs(mlx_struct& Pntr) {
+#ifdef MLXTEST_621b
+ if(Pntr.mlxDevice == mlx90620) {
+ printf("\r\n\r\nMLX90620 Ta_T0 regs:\r\n");
+ //printf("ConfigReg54 = %d\r\n", ConfigReg54);
+ //printf("ScaleCR54 = %d\r\n", ScaleCR54);
+ //printf("Ktbits = %02x\r\n",Pntr.MLXEEbuf[MLX621_KT12_SCALE]);
+ printf("Kt1,%d,%x\r\n", Kt1, Kt1);
+ //printf("Kt1_0xd2 = %d\r\n", 1 << ((Pntr.MLXEEbuf[MLX621_KT12_SCALE] & MLX621_KT1SCALE_BITS) >> 4));
+ printf("Kt2,%d,%x\r\n", Kt2, Kt2);
+ //printf("Kt2_0xd2 = %d %x\r\n", 1 << (Pntr.MLXEEbuf[MLX621_KT12_SCALE] & MLX621_KT2SCALE_BITS), 1 << (Pntr.MLXEEbuf[MLX621_KT12_SCALE] & MLX621_KT2SCALE_BITS));
+ //printf("Kt2_0xd2 2 = %d %x\r\n", 1 << 10 << (Pntr.MLXEEbuf[MLX621_KT12_SCALE] & MLX621_KT2SCALE_BITS), 1 << 10 << (Pntr.MLXEEbuf[MLX621_KT12_SCALE] & MLX621_KT2SCALE_BITS));
+ printf("Vth25,%d,%x\r\n", Vth25, Vth25);
+ printf("Kt1_f,%f\r\n", Kt1_f);
+ printf("Kt2_f,%f\r\n", Kt2_f);
+ printf("Pntr.PtatD,%d,%x\r\n", Pntr.PtatD, Pntr.PtatD);
+ printf("Ta,%f\r\n", Ta);
+ //printf("Tak4 = %f\r\n", Tak4);
+
+ //printf("MLX621_KS4_EE = %d\r\n", Pntr.MLXEEbuf[MLX621_KS4_EE]);
+ //printf("MLX621_KS_SCALE = %d\r\n", Pntr.MLXEEbuf[MLX621_KS_SCALE]);
+ //printf("ks4 = %d\r\n", ks4);
+ //printf("Acommon = %d\r\n", Acommon);
+ //printf("deltaAi621 = %d\r\n", deltaAi621);
+ //printf("deltaAiScale621 = %d\r\n", deltaAiScale621);
+ //printf("Ai_ij = %d\r\n", Ai_ij);
+
+ //printf("BiScale621 = %d\r\n", BiScale621);
+ //printf("Bi_ijEEP = %d **\r\n", Bi_ijEEP);
+ //printf("Bi_ij = %d\r\n", Bi_ij);
+
+ //printf("ACP_ee = %d **\r\n", ACP_ee);
+ //printf("aCP = %d\r\n", aCP); //was 8 bit, now 16
+
+ //printf("Vth(25) = %6d 0x%x\nTa1 = %6d 0x%x\nTa2 = %6d 0x%x\n", Vth25, Vth25, Kt1, Kt1, Kt2, Kt2);
+ //printf("Kt1_f = %f\nKt2_f = %f\nTa = %f\n\n", Kt1_f, Kt2_f, Ta);
+ //printf("Acp = %6d 0x%x\nBcp = %6d 0x%x\nThCP = %6d 0x%x\n", AcpX, AcpX, BcpX, BcpX, thetaCPX, thetaCPX);
+ //printf("TGC = %6d 0x%x\nBiS = %6d 0x%x\nTh0 = %6d 0x%x\n", TGCX, TGCX, BiScaleX, BiScaleX, theta0X, theta0X);
+ //printf("T0s = %6d 0x%x\nDts = %6d 0x%x\nelip = %6d 0x%x\n\n", theta0ScaleX, theta0ScaleX, deltaThetaScaleX, deltaThetaScaleX, elipsonX, elipsonX);
+ } else {
+ printf("\r\n\r\nMLX90621 Ta_T0 regs:\r\n");
+ printf("ConfigReg54,%d,%02x\r\n", (Pntr.Config & MLX621_RESOLUTION) >> 4, (Pntr.Config & MLX621_RESOLUTION) >> 4);
+ printf("Pntr.PtatD,%d,%x\r\n", Pntr.PtatD, Pntr.PtatD);
+ printf("Vth25 mod,%d,%x\r\n", Vth25, Vth25);
+ printf("Kt1_f,%.16f\r\n", Kt1_f);
+ printf("Kt2_f,%.16f\r\n", Kt2_f);
+ printf("Ta,%.16f\r\n\r\n", Ta);
+
+ printf("ScaleCR54,%d,%x\r\n", 1 << (3 - ((Pntr.Config & MLX621_RESOLUTION) >> 4)), 1 << (3 - ((Pntr.Config & MLX621_RESOLUTION) >> 4)));
+ printf("Ktbits,%02x\r\n",Pntr.MLXEEbuf[MLX621_KT12_SCALE]);
+ printf("Kt1,%d,%x\r\n", (int16_t)(Pntr.MLXEEbuf[MLX621_KT1_HI] << 8) | Pntr.MLXEEbuf[MLX621_KT1_LO], (Pntr.MLXEEbuf[MLX621_KT1_HI] << 8) | Pntr.MLXEEbuf[MLX621_KT1_LO]);
+ printf("Kt1_0xd2,%d\r\n", 1 << ((Pntr.MLXEEbuf[MLX621_KT12_SCALE] & MLX621_KT1SCALE_BITS) >> 4));
+ printf("Kt1 mod,%d,%x\r\n", Kt1, Kt1);
+ printf("Kt2,%d,%x\r\n", (int16_t)((Pntr.MLXEEbuf[MLX621_KT2_HI] << 8) | Pntr.MLXEEbuf[MLX621_KT2_LO]), ((Pntr.MLXEEbuf[MLX621_KT2_HI] << 8) | Pntr.MLXEEbuf[MLX621_KT2_LO]));
+ printf("Kt2_0xd2,%d,%x\r\n", 1 << (Pntr.MLXEEbuf[MLX621_KT12_SCALE] & MLX621_KT2SCALE_BITS), 1 << (Pntr.MLXEEbuf[MLX621_KT12_SCALE] & MLX621_KT2SCALE_BITS));
+ printf("Kt2_0xd2_2,%d,%x\r\n", 1 << 10 << (Pntr.MLXEEbuf[MLX621_KT12_SCALE] & MLX621_KT2SCALE_BITS), 1 << 10 << (Pntr.MLXEEbuf[MLX621_KT12_SCALE] & MLX621_KT2SCALE_BITS));
+ printf("Kt2 mod,%d,%x\r\n", Kt2, Kt2);
+ printf("Vth25,%d,%x\r\n", (int16_t)(((Pntr.MLXEEbuf[MLX621_VTH25_HI] << 8) | Pntr.MLXEEbuf[MLX621_VTH25_LO])), (((Pntr.MLXEEbuf[MLX621_VTH25_HI] << 8) | Pntr.MLXEEbuf[MLX621_VTH25_LO])));
+ printf("Kt1_f^2,%12f\r\n", pow(Kt1_f, 2.0));
+ printf("Vth25-PtatD,%12f\r\n", (Vth25 - (double)Pntr.PtatD));
+ printf("4*Kt2_f,%12f\r\n", 4.0 * Kt2_f);
+ printf("4*Kt2_f*(Vth25 - Pntr.PtatD),%12f\r\n", 4.0 * Kt2_f * (Vth25 - (double)Pntr.PtatD));
+ printf("TopBeforesqrt,%12f\r\n", -pow(Kt1_f, 2.0) - 4.0 * Kt2_f * (Vth25 - (double)Pntr.PtatD));
+ printf("\r\n");
+
+ printf("Acommon,%d,%x\r\n", (int16_t)(Pntr.MLXEEbuf[MLX621_A_COMMON_HI] << 8) + Pntr.MLXEEbuf[MLX621_A_COMMON_LO], (Pntr.MLXEEbuf[MLX621_A_COMMON_HI] << 8) + Pntr.MLXEEbuf[MLX621_A_COMMON_LO]);
+ printf("Acommon mod,%d,%x\r\n", Acommon, Acommon);
+ printf("Emiss,%d,%x\r\n", (uint16_t)((Pntr.MLXEEbuf[MLX621_A_EMMIS_HI] << 8) + Pntr.MLXEEbuf[MLX621_A_EMMIS_LO]), ((Pntr.MLXEEbuf[MLX621_A_EMMIS_HI] << 8) + Pntr.MLXEEbuf[MLX621_A_EMMIS_LO]));
+ printf("Emiss mod,%d,%x\r\n", Emiss, Emiss);
+ printf("ACP_ee,%d,%x\r\n", (int16_t)(Pntr.MLXEEbuf[MLX621_ACP_HI] << 8) + Pntr.MLXEEbuf[MLX621_ACP_LO], (Pntr.MLXEEbuf[MLX621_ACP_HI] << 8) + Pntr.MLXEEbuf[MLX621_ACP_LO]);
+ printf("ACP_ee mod,%d,%x\r\n", ACP_ee, ACP_ee);
+ printf("AlphaCP,%d,%x\r\n", (int16_t)((Pntr.MLXEEbuf[MLX621_ALPHACP_HI] << 8) + Pntr.MLXEEbuf[MLX621_ALPHACP_LO]), ((Pntr.MLXEEbuf[MLX621_ALPHACP_HI] << 8) + Pntr.MLXEEbuf[MLX621_ALPHACP_LO]));
+ printf("AlphaCP mod,%d,%x\r\n", AlphaCP, AlphaCP);
+ printf("aCP,%.16f\r\n", aCP);
+ printf("AiScale621,%d,%x\r\n", (int16_t)(Pntr.MLXEEbuf[MLX621_DELTA_ABI_SCALE] & MLX621_DAISCALE_BITS) >> 4, (Pntr.MLXEEbuf[MLX621_DELTA_ABI_SCALE] & MLX621_DAISCALE_BITS) >> 4);
+ printf("BiScale621,%d,%x\r\n", (int16_t)(Pntr.MLXEEbuf[MLX621_DELTA_ABI_SCALE] & MLX621_DBISCALE_BITS), (Pntr.MLXEEbuf[MLX621_DELTA_ABI_SCALE] & MLX621_DBISCALE_BITS));
+ printf("bCP,%d,%x\r\n", (int8_t)Pntr.MLXEEbuf[MLX621_BCP], Pntr.MLXEEbuf[MLX621_BCP]);
+ printf("bCP mod,%.16f\r\n", bCP);
+
+ printf("TempTCG,%d,%x\r\n", (int8_t)Pntr.MLXEEbuf[MLX621_TGC], Pntr.MLXEEbuf[MLX621_TGC]);
+ printf("TempTCG mod,%d,%x\r\n", TempTCG, TempTCG);
+ printf("Tgc621 mod,%.16f\r\n", Tgc621);
+ //printf("TGCReg,%d,%x\r\n", (int16_t)TGCReg, TGCReg);
+ printf("VCP,%d,%x\r\n", (int16_t)Pntr.VCP, Pntr.VCP);
+ printf("VcpCPOffComp,%.16f\r\n", VcpCPOffComp);
+ printf("KsTa,%d,%x\r\n", (int16_t)KsTa, KsTa);
+ printf("KsTaF,%.16f\r\n", KsTaF);
+ printf("Ks4_ee,%d,%x\r\n", (int16_t)Ks4_ee, Ks4_ee);
+ printf("Ks4_scale,%d,%x\r\n", Pntr.MLXEEbuf[MLX621_KS_SCALE], Pntr.MLXEEbuf[MLX621_KS_SCALE]);
+ printf("Ks4,%.16f\r\n", Ks4);
+ printf("TaK4,%.16f\r\n", TaK4);
+ printf("Th_0,%d,%x\r\n", (int16_t)Th_0, Th_0);
+ printf("Th_0_sc,%d,%x\r\n", (int16_t)Th_0_sc, Th_0_sc);
+ printf("d_Th_sc,%d,%x\r\n", (int16_t)d_Th_sc, d_Th_sc);
+ printf("\r\n");
+ }
+#endif
+}
+
+//--------------------------------------------------------------------------------------------------------------------------------------//
+// Initial Calculations for Ta and To
+
+void MLX9062x::CalcTa_To(mlx_struct& Pntr) {
+#ifdef MLXTEST_621b
+ DSSetup(Pntr, 11);
+#endif
+ if(Pntr.mlxDevice == mlx90620) {
+ //Calculate Ta first
+ Vth25 = (Pntr.MLXEEbuf[MLX_TAINDEX + 1] << 8) + Pntr.MLXEEbuf[MLX_TAINDEX + 0];
+ Kt1 = (Pntr.MLXEEbuf[MLX_TAINDEX + 3] << 8) + Pntr.MLXEEbuf[MLX_TAINDEX + 2];
+ Kt2 = (Pntr.MLXEEbuf[MLX_TAINDEX + 5] << 8) + Pntr.MLXEEbuf[MLX_TAINDEX + 4];
+ if(Vth25 > 32767) Vth25 -= 65536;
+ if(Kt1 > 32767) Kt1 -= 65536;
+ if(Kt2 > 32767) Kt2 -= 65536;
+
+ Kt1_f = (double)Kt1 / 1024.0f;
+ Kt2_f = (double)Kt2 / 1048576.0f;
+ ScaleCR54 = 1;
+ Ta = MLX9062x::GetDieTemp(Pntr);
+
+ //Calculate To
+ AcpX = Pntr.MLXEEbuf[MLX621_A_COMMON_LO]; //[MLX_TOINDEX + 0];
+ BcpX = Pntr.MLXEEbuf[MLX621_A_COMMON_HI]; //[MLX_TOINDEX + 1];
+ //uint16_t thetaCPX = (EEbuf[MLX_TOINDEX + 3] << 8) + MLXEEbuf[MLX_TOINDEX + 2];
+ TGCX = Pntr.MLXEEbuf[MLX_TGCX_REG]; //[MLX_TOINDEX + 4];
+ BiScaleX = Pntr.MLXEEbuf[MLX621_DELTA_ABI_SCALE]; //[MLX_TOINDEX + 5];
+ theta0X = (Pntr.MLXEEbuf[MLX_THETA0_REG_HI] << 8) + Pntr.MLXEEbuf[MLX_THETA0_REG_LO]; //[MLX_TOINDEX + 13] << 8) + Pntr.MLXEEbuf[MLX_TOINDEX + 12];
+ theta0ScaleX = Pntr.MLXEEbuf[MLX_THETA0_SCALE_REG]; //[MLX_TOINDEX + 14];
+ deltaThetaScaleX = Pntr.MLXEEbuf[MLX_DELTA_TH_SCALE_REG]; //[MLX_TOINDEX + 15];
+ elipsonX = (Pntr.MLXEEbuf[MLX_EPSILON_REG_HI] << 8) + Pntr.MLXEEbuf[MLX_EPSILON_REG_LO]; //[MLX_TOINDEX + 17] << 8) + Pntr.MLXEEbuf[MLX_TOINDEX + 16];
+ } else {
+ ConfigReg54 = (Pntr.Config & MLX621_RESOLUTION) >> 4;
+ ScaleCR54 = 1 << (3 - ((Pntr.Config & MLX621_RESOLUTION) >> 4)); //1 << (3 - ConfigReg54);
+ Kt1 = (int16_t)((Pntr.MLXEEbuf[MLX621_KT1_HI] << 8) | Pntr.MLXEEbuf[MLX621_KT1_LO]);
+ Kt2 = (int16_t)((Pntr.MLXEEbuf[MLX621_KT2_HI] << 8) | Pntr.MLXEEbuf[MLX621_KT2_LO]);
+ Vth25 = (int16_t)(((Pntr.MLXEEbuf[MLX621_VTH25_HI] << 8) | Pntr.MLXEEbuf[MLX621_VTH25_LO]));
+
+#ifdef MLXTEST_621
+#warning "MLX90620 test mode"
+ //for testing only
+ ConfigReg54 = 0;
+ ScaleCR54 = 1 << (3 - ConfigReg54);
+ Vth25 = 0x6420;
+ Kt1 = 0x5589;
+ Kt2 = 0x5e7e;
+#endif
+
+ if(Kt1 > 32767) Kt1 -= 65536;
+ if(Kt2 > 32767) Kt2 -= 65536;
+ if(Vth25 > 32767) Vth25 -= 65536;
+ Vth25 /= ScaleCR54;
+ Kt1_f = (double)Kt1 / ((1 << ((Pntr.MLXEEbuf[MLX621_KT12_SCALE] & MLX621_KT1SCALE_BITS) >> 4)) * ScaleCR54);
+ Kt2_f = (double)Kt2 / ((1 << 10 << (Pntr.MLXEEbuf[MLX621_KT12_SCALE] & MLX621_KT2SCALE_BITS)) * ScaleCR54);
+ Ta = MLX9062x::GetDieTemp(Pntr);
+ //double Tak4 = pow(Ta + 273.15, 4.0);
+
+ Acommon = (int16_t)(Pntr.MLXEEbuf[MLX621_A_COMMON_HI] << 8) + Pntr.MLXEEbuf[MLX621_A_COMMON_LO];
+ Emiss = (uint16_t)((Pntr.MLXEEbuf[MLX621_A_EMMIS_HI] << 8) + Pntr.MLXEEbuf[MLX621_A_EMMIS_LO]) / 32768;
+ ACP_ee = (int16_t)(Pntr.MLXEEbuf[MLX621_ACP_HI] << 8) + Pntr.MLXEEbuf[MLX621_ACP_LO];
+ AlphaCP = (int16_t)((Pntr.MLXEEbuf[MLX621_ALPHACP_HI] << 8) + Pntr.MLXEEbuf[MLX621_ALPHACP_LO]) / ScaleCR54;
+
+ if(Acommon > 32767) Acommon -= 65536;
+ //if(Emiss > 32767) Emiss -= 65536;
+ if(ACP_ee > 32767) ACP_ee -= 65536;
+ aCP = (float)(ACP_ee / ScaleCR54);
+ AiScale621 = (int16_t)(Pntr.MLXEEbuf[MLX621_DELTA_ABI_SCALE] & MLX621_DAISCALE_BITS) >> 4;
+ BiScale621 = (int16_t)(Pntr.MLXEEbuf[MLX621_DELTA_ABI_SCALE] & MLX621_DBISCALE_BITS);
+ bCP = (float)Pntr.MLXEEbuf[MLX621_BCP];
+ if(bCP > 127.0f) bCP -= 256.0f;
+ bCP /= (pow(2.0f, (float)BiScale621) * (float)ScaleCR54);
+ TempTCG = Pntr.MLXEEbuf[MLX621_TGC];
+ if(TempTCG > 127) TempTCG -= 256;
+ Tgc621 = (float)TempTCG / 32.0f;
+ TGCReg = GetTGCReg(Pntr);
+ if(Pntr.VCP > 32767) Pntr.VCP -= 65536;
+ VcpCPOffComp = (double)Pntr.VCP - ((double)aCP + bCP * (Ta - 25.0));
+ KsTa = (Pntr.MLXEEbuf[MLX621_KSTA_HI] << 8) + Pntr.MLXEEbuf[MLX621_KSTA_LO];
+ if(KsTa > 32767) KsTa -= 65536;
+ KsTaF = (double)KsTa / pow(2.0, 20);
+ Ks4_ee = Pntr.MLXEEbuf[MLX621_KS4_EE];
+ if(Ks4_ee > 127) Ks4_ee -= 256;
+ Ks4 = (double)Ks4_ee / pow(2.0, (double)((Pntr.MLXEEbuf[MLX621_KS_SCALE] & 15) + 8.0));
+ TaK4 = pow((Ta + 273.15), 4.0);
+ Th_0 = (Pntr.MLXEEbuf[MLX621_THETA0_HI] << 8) + Pntr.MLXEEbuf[MLX621_THETA0_LO];
+ Th_0_sc = Pntr.MLXEEbuf[MLX621_THETA0_SCALE];
+ d_Th_sc = Pntr.MLXEEbuf[MLX621_DELTA_TH_SCALE];
+ }
+ DumpRawRegs(Pntr);
}
//--------------------------------------------------------------------------------------------------------------------------------------//
// Pixel Temperature Calculation
-double MLX90620::CalcPixel(mlx_struct& Pntr, int Pixel) {
- AiPixelX = Pntr.MLXEEbuf[Pixel]; //eeprom address range 0x00 - 0x3f
- BiPixelX = Pntr.MLXEEbuf[Pixel + 0x40]; //eeprom address range 0x40 - 0x7f
- dThetaPixelX = Pntr.MLXEEbuf[Pixel + 0x80]; //eeprom address range 0x08 - 0xbf
- VirPixelX = (Pntr.MLXRamBuf[Pixel * 2 + 1] << 8) + Pntr.MLXRamBuf[Pixel * 2]; //ram address range 0x000 - 0x08f, 16b
- float Vcp_off_comp = VCP - (AcpX + BcpX / powf(2.0f,BiScaleX) * (TaXX - 25.0f));
- float VirPixel_off_comp = VirPixelX - (AiPixelX + BiPixelX / powf(2.0f,BiScaleX) * (TaXX - 25.0f));
- float VirPixel_off_comp2 = (float(AiPixelX) + float(BiPixelX) / float(1 << BiScaleX) * (TaXX - 25.0f));
- VirPixel_off_comp2 = VirPixelX - VirPixel_off_comp2;
- float VirPixel_tgc_comp = VirPixel_off_comp - TGCX / 32.0 * Vcp_off_comp;
- float elipsonf = elipsonX / 32768.0;
- float VirPixel_comp = VirPixel_tgc_comp / elipsonf;
- double theta28 = theta0X / powf(2.0, theta0ScaleX) + dThetaPixelX / powf(2.0, deltaThetaScaleX);
- double TempPxl = powf((VirPixel_comp / theta28 + powf((TaXX + 273.15f), 4.0f)), (1.0f / 4.0f)) - 273.15f;
-/*
- printf("\r\n\r\npixel = %d\r\n", Pixel);
- printf("Acp = %d\r\nBcp = %d\r\nBiS = %d\r\n", AcpX, BcpX, BiScaleX);
- printf("Vcp = %d\r\neps = %d\r\nTGC = %d\r\n", VCP, elipsonX, TGCX);
- printf("Vcp_off_comp = %f\r\n", Vcp_off_comp);
- printf("VirPixel_off_comp = %f\r\n", VirPixel_off_comp);
- printf("VirPixel = %d\r\n", VirPixelX);
- printf("AiPixel = %d\r\n", AiPixelX);
- printf("BiPixel = %d\r\n", BiPixelX);
- printf("BiScale = %d\r\n", BiScaleX);
- printf("2^BiScale = %f\r\n", (powf(2.0,BiScaleX)));
- printf("1 << BiScale = %d\r\n", (1 << BiScaleX));
- printf("Ta-25.0 = %f\r\n", (TaXX - 25.0f));
- printf("BiPix/2^BiScale = %f\r\n", (BiPixelX / powf(2.0,BiScaleX)));
- printf("AiP+BiP/2^BiScale)*(Ta-25= %f\r\n", (AiPixelX + BiPixelX / powf(2.0,BiScaleX) * (TaXX - 25.0f)));
- printf("VirPixel_off_comp again = %f\r\n", (VirPixelX - (AiPixelX + BiPixelX / powf(2.0,BiScaleX) * (TaXX - 25.0f))));
- printf("VirPixel_off_comp2 step = %f\r\n", VirPixel_off_comp2);
- printf("VirPixel_tgc_comp = %f\r\n", VirPixel_tgc_comp);
- printf("elipsonf = %f\r\n", elipsonf);
- printf("VirPixel_comp = %f\r\n", VirPixel_comp);
- printf("theta28 = %f << double print problem\r\n", (theta28 * 100000000.0)); //<<< can't print a double
- printf("TempPxl = %f\r\n", TempPxl);
-*/
+double MLX9062x::CalcPixel(mlx_struct& Pntr, int Pixel) {
+ if(Pntr.mlxDevice == mlx90620) {
+ AiPix = Pntr.MLXEEbuf[Pixel]; //eeprom address range 0x00 - 0x3f
+ BiPix = Pntr.MLXEEbuf[Pixel + 0x40]; //eeprom address range 0x40 - 0x7f
+ d_Th_Pix = Pntr.MLXEEbuf[Pixel + 0x80]; //eeprom address range 0x08 - 0xbf
+ VirPix = (Pntr.MLXRamBuf[Pixel * 2 + 1] << 8) + Pntr.MLXRamBuf[Pixel * 2]; //ram address range 0x000 - 0x08f, 16b
+ float Vcp_off_comp = Pntr.VCP - (AcpX + BcpX / powf(2.0f,BiScaleX) * (Ta - 25.0f));
+ float VirPix_off_comp = VirPix - (AiPix + BiPix / powf(2.0f,BiScaleX) * (Ta - 25.0f));
+ float VirPix_off_comp2 = (float(AiPix) + float(BiPix) / float(1 << BiScaleX) * (Ta - 25.0f));
+ VirPix_off_comp2 = VirPix - VirPix_off_comp2;
+ float VirPix_tgc_comp = VirPix_off_comp - TGCX / 32.0 * Vcp_off_comp;
+ float elipsonf = elipsonX / 32768.0;
+ float VirPix_comp = VirPix_tgc_comp / elipsonf;
+ double theta28 = theta0X / powf(2.0, theta0ScaleX) + d_Th_Pix / powf(2.0, deltaThetaScaleX);
+ TempPxl = powf((VirPix_comp / theta28 + powf((Ta + 273.15f), 4.0f)), (1.0f / 4.0f)) - 273.15f;
+ } else {
+ AiPix = Pntr.MLXEEbuf[Pixel]; //eeprom address range 0x00 - 0x3f
+ BiPix = Pntr.MLXEEbuf[Pixel + 0x40]; //eeprom address range 0x40 - 0x7f
+ d_Th_Pix = Pntr.MLXEEbuf[Pixel + 0x80]; //eeprom address range 0x08 - 0xbf
+ VirPix = (Pntr.MLXRamBuf[Pixel * 2 + 1] << 8) + Pntr.MLXRamBuf[Pixel * 2]; //ram address range 0x000 - 0x08f, 16b
+#ifdef MLXTEST_621b
+ VirPix = 0x01b7;
+#endif
+ if(VirPix > 32767) VirPix -= 65536;
+ if(BiPix > 127) BiPix -= 256;
+ Ai_ij = (float)(Acommon + AiPix * pow(2.0, AiScale621)) / (float)ScaleCR54;
+ Bi_ij = (float)BiPix / (float)((1 << BiScale621) * ScaleCR54);
+
+ VirOffComp = (float)VirPix - (Ai_ij + Bi_ij * (Ta - 25.0f));
+ VirTGCComp = VirOffComp - Tgc621 * VcpCPOffComp;
+ VirComp = VirTGCComp / Emiss;
+
+ ThPix = (((double)Th_0 / pow(2.0,(double)Th_0_sc) + ((double)d_Th_Pix / pow(2.0,(double)d_Th_sc)))) / ScaleCR54;
+ ThetaCP = (double)AlphaCP / (pow(2.0, (double)Th_0_sc) * ScaleCR54);
+ ThetaCompPix = (1.0 + KsTaF * (Ta - 25.0)) * (ThPix - Tgc621 * ThetaCP);
+ SxGuts = pow(ThetaCompPix, 3.0) * VirComp + (pow(ThetaCompPix, 4.0) * TaK4);
+ Sx = sqrt(SxGuts);
+ Sx = Ks4 * sqrt(Sx);
+
+ TempPxl = ThetaCompPix * (1.0 - (Ks4 * 273.15)) + Sx;
+ TempPxl = (VirComp / TempPxl) + TaK4;
+ TempPxl = sqrt(TempPxl);
+ TempPxl = sqrt(TempPxl) - 273.15;
+ }
+ DumpPixRegs(Pntr, Pixel);
return(TempPxl);
}
-
-