Example program using the MLX90620 and KL25Z. Best viewed with wide-screen VT-100 color terminal. Tested with Tera Term. Easy i2c pin name change for mbed1768.

Dependencies:   MLX9062x PrintBuffer mbed

KL25Z_MLX90620 home page:

This program takes temperature data from the MLX90620 and displays the temperature data in the same format as the 16x4 pixel array. The display is updated once a second. Temperature can be displayed in degrees C or F and changed on the fly. Also, the data pixel format can be swapped. If the MLX90620 is pointing inward (toward you) or outward (away from you) you can change that on the fly as well. For each display output, the coolest pixel is displayed in BLUE and the warmest pixel in RED. The new data is painted over the old data.

NOTE: This program relys heavily on the mbed's USB Serial communication. ASCII ESCape codes are used. Use a terminal emulator like Tera Term. Be sure that the terminal has a wide screen (136 characters wide), with VT100 color emulation enabled and an even spaced character font like "Terminal".

The maximum USB serial communication you can use on the mbed1768 is 921600 baud. The KL25Z is limited to 115200 baud. Faster speeds cause characters drop out.

If you get bored, you can watch the RGB led on the KL25Z change color. Since the LED does not blend colors well, put a small piece of kleenex or a single layer from a napkin over the LED. You'll have a much better appreciation for the LED that way. Thanks to David Dicarlo's FRDM_RGBLED program for that idea.

Typical output from program:

/media/uploads/loopsva/mlx90620output.jpg

...kevin

main.cpp

Committer:
loopsva
Date:
2016-07-22
Revision:
2:1f1157f04539
Parent:
1:9d7894633924

File content as of revision 2:1f1157f04539:

#include "mbed.h"
#include "PrintBuffer.h"
#include "MLX90620.h"

int revision = 110;

#define BS          0x08                    //ascii backspace
#define CR          0x0d                    //ascii CR
#define LF          0x0a                    //ascii LF
#define SP          0x20                    //ascii space
#define ESC         0x1b                    //ascii escape
#define DP          0x2e                    //ascii decimal point / period
#define ticC        0x03                    //ascii control C
#define ticX        0x18                    //ascii control X

#define DOBLACK     "\033[0;30;2m"
#define DORED       "\033[0;31;2m"
#define DOGREEN     "\033[0;32;2m"
#define DOYELLOW    "\033[0;33;2m"
#define DOBLUE      "\033[0;34;2m"
#define DOMAGENTA   "\033[0;35;2m"
#define DOCYAN      "\033[0;36;2m"
#define DOWHITE     "\033[0;37;2m"
#define DODEFAULT   "\033[0;39;2m"
#define DONONE      "\033[0m"

char *doBLACK   = DOBLACK;
char *doRED     = DORED;
char *doGREEN   = DOGREEN;
char *doYELLOW  = DOYELLOW;
char *doBLUE    = DOBLUE;
char *doMAGENTA = DOMAGENTA;
char *doCYAN    = DOCYAN;
char *doWHITE   = DOWHITE;
char *doDEFAULT = DODEFAULT;
char *doNONE    = DONONE;


#if defined(TARGET_KL25Z)
extern "C" void NVIC_SystemReset();         //for KL25Z
#else
#include "FATFileSystem.h" 
extern "C" void mbed_reset();               //for mbed1768
#endif

int gDebug = 2;

Serial pc (USBTX, USBRX);

#if defined(TARGET_KL25Z)
I2C i2c1(PTE0, PTE1); 
I2C i2c2(PTE25, PTE24);
//MLX90620 mlx(PTE0, PTE1, "mlx");            //MLX90620 register access
MLX9062x mlx(PTE0, PTE1, MLX9062x::mlx90621, "mlx"); //MLX90620 or MLX90621 IR array
MLX9062x::mlx_struct mlxSTR = {};               //data structure for MLX90260
#else 
LocalFileSystem local("local");             //for access of files on mbed itself
I2C i2c1(p9, p10); 
MLX90620 mlx(p9, p10, "mlx");
#endif

PrintBuffer pb("pb");                       //new for 132.  Moved PrintBuffer off to .cpp and .h files

#if defined(TARGET_KL25Z)
PwmOut rled(LED_RED);
PwmOut gled(LED_GREEN);
PwmOut bled(LED_BLUE);

