Program which has to be implemented to the MLX Mbed for micro tesla meter bench version.

Dependencies:   C12832 mbed

Fork of MicroteslameterV2 by Olivier Dubrulle

main.cpp

Committer:
zbobze
Date:
2017-08-21
Revision:
1:50fbbe10dea4
Parent:
0:d35d9bdef147

File content as of revision 1:50fbbe10dea4:

#include "mbed.h"
#include "C12832.h"
#include "microteslameter.h"
#include "MLX90393.h"
#define FIELD_LIMIT 100



//******************************************************************************************************************
                                                    // Global variable:
//******************************************************************************************************************

DigitalOut LedRGR(p9);
DigitalOut LedRGG(p10);
DigitalOut LedG1(p17);
DigitalOut LedG2(p18);
DigitalOut LedG3(p19);
DigitalOut LedG4(p20);
DigitalOut LedG5(p21);
DigitalOut LedG6(p22);
DigitalOut LedG7(p23);
DigitalOut LedR1(p24);
DigitalOut LedR2(p25);
DigitalOut LedR3(p26);

AnalogIn BatteryVolt(p15); //  analog input on p15 for getting Battery level
C12832 lcd(p5, p7, p6, p8, p11); //define pin for LCD screen


InterruptIn button(p14); // button used for zeroing - joystick
InterruptIn button2(p12); // button used for change Display on screen
InterruptIn button3(p13);
I2C i2c(p28, p27);
Serial pc(USBTX, USBRX);
Timeout to1; // timeer...
MLX90393 sensor(MLX90393::i2c_address,&i2c);

float CorrX,CorrY,CorrZ;
bool Led_on = false;
bool Blink_started = false;
bool CleanScreen = false;
bool IsConnected = true;
int ScreenDisplay = 1;
int const NbValHist=5;
float SaveData[NbValHist];
int DataTable (0);
float modulus;



 //****************************************************************************************************************** 
 //****************************************************************************************************************** 
                                        // Begining of the Main function
 //****************************************************************************************************************** 
 //****************************************************************************************************************** 

 
int main() 
{
    float X,Y,Z,T,X2,Y2,Z2,BatLevel;
    int content_buffer[63];
    char read_buffer[11];
    
    init();    
                                    // Wake up Messages
 //****************************************************************************************************************** 
     
    lcd.cls(); // clean screen
    lcd.locate(0,12);
    lcd.printf("Micro Tesla Meter");
    wait(1.5);
    lcd.cls();
                                    // interruption Button for zeroing and choice of display
 //******************************************************************************************************************     
 
 
    button.rise(&startZeroing);                //link button on the joystick with the start of zeroing
    button2.rise(&changeDisplay);
    button3.rise(&saveData);
    
    lcd.cls();      
    updateLCD_2(X,Y,Z,modulus);                //Display the opperator mode ( default)
    
    
                                    // Get and display on led the level of the battery 
 //******************************************************************************************************************      
    BatLevel = BatteryVolt.read();
    if (BatLevel> 0.77)
    {
        LedRGR = 0;
        LedRGG = 1;
    }
    else 
    {
        LedRGR = 1;
        LedRGG = 0;
    }
    
    
    
        
    pc.printf("Microteslameter");
    if(0)//activate deactivate memory dump
    {    
        pc.printf("Memory dump at startup: \n");
        for (int i = 0; i<63; i++) {
                        sensor.RR(read_buffer,i,0);
                        content_buffer[i] = (read_buffer[0]*65536)+(read_buffer[1]*256) + read_buffer[2];
                    }
                    for (int i = 0; i<63; i++) {
                        pc.printf("%i \n",content_buffer[i]);
                        }
     }               
    //sensor.WR(read_buffer, 2, 2016, 0); //put DIF_FILT at max
  
  
                                    
//******************************************************************************************************************                                    
//******************************************************************************************************************  
                                     // Begining of the infinite loop
//******************************************************************************************************************    
//******************************************************************************************************************  
    
    while(1) 
    {
        //X=p1.read()*200; //use potentiometer for debug
        //Y=0;
        //Z=0;    
 
                                    // Get and display on led the level of the battery 
 //****************************************************************************************************************** 
        BatLevel = BatteryVolt.read();
        if (BatLevel> 0.77)
        {
            LedRGR = 0;
            LedRGG = 1;
        }
        else 
        {   
            LedRGR = 1;
            LedRGG = 0;
        }
 
                                     // Get measurement of the tesla sensor 
 //******************************************************************************************************************        
        MeasureXYZT(&X,&Y,&Z,&T);
        CorrectXYZ(&X,&Y,&Z); // correct for zeroing and convert LSB in uT       
        modulus=calculateModulus(X,Y,Z);
        IsConnected = isConnected(&X,&Y ,&Z, &X2,&Y2,&Z2);         // verifie if the sensor is or insnt connected
        //--------------- interface----------------
        setColor(normalize(modulus));                             // display the correct Led value  
        //lcd.printf("%f ",BatLevel);  // debug purpose
        if (IsConnected)                       
        {
            
            if ( ScreenDisplay == 0)
            {
                updateLCD_1(X,Y,Z,modulus);
            } 
            else if (ScreenDisplay == 1) 
            { 
                updateLCD_2(X,Y,Z,modulus);
            }
            else if (ScreenDisplay == 2) 
            { 
                updateLCD_3(SaveData[0],SaveData[1],SaveData[2],modulus);
                //updateLCD_2(X,Y,Z,modulus);
            }
            
            //lcd.printf("isConnected");
        }
        else 
        {
            lcd.cls();
            lcd.locate(0,12);
            lcd.printf(" the sensor isn't well connected");
            lcd.cls();
            //lcd.printf("isntConnected");
            
    
        } 
        pc.printf("T= %f,X= %f, Y= %f, Z= %f\n",T,X,Y,Z);  
        
    }
}









                                    //Function init the variable
 //******************************************************************************************************************
void init(void)
{    
    LedG1 =0;
    LedG2 =0;
    LedG3 =0;
    LedG4 =0;
    LedG5 =0;
    LedG6 =0;
    LedG7 =0;
    LedR1 =0;
    LedR2 =0;
    LedR3 =0;
    
    
    i2c.frequency(7000);  
}

                                    //Function detecting if the sensor is or isnt connected 
 //******************************************************************************************************************
 
bool isConnected (float *X, float *Y,float *Z,float *X2, float *Y2,float *Z2)
{
    float DiffX,DiffY, DiffZ;
    bool isConnected;
     
     DiffX = (*X)-(*X2);
     DiffY = (*Y)-(*Y2);
     DiffZ = (*Z)-(*Z2);
     
     /*lcd.cls();
     lcd.locate(0,0);
     lcd.printf("X= %4.1fuT",DiffX);
     lcd.locate(0,10);
     lcd.printf("Y= %4.1fuT",DiffY);
     lcd.locate(0,20);
     lcd.printf("Z= %4.1fuT",DiffZ);
     */
     if (DiffX > 1000 || DiffY > 1000 || DiffZ > 1000)
     {
         isConnected = false;
     }
     else 
     {
        isConnected = true;
     }
     *X2 = *X;
     *Y2 = *Y;
     *Z2 = *Z; 
     return isConnected;
}


void setColor(int intensity) // Display the corresponding Leds
{
    if (IsConnected)
    {
        to1.detach();
        Blink_started=false;
        if(intensity<=10) //if intensity if greater than 100 blink the led in red
        {
            LedG1 =1;
            LedG2 =0;
            LedG3 =0;
            LedG4 =0;
            LedG5 =0;
            LedG6 =0;
            LedG7 =0;
            LedR1 =0;
            LedR2 =0;
            LedR3 =0;
        }
        else if (intensity<=20) 
        {
            LedG1 =1;
            LedG2 =1;
            LedG3 =0;
            LedG4 =0;
            LedG5 =0;
            LedG6 =0;
            LedG7 =0;
            LedR1 =0;
            LedR2 =0;
            LedR3 =0;      
        }
        else if (intensity<=30) 
        {
            LedG1 =1;
            LedG2 =1;
            LedG3 =0;
            LedG4 =0;
            LedG5 =0;
            LedG6 =0;
            LedG7 =0;
            LedR1 =0;
            LedR2 =0;
            LedR3 =0;      
        }
        else if (intensity<=40) 
        {
            LedG1 =1;
            LedG2 =1;
            LedG3 =1;
            LedG4 =0;
            LedG5 =0;
            LedG6 =0;
            LedG7 =0;
            LedR1 =0;
            LedR2 =0;
            LedR3 =0;      
        }
        else if (intensity<=50) 
        {
            LedG1 =1;
            LedG2 =1;
            LedG3 =1;
            LedG4 =1;
            LedG5 =0;
            LedG6 =0;
            LedG7 =0;
            LedR1 =0;
            LedR2 =0;
            LedR3 =0;      
        }
        else if (intensity<=60) 
        {
            LedG1 =1;
            LedG2 =1;
            LedG3 =1;
            LedG4 =1;
            LedG5 =1;
            LedG6 =0;
            LedG7 =0;
            LedR1 =0;
            LedR2 =0;
            LedR3 =0;      
        }
        else if (intensity<=70) 
        {
            LedG1 =1;
            LedG2 =1;
            LedG3 =1;
            LedG4 =1;
            LedG5 =1;
            LedG6 =1;
            LedG7 =0;
            LedR1 =0;
            LedR2 =0;
            LedR3 =0;      
        }
        else if (intensity<=80) 
        {
            LedG1 =1;
            LedG2 =1;
            LedG3 =1;
            LedG4 =1;
            LedG5 =1;
            LedG6 =1;
            LedG7 =1;
            LedR1 =0;
            LedR2 =0;
            LedR3 =0;      
       }
        else if (intensity<=90) 
        {
            LedG1 =1;
            LedG2 =1;
            LedG3 =1;
            LedG4 =1;
            LedG5 =1;
            LedG6 =1;
            LedG7 =1;
            LedR1 =1;
            LedR2 =0;
            LedR3 =0;      
        }
        else if (intensity<=100) 
        {
            LedG1 =1;
            LedG2 =1;
            LedG2 =1;
            LedG3 =1;
            LedG4 =1;
            LedG5 =1;
            LedG6 =1;
            LedG7 =1;
            LedR1 =1;
            LedR2 =1;
            LedR3 =0;      
        }
        else     {
            LedG1 =1;
            LedG2 =1;
            LedG3 =1;
            LedG4 =1;
            LedG5 =1;
            LedG6 =1;
            LedG7 =1;
            LedR1 =1;
            LedR2 =1;
            LedR3 =1;      
        }
    }
    else 
    {
        if(Blink_started==false) to1.attach(&blink, 0.2);
    }
        


}

                                                    //LCD Display options
 //******************************************************************************************************************
void changeDisplay()
{
    if ( ScreenDisplay == 0)
    {
        ScreenDisplay = 1 ;
        lcd.cls();
        lcd.locate(0,14);
        lcd.printf("Display opperator mode"); 
        wait(1.5);
    }
    else if ( ScreenDisplay == 1 ) 
    {
        ScreenDisplay = 2;
        lcd.cls();
        lcd.locate(0,14);
        lcd.printf("Display Historical mode");
        wait(1.5);
    }
    else if ( ScreenDisplay == 2 ) 
    {
        ScreenDisplay = 0;
        lcd.cls();
        lcd.locate(0,14);
        lcd.printf("Display debugger mode");
        wait(1.5);
    }
    CleanScreen = true;
} 

void saveData()
{
    SaveData[DataTable] = modulus;
    
    switch (DataTable){
        
    case 0  : //or 3 or 4: change for bigger screen
        DataTable++;
        break;
        
    case 1  : //or 3 or 4: change for bigger screen
        DataTable++;
        break;
        
    case 2  : //or 3 or 4: change for bigger screen
        DataTable++;
        break;
        
    case 3 : 
        DataTable = 0;
        break;
    }
}

void updateLCD_1(float X,float Y,float Z,float modulus)                   // display the dubugger screen!
{
        if(CleanScreen==true) // clean screen in case the screen displayed something else
        {   
            lcd.cls();
            CleanScreen=false;    
        }
        
        //lcd.setmode(XOR); 
        lcd.line(lcd.width()/2, 0, lcd.width()/2, lcd.height(), 1); // vertical line to separate field to norm...
        lcd.locate(0,0);
        lcd.printf("X= %7.1fuT",X);
        lcd.locate(0,10);
        lcd.printf("Y= %7.1fuT",Y);
        lcd.locate(0,20);
        lcd.printf("Z= %7.1fuT",Z);
        lcd.locate((lcd.width()/2)+5,0);
        lcd.printf("n= %7.1fuT",modulus);
        if(modulus>FIELD_LIMIT)
        {
            lcd.locate((lcd.width()/2)+20,15);
            lcd.printf("ALERT");
            lcd.print_bm(bitmWarning,(lcd.width()/2)+2,15); // print warning sign
            lcd.copy_to_lcd();           // update lcd    
        } 
        else
        {
            lcd.locate((lcd.width()/2)+2,15);
            lcd.printf("           ");  // clean the warning sign             
        }           
        wait(0.010);   // needed?      
    
}  

void updateLCD_2(float X,float Y,float Z,float modulus)                           // Display the operator screen
{
         if(CleanScreen==true) // clean screen in case the screen displayed something else
        {   
            lcd.cls();
            CleanScreen=false;    
        }
        //lcd.setmode(XOR); 
        
        lcd.locate( 0,(lcd.height()/2));
        lcd.printf("n= %7.1fuT",modulus);
        if(modulus>FIELD_LIMIT)
        {
            lcd.locate((lcd.width()/2)+20,15);
            lcd.printf("ALERT");
            lcd.print_bm(bitmWarning,(lcd.width()/2)+2,15); // print warning sign
            lcd.copy_to_lcd();           // update lcd    
        } 
        else
        {
            lcd.locate((lcd.width()/2)+2,15);
            lcd.printf("           ");  // clean the warning sign             
        }           
        wait(0.010);   // needed?      
    
}  

void updateLCD_3(float SaveData0, float SaveData1 ,float SaveData2 ,float modulus)                   // display the dubugger screen!
{
        if(CleanScreen==true) // clean screen in case the screen displayed something else
        {   
            lcd.cls();
            CleanScreen=false;    
        }
        
        //lcd.setmode(XOR); 
        lcd.line(lcd.width()/2, 0, lcd.width()/2, lcd.height(), 1); // vertical line to separate field to norm...
        lcd.locate(0,0);
        lcd.printf("N1= %5.1fuT",SaveData0);
        lcd.locate(0,10);
        lcd.printf("N2= %5.1fuT",SaveData1);
        lcd.locate(0,20);
        lcd.printf("N3= %5.1fuT",SaveData2);
        lcd.locate((lcd.width()/2)+5,0);
        lcd.printf("n= %5.1fuT",modulus);
        if(modulus>FIELD_LIMIT)
        {
            lcd.locate((lcd.width()/2)+20,15);
            lcd.printf("ALERT");
            lcd.print_bm(bitmWarning,(lcd.width()/2)+2,15); // print warning sign
            lcd.copy_to_lcd();           // update lcd    
        } 
        else
        {
            lcd.locate((lcd.width()/2)+2,15);
            lcd.printf("           ");  // clean the warning sign             
        }           
        wait(0.010);   // needed?      
    
}    


float calculateModulus(float X, float Y, float Z)
{
    float norm;
    norm=X*X;
    norm+=Y*Y;
    norm+=Z*Z;
    norm=sqrt(norm);
    return norm; 
    
}

float normalize(float field) //normalize the field versus the field limit to have something in percent of field limit
{
    return (field/FIELD_LIMIT )*100;
}

                                    //Make blink the leds
 //******************************************************************************************************************
void blink()
{
    if(Led_on==false) 
    {
        LedG1 =0;
        LedG2 =0;
        LedG3 =0;
        LedG4 =0;
        LedG5 =0;
        LedG6 =0;
        LedG7 =0;
        LedR1 =0;
        LedR2 =0;
        LedR3 =0;//led on in red
        Led_on=true;
    }
    else 
    {
        LedG1 =1;
        LedG2 =1;
        LedG3 =1;
        LedG4 =1;
        LedG5 =1;
        LedG6 =1;
        LedG7 =1;
        LedR1 =1;
        LedR2 =1;
        LedR3 =1; //led off
        Led_on=false;    
    }
    to1.attach(&blink, 0.2);   
}


                                    //Function Measuring the magnetic field
 //******************************************************************************************************************
void MeasureXYZT(float *X,float *Y,float *Z, float *T)
{
    char read_buffer[11];
    sensor.SM(read_buffer, 15, 0); //start measurement
    wait(0.2);// needed? according the AN worse case (big filter and low conversion time) the measurment take 198.5 ms
    sensor.RM(read_buffer, 15, 0);//read measurement
    
    // concatenate the two bytes
    *T=read_buffer[1]*256+read_buffer[2];
    *X=read_buffer[3]*256+read_buffer[4];
    *Y=read_buffer[5]*256+read_buffer[6];
    *Z=read_buffer[7]*256+read_buffer[8];
    
    //deal with sign
    if(*X>32768) *X-=65536;
    if(*Y>32768) *Y-=65536;
    if(*Z>32768) *Z-=65536;
}


                                    //Make the Zero
 //******************************************************************************************************************
void startZeroing() 
{
    to1.attach(&blink, 0.2);
    float X,Y,Z,T;
    int iteration=20;// to be defined
    //char read_buffer[11];
    CorrX=0;CorrY=0;CorrZ=0;
    SaveData[0]=SaveData[1]=SaveData[2]=SaveData[3]=SaveData[4]=0;
    lcd.cls();
    
    for(int i=0;i<iteration;i++)
    {
        MeasureXYZT(&X,&Y,&Z,&T);
        CorrX+=X;
        CorrY+=Y;
        CorrZ+=Z;
        lcd.locate(0,0);
        lcd.printf("ZEROING progress: %i%%",i*100/iteration);
    }
    to1.detach();
    CorrX/=iteration;
    CorrY/=iteration;
    CorrZ/=iteration;
    CleanScreen=true;  
}



float getGainXY(int GAIN_SEL,int RES_XYZ)
{
    return 2.576; //fix value for the moment...    for RES_XYZ=3 and GAIN_SEL=4
}

float getGainZ(int GAIN_SEL,int RES_XYZ)
{
    return 4.698; //fix value for the moment...    for RES_XYZ=3 and GAIN_SEL=4
}


                //Function Correct the magnetic field depending on the the zeroing and the corresponding gain
 //******************************************************************************************************************
void CorrectXYZ(float *X,float *Y,float *Z) // correct for zeroing and convert LSB in uT
{
    *X-=CorrX;
    *Y-=CorrY;
    *Z-=CorrZ;
    
    *X= *X*getGainXY(0,0);
    *Y= *Y*getGainXY(0,0);
    *Z= *Z*getGainZ(0,0);      
}