KL46Z-lab3_full

Dependencies:   SLCD- mbed KL46Z-USBHost TSI MMA8451Q MAG3110 FATFileSystem

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
+}