int rLedDelay = 0;
float rLedPwm = 0.01;                       //LED1 brightness
bool rLedUp = true;                         //LED1 auto up-down
int gLedDelay = 0;
float gLedPwm = 0.01;                       //LED1 brightness
bool gLedUp = true;                         //LED1 auto up-down
int bLedDelay = 0;
float bLedPwm = 0.01;                       //LED1 brightness
bool bLedUp = true;                         //LED1 auto up-down
#endif

//MLX90620 buffers used by MLX90620.cpp
char* EEbuf = new char[256];
char* RamCmmd = new char[8];                //holds / sends MLX90620 RAM commands
char* RamBuf = new char[128];               //0x3f words, values are 'unsigned short'
int SaveEEP = 0;                            //***USED BY .INI FILE  save EEPROM Contents to EEP.CSV

//For MLX90620
unsigned short ConfigReg = 0;               //MLX90620 configuration register
float Ta = 0.0;
double TempPxl = 0;

//Used for display of temperature and extreme values
float HotPxl = -40.0;                       //hottest pixel in the array
float ColdPxl = 200.0;                      //coldest pixel in the array 
unsigned short HotColor = 0xffff;           //color of hottest pixel
unsigned short ColdColor = 0xffff;          //color of coldest pixel
int AutoScale = 0;                          //***USED BY .INI FILE  autoscale display 0 or 1
bool ReFrame = false;                       //do a reframe if asked
int HottestX = 0;                           //hottest pixel X
int HottestY = 0;                           //hottest pixel Y
int ColdestX = 0;                           //coldest pixel X
int ColdestY = 0;                           //coldest pixel Y
bool PickPix = false;                       //pick a pixel to dump all data on flag
int pixX = 0;                               //display pixel X (0-15)
int pixY = 0;                               //display pixel Y (0-3)

//Display Options
int TempC = 'C';                            //***USED BY .INI FILE  display temperatures in degrees C or F
int SensFacingAway = 0;                     //***USED BY .INI FILE  sensor facing towards you or away from you
int xHatch = 1;                             //***USED BY .INI FILE  display hatch pattern between pixels or allow pixels to blend together
float lowEnd = 20.0;                        //***USED BY .INI FILE  low end of color temperature scale (blue end)
float hiEnd = 100.0;                        //***USED BY .INI FILE  top end of color temperature scale (red end)
int PutOnPC = 1;                            //***USED BY .INI FILE  display temperature array on PC  0 or 1.  Requires VT100 terminal operation

//USB Serial Port Support
const int PCRXBUFSIZE = 128;                //pc RX buffer size
char pcRxBuffer[PCRXBUFSIZE];               //RX data buffer
volatile int pcRxQty = 0;                   //RX data counter/pointer
volatile char inchar = 0;                   //RX input character
volatile bool LocalEcho = false;            //whether or not, to local echo input chars from pc
volatile bool pcRxLine = false;             //CR or LF detected in RX buffer
volatile bool pcRxTicC = false;             //^C detected in RX buffer
volatile bool pcRxEOB = false;              //RX buffer EOB (full)
volatile bool pcRxIsNumb = false;           //whether or not string is a valid number (including dp)
volatile double pcRxNumb = 0.0;             //RX buffer comversion
int pcRxCharCnt = 0;                        //total number of pc RX characters received since boot
int pcRxIRQCnt = 0;                         //total number of pc RX interrupts received since boot

//--------------------------------------------------------------------------------------------------------------------------------------//
// Checks to see if a ^C happend.  reboot if so...

void PcChekTicC() {
    if(pcRxTicC == true) {
        pc.printf("\n\n%s*** Control C detected, Resetting ***%s \n", doRED, doNONE);
//        i2c1.stop();
        wait_ms(200);

#if defined(TARGET_KL25Z)
        NVIC_SystemReset();
#else
        mbed_reset();
#endif
    }
}

//--------------------------------------------------------------------------------------------------------------------------------------//
// This function is called when a character goes into the RX buffer.

int TicC2 = 0;

