My ELEC2645 sensor project Bader Alathri 200826344

Dependencies:   FXOS8700Q N5110 SRF02 mbed

Revision:
0:fedc789ee1f0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu May 05 14:59:50 2016 +0000
@@ -0,0 +1,400 @@
+/*
+
+Bader Alathri
+ELEC2645_project
+
+*/
+
+
+#include "main.h"
+
+BusIn input(PTC5,PTC7); /// external button inputs (toggle,select)
+
+
+struct State { /// struct to group state information
+    int output;  /// output value
+    float time;    /// time in state
+    int nextState[4];  /// array of next states
+};
+
+typedef const struct State STyp;
+
+
+STyp fsm[9] = { /// finite state machine (FSM) transition table
+    {0,0.15,{0,1,3,0}},
+    {1,0.15,{1,2,7,1}},
+    {2,0.15,{2,0,8,2}},
+    {3,0.15,{3,4,5,3}},
+    {4,0.15,{4,3,6,4}},
+    {5,0.15,{5,0,5,5}},
+    {6,0.15,{6,0,6,6}},
+    {7,0.15,{7,0,7,7}},
+    {8,0.15,{8,0,8,8}}
+
+};
+
+
+int main()
+{
+
+    init_K64F();   /// initialise the board and serial port
+    init_serial(); /// initialise serial port
+    lcd.init(); /// initialise display
+    brightness = 0.4; /// setting initial brightness value to 0.4
+    lcd.setBrightness(brightness); /// sets lcd brightness to match 'brightness' variable
+    toggle.rise(&toggle_isr); /// rising edge for interrupt input set to trigger ISR (toggle button)
+    select.rise(&select_isr); /// rising edge for interrupt interrupt set to trigger ISR (select button)
+
+    toggle.mode(PullDown); /// interrupt input pin set to pulldown mode (toggle button)
+    select.mode(PullDown); /// interrupt input pin set to pulldown mode (select button)
+    /// as both buttons are connected to 3V3
+
+    int state = 0; /// intitial FSM state set to 0
+
+    while(1) {
+
+        int output; // /stores value of state output
+        output = fsm[state].output;  /// set ouput depending on current state
+        wait(fsm[state].time);       /// wait in that state for desired time
+        state = fsm[state].nextState[input];  /// read input (BusIn) and update curent state
+
+        if ( output == 0) { /// first state
+
+            acc.disable(); /// disable accelerometer, from FXOS8700Q library
+            ticker1.detach(); /// stops ticker from triggering timer1 ISR
+            g_toggle_flag = 0; /// resets toggle flag to 0
+            r_led = 0; /// turns off external red LED
+            g_led = 0; /// turns off external green LED
+
+            lcd.clear(); /// clears lcd
+            lcd.drawCircle(3,12,1,1); /// displays small circle next to selected option
+            /// display options on lcd
+            lcd.printString("get distance",7,1);
+            lcd.printString("spirit level",7,3);
+            lcd.printString("brightness",7,5);
+
+
+
+        } else if ( output == 1 ) { /// second state
+
+            g_toggle_flag = 0; /// resets toggle flag to 0
+            lcd.clear(); /// clears lcd
+            lcd.drawCircle(3,28,1,1); /// displays small circle next to selected option
+            /// display options on lcd
+            lcd.printString("get distance",7,1);
+            lcd.printString("spirit level",7,3);
+            lcd.printString("brightness",7,5);
+
+
+
+        } else if ( output == 2 ) { /// third state
+
+            g_toggle_flag = 0; /// resets toggle flag to 0
+            lcd.clear(); /// clears lcd
+            lcd.drawCircle(3,44,1,1); /// displays small circle next to selected option
+            /// display options on lcd
+            lcd.printString("get distance",7,1);
+            lcd.printString("spirit level",7,3);
+            lcd.printString("brightness",7,5);
+
+
+
+
+        } else if ( output == 3 ) { /// fourth state
+
+            g_select_flag = 0; /// resets select flag to 0
+            lcd.clear(); /// clears lcd
+            lcd.drawCircle(3,12,1,1); /// displays small circle next to selected option
+            /// display unit options on lcd
+            lcd.printString("centimetres",7,1);
+            lcd.printString("inches",7,3);
+
+        } else if ( output == 4 ) { /// fifth state
+
+            g_toggle_flag = 0; /// resets toggle flag to 0
+            lcd.clear(); /// clears lcd
+            lcd.drawCircle(3,28,1,1); /// displays small circle next to selected option
+            /// display unit options on lcd
+            lcd.printString("centimetres",7,1);
+            lcd.printString("inches",7,3);
+
+        } else if ( output == 5 && g_select_flag == 1 ) { /// sixth state, two conditions so that state triggers only once
+
+            g_select_flag = 0; /// resets select flag to 0
+            lcd.clear(); /// clears lcd
+            measuring_transition(); /// displays transition while measurement is taking place
+            get_average_distance_cm(); /// calculates average distance in cm from readings
+            lcd.clear(); /// clears lcd
+
+
+
+            if (g_error_flag) { /// checks if error flag is triggered
+                g_error_flag = 0; /// resets error flag to 0
+                measurement_error(); /// displays error message
+
+            }
+
+
+            else { /// if error flag was not triggered
+                display_distance_cm(); /// displays distance in cm
+                g_led = 1; /// turns on green external LED
+            }
+            lcd.refresh(); ///refreshes lcd
+            sleep(); /// puts K64F into sleep mode
+        }
+
+
+        else if ( output == 6 && g_select_flag == 1 ) { /// seventh state, two conditions so that state triggers only once
+
+            g_select_flag = 0; /// resets select flag to 0
+            lcd.clear(); /// clears lcd
+            measuring_transition(); /// displays transition while measurement is taking place
+            get_average_distance_in(); ///c alculates average distance in inches from readings
+            lcd.clear(); /// clears lcd
+
+
+            if (g_error_flag) { /// checks if error flag is triggered
+                g_error_flag = 0; /// resets error flag to 0
+                measurement_error(); /// displays error message
+            }
+
+
+            else { /// if error flag was not triggered
+                display_distance_in(); /// displays distance in inches
+                g_led = 1; /// turns on green external LED
+            }
+            lcd.refresh(); /// refreshes lcd
+            sleep(); /// puts K64F into sleep mode
+        }
+
+        else if ( output == 7 ) { /// eighth state
+
+            acc.enable(); /// enabling FXOS8700 accelerometer, credit: https://developer.mbed.org/teams/Freescale/code/Hello_FXOS8700Q/
+            ticker1.attach(&timer1_isr,0.125); /// attaching ticker1 to timer1 ISR
+            /// ISR triggered every 0.125 seconds
+
+            if (g_timer1_flag) { /// checks if ISR is triggered
+
+                g_timer1_flag = 0; /// resets timer flag to 0
+
+                get_z_axis_value(); ///calculates average z-axis reading
+                lcd.clear(); /// clears lcd
+                display_flatness(); /// displays whether surface is found to be flat
+                lcd.refresh(); /// refreshes lcd
+                sleep(); /// puts K64F into sleep mode
+            }
+
+
+        } else if ( output == 8 && g_select_flag == 1 ) { /// ninth state
+            g_select_flag = 0; /// resets select flag to 0
+            lcd.clear(); /// clears lcd
+            adjust_brightness(); /// adjusts brightness according to current value of 'brightness' variable
+            display_brightness(); /// displays brightness as a percentage on lcd
+            lcd.refresh(); /// refreshes lcd
+            sleep(); /// puts K64F into sleep mode
+
+        }
+
+    }
+}
+
+
+void init_serial()
+{
+
+    pc.baud(115200); /// set to highest baud - ensure terminal software matches
+}
+
+void init_K64F()
+{
+    /// on-board LEDs are active-low, so set pin high to turn them off.
+    red_led = 1;
+    green_led = 1;
+    blue_led = 1;
+
+}
+
+void timer1_isr()
+{
+    g_timer1_flag = 1;  /// set timer1 flag in ISR
+}
+
+void select_isr()
+{
+    g_select_flag = 1; /// set select flag in ISR
+}
+
+void toggle_isr()
+{
+    g_toggle_flag = 1; /// set toggle flag in ISR
+}
+
+void measurement_error()
+{
+    lcd.printString("error",25,2); /// displays 'error' on lcd
+    r_led = 1; /// turns on external red LED
+
+}
+
+void measuring_transition()
+{
+    /// turns off external LEDs
+    r_led = 0;
+    g_led = 0;
+    lcd.printString("measuring...",10,2); /// displays measuring message on lcd
+}
+
+void get_average_distance_cm()
+{
+    total_distance = 0.0; /// resets value for total distance
+    average_distance_cm = 0.0; /// resets value for average distance (cm)
+    for ( int i=0; i<10; i++) { /// 10 iterations
+
+        float distance = sensor.getDistanceCm(); /// gets 1 distance reading from sensor in cm
+        total_distance = total_distance + distance; /// stores sum of readings
+
+        if ( distance >= 249 ) { /// if a single measurement is above the range of the sensor
+
+            g_error_flag = 1; /// trigger error flag
+
+
+        }
+
+        else if ( distance <= 15 ) { /// if a single measurement is below the range of the sensor
+
+            g_error_flag = 1; /// trigger error flag
+
+        }
+        pc.printf("Distance = %.2f cm\n",distance); /// prints distance measurements to pc in cm
+    }
+
+    average_distance_cm = total_distance/10; /// calculates average distance in cm
+}
+
+void get_average_distance_in()
+{
+    total_distance = 0.0; /// resets value for total distance
+    average_distance_in = 0.0; /// resets value for average distance (inches)
+    for ( int i=0; i<10; i++) { /// 10 iterations
+
+        float distance = sensor.getDistanceCm(); /// gets 1 distance reading from sensor in cm
+        total_distance = total_distance + distance; /// stores sum of readings
+
+        if ( distance >= 249 ) { /// if a single measurement is above the range of the sensor
+
+            g_error_flag = 1; /// trigger error flag
+
+
+        }
+
+        else if ( distance <= 15 ) { /// if a single measurement is below the range of the sensor
+
+            g_error_flag = 1; /// trigger error flag
+
+        }
+        pc.printf("Distance = %.2f cm\n",distance); /// prints distance measurements to pc in cm
+    }
+
+    average_distance_in = (total_distance/10) * 0.394; /// calculates average distance in cm then converts it to inches
+}
+
+void display_distance_cm()
+{
+    /// prints value of distance and units
+    lcd.printString("Distance:",15,1);
+    char buffer[14];
+    float length = sprintf(buffer,"%.2f cm",average_distance_cm); /// print formatted data to buffer
+    lcd.printString(buffer,17,3); /// display on lcd
+
+}
+
+void display_distance_in()
+{
+    lcd.printString("Distance:",15,1);
+    char buffer[14];
+    float length = sprintf(buffer,"%.2f inches",average_distance_in); /// print formatted data to buffer
+    lcd.printString(buffer,9,3); /// display on lcd
+
+}
+
+
+void get_z_axis_value()
+{
+
+    int16_t raZ; /// variable for storing z-axis reading taken from FXOS8700Q library
+    /// from FXOS8700Q library
+
+    acc.getAxis(acc_data); /// gets data from accelerometer, from FXOS8700Q library
+
+
+
+    acc.getZ(&raZ); /// get z-axis reading, from FXOS8700Q library
+
+
+
+    int total_z = 0; /// variable to store sum of z-axis values
+
+    for ( int i=0; i<10; i++) { /// 10 iterations
+
+        int z = raZ; /// variable to store single z-axis reading, from FXOS8700Q library
+        total_z = total_z + z; /// summing z-axis readings
+
+        wait (0.01); /// delay of 0.01 seconds between loop iterations
+    }
+
+    average_z = total_z / 10 ; /// calculates average z-axis value
+
+    pc.printf("Z=%.2f\n  ", average_z); /// prints average z-axis value to pc
+}
+
+void display_flatness()
+{
+    if ((average_z <= 280) && (average_z >= 80)) { ///if average z-axis value within specified range (vertically flat)
+        r_led = 0; /// turns off external red LED
+        g_led = 1; /// turns on external green LED
+        lcd.printString("vertically",7,1); /// displays 'vertically flat' message on lcd
+        lcd.printString("flat",30,3);
+    }
+
+    else if ((average_z <= 4160) && (average_z >= 4147)) { ///if average z-axis value within specified range (horizontaly flat)
+        r_led = 0; /// turns off external red LED
+        g_led = 1; /// turns on external green LED
+        lcd.printString("horizontally",7,1); /// displays 'horizontaly flat' message on lcd
+        lcd.printString("flat",30,3);
+    }
+
+    else if ((average_z <= -3860) && (average_z >= -3880)) { ///if average z-axis value within specified range (horizontaly flat)
+        r_led = 0; /// turns off external red LED
+        g_led = 1; /// turns on external green LED
+        lcd.printString("horizontally",7,1);  /// displays 'horizontaly flat' message on lcd
+        lcd.printString("flat",30,3);
+    }
+
+    else { /// otherwise if average z-axis value within specified ranges (not flat)
+        r_led = 1; /// turns on external red LED
+        g_led = 0; /// turns off external green LED
+        lcd.printString("not flat",18,2); /// displays 'not flat' message on lcd
+
+    }
+        
+}
+
+void adjust_brightness()
+{
+    if ( brightness == 1.0 ) { /// if the brightness value is at 1.0
+        brightness = 0.0; /// set brightness back to 0
+    } else { /// if the brightness value is not 1.0
+        brightness = brightness + 0.2; /// increase its value by 0.2
+    }
+
+    lcd.setBrightness(brightness); /// sets lcd brightness to valeu of 'brightness' variable
+}
+
+void display_brightness()
+{
+    lcd.printString("brightness:",7,1);
+    int brightness_percentage = brightness * 100; /// calculates brightness percentage
+    char buffer[14];
+    float length = sprintf(buffer,"%d%%",brightness_percentage); /// print formatted data to buffer
+    lcd.printString(buffer,31,3); /// display on lcd
+}
\ No newline at end of file