![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
KL46Z-lab3_full
Dependencies: SLCD- mbed KL46Z-USBHost TSI MMA8451Q MAG3110 FATFileSystem
Diff: main_lab3.cpp
- Revision:
- 0:147f106a5503
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main_lab3.cpp Thu Feb 21 07:42:01 2019 +0000 @@ -0,0 +1,278 @@ +//USB Academy - Lab3 rev 00 +//_____________________________________________________________// +//======== INCLUDES ===========================================// +//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯// +#include "mbed.h" +#include "MMA8451Q.h" +#include "MAG3110.h" +#include "SLCD.h" +#include "TSISensor.h" + + +//#include "USBMouse.h" //Lab1-Hid +//#include "USBSerial.h" //Lab2-cdc +#include "USBHostMSD.h" //Lab3-MSd + + + + + +//_____________________________________________________________// +//======== DEFINES & VARIABLES ================================// +//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯// +#define LED_ON 0 //outON, pwmON +#define LED_OFF 1 //outOFF,pwmOFF +DigitalOut gLED(LED_GREEN); //PTD5 + +#define rLEDperiod 150 //[ms] +PwmOut rLED(LED_RED); //PTE29 + +#define PRESS_ON 0 +#define PRESS_OFF 1 +DigitalIn sw1(PTC3); //if(sw1) Release else Press +DigitalIn sw3(PTC12); //while(sw3); wait for Press + +#define MMA8451_I2C_ADDRESS (0x1d<<1) +MMA8451Q acc(PTE25, PTE24, MMA8451_I2C_ADDRESS); + +SLCD slcd; //[88:88][8.8.8.8] SegmentLCD + +AnalogIn light(PTE22); //analog-light input + +TSISensor slider; //Capacitive Touch Slider + +MAG3110 mag(PTE25, PTE24); //Magnetometer + +Serial usb_osda(USBTX, USBRX); //OpenSDA Terminal +#define pf usb_osda //printf out -> osda (lab1,2,3) + +struct KL46_SENSOR_DATA { + int sw1State; + int sw3State; + float accValX; + float accValY; + float accValZ; + + float slider; + float light; + int magValX; + int magValY; + int magValZ; + + float magHeading; +} sensorData; +#define sD sensorData + +void SLCD_blinking_msg_wait(char *slcd_msg1, char *slcd_msg2); + + +int MagCalibrationXY(void); //mag calib + + + +//_____________________________________________________________// +//======== MAIN() =============================================// +//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯// +int main(void) +{ + int mag_calib = 0; + FILE* fp; + //Lab3add + + + //---- MAIN/Inits -----------------------------------------// + + sw1.mode(PullUp); + sw3.mode(PullUp); + + gLED = LED_ON; //Green LED ON to indicate running/writing + rLED = LED_OFF; //Red LED OFF + rLED.period(rLEDperiod); //Red LED (rLED) tsi/accZ/mag + + //---- MAIN/Inits (Wait4SW1) -> Start! --------------------// + + //wait for Press SW1 - e.g. for HID/CDC/MSD Windows install. + //SLCD_blinking_msg_wait(" o","Helo"); //Helo (no usb); + SLCD_blinking_msg_wait(" o","MSd ");//Lab1=Hid;2=cdc;3=Msd + + //---- MAIN/Inits Interface -------------------------------// + + usb_osda.baud(115200); + usb_osda.printf("\n___________________________________\r\n"); + usb_osda.printf("\nFRDM-KL46Z_Lab\r\n \r\n I am a CDC serial port @OpenSDA/mUSB. Baud=115200 \r\n"); + + //---- MAIN/Inits Labs ------------------------------------// + //---- MAIN/Inits (Wait4SW1) -> Calib. eCompass -----------// + while (!mag_calib) { + pf.printf(" Press and release SW1 to calibrate eCompass.\r\n"); + SLCD_blinking_msg_wait(" o","CAL "); + + // Calibrate Magnetometer to eCompass + pf.printf(" ... r o t a t e the FRDM board in 3d/360° until [donE].\r\n"); + + mag_calib = MagCalibrationXY(); //to wait untill calib or cancel!!! + + if (mag_calib) { + if (mag_calib == -1) + { + pf.printf(" [SKiP]! Calibration skipped! ... See Accelerometer Z-axis.\r\n"); + SLCD_blinking_msg_wait(" o","SKiP"); //->acc + } else { + pf.printf(" [donE]! Calibration completed! ... Press and release SW1 to try eCompass.\r\n"); + SLCD_blinking_msg_wait(" o","donE"); //->mag + } + break; //while (!mag_calib) + } else { + slcd.printf("erro"); + pf.printf("r\n Error Calib !!! try again !!!\r\n\r\n"); + } //repet calib + } + + pf.printf("\r\n Lab3: pls plug USB-stick into mUSB/KL46Z \r\n"); + + slcd.printf("USb~"); //Lab1=Hid;2=cdc;3=Msd + USBHostMSD msd("usb"); //wait for plugged USB-stick + if (!msd.connect()) { + error(" USB Flash drive not found.\r\n"); + } + + //Attempt to crete file /usb/usb_lab3.txt @USB-stick. + fp = fopen("/usb/usb_lab3.txt", "w"); //rewrite, or create + if (fp) { + pf.printf(" ... sucess file-open (/usb/usb_lab3.txt @USB-stick)!\r\n\r\n"); + fprintf(fp, " Lab3: from FRDM-KL46Z \r\n\r\n"); + fclose(fp); fp=NULL; + } else pf.printf(" ... failed file-open (/usb/usb_lab3.txt @USB-stick)!\r\n\r\n"); + + + //---- MAIN/Inits (Wait4SW1) -> Calib. eCompass -----------// + + //---- MAIN/Inits Done! (Wait4SW1) -> MANI/Loop -----------// + + gLED = LED_OFF; //Inits are done + + //---- MAIN/Loop -----------------------------------------// + while (1) { + //disable all SLCD DPs + slcd.DP(0, false); slcd.DP(1, false); slcd.DP(2, false); + + // MAIN/Loop/Sensing and Storing data -----------------// + sD.sw1State = sw1; sD.sw3State = sw3; + sD.accValX = acc.getAccX(); //accX[-1..1]->mouse (Lab1) + sD.accValY = acc.getAccY(); //accY[-1..1]->mouse (Lab1) + sD.accValZ = acc.getAccZ(); //accZ[-1..1]->rLED + + sD.slider = slider.readPercentage() * 100; + sD.light = light; + sD.magValX = mag.readVal(MAG_OUT_X_MSB); + sD.magValY = mag.readVal(MAG_OUT_Y_MSB); + sD.magValZ = mag.readVal(MAG_OUT_Z_MSB); + sD.magHeading = mag.getHeading(); //calculate heading + // MAIN/Loop/Processing and Actions -------------------// + //sensor -> terminal + if (fp) { gLED = !gLED; //blinkig + pf.printf("%.2f\t", sD.magHeading); //->terminal + fprintf(fp,"%.2f\t ", sD.magHeading); //->usb_file + + pf.printf("% 1.2f\r\n", sD.accValZ); //->terminal + fprintf(fp,"% 1.2f\r\n", sD.accValZ); //->usb_file + } else gLED = LED_OFF; + + if(!fp && sw1==PRESS_ON) fp=fopen("/usb/usb_lab3.txt", "a"); + else + if(fp && sw1==PRESS_OFF) {fclose(fp); fp=NULL; gLED=LED_OFF;} + + rLED = abs(sD.accValZ); + + slcd.CharPosition=0; //prevent slcd rolling + slcd.printf("% 3.0f", sD.magHeading); + //slcd.printf("% 3.0f", sD.accValZ); + + + //acc: z-axis 1g min-blinking//acc: z-axis 1g min-blinking + rLED = abs(sD.accValZ); + + wait(0.05); //wait 50ms + } + +} + + + + + +//_____________________________________________________________// +//======== FUNC() =============================================// +//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯// + +//Lab2add +void SLCD_blinking_msg_wait(char *slcd_msg1, char *slcd_msg2) +{ + char wait4sw1=0; //~500ms blinking + + //wait for Press SW1 - to start mag calibration + while(sw1 == PRESS_ON); //wait for release + while(sw1 == PRESS_OFF) { //wait for press + if (++wait4sw1 < 150) //300ms + slcd.printf(slcd_msg1); + else //200ms + slcd.printf(slcd_msg2); + wait(0.002); + } + while(sw1 == PRESS_ON); //wait for release +} +//Lab3add +int MagCalibrationXY(void) +{ + int newX, tempXmax, tempXmin; + int newY, tempYmax, tempYmin; + int newZ, tempZmax, tempZmin; + int delta_avg=0, delta_avg_min=0, delta_avg_max=0, delta_calib_limit=800; + + // Read initial values of magnetomoter + //read it here to create a slight delay for calPin to settle!!! + tempXmax = tempXmin = mag.readVal(MAG_OUT_X_MSB); + tempYmax = tempYmin = mag.readVal(MAG_OUT_Y_MSB); + tempZmax = tempZmin = mag.readVal(MAG_OUT_Z_MSB); + + // Update min and max values until calPin asserted again + while(sw1) {//wait for Press == manual calib stop + newX = mag.readVal(MAG_OUT_X_MSB); + newY = mag.readVal(MAG_OUT_Y_MSB); + newZ = mag.readVal(MAG_OUT_Z_MSB); + + if (newX > tempXmax) tempXmax = newX; + if (newX < tempXmin) tempXmin = newX; newX = tempXmax - tempXmin; + if (newY > tempYmax) tempYmax = newY; + if (newY < tempYmin) tempYmin = newY; newY = tempYmax - tempYmin; + if (newZ > tempZmax) tempZmax = newZ; + if (newZ < tempZmin) tempZmin = newZ; newZ = tempZmax - tempZmin; + + delta_avg = (newX + newY + newZ); + + //delta is too high? -> error, try new calib!!! + if (delta_avg > 5 * delta_calib_limit) {delta_avg = 0; break; } + + //div3 with error +0.8 pct + delta_avg = (21*(newX + newY + newZ))>>6; + + //calib ok for delat ~800-1200 (~80-120uT) + if (delta_avg > delta_calib_limit){ + delta_avg_min = delta_avg - (delta_avg>>2); + delta_avg_max = delta_avg + (delta_avg>>1); + if (delta_avg_min < newX && delta_avg_max > newX + && delta_avg_min < newY && delta_avg_max > newY + && delta_avg_min < newZ && delta_avg_max > newZ) break; + } + + //show calib progress 0->100% + slcd.printf("C%3.0f", (float)delta_avg/delta_calib_limit*100); + } + + if (sw1 == PRESS_ON || delta_avg ) { + mag.setCalibration( tempXmin, tempXmax, tempYmin, tempYmax ); + if (sw1 == PRESS_ON) return -1; //==-1 ..user skip + return delta_avg; //>0 .. done, ok calib + } + return 0; //==0 .. error, no calib +}