void PcRxChar() {
    pcRxCharCnt++;
    if(inchar == BS) { 
        if(pcRxQty == 0) {
            pcRxBuffer[pcRxQty] = 0;
        } else {
            if(LocalEcho) pc.printf("%c %c", BS, BS);
            pcRxQty--;
        }
    } else if((inchar == CR) || (inchar == LF)) { 
        pcRxLine = true;
        if(LocalEcho) pc.printf("\n");
    } else if(inchar == ticC) {
        pcRxTicC = true;
        TicC2++;
        if(TicC2 > 2) {
            wait_ms(200);
            pc.printf("\n\n%s*** Control C detected, Resetting %sfrom IRQ!!!%s***%s \n", doRED, doGREEN, doRED, doNONE);
            wait_ms(200);
            i2c1.stop();

#if defined(TARGET_KL25Z)
            NVIC_SystemReset();
#else
            mbed_reset();
#endif

        }
    } else if((inchar == 'C') || (inchar == 'c')) { 
        TempC = inchar;
    } else if((inchar == 'F') || (inchar == 'f')) { 
        TempC = inchar;
    } else if((inchar == 'I') || (inchar == 'i')) { 
        SensFacingAway = 0;
    } else if((inchar == 'O') || (inchar == 'o')) { 
        SensFacingAway = 1;
    } else {
        if(pcRxQty < sizeof(pcRxBuffer)) {
            pcRxBuffer[pcRxQty] = inchar;
//            pcRxQty++;    //NOTE: no buffer needed for this code, don't inc char pointer
            pcRxBuffer[pcRxQty] = 0;
            if(LocalEcho) pc.putc(inchar);
        } else {
            pc.printf ("\n*** pcRxBuffer is full!!\n");
            pcRxEOB = true;
            pcRxQty = 0;
            pcRxBuffer[pcRxQty] = 0;
        }
    }
    
    bool oneDot = false;
    pcRxIsNumb = true;
    for(int i = 0; i < pcRxQty; i++) {
        if(pcRxBuffer[i] == '.') {
            if(oneDot == true) {
                pcRxIsNumb = false;
                break;
            } else {
                oneDot = true;
            }
        }
        else if((pcRxBuffer[i] < '0') || (pcRxBuffer[i] > '9')) {
            if(!((i == 0) && (pcRxBuffer[i] == '-'))) {
                pcRxIsNumb = false;
                break;
            }
        }
    }
}

//--------------------------------------------------------------------------------------------------------------------------------------//
// Read received chars from USB UART

void PcRxIRQ(void){
    pcRxIRQCnt++;
#if defined(TARGET_KL25Z)
    NVIC_DisableIRQ(UART0_IRQn);        // n=0, 1 or 2  Disable Rx interrupt on kl25z
#else
    LPC_UART0->IER = 0;                 //Disable Rx interrupt on mbed1768
#endif
    while (pc.readable()) {
        inchar = pc.getc();             //read data from USB
        PcRxChar();                     //go process char
    }
#if defined(TARGET_KL25Z)
    NVIC_EnableIRQ(UART0_IRQn);         //re-enable Rx interrupt on kl25z
#else
    LPC_UART0->IER = 1;                 //re-enable Rx interrupt on mbed1768
#endif
}

//--------------------------------------------------------------------------------------------------------------------------------------//
//fixing a screwup on the eeprom from an accidental write

void FixEEP() {    
    EEbuf[0] = 0x10;               //starting address of EEP to write to, pages 0 - 31 * 8
    EEbuf[1] = 0xed;
    EEbuf[2] = 0xee;
    EEbuf[3] = 0xee;
    EEbuf[4] = 0xec;
    EEbuf[5] = 0xee;
    EEbuf[6] = 0xef; 
    EEbuf[7] = 0xef; 
    EEbuf[8] = 0xed; 
    i2c1.write(0xa0, EEbuf, 9, false);
    wait_ms(6);                 //datasheet says 5mS max

}

//--------------------------------------------------------------------------------------------------------------------------------------//
//Reload EEPROM image from file /local/EEP.CSV

#if defined(TARGET_KL25Z)
#else
char* FileBuf = new char[1024];
char tbuf[256];

int ReloadEEP() {
    FILE *fps = fopen("/local/EEP.CSV", "r");
    if (fps == NULL) {
        return(0);
    } else {
        for(int i = 0; i < 256; i++) {
            int x = -1;
            do{
                x++;
                FileBuf[x] = fgetc(fps);
                if(FileBuf[x] == '\n') {
                    x--;
                }
            } while((FileBuf[x] != ','));
            x--;
            tbuf[i] = char(strtod(FileBuf, &FileBuf));
            EEbuf[i] = tbuf[i];
        }
        fclose(fps);
        return(1);
    } 
}

