Olivier Dubrulle
/
MicroteslameterV2
test 15/05/17
main.cpp@0:d35d9bdef147, 2017-05-15 (annotated)
- Committer:
- odu
- Date:
- Mon May 15 15:30:56 2017 +0000
- Revision:
- 0:d35d9bdef147
- Child:
- 1:433aa8107296
test 15/05/17
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
odu | 0:d35d9bdef147 | 1 | #include "mbed.h" |
odu | 0:d35d9bdef147 | 2 | #include "C12832.h" |
odu | 0:d35d9bdef147 | 3 | #include "microteslameter.h" |
odu | 0:d35d9bdef147 | 4 | #include "MLX90393.h" |
odu | 0:d35d9bdef147 | 5 | #define FIELD_LIMIT 100 |
odu | 0:d35d9bdef147 | 6 | |
odu | 0:d35d9bdef147 | 7 | // Global variable: |
odu | 0:d35d9bdef147 | 8 | |
odu | 0:d35d9bdef147 | 9 | PwmOut r (p23); //PWM output for the RBG led |
odu | 0:d35d9bdef147 | 10 | PwmOut g (p24); //PWM output for the RBG led |
odu | 0:d35d9bdef147 | 11 | PwmOut b (p25); //PWM output for the RBG led |
odu | 0:d35d9bdef147 | 12 | AnalogIn p1(p19); // define analog input on p19 just for debug purpose |
odu | 0:d35d9bdef147 | 13 | C12832 lcd(p5, p7, p6, p8, p11); //define pin for LCD screen |
odu | 0:d35d9bdef147 | 14 | InterruptIn button(p14); // button used for zeroing - joystick |
odu | 0:d35d9bdef147 | 15 | I2C i2c(p28, p27); |
odu | 0:d35d9bdef147 | 16 | Serial pc(USBTX, USBRX); |
odu | 0:d35d9bdef147 | 17 | Timeout to1; // timeer... |
odu | 0:d35d9bdef147 | 18 | MLX90393 sensor(MLX90393::i2c_address,&i2c); |
odu | 0:d35d9bdef147 | 19 | |
odu | 0:d35d9bdef147 | 20 | float CorrX,CorrY,CorrZ; |
odu | 0:d35d9bdef147 | 21 | bool Led_on=false; |
odu | 0:d35d9bdef147 | 22 | bool Blink_started=false; |
odu | 0:d35d9bdef147 | 23 | bool CleanScreen=false; |
odu | 0:d35d9bdef147 | 24 | |
odu | 0:d35d9bdef147 | 25 | |
odu | 0:d35d9bdef147 | 26 | |
odu | 0:d35d9bdef147 | 27 | int main() |
odu | 0:d35d9bdef147 | 28 | { |
odu | 0:d35d9bdef147 | 29 | float X,Y,Z,modulus,T; |
odu | 0:d35d9bdef147 | 30 | int content_buffer[63]; |
odu | 0:d35d9bdef147 | 31 | char read_buffer[11]; |
odu | 0:d35d9bdef147 | 32 | |
odu | 0:d35d9bdef147 | 33 | init(); |
odu | 0:d35d9bdef147 | 34 | lcd.cls(); // clean screen |
odu | 0:d35d9bdef147 | 35 | button.rise(&startZeroing); //link button on the joystick with the start of zeroing |
odu | 0:d35d9bdef147 | 36 | |
odu | 0:d35d9bdef147 | 37 | pc.printf("Microteslameter"); |
odu | 0:d35d9bdef147 | 38 | if(0)//activate deactivate memory dump |
odu | 0:d35d9bdef147 | 39 | { |
odu | 0:d35d9bdef147 | 40 | pc.printf("Memory dump at startup: \n"); |
odu | 0:d35d9bdef147 | 41 | for (int i = 0; i<63; i++) { |
odu | 0:d35d9bdef147 | 42 | sensor.RR(read_buffer,i,0); |
odu | 0:d35d9bdef147 | 43 | content_buffer[i] = (read_buffer[0]*65536)+(read_buffer[1]*256) + read_buffer[2]; |
odu | 0:d35d9bdef147 | 44 | } |
odu | 0:d35d9bdef147 | 45 | for (int i = 0; i<63; i++) { |
odu | 0:d35d9bdef147 | 46 | pc.printf("%i \n",content_buffer[i]); |
odu | 0:d35d9bdef147 | 47 | } |
odu | 0:d35d9bdef147 | 48 | } |
odu | 0:d35d9bdef147 | 49 | //sensor.WR(read_buffer, 2, 2016, 0); //put DIF_FILT at max |
odu | 0:d35d9bdef147 | 50 | |
odu | 0:d35d9bdef147 | 51 | while(1) |
odu | 0:d35d9bdef147 | 52 | { |
odu | 0:d35d9bdef147 | 53 | //X=p1.read()*200; //use potentiometer for debug |
odu | 0:d35d9bdef147 | 54 | //Y=0; |
odu | 0:d35d9bdef147 | 55 | //Z=0; |
odu | 0:d35d9bdef147 | 56 | |
odu | 0:d35d9bdef147 | 57 | MeasureXYZT(&X,&Y,&Z,&T); |
odu | 0:d35d9bdef147 | 58 | CorrectXYZ(&X,&Y,&Z); // correct for zeroing and convert LSB in uT |
odu | 0:d35d9bdef147 | 59 | modulus=calculateModulus(X,Y,Z); |
odu | 0:d35d9bdef147 | 60 | //--------------- interface---------------- |
odu | 0:d35d9bdef147 | 61 | setColor(normalize(modulus)); |
odu | 0:d35d9bdef147 | 62 | updateLCD(X,Y,Z,modulus); |
odu | 0:d35d9bdef147 | 63 | pc.printf("T= %f,X= %f, Y= %f, Z= %f\n",T,X,Y,Z); |
odu | 0:d35d9bdef147 | 64 | } |
odu | 0:d35d9bdef147 | 65 | } |
odu | 0:d35d9bdef147 | 66 | |
odu | 0:d35d9bdef147 | 67 | |
odu | 0:d35d9bdef147 | 68 | void init(void) |
odu | 0:d35d9bdef147 | 69 | { |
odu | 0:d35d9bdef147 | 70 | b=1; // RGB led off |
odu | 0:d35d9bdef147 | 71 | r=1; // RGB led off |
odu | 0:d35d9bdef147 | 72 | g=1; // RGB led off |
odu | 0:d35d9bdef147 | 73 | i2c.frequency(7000); |
odu | 0:d35d9bdef147 | 74 | } |
odu | 0:d35d9bdef147 | 75 | |
odu | 0:d35d9bdef147 | 76 | |
odu | 0:d35d9bdef147 | 77 | void setColor(int intensity) // give intensity color from green 0% to red 100% |
odu | 0:d35d9bdef147 | 78 | { |
odu | 0:d35d9bdef147 | 79 | float duty_cycle; |
odu | 0:d35d9bdef147 | 80 | if(intensity>=100) //if intensity if greater than 100 blink the led in red |
odu | 0:d35d9bdef147 | 81 | { |
odu | 0:d35d9bdef147 | 82 | 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 |
odu | 0:d35d9bdef147 | 83 | } |
odu | 0:d35d9bdef147 | 84 | else |
odu | 0:d35d9bdef147 | 85 | { |
odu | 0:d35d9bdef147 | 86 | to1.detach(); //detach timer to stop blinking |
odu | 0:d35d9bdef147 | 87 | Blink_started=false; |
odu | 0:d35d9bdef147 | 88 | } |
odu | 0:d35d9bdef147 | 89 | |
odu | 0:d35d9bdef147 | 90 | duty_cycle=100-intensity; |
odu | 0:d35d9bdef147 | 91 | duty_cycle=duty_cycle/100; |
odu | 0:d35d9bdef147 | 92 | r=duty_cycle; //balance between red and green depending on intensity |
odu | 0:d35d9bdef147 | 93 | g=1-duty_cycle; |
odu | 0:d35d9bdef147 | 94 | } |
odu | 0:d35d9bdef147 | 95 | |
odu | 0:d35d9bdef147 | 96 | void updateLCD(float X,float Y,float Z,float modulus) |
odu | 0:d35d9bdef147 | 97 | { |
odu | 0:d35d9bdef147 | 98 | if(CleanScreen==true) // clean screen in case the screen displayed something else |
odu | 0:d35d9bdef147 | 99 | { |
odu | 0:d35d9bdef147 | 100 | lcd.cls(); |
odu | 0:d35d9bdef147 | 101 | CleanScreen=false; |
odu | 0:d35d9bdef147 | 102 | } |
odu | 0:d35d9bdef147 | 103 | //lcd.setmode(XOR); |
odu | 0:d35d9bdef147 | 104 | lcd.line(lcd.width()/2, 0, lcd.width()/2, lcd.height(), 1); // vertical line to separate field to norm... |
odu | 0:d35d9bdef147 | 105 | lcd.locate(0,0); |
odu | 0:d35d9bdef147 | 106 | lcd.printf("X= %7.1fuT",X); |
odu | 0:d35d9bdef147 | 107 | lcd.locate(0,10); |
odu | 0:d35d9bdef147 | 108 | lcd.printf("Y= %7.1fuT",Y); |
odu | 0:d35d9bdef147 | 109 | lcd.locate(0,20); |
odu | 0:d35d9bdef147 | 110 | lcd.printf("Z= %7.1fuT",Z); |
odu | 0:d35d9bdef147 | 111 | lcd.locate((lcd.width()/2)+5,0); |
odu | 0:d35d9bdef147 | 112 | lcd.printf("n= %7.1fuT",modulus); |
odu | 0:d35d9bdef147 | 113 | if(modulus>FIELD_LIMIT) |
odu | 0:d35d9bdef147 | 114 | { |
odu | 0:d35d9bdef147 | 115 | lcd.locate((lcd.width()/2)+20,15); |
odu | 0:d35d9bdef147 | 116 | lcd.printf("ALERT"); |
odu | 0:d35d9bdef147 | 117 | lcd.print_bm(bitmWarning,(lcd.width()/2)+2,15); // print warning sign |
odu | 0:d35d9bdef147 | 118 | lcd.copy_to_lcd(); // update lcd |
odu | 0:d35d9bdef147 | 119 | } |
odu | 0:d35d9bdef147 | 120 | else |
odu | 0:d35d9bdef147 | 121 | { |
odu | 0:d35d9bdef147 | 122 | lcd.locate((lcd.width()/2)+2,15); |
odu | 0:d35d9bdef147 | 123 | lcd.printf(" "); // clean the warning sign |
odu | 0:d35d9bdef147 | 124 | } |
odu | 0:d35d9bdef147 | 125 | wait(0.010); // needed? |
odu | 0:d35d9bdef147 | 126 | |
odu | 0:d35d9bdef147 | 127 | } |
odu | 0:d35d9bdef147 | 128 | |
odu | 0:d35d9bdef147 | 129 | |
odu | 0:d35d9bdef147 | 130 | float calculateModulus(float X, float Y, float Z) |
odu | 0:d35d9bdef147 | 131 | { |
odu | 0:d35d9bdef147 | 132 | float norm; |
odu | 0:d35d9bdef147 | 133 | norm=X*X; |
odu | 0:d35d9bdef147 | 134 | norm+=Y*Y; |
odu | 0:d35d9bdef147 | 135 | norm+=Z*Z; |
odu | 0:d35d9bdef147 | 136 | norm=sqrt(norm); |
odu | 0:d35d9bdef147 | 137 | return norm; |
odu | 0:d35d9bdef147 | 138 | |
odu | 0:d35d9bdef147 | 139 | } |
odu | 0:d35d9bdef147 | 140 | |
odu | 0:d35d9bdef147 | 141 | float normalize(float field) //normalize the field versus the field limit to have something in percent of field limit |
odu | 0:d35d9bdef147 | 142 | { |
odu | 0:d35d9bdef147 | 143 | return (field/FIELD_LIMIT )*100; |
odu | 0:d35d9bdef147 | 144 | } |
odu | 0:d35d9bdef147 | 145 | |
odu | 0:d35d9bdef147 | 146 | void blink() |
odu | 0:d35d9bdef147 | 147 | { |
odu | 0:d35d9bdef147 | 148 | if(Led_on==false) |
odu | 0:d35d9bdef147 | 149 | { |
odu | 0:d35d9bdef147 | 150 | r=0;//led on in red |
odu | 0:d35d9bdef147 | 151 | Led_on=true; |
odu | 0:d35d9bdef147 | 152 | } |
odu | 0:d35d9bdef147 | 153 | else |
odu | 0:d35d9bdef147 | 154 | { |
odu | 0:d35d9bdef147 | 155 | r=1; //led off |
odu | 0:d35d9bdef147 | 156 | Led_on=false; |
odu | 0:d35d9bdef147 | 157 | } |
odu | 0:d35d9bdef147 | 158 | to1.attach(&blink, 0.2); |
odu | 0:d35d9bdef147 | 159 | } |
odu | 0:d35d9bdef147 | 160 | |
odu | 0:d35d9bdef147 | 161 | void MeasureXYZT(float *X,float *Y,float *Z, float *T) |
odu | 0:d35d9bdef147 | 162 | { |
odu | 0:d35d9bdef147 | 163 | char read_buffer[11]; |
odu | 0:d35d9bdef147 | 164 | sensor.SM(read_buffer, 15, 0); //start measurement |
odu | 0:d35d9bdef147 | 165 | wait(0.2);// needed? according the AN worse case (big filter and low conversion time) the measurment take 198.5 ms |
odu | 0:d35d9bdef147 | 166 | sensor.RM(read_buffer, 15, 0);//read measurement |
odu | 0:d35d9bdef147 | 167 | |
odu | 0:d35d9bdef147 | 168 | // concatenate the two bytes |
odu | 0:d35d9bdef147 | 169 | *T=read_buffer[1]*256+read_buffer[2]; |
odu | 0:d35d9bdef147 | 170 | *X=read_buffer[3]*256+read_buffer[4]; |
odu | 0:d35d9bdef147 | 171 | *Y=read_buffer[5]*256+read_buffer[6]; |
odu | 0:d35d9bdef147 | 172 | *Z=read_buffer[7]*256+read_buffer[8]; |
odu | 0:d35d9bdef147 | 173 | |
odu | 0:d35d9bdef147 | 174 | //deal with sign |
odu | 0:d35d9bdef147 | 175 | if(*X>32768) *X-=65536; |
odu | 0:d35d9bdef147 | 176 | if(*Y>32768) *Y-=65536; |
odu | 0:d35d9bdef147 | 177 | if(*Z>32768) *Z-=65536; |
odu | 0:d35d9bdef147 | 178 | } |
odu | 0:d35d9bdef147 | 179 | |
odu | 0:d35d9bdef147 | 180 | void startZeroing() |
odu | 0:d35d9bdef147 | 181 | { |
odu | 0:d35d9bdef147 | 182 | float X,Y,Z,T; |
odu | 0:d35d9bdef147 | 183 | int iteration=20;// to be defined |
odu | 0:d35d9bdef147 | 184 | //char read_buffer[11]; |
odu | 0:d35d9bdef147 | 185 | CorrX=0;CorrY=0;CorrZ=0; |
odu | 0:d35d9bdef147 | 186 | lcd.cls(); |
odu | 0:d35d9bdef147 | 187 | |
odu | 0:d35d9bdef147 | 188 | for(int i=0;i<iteration;i++) |
odu | 0:d35d9bdef147 | 189 | { |
odu | 0:d35d9bdef147 | 190 | MeasureXYZT(&X,&Y,&Z,&T); |
odu | 0:d35d9bdef147 | 191 | CorrX+=X; |
odu | 0:d35d9bdef147 | 192 | CorrY+=Y; |
odu | 0:d35d9bdef147 | 193 | CorrZ+=Z; |
odu | 0:d35d9bdef147 | 194 | lcd.locate(0,0); |
odu | 0:d35d9bdef147 | 195 | lcd.printf("ZEROING progress: %i%%",i*100/iteration); |
odu | 0:d35d9bdef147 | 196 | } |
odu | 0:d35d9bdef147 | 197 | CorrX/=iteration; |
odu | 0:d35d9bdef147 | 198 | CorrY/=iteration; |
odu | 0:d35d9bdef147 | 199 | CorrZ/=iteration; |
odu | 0:d35d9bdef147 | 200 | CleanScreen=true; |
odu | 0:d35d9bdef147 | 201 | } |
odu | 0:d35d9bdef147 | 202 | |
odu | 0:d35d9bdef147 | 203 | |
odu | 0:d35d9bdef147 | 204 | |
odu | 0:d35d9bdef147 | 205 | float getGainXY(int GAIN_SEL,int RES_XYZ) |
odu | 0:d35d9bdef147 | 206 | { |
odu | 0:d35d9bdef147 | 207 | return 2.576; //fix value for the moment... for RES_XYZ=3 and GAIN_SEL=4 |
odu | 0:d35d9bdef147 | 208 | } |
odu | 0:d35d9bdef147 | 209 | |
odu | 0:d35d9bdef147 | 210 | float getGainZ(int GAIN_SEL,int RES_XYZ) |
odu | 0:d35d9bdef147 | 211 | { |
odu | 0:d35d9bdef147 | 212 | return 4.698; //fix value for the moment... for RES_XYZ=3 and GAIN_SEL=4 |
odu | 0:d35d9bdef147 | 213 | } |
odu | 0:d35d9bdef147 | 214 | |
odu | 0:d35d9bdef147 | 215 | void CorrectXYZ(float *X,float *Y,float *Z) // correct for zeroing and convert LSB in uT |
odu | 0:d35d9bdef147 | 216 | { |
odu | 0:d35d9bdef147 | 217 | *X-=CorrX; |
odu | 0:d35d9bdef147 | 218 | *Y-=CorrY; |
odu | 0:d35d9bdef147 | 219 | *Z-=CorrZ; |
odu | 0:d35d9bdef147 | 220 | |
odu | 0:d35d9bdef147 | 221 | *X= *X*getGainXY(0,0); |
odu | 0:d35d9bdef147 | 222 | *Y= *Y*getGainXY(0,0); |
odu | 0:d35d9bdef147 | 223 | *Z= *Z*getGainZ(0,0); |
odu | 0:d35d9bdef147 | 224 | } |