Olivier Dubrulle
/
MicroteslameterV2
test 15/05/17
Diff: main.cpp
- Revision:
- 0:d35d9bdef147
- Child:
- 1:433aa8107296
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon May 15 15:30:56 2017 +0000 @@ -0,0 +1,224 @@ +#include "mbed.h" +#include "C12832.h" +#include "microteslameter.h" +#include "MLX90393.h" +#define FIELD_LIMIT 100 + +// Global variable: + +PwmOut r (p23); //PWM output for the RBG led +PwmOut g (p24); //PWM output for the RBG led +PwmOut b (p25); //PWM output for the RBG led +AnalogIn p1(p19); // define analog input on p19 just for debug purpose +C12832 lcd(p5, p7, p6, p8, p11); //define pin for LCD screen +InterruptIn button(p14); // button used for zeroing - joystick +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; + + + +int main() +{ + float X,Y,Z,modulus,T; + int content_buffer[63]; + char read_buffer[11]; + + init(); + lcd.cls(); // clean screen + button.rise(&startZeroing); //link button on the joystick with the start of zeroing + + 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 + + while(1) + { + //X=p1.read()*200; //use potentiometer for debug + //Y=0; + //Z=0; + + MeasureXYZT(&X,&Y,&Z,&T); + CorrectXYZ(&X,&Y,&Z); // correct for zeroing and convert LSB in uT + modulus=calculateModulus(X,Y,Z); + //--------------- interface---------------- + setColor(normalize(modulus)); + updateLCD(X,Y,Z,modulus); + pc.printf("T= %f,X= %f, Y= %f, Z= %f\n",T,X,Y,Z); + } +} + + +void init(void) +{ + b=1; // RGB led off + r=1; // RGB led off + g=1; // RGB led off + i2c.frequency(7000); +} + + +void setColor(int intensity) // give intensity color from green 0% to red 100% +{ + float duty_cycle; + if(intensity>=100) //if intensity if greater than 100 blink the led in red + { + if(Blink_started==false) to1.attach(&blink, 0.2); //attach timer to the blink function to start blinking the led, only if this was not done previously + } + else + { + to1.detach(); //detach timer to stop blinking + Blink_started=false; + } + + duty_cycle=100-intensity; + duty_cycle=duty_cycle/100; + r=duty_cycle; //balance between red and green depending on intensity + g=1-duty_cycle; +} + +void updateLCD(float X,float Y,float Z,float modulus) +{ + 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? + +} + + +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; +} + +void blink() +{ + if(Led_on==false) + { + r=0;//led on in red + Led_on=true; + } + else + { + r=1; //led off + Led_on=false; + } + to1.attach(&blink, 0.2); +} + +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; +} + +void startZeroing() +{ + float X,Y,Z,T; + int iteration=20;// to be defined + //char read_buffer[11]; + CorrX=0;CorrY=0;CorrZ=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); + } + 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 +} + +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); +} \ No newline at end of file