//--------------------------------------------------------------------------------------------------------------------------------------//
//re-write all of the MLX EEPROM from file EEP.CSV. Returns 0, no write error. 1 - 32 for failed page
//tbuf contains the source data.  ReloadEEP() must be run first!!!

int FixAllEEP() {
    for(int i = 0; i < 32; i++) {           //32, 8 byte pages 
        EEbuf[0] = i * 8;                   //EEPROM page #
        EEbuf[1] = tbuf[i * 8];
        EEbuf[2] = tbuf[i * 8 + 1];
        EEbuf[3] = tbuf[i * 8 + 2];
        EEbuf[4] = tbuf[i * 8 + 3];
        EEbuf[5] = tbuf[i * 8 + 4];
        EEbuf[6] = tbuf[i * 8 + 5]; 
        EEbuf[7] = tbuf[i * 8 + 6]; 
        EEbuf[8] = tbuf[i * 8 + 7]; 
        if(!(i2c1.write(0xa0, EEbuf, 9, false))) {  //store 8 byte page
            i2c1.stop();
        }
        wait_ms(10);                        //datasheet says 5mS max
    }
    return(0);
}
#endif

//--------------------------------------------------------------------------------------------------------------------------------------//
//Detect I2C device chain

int i2cQty = 16;                            //number of bytes to get
char i2cData[32];                           //i2c buffer data

void find_i2c1() {
    if(gDebug > 1) pc.printf("Searching for I2C devices on bus 1...\n");

    int count = 0;
    for (int address = 2; address < 256; address +=2) {
        if (!i2c1.write(address, NULL, 0)) { // 0 returned is ok
            wait_ms(5);
            if(gDebug > 1) pc.printf(" - I2C device found at address 0x%02X\n", address);
            for (int clrb = 0; clrb < i2cQty; clrb +=1) {  //clear out i2c buffer before reading in data
                i2cData[clrb] = 0;
            }
            count++;
        }         
    }
    if(gDebug > 1) pc.printf(" - I2seeU! %d devices found\n", count);
}

//---------
#if defined(TARGET_KL25Z)
void find_i2c2() {
    if(gDebug > 1) pc.printf("Searching for I2C devices on bus 2...\n");

    int count = 0;
    for (int address = 2; address < 256; address +=2) {
        if (!i2c2.write(address, NULL, 0)) { // 0 returned is ok
            wait_ms(5);
            if(gDebug > 1) pc.printf(" - I2C device found at address 0x%02X\n", address);
            for (int clrb = 0; clrb < i2cQty; clrb +=1) {  //clear out i2c buffer before reading in data
                i2cData[clrb] = 0;
            }
            count++;
        }         
    }
    if(gDebug > 1) pc.printf(" - I2seeU! %d devices found\n", count);
}

//--------------------------------------------------------------------------------------------------------------------------------------//
// moving RGB LED display.  Hacked from:  david dicarlo / FRDM_RGBLED

const float pi = 3.1415927;
float iLeds = 0.0;

void sinLEDs() {
    iLeds += 0.02;                          // was 0.001 in original code
    if(iLeds > (60.0 * pi)) iLeds = 0.0;
    rLedPwm = (1 + sin(2 * iLeds)) / 2;     // calculate values for RGB based on different
    gLedPwm = (1 + sin(3 * iLeds)) / 2;     // frequency sin waves. This should give a nice
    bLedPwm = (1 + sin(5 * iLeds)) / 2;     // smooth transistion between colors and a 
    rled = rLedPwm;                         // send RGB values to LED PWMs
    gled = gLedPwm;
    bled = bLedPwm;
}

#endif
//--------------------------------------------------------------------------------------------------------------------------------------//
// See if new temperature in array is higher then the current hottest or colder then the current coldest

void CheckNewExtreme() {
    if(TempPxl > HotPxl) {
        HotPxl = TempPxl;
        HottestX = pixX / 4;
        HottestY = pixY;
    }
    if(TempPxl < ColdPxl) {
        ColdPxl = TempPxl;
        ColdestX = pixX / 4;
        ColdestY = pixY;
    }
}

//--------------------------------------------------------------------------------------------------------------------------------------//
// Change color of extreme tempeature values on PC using VT100 escape sequences

bool PCdeftFlag = true;

void PCExtreme() {
    if((HottestX == (pixX / 4)) && (HottestY == pixY)) {
        PCdeftFlag = false;
        pc.printf("%c[8;31;2m", ESC);
        return;
    } else 
    if((ColdestX == (pixX / 4)) && (ColdestY == pixY)) {
        PCdeftFlag = false;
        pc.printf("%c[8;34;2m", ESC);
        return;
    } else 
    if(PCdeftFlag == false) {
        PCdeftFlag = true;
        pc.printf("%c[8;30m", ESC);
    }
}

//--------------------------------------------------------------------------------------------------------------------------------------//
// Pick a pixel to print out temperature. X = column 0 - 15, Y = row 0 - 3

void PickaPixel(int pX, int pY) {
    TempPxl = mlx.CalcPixel(mlxSTR, pX + pY);
    if ((TempC == 'c') || (TempC == 'C')) {  
        pc.printf("Pixel X:%d  Y:%d  Temp: %.2f degC\n", pX / 4, pY, TempPxl);
    } else {
        pc.printf("Pixel X:%d  Y:%d  Temp: %.2f degF\n", pX / 4, pY, TempPxl * 9.0 / 5.0 + 32.0);
    }
}

//--------------------------------------------------------------------------------------------------------------------------------------//
// Display on PC using VT100 escape codes

const int TTX = 45;
const int TTY = 120;
int tX = TTX;
int tY = TTY;;

int AllowVT100 = 0;

void ShowTempsVT100() {
    if(AllowVT100 <= 3) {       //update PC display every 4th TFT pixel update
        return;
    }
    AllowVT100 = 0;
    double HoldTemp = TempPxl;
    if(SensFacingAway == 1) {
        pc.printf("%c[8;30m%c[6AArray Temperature  deg%c         \\\\ ^ // \n   F       E       D       C       B       A       9       8       7       6       5       4       3       2       1       0        \n", ESC, ESC, (TempC & 0x5f));
        for(pixY = 0; pixY <= 3; pixY++) {
            for(pixX = 60; pixX >= 0; pixX = pixX - 4) {
                TempPxl = mlx.CalcPixel(mlxSTR, pixX + pixY);
                if ((TempC == 'c') || (TempC == 'C')) {  
                    HoldTemp = TempPxl;
                } else {
                    HoldTemp = TempPxl * 9.0 / 5.0 + 32.0;
                }
                PCExtreme();
                if(HoldTemp >= 100.0) {
                    pc.printf(" %.1f  ", HoldTemp);    
                } else
                if((HoldTemp <= 10.0) && (HoldTemp >= 0.0)) {
                    pc.printf("  %.2f  ", HoldTemp);
                } else 
                if((HoldTemp >= -10.0) && (HoldTemp < 0.0)) {
                    pc.printf(" %.2f  ", HoldTemp);
                } else
                if(HoldTemp < -10.0) {
                    pc.printf("%.2f  ", HoldTemp);
                } else {
                    pc.printf(" %.2f  ", HoldTemp);
                }
            }
            PCdeftFlag = true;
            pc.printf("%c[8;30m%2d   \n", ESC, pixY);
//            pc.printf("%2d   \n", pixY);
        }
    } else {
        pc.printf("%c[8;30m%c[6AArray Temperature  deg%c         // v \\\\ \n   0       1       2       3       4       5       6       7       8       9       A       B       C       D       E       F        \n", ESC, ESC, (TempC & 0x5f));
        for(pixY = 0; pixY <= 3; pixY++) { 
            for(pixX = 0; pixX < 64; pixX = pixX + 4) {
                TempPxl = mlx.CalcPixel(mlxSTR, pixX + pixY);
                if ((TempC == 'c') || (TempC == 'C')) {  
                    HoldTemp = TempPxl;
                } else {
                    HoldTemp = TempPxl * 9.0 / 5.0 + 32.0;
                }
                PCExtreme();
                if(HoldTemp >= 100.0) {
                    pc.printf(" %.1f  ", HoldTemp);    
                } else
                if((HoldTemp <= 10.0) && (HoldTemp >= 0.0)) {
                    pc.printf("  %.2f  ", HoldTemp);
                } else 
                if((HoldTemp >= -10.0) && (HoldTemp < 0.0)) {
                    pc.printf(" %.2f  ", HoldTemp);
                } else
                if(HoldTemp < -10.0) {
                    pc.printf("%.2f  ", HoldTemp);
                } else {
                    pc.printf(" %.2f  ", HoldTemp);
                }
            }
            pc.printf("%c[8;30m%2d   \n", ESC, pixY);
        }
    }
}

//--------------------------------------------------------------------------------------------------------------------------------------//
// Display Pixels in color

int loop = 0;
bool GotAmbient = false;
bool FirstRamDump = true;

int ShowTempsColor() {
//    ConfigReg = mlx.GetConfigReg();
    
    //because of change to normal mode...
    ConfigReg = 0;
    wait_ms(185);   //balance out to display is about once per second
    //end of because of change

/*
#ifdef MLX_KL25Z
    NVIC_DisableIRQ(UART0_IRQn);        // n=0, 1 or 2  Disable Rx interrupt on kl25z
#else
    LPC_UART0->IER = 0;                 //Disable Rx interrupt on mbed1768
#endif
*/    
    if(GotAmbient == false) {
        if((ConfigReg & MLX_TAMEASFLAG) == 0) {
            mlx.CalcTa_To(mlxSTR);
            Ta = mlx.GetDieTemp(mlxSTR);
//            pc.printf("Ta = %f\n\n\n\n\n\n\n", Ta);
            GotAmbient = true;
        } else {
            return(ConfigReg & MLX_TAMEASFLAG);
        }
    }
    if((ConfigReg & MLX_IRMEASFLAG) == 0) {
        loop++;
        GotAmbient = false;
        if(ReFrame == true) {
            if(gDebug > 2) pc.printf("AutoScale Update, lowEnd: %4.0fC  hiEnd: %4.0fC\n", lowEnd, hiEnd);
            ReFrame = false;
        }
        AllowVT100++;
        HotPxl = -40.0;
        ColdPxl = 200.0;
        mlx.LoadMLXRam(mlxSTR);
        if((gDebug > 1) && (FirstRamDump == true)) {
            FirstRamDump = false;
            pc.printf("First RAM dump");
            pb.dump("Ram Buffer:", 8, 0, RamBuf);
            if(PutOnPC == 1) {
                //pc.printf("\n\n\n\n\n\n\n");
            }
        } else 
        if((PutOnPC == 1) && (FirstRamDump == true)) {
            FirstRamDump = false;
            pc.printf("\n\n\n\n\n\n\n");
        }
        
        tX = TTX;
        tY = TTY;
        mlx.StartMeasurement(mlxSTR);
/*        
#ifdef MLX_KL25Z
        NVIC_EnableIRQ(UART0_IRQn);         //re-enable Rx interrupt on kl25z
#else
        LPC_UART0->IER = 1;                 //re-enable Rx interrupt on mbed1768
#endif
*/   
        if(gDebug > 3) pc.printf("Array Temperature degC\n  3      2      1      0\n");
        if(SensFacingAway == 1) {
            for(pixX = 60; pixX >= 0; pixX = pixX - 4) {
                for(pixY = 3; pixY >= 0; pixY--) {
                    if((pixX == 16 * 4) && (pixY == 2)) {
                        PickaPixel(pixX, pixY);
                        PickPix = true;
                    } else {
                        PickPix = false;
                    }
                    TempPxl = mlx.CalcPixel(mlxSTR, pixX + pixY);
                    CheckNewExtreme();
                    if(gDebug > 3) pc.printf("%4.2f  ", TempPxl);
                }
                if(gDebug > 3) pc.printf("%2d\n", (pixX / 4));
            }
        } else {
            for(pixX = 0; pixX < 64; pixX = pixX + 4) {
                for(pixY = 3; pixY >= 0; pixY--) {
                    if((pixX == 16 * 4) && (pixY == 1)) {                                //0-15 and 0-3
                        PickaPixel(pixX, pixY);
                        PickPix = true;
                    } else {
                        PickPix = false;
                    }
                    TempPxl = mlx.CalcPixel(mlxSTR, pixX + pixY);
                    CheckNewExtreme();
                    if(gDebug > 3) pc.printf("%4.2f  ", TempPxl);
                }
                if(gDebug > 3) pc.printf("%2d\n", (pixX / 4));
            }
        }
        if(gDebug > 3) pc.printf("\nloop: %d\n", loop);
    }
    return(0);
}

//--------------------------------------------------------------------------------------------------------------------------------------//
//--------------------------------------------------------------------------------------------------------------------------------------//

int main(void) {
    GotAmbient = false;
    i2c1.frequency(400000);                  //set up i2c speed
    i2c1.stop();
    
#if defined(TARGET_KL25Z)
    i2c2.frequency(400000);                  //set up i2c speed
    i2c2.stop();
    rled.period_us(1000);
    gled.period_us(1000);
    bled.period_us(1000);
    gLedUp = false;
    rLedPwm = 0.001;
    gLedPwm = 0.700;
    bLedPwm = 0.300;
    rled = 1.0 - rLedPwm;
    gled = 1.0 - gLedPwm;
    bled = 1.0 - bLedPwm; 
    pc.baud(115200);
#else
    pc.baud(921600);
#endif

    pc.printf("\n\n--------------------------------------------\n");
    pc.printf("mbed1768 / FRDM-KL25Z  MLX90620 Tests  %sv%d%s\n", doBLUE, revision, doNONE);
    
    //initialize the USB serial port interrupt
    pc.printf("Initializing Serial Port Rx Interrupt...   \n");
    pc.attach(&PcRxIRQ, pc.RxIrq);
    
    //look for devices on i2c buses
    find_i2c1();

#if defined(TARGET_KL25Z)
    find_i2c2();
#else
    //mbed1768 only, see if MLX90620 eeprom contents file saved.  If so, dump on display
    if (ReloadEEP()) {
        if(gDebug > 1) {
            pb.dump("\nEEP.CVS file dump", 16, 0,tbuf);
        }
    } else {
        pc.printf("*** file /local/EEP.CSV does not exist\n");
    }
#endif

    //DANGEROUS!!!  FixEEP is for fixing small portions of the EEPROM on the MLX90620.
    //Fixes 8 bytes in EEPROM at a time.  This is a manual operation, requiring a recompile each
    //time.  You have to set up the starting EEP address and 8 bytes of data to be written
    //in routine FixEEP
    
    //FixEEP();

    int initFail = 0;
    //load up eeprom into buffer
    if((mlx.LoadEEPROM(mlxSTR))) {
        pc.printf("*** MLX90620 dump failed!!!\n");
        initFail++;
    } else {   
        if(gDebug > 1) {
            //pc.printf("\nEEPROM array");
            pb.dump("EEPROM Array:", 16, 0, EEbuf);
        }
    }
    
    //Init MLX90620
    unsigned short x = 0;
    if((mlx.SetOscTrimReg(mlxSTR))) {
        pc.printf("*** set osc trim failed!!!\n");
        initFail++;
    } else {
        x = mlx.GetOscTrimReg(mlxSTR);
        pc.printf("Osc Trim Value:  0x%04x\n", x);
    }
    
    if((mlx.SetConfigReg(mlxSTR))) {
        pc.printf("*** set MLX config failed!!!\n");
        initFail++;
    } else {
        x = mlx.GetConfigReg(mlxSTR);
        pc.printf("Config Register: 0x%04x\n", x);
        x = mlx.GetPTATReg(mlxSTR);
        pc.printf("PTAT Register:   0x%04x\n", x);
    }
    
    if((mlx.StartMeasurement(mlxSTR))) {
        pc.printf("*** Start Measurement failed!!!\n");
        initFail++;
    }
    wait_ms(300);
    
    if(initFail == 0) {
        pc.printf("Calculating Ta...\n");
        mlx.CalcTa_To(mlxSTR);
        pc.printf("Getting die temperature...\n");
        Ta = mlx.GetDieTemp(mlxSTR);
        pc.printf("Ta = %f\n\n", Ta);
    } else {
        pc.printf("*** MLX90620 non operational!!!\n");
    }
    ShowTempsColor();

    pc.printf("At any time, type:\n %sO%s = Pointing Outward\n %sI%s = Pointing Inward\n %sC%s = Temp Degrees C\n %sF%s = Temp Degrees F\n%s^C%s = reboot\n\n",
                doGREEN, doNONE, doGREEN, doNONE, doGREEN, doNONE, doGREEN, doNONE, doRED, doNONE);
    pc.printf("Ready...\n");
    pc.printf("\n\n\n\n\n\n\n");
    
    while (true) {
        PcChekTicC();
        int lc = 0;
        if(!(ShowTempsColor())) {
            do {
                lc++;
                //pc.printf("waiting... %d\n", lc);
                wait_ms(1);
            } while(ShowTempsColor() != 0);

#if defined(TARGET_KL25Z)
            sinLEDs();
#endif

        }
        if(PutOnPC == 1) {
            ShowTempsVT100();
        }
    }
}