My ELEC2645 sensor project Bader Alathri 200826344
Dependencies: FXOS8700Q N5110 SRF02 mbed
main.cpp
- Committer:
- fy13ba
- Date:
- 2016-05-05
- Revision:
- 0:fedc789ee1f0
File content as of revision 0:fedc789ee1f0:
/* 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 }