The project is a fast lock in amplifier (LIA) which can update its output at rate of 1000 measurements/s. It performs digital dual mixing and filtering to obtain a DC value proportional to the AC input signal.
main.cpp@4:2264789de7b2, 2017-09-22 (annotated)
- Committer:
- Nikollao
- Date:
- Fri Sep 22 09:18:46 2017 +0000
- Revision:
- 4:2264789de7b2
- Parent:
- 3:dd4eb355f8d9
publish project;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Nikollao | 0:4e20939af8bb | 1 | #include "main.h" |
Nikollao | 0:4e20939af8bb | 2 | |
Nikollao | 0:4e20939af8bb | 3 | int main() |
Nikollao | 0:4e20939af8bb | 4 | { |
Nikollao | 2:c9b24787d5e1 | 5 | lcd_intro(); |
Nikollao | 2:c9b24787d5e1 | 6 | calibrateJoystick(); ///calibrate joystick |
Nikollao | 2:c9b24787d5e1 | 7 | settings_menu(); |
Nikollao | 3:dd4eb355f8d9 | 8 | lcd.clear(); |
Nikollao | 0:4e20939af8bb | 9 | dref.rise(&voltageRise); /// set interrupt to calculate reference frequency |
Nikollao | 0:4e20939af8bb | 10 | setupK64Fclocks(); |
Nikollao | 2:c9b24787d5e1 | 11 | //settings_menu(); |
Nikollao | 0:4e20939af8bb | 12 | /// initialise DAC output dac0_out |
Nikollao | 0:4e20939af8bb | 13 | while (ref_freq < 1e2) { |
Nikollao | 0:4e20939af8bb | 14 | sleep(); |
Nikollao | 0:4e20939af8bb | 15 | } |
Nikollao | 3:dd4eb355f8d9 | 16 | double freq_check = ref_freq*0.001; |
Nikollao | 3:dd4eb355f8d9 | 17 | double out_speed = 2*var_speed; |
Nikollao | 3:dd4eb355f8d9 | 18 | |
Nikollao | 3:dd4eb355f8d9 | 19 | if (freq_check < out_speed) { |
Nikollao | 3:dd4eb355f8d9 | 20 | lcd.printString("RefFreq Low",0,0); |
Nikollao | 3:dd4eb355f8d9 | 21 | lcd.printString("OR: ",0,1); |
Nikollao | 3:dd4eb355f8d9 | 22 | lcd.printString("AnOut too Fast",0,2); |
Nikollao | 3:dd4eb355f8d9 | 23 | |
Nikollao | 3:dd4eb355f8d9 | 24 | while (freq_check < out_speed) { |
Nikollao | 3:dd4eb355f8d9 | 25 | sleep(); |
Nikollao | 3:dd4eb355f8d9 | 26 | } |
Nikollao | 3:dd4eb355f8d9 | 27 | } |
Nikollao | 0:4e20939af8bb | 28 | /// make sure frequency is read before we go to the program |
Nikollao | 0:4e20939af8bb | 29 | /// cancel event-triggered rise interrupt, not to interfere with program |
Nikollao | 0:4e20939af8bb | 30 | dref.rise(NULL); |
Nikollao | 0:4e20939af8bb | 31 | pc.printf("Ref_Freq is:%.2f kHz\n\r",ref_freq*0.001); |
Nikollao | 3:dd4eb355f8d9 | 32 | lcd.clear(); |
Nikollao | 3:dd4eb355f8d9 | 33 | char refFreq_char[20]; ///create an array of chars |
Nikollao | 3:dd4eb355f8d9 | 34 | sprintf(refFreq_char,"%.3f",ref_freq); ///create string |
Nikollao | 3:dd4eb355f8d9 | 35 | |
Nikollao | 3:dd4eb355f8d9 | 36 | lcd.printString("Ref Freq: ",0,0); |
Nikollao | 3:dd4eb355f8d9 | 37 | lcd.printString(refFreq_char,35,1); |
Nikollao | 1:bf693859586c | 38 | /// constant 6 for correct sampling time |
Nikollao | 1:bf693859586c | 39 | /// compensates for delay caused by computations |
Nikollao | 0:4e20939af8bb | 40 | sample_freq = 6*samples16*ref_freq; |
Nikollao | 0:4e20939af8bb | 41 | sample_time = 1/sample_freq; |
Nikollao | 0:4e20939af8bb | 42 | |
Nikollao | 0:4e20939af8bb | 43 | initDAC(); |
Nikollao | 0:4e20939af8bb | 44 | delay_freq = ref_freq*amp_points; |
Nikollao | 0:4e20939af8bb | 45 | amplitude_delay = 1/delay_freq; |
Nikollao | 3:dd4eb355f8d9 | 46 | |
Nikollao | 3:dd4eb355f8d9 | 47 | wait(1); |
Nikollao | 3:dd4eb355f8d9 | 48 | lcd.clear(); |
Nikollao | 3:dd4eb355f8d9 | 49 | lcd.printString("LIA ",0,0); |
Nikollao | 3:dd4eb355f8d9 | 50 | lcd.printString("In process...",0,1); |
Nikollao | 3:dd4eb355f8d9 | 51 | lcd.refresh(); |
Nikollao | 1:bf693859586c | 52 | /// find the offset of the signal |
Nikollao | 0:4e20939af8bb | 53 | offset_ticker.attach(&offset_isr,0.001); |
Nikollao | 3:dd4eb355f8d9 | 54 | |
Nikollao | 3:dd4eb355f8d9 | 55 | double update_value = 0.0; |
Nikollao | 3:dd4eb355f8d9 | 56 | |
Nikollao | 0:4e20939af8bb | 57 | while (offset == 0) { |
Nikollao | 0:4e20939af8bb | 58 | if (g_offset_flag == 1) { |
Nikollao | 0:4e20939af8bb | 59 | g_offset_flag = 0; |
Nikollao | 0:4e20939af8bb | 60 | offset = mavg_filter(filter_points); |
Nikollao | 0:4e20939af8bb | 61 | } |
Nikollao | 0:4e20939af8bb | 62 | sleep(); |
Nikollao | 0:4e20939af8bb | 63 | } |
Nikollao | 0:4e20939af8bb | 64 | offset_ticker.detach(); |
Nikollao | 1:bf693859586c | 65 | /// once the offset is calculated detach the offset ticker |
Nikollao | 3:dd4eb355f8d9 | 66 | /// attach the output ticker to update every x ms |
Nikollao | 3:dd4eb355f8d9 | 67 | update_value = var_speed*0.001; |
Nikollao | 3:dd4eb355f8d9 | 68 | output_ticker.attach(&output_isr,update_value); |
Nikollao | 0:4e20939af8bb | 69 | |
Nikollao | 0:4e20939af8bb | 70 | while (true) { |
Nikollao | 0:4e20939af8bb | 71 | // gpo = !gpo; |
Nikollao | 1:bf693859586c | 72 | digitalMix(offset); /// perform digital mixing |
Nikollao | 1:bf693859586c | 73 | while (g_output_flag == 0) {sleep();} /// sleep until flag is set |
Nikollao | 1:bf693859586c | 74 | /// update output |
Nikollao | 0:4e20939af8bb | 75 | if (g_output_flag == 1) { |
Nikollao | 0:4e20939af8bb | 76 | g_output_flag = 0; |
Nikollao | 0:4e20939af8bb | 77 | //aout = max(samples16); |
Nikollao | 3:dd4eb355f8d9 | 78 | aout = var_gain*max(samples16); |
Nikollao | 1:bf693859586c | 79 | /// DC output by taking the maximum value of the mixed signal (R) |
Nikollao | 0:4e20939af8bb | 80 | } |
Nikollao | 0:4e20939af8bb | 81 | } |
Nikollao | 0:4e20939af8bb | 82 | } |
Nikollao | 0:4e20939af8bb | 83 | |
Nikollao | 0:4e20939af8bb | 84 | double max(int points) |
Nikollao | 0:4e20939af8bb | 85 | { |
Nikollao | 0:4e20939af8bb | 86 | double amp = 0; |
Nikollao | 0:4e20939af8bb | 87 | |
Nikollao | 0:4e20939af8bb | 88 | for (int i = 0; i < points; i++) { |
Nikollao | 0:4e20939af8bb | 89 | if (amp < R[i]) |
Nikollao | 1:bf693859586c | 90 | amp = R[i]; /// find max of R |
Nikollao | 0:4e20939af8bb | 91 | //wait(amplitude_delay); |
Nikollao | 0:4e20939af8bb | 92 | } |
Nikollao | 0:4e20939af8bb | 93 | return amp; |
Nikollao | 0:4e20939af8bb | 94 | } |
Nikollao | 0:4e20939af8bb | 95 | |
Nikollao | 0:4e20939af8bb | 96 | double mavg_filter(int filt_points) |
Nikollao | 0:4e20939af8bb | 97 | { |
Nikollao | 0:4e20939af8bb | 98 | double avg = 0, signal = 0; |
Nikollao | 2:c9b24787d5e1 | 99 | //double delay = 0.9/(1*ref_freq*filter_points); |
Nikollao | 0:4e20939af8bb | 100 | for (int i = 0; i < filter_points; i++) { |
Nikollao | 0:4e20939af8bb | 101 | signal = ain.read(); |
Nikollao | 0:4e20939af8bb | 102 | avg = avg + signal; |
Nikollao | 0:4e20939af8bb | 103 | wait((float)(5e-5)); |
Nikollao | 0:4e20939af8bb | 104 | } |
Nikollao | 1:bf693859586c | 105 | avg = avg/filter_points; /// find offset of input signal |
Nikollao | 0:4e20939af8bb | 106 | return avg; |
Nikollao | 0:4e20939af8bb | 107 | } |
Nikollao | 0:4e20939af8bb | 108 | |
Nikollao | 0:4e20939af8bb | 109 | void digitalMix(double remove_offset) { |
Nikollao | 0:4e20939af8bb | 110 | /// perform mixing of input and reference signals |
Nikollao | 0:4e20939af8bb | 111 | double input = 0; |
Nikollao | 0:4e20939af8bb | 112 | for (int i = 0; i < samples16;i++) { |
Nikollao | 0:4e20939af8bb | 113 | /// remove the offset before doing the multiplication of signals |
Nikollao | 0:4e20939af8bb | 114 | input = ain.read()-remove_offset; |
Nikollao | 0:4e20939af8bb | 115 | /// find the X component by multiplying with sine 17 values array |
Nikollao | 0:4e20939af8bb | 116 | double refX = input*sin_array16[i]; |
Nikollao | 0:4e20939af8bb | 117 | /// find the Y component by multiplying with cosine 17 values array |
Nikollao | 0:4e20939af8bb | 118 | double refY = input*cos_array16[i]; |
Nikollao | 0:4e20939af8bb | 119 | //double XY = exp(2*log(refX))+exp(2*log(refY)); |
Nikollao | 0:4e20939af8bb | 120 | double XY = (refX*refX)+(refY*refY); /// R square |
Nikollao | 0:4e20939af8bb | 121 | //double R = exp(0.5*log(XY))/4; |
Nikollao | 0:4e20939af8bb | 122 | R[i] = pow(XY,0.5); /// R |
Nikollao | 0:4e20939af8bb | 123 | //aout = (1+sin_array16[i])/4; |
Nikollao | 0:4e20939af8bb | 124 | //aout = R[i]/2; |
Nikollao | 0:4e20939af8bb | 125 | wait(sample_time); /// sample time |
Nikollao | 0:4e20939af8bb | 126 | } |
Nikollao | 0:4e20939af8bb | 127 | } |
Nikollao | 0:4e20939af8bb | 128 | |
Nikollao | 0:4e20939af8bb | 129 | void voltageRise() { |
Nikollao | 0:4e20939af8bb | 130 | if (g_counter == 1) { |
Nikollao | 0:4e20939af8bb | 131 | /// first time function is called is the first rise |
Nikollao | 0:4e20939af8bb | 132 | /// start timer |
Nikollao | 0:4e20939af8bb | 133 | period_timer.start(); |
Nikollao | 0:4e20939af8bb | 134 | /// increase counter so next time function is called we calculate freq. |
Nikollao | 0:4e20939af8bb | 135 | g_counter++; |
Nikollao | 0:4e20939af8bb | 136 | } |
Nikollao | 0:4e20939af8bb | 137 | else if (g_counter == 2) { |
Nikollao | 0:4e20939af8bb | 138 | /// second time function is called is the second rise |
Nikollao | 0:4e20939af8bb | 139 | /// stop timer |
Nikollao | 0:4e20939af8bb | 140 | period_timer.stop(); |
Nikollao | 0:4e20939af8bb | 141 | /// calculate the time taken between the two rises to find period |
Nikollao | 0:4e20939af8bb | 142 | ref_period = period_timer.read(); |
Nikollao | 0:4e20939af8bb | 143 | /// frequency is the inverse of the signal period |
Nikollao | 0:4e20939af8bb | 144 | ref_freq = 1/ref_period; |
Nikollao | 0:4e20939af8bb | 145 | /// reset timer |
Nikollao | 0:4e20939af8bb | 146 | period_timer.reset(); |
Nikollao | 0:4e20939af8bb | 147 | /// increase counter because we only want to calculate once per cycle |
Nikollao | 0:4e20939af8bb | 148 | /// if we want to actively track the ref_freq we should decrease counter |
Nikollao | 0:4e20939af8bb | 149 | g_counter++; |
Nikollao | 0:4e20939af8bb | 150 | } |
Nikollao | 0:4e20939af8bb | 151 | } |
Nikollao | 0:4e20939af8bb | 152 | |
Nikollao | 0:4e20939af8bb | 153 | void setupK64Fclocks() { |
Nikollao | 0:4e20939af8bb | 154 | if(1) { |
Nikollao | 0:4e20939af8bb | 155 | uint32_t div1=0,div2=0,busClk=0,adcClk=0; |
Nikollao | 0:4e20939af8bb | 156 | SystemCoreClockUpdate(); |
Nikollao | 0:4e20939af8bb | 157 | pc.printf("SystemCoreClock= %u \r\n",SystemCoreClock); |
Nikollao | 0:4e20939af8bb | 158 | /// System Core Clock: 120 MHz |
Nikollao | 0:4e20939af8bb | 159 | div1=( (SIM->CLKDIV1) & SIM_CLKDIV1_OUTDIV1_MASK)>>SIM_CLKDIV1_OUTDIV1_SHIFT; |
Nikollao | 0:4e20939af8bb | 160 | div1=1+div1; |
Nikollao | 0:4e20939af8bb | 161 | div2=1+( (SIM->CLKDIV1) & SIM_CLKDIV1_OUTDIV2_MASK)>>SIM_CLKDIV1_OUTDIV2_SHIFT; |
Nikollao | 0:4e20939af8bb | 162 | busClk=SystemCoreClock*div1/div2; |
Nikollao | 0:4e20939af8bb | 163 | pc.printf("Divider1== %u div2=%u \r\n",div1,div2); |
Nikollao | 0:4e20939af8bb | 164 | pc.printf("MCGOUTCLK= %u, busClk = %u \r\n",SystemCoreClock*div1,busClk); |
Nikollao | 0:4e20939af8bb | 165 | /// MCGOUTCLK 120 MHz, Bus Clock = 120 MHz |
Nikollao | 1:bf693859586c | 166 | ADC1->SC3 &= ~ADC_SC3_AVGE_MASK;//disable averages |
Nikollao | 1:bf693859586c | 167 | ADC1->CFG1 &= ~ADC_CFG1_ADLPC_MASK;//high-power mode |
Nikollao | 1:bf693859586c | 168 | ADC1->CFG1 &= ~0x0063 ; //clears ADICLK and ADIV |
Nikollao | 1:bf693859586c | 169 | ADC1->CFG1 |= ADC_CFG1_ADIV(2); //divide clock 0=/1, 1=/2, 2=/4, 3=/8 |
Nikollao | 0:4e20939af8bb | 170 | //ADC0->SC3 |= 0x0007;//enable 32 averages |
Nikollao | 0:4e20939af8bb | 171 | |
Nikollao | 1:bf693859586c | 172 | if (((ADC1->CFG1)& 0x03) == 0) adcClk = busClk/(0x01<<(((ADC1->CFG1)&0x60)>>5)); |
Nikollao | 1:bf693859586c | 173 | if (((ADC1->SC3)& 0x04) != 0) adcClk = adcClk/(0x01<<(((ADC1->SC3)&0x03)+2)); |
Nikollao | 0:4e20939af8bb | 174 | pc.printf("adcCLK= %u \r\n",adcClk); |
Nikollao | 0:4e20939af8bb | 175 | /// ADC Clock: 60 MHz |
Nikollao | 0:4e20939af8bb | 176 | } |
Nikollao | 0:4e20939af8bb | 177 | } |
Nikollao | 0:4e20939af8bb | 178 | |
Nikollao | 0:4e20939af8bb | 179 | void offset_isr() { |
Nikollao | 0:4e20939af8bb | 180 | g_offset_flag = 1; |
Nikollao | 0:4e20939af8bb | 181 | } |
Nikollao | 0:4e20939af8bb | 182 | |
Nikollao | 0:4e20939af8bb | 183 | void output_isr() { |
Nikollao | 0:4e20939af8bb | 184 | g_output_flag = 1; |
Nikollao | 0:4e20939af8bb | 185 | } |
Nikollao | 0:4e20939af8bb | 186 | |
Nikollao | 0:4e20939af8bb | 187 | void initDAC() { |
Nikollao | 0:4e20939af8bb | 188 | DAC0->C0 = 0; |
Nikollao | 0:4e20939af8bb | 189 | DAC0->C1 = 0; //reset DAC state |
Nikollao | 0:4e20939af8bb | 190 | DAC0->C0 = DAC_C0_DACEN_MASK | DAC_C0_DACSWTRG_MASK| DAC_C0_DACRFS_MASK; |
Nikollao | 0:4e20939af8bb | 191 | } |
Nikollao | 2:c9b24787d5e1 | 192 | void lcd_intro() |
Nikollao | 2:c9b24787d5e1 | 193 | { |
Nikollao | 3:dd4eb355f8d9 | 194 | pc.baud(115200); |
Nikollao | 3:dd4eb355f8d9 | 195 | joyButton.rise(&joyButton_isr); ///assign rise with ISR |
Nikollao | 3:dd4eb355f8d9 | 196 | joyButton.mode(PullDown); ///use PullDown mode |
Nikollao | 3:dd4eb355f8d9 | 197 | swButton.rise(&swButton_isr); ///assign rise with ISR |
Nikollao | 3:dd4eb355f8d9 | 198 | swButton.mode(PullDown); ///use PullDown mode |
Nikollao | 2:c9b24787d5e1 | 199 | lcd.init(); |
Nikollao | 2:c9b24787d5e1 | 200 | lcd.setBrightness(0.7); // put LED backlight on 50% |
Nikollao | 2:c9b24787d5e1 | 201 | lcd.printString("THE CIRCUIT IS",1,1); |
Nikollao | 2:c9b24787d5e1 | 202 | lcd.printString("A FAST LIA!",7,3); |
Nikollao | 2:c9b24787d5e1 | 203 | lcd.refresh(); |
Nikollao | 2:c9b24787d5e1 | 204 | Timeout timeout; |
Nikollao | 2:c9b24787d5e1 | 205 | timeout.attach(&timeout_isr,3); |
Nikollao | 2:c9b24787d5e1 | 206 | sleep(); |
Nikollao | 2:c9b24787d5e1 | 207 | lcd.clear(); |
Nikollao | 2:c9b24787d5e1 | 208 | } |
Nikollao | 2:c9b24787d5e1 | 209 | |
Nikollao | 2:c9b24787d5e1 | 210 | void settings_menu() |
Nikollao | 2:c9b24787d5e1 | 211 | { |
Nikollao | 2:c9b24787d5e1 | 212 | lcd.setBrightness(0.7); // put LED backlight on 50% |
Nikollao | 2:c9b24787d5e1 | 213 | menu_ticker.attach(&menu_isr,0.2); |
Nikollao | 2:c9b24787d5e1 | 214 | |
Nikollao | 2:c9b24787d5e1 | 215 | while (exit_menu == 0) { |
Nikollao | 2:c9b24787d5e1 | 216 | if (g_menu_flag == 1) { |
Nikollao | 2:c9b24787d5e1 | 217 | g_menu_flag = 0; |
Nikollao | 2:c9b24787d5e1 | 218 | |
Nikollao | 2:c9b24787d5e1 | 219 | updateJoystick(); |
Nikollao | 3:dd4eb355f8d9 | 220 | init_LIA_menu(); |
Nikollao | 3:dd4eb355f8d9 | 221 | setup_selector(); |
Nikollao | 3:dd4eb355f8d9 | 222 | |
Nikollao | 3:dd4eb355f8d9 | 223 | lcd.refresh(); |
Nikollao | 3:dd4eb355f8d9 | 224 | |
Nikollao | 3:dd4eb355f8d9 | 225 | |
Nikollao | 3:dd4eb355f8d9 | 226 | } |
Nikollao | 3:dd4eb355f8d9 | 227 | sleep(); |
Nikollao | 3:dd4eb355f8d9 | 228 | } |
Nikollao | 3:dd4eb355f8d9 | 229 | menu_ticker.detach(); |
Nikollao | 3:dd4eb355f8d9 | 230 | } |
Nikollao | 3:dd4eb355f8d9 | 231 | |
Nikollao | 3:dd4eb355f8d9 | 232 | void init_LIA_menu() { |
Nikollao | 3:dd4eb355f8d9 | 233 | lcd.clear(); |
Nikollao | 2:c9b24787d5e1 | 234 | |
Nikollao | 2:c9b24787d5e1 | 235 | lcd.printString("Settings:",0,0); |
Nikollao | 2:c9b24787d5e1 | 236 | |
Nikollao | 2:c9b24787d5e1 | 237 | char gain_char[20]; ///create an array of chars |
Nikollao | 3:dd4eb355f8d9 | 238 | |
Nikollao | 3:dd4eb355f8d9 | 239 | sprintf(gain_char,"%.2f",var_gain); ///create string |
Nikollao | 2:c9b24787d5e1 | 240 | |
Nikollao | 2:c9b24787d5e1 | 241 | char speed_char[20]; ///create an array of chars |
Nikollao | 3:dd4eb355f8d9 | 242 | sprintf(speed_char,"%.2f",var_speed); ///create string |
Nikollao | 2:c9b24787d5e1 | 243 | |
Nikollao | 3:dd4eb355f8d9 | 244 | lcd.printString("Gain: ",0,1); |
Nikollao | 3:dd4eb355f8d9 | 245 | lcd.printString(gain_char,35,2); |
Nikollao | 3:dd4eb355f8d9 | 246 | lcd.printString("Speed (ms)",0,3); |
Nikollao | 3:dd4eb355f8d9 | 247 | lcd.printString(speed_char,35,4); |
Nikollao | 3:dd4eb355f8d9 | 248 | lcd.printString("Confirm",0,5); |
Nikollao | 3:dd4eb355f8d9 | 249 | } |
Nikollao | 3:dd4eb355f8d9 | 250 | |
Nikollao | 3:dd4eb355f8d9 | 251 | void setup_selector() |
Nikollao | 3:dd4eb355f8d9 | 252 | { |
Nikollao | 3:dd4eb355f8d9 | 253 | switch (joystick.direction) { ///check the direction of joystick |
Nikollao | 3:dd4eb355f8d9 | 254 | case UP: |
Nikollao | 3:dd4eb355f8d9 | 255 | menu_option--; |
Nikollao | 3:dd4eb355f8d9 | 256 | break; |
Nikollao | 3:dd4eb355f8d9 | 257 | case DOWN: |
Nikollao | 3:dd4eb355f8d9 | 258 | menu_option++; |
Nikollao | 3:dd4eb355f8d9 | 259 | break; |
Nikollao | 3:dd4eb355f8d9 | 260 | case RIGHT: |
Nikollao | 3:dd4eb355f8d9 | 261 | switch (menu_option) { |
Nikollao | 3:dd4eb355f8d9 | 262 | case 0: |
Nikollao | 3:dd4eb355f8d9 | 263 | var_gain += 0.1; |
Nikollao | 3:dd4eb355f8d9 | 264 | if (var_gain > 3) |
Nikollao | 3:dd4eb355f8d9 | 265 | var_gain = 0.1; |
Nikollao | 3:dd4eb355f8d9 | 266 | break; |
Nikollao | 3:dd4eb355f8d9 | 267 | case 1: |
Nikollao | 3:dd4eb355f8d9 | 268 | var_speed++; |
Nikollao | 3:dd4eb355f8d9 | 269 | if (var_speed > 10) |
Nikollao | 3:dd4eb355f8d9 | 270 | var_speed = 1; |
Nikollao | 3:dd4eb355f8d9 | 271 | break; |
Nikollao | 3:dd4eb355f8d9 | 272 | } |
Nikollao | 3:dd4eb355f8d9 | 273 | break; |
Nikollao | 3:dd4eb355f8d9 | 274 | case LEFT: |
Nikollao | 3:dd4eb355f8d9 | 275 | switch (menu_option) { |
Nikollao | 3:dd4eb355f8d9 | 276 | case 0: |
Nikollao | 3:dd4eb355f8d9 | 277 | var_gain -= 0.1; |
Nikollao | 3:dd4eb355f8d9 | 278 | if (var_gain < 0.1) |
Nikollao | 3:dd4eb355f8d9 | 279 | var_gain = 3; |
Nikollao | 3:dd4eb355f8d9 | 280 | break; |
Nikollao | 3:dd4eb355f8d9 | 281 | case 1: |
Nikollao | 3:dd4eb355f8d9 | 282 | var_speed--; |
Nikollao | 3:dd4eb355f8d9 | 283 | if (var_speed < 1) |
Nikollao | 3:dd4eb355f8d9 | 284 | var_speed = 10; |
Nikollao | 3:dd4eb355f8d9 | 285 | break; |
Nikollao | 3:dd4eb355f8d9 | 286 | } |
Nikollao | 3:dd4eb355f8d9 | 287 | break; |
Nikollao | 3:dd4eb355f8d9 | 288 | } |
Nikollao | 3:dd4eb355f8d9 | 289 | if (menu_option < 0) { /// if the last (down) option is set for selection and user presses joystick down, selector moves at the top |
Nikollao | 3:dd4eb355f8d9 | 290 | menu_option = 2; |
Nikollao | 3:dd4eb355f8d9 | 291 | } |
Nikollao | 3:dd4eb355f8d9 | 292 | if (menu_option > 2) { /// if the first (up) option is set for selection and user presses joystick up, selector moves at the bottom |
Nikollao | 3:dd4eb355f8d9 | 293 | menu_option = 0; |
Nikollao | 3:dd4eb355f8d9 | 294 | } |
Nikollao | 3:dd4eb355f8d9 | 295 | |
Nikollao | 3:dd4eb355f8d9 | 296 | if (menu_option == 0) { ///selection in menu depends on the value of int option |
Nikollao | 3:dd4eb355f8d9 | 297 | lcd.drawCircle(75,10,3,1); |
Nikollao | 3:dd4eb355f8d9 | 298 | } else if (menu_option == 1) { |
Nikollao | 3:dd4eb355f8d9 | 299 | lcd.drawCircle(75,27,3,1); |
Nikollao | 3:dd4eb355f8d9 | 300 | } else if (menu_option == 2) { |
Nikollao | 3:dd4eb355f8d9 | 301 | lcd.drawCircle(55,43,3,1); |
Nikollao | 3:dd4eb355f8d9 | 302 | if (g_joyButton_flag == 1) { |
Nikollao | 3:dd4eb355f8d9 | 303 | g_joyButton_flag = 0; |
Nikollao | 3:dd4eb355f8d9 | 304 | confirmationJoyButton(); |
Nikollao | 2:c9b24787d5e1 | 305 | } |
Nikollao | 3:dd4eb355f8d9 | 306 | } |
Nikollao | 3:dd4eb355f8d9 | 307 | g_joyButton_flag = 0; |
Nikollao | 3:dd4eb355f8d9 | 308 | } |
Nikollao | 3:dd4eb355f8d9 | 309 | |
Nikollao | 3:dd4eb355f8d9 | 310 | void confirmationJoyButton () { |
Nikollao | 3:dd4eb355f8d9 | 311 | |
Nikollao | 3:dd4eb355f8d9 | 312 | bool confirm = 1; |
Nikollao | 3:dd4eb355f8d9 | 313 | while (confirm) { |
Nikollao | 3:dd4eb355f8d9 | 314 | lcd.clear(); |
Nikollao | 3:dd4eb355f8d9 | 315 | lcd.printString("Continue ?",0,0); |
Nikollao | 3:dd4eb355f8d9 | 316 | lcd.printString("Yes",0,2); |
Nikollao | 3:dd4eb355f8d9 | 317 | lcd.printString("No",0,3); |
Nikollao | 3:dd4eb355f8d9 | 318 | updateJoystick(); |
Nikollao | 3:dd4eb355f8d9 | 319 | switch (joystick.direction) { ///check the direction of joystick |
Nikollao | 3:dd4eb355f8d9 | 320 | case UP: |
Nikollao | 3:dd4eb355f8d9 | 321 | save_option--; |
Nikollao | 3:dd4eb355f8d9 | 322 | break; |
Nikollao | 3:dd4eb355f8d9 | 323 | case DOWN: |
Nikollao | 3:dd4eb355f8d9 | 324 | save_option++; |
Nikollao | 3:dd4eb355f8d9 | 325 | break; |
Nikollao | 3:dd4eb355f8d9 | 326 | } |
Nikollao | 3:dd4eb355f8d9 | 327 | |
Nikollao | 3:dd4eb355f8d9 | 328 | if (save_option < 0) { /// if the last (down) option is set for selection and user presses joystick down, selector moves at the top |
Nikollao | 3:dd4eb355f8d9 | 329 | save_option = 1; |
Nikollao | 3:dd4eb355f8d9 | 330 | } |
Nikollao | 3:dd4eb355f8d9 | 331 | if (save_option > 1) { /// if the first (up) option is set for selection and user presses joystick up, selector moves at the bottom |
Nikollao | 3:dd4eb355f8d9 | 332 | save_option = 0; |
Nikollao | 3:dd4eb355f8d9 | 333 | } |
Nikollao | 3:dd4eb355f8d9 | 334 | |
Nikollao | 3:dd4eb355f8d9 | 335 | if (save_option == 0) { |
Nikollao | 3:dd4eb355f8d9 | 336 | lcd.drawCircle(30,19,3,1); |
Nikollao | 3:dd4eb355f8d9 | 337 | } |
Nikollao | 3:dd4eb355f8d9 | 338 | else if (save_option == 1) { |
Nikollao | 3:dd4eb355f8d9 | 339 | lcd.drawCircle(30,28,3,1); |
Nikollao | 3:dd4eb355f8d9 | 340 | } |
Nikollao | 3:dd4eb355f8d9 | 341 | if (g_swButton_flag == 1) { |
Nikollao | 3:dd4eb355f8d9 | 342 | g_swButton_flag = 0; |
Nikollao | 3:dd4eb355f8d9 | 343 | if (save_option == 0) { |
Nikollao | 3:dd4eb355f8d9 | 344 | confirm = 0; // exit continue |
Nikollao | 3:dd4eb355f8d9 | 345 | exit_menu = 1; // exit menu |
Nikollao | 3:dd4eb355f8d9 | 346 | } |
Nikollao | 3:dd4eb355f8d9 | 347 | else if (save_option == 1) { |
Nikollao | 3:dd4eb355f8d9 | 348 | confirm = 0; // just exit continue |
Nikollao | 3:dd4eb355f8d9 | 349 | } |
Nikollao | 3:dd4eb355f8d9 | 350 | } |
Nikollao | 3:dd4eb355f8d9 | 351 | lcd.refresh(); |
Nikollao | 2:c9b24787d5e1 | 352 | sleep(); |
Nikollao | 2:c9b24787d5e1 | 353 | } |
Nikollao | 2:c9b24787d5e1 | 354 | } |
Nikollao | 2:c9b24787d5e1 | 355 | |
Nikollao | 2:c9b24787d5e1 | 356 | void menu_isr() { |
Nikollao | 2:c9b24787d5e1 | 357 | g_menu_flag = 1; |
Nikollao | 2:c9b24787d5e1 | 358 | } |
Nikollao | 2:c9b24787d5e1 | 359 | |
Nikollao | 2:c9b24787d5e1 | 360 | void timeout_isr() {} |
Nikollao | 2:c9b24787d5e1 | 361 | |
Nikollao | 3:dd4eb355f8d9 | 362 | void joyButton_isr() { |
Nikollao | 3:dd4eb355f8d9 | 363 | g_joyButton_flag = 1; |
Nikollao | 3:dd4eb355f8d9 | 364 | } |
Nikollao | 3:dd4eb355f8d9 | 365 | |
Nikollao | 3:dd4eb355f8d9 | 366 | |
Nikollao | 3:dd4eb355f8d9 | 367 | void swButton_isr() { |
Nikollao | 3:dd4eb355f8d9 | 368 | g_swButton_flag = 1; |
Nikollao | 3:dd4eb355f8d9 | 369 | } |
Nikollao | 3:dd4eb355f8d9 | 370 | |
Nikollao | 2:c9b24787d5e1 | 371 | void calibrateJoystick() |
Nikollao | 2:c9b24787d5e1 | 372 | { |
Nikollao | 2:c9b24787d5e1 | 373 | // must not move during calibration |
Nikollao | 2:c9b24787d5e1 | 374 | joystick.x0 = xPot; // initial positions in the range 0.0 to 1.0 (0.5 if centred exactly) |
Nikollao | 2:c9b24787d5e1 | 375 | joystick.y0 = yPot; |
Nikollao | 2:c9b24787d5e1 | 376 | } |
Nikollao | 2:c9b24787d5e1 | 377 | |
Nikollao | 2:c9b24787d5e1 | 378 | void updateJoystick() |
Nikollao | 2:c9b24787d5e1 | 379 | { |
Nikollao | 2:c9b24787d5e1 | 380 | // read current joystick values relative to calibrated values (in range -0.5 to 0.5, 0.0 is centred) |
Nikollao | 2:c9b24787d5e1 | 381 | joystick.x = xPot - joystick.x0; |
Nikollao | 2:c9b24787d5e1 | 382 | joystick.y = yPot - joystick.y0; |
Nikollao | 2:c9b24787d5e1 | 383 | // read button state |
Nikollao | 3:dd4eb355f8d9 | 384 | joystick.button = joyButton; |
Nikollao | 2:c9b24787d5e1 | 385 | |
Nikollao | 2:c9b24787d5e1 | 386 | // calculate direction depending on x,y values |
Nikollao | 2:c9b24787d5e1 | 387 | // tolerance allows a little lee-way in case joystick not exactly in the stated direction |
Nikollao | 2:c9b24787d5e1 | 388 | if ( fabs(joystick.y) < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { |
Nikollao | 2:c9b24787d5e1 | 389 | joystick.direction = CENTRE; |
Nikollao | 2:c9b24787d5e1 | 390 | } else if ( joystick.y > DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { |
Nikollao | 2:c9b24787d5e1 | 391 | joystick.direction = UP; |
Nikollao | 2:c9b24787d5e1 | 392 | } else if ( joystick.y < DIRECTION_TOLERANCE && fabs(joystick.x) < DIRECTION_TOLERANCE) { |
Nikollao | 2:c9b24787d5e1 | 393 | joystick.direction = DOWN; |
Nikollao | 2:c9b24787d5e1 | 394 | } else if ( joystick.x > DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { |
Nikollao | 3:dd4eb355f8d9 | 395 | joystick.direction = LEFT; |
Nikollao | 2:c9b24787d5e1 | 396 | } else if ( joystick.x < DIRECTION_TOLERANCE && fabs(joystick.y) < DIRECTION_TOLERANCE) { |
Nikollao | 3:dd4eb355f8d9 | 397 | joystick.direction = RIGHT; |
Nikollao | 3:dd4eb355f8d9 | 398 | }/* |
Nikollao | 3:dd4eb355f8d9 | 399 | else if (joystick.y > DIRECTION_TOLERANCE && joystick.x < DIRECTION_TOLERANCE) { |
Nikollao | 2:c9b24787d5e1 | 400 | joystick.direction = UP_LEFT; |
Nikollao | 2:c9b24787d5e1 | 401 | } else if (joystick.y > DIRECTION_TOLERANCE && joystick.x > DIRECTION_TOLERANCE) { |
Nikollao | 2:c9b24787d5e1 | 402 | joystick.direction = UP_RIGHT; |
Nikollao | 2:c9b24787d5e1 | 403 | } else if (joystick.y < DIRECTION_TOLERANCE && joystick.x < DIRECTION_TOLERANCE) { |
Nikollao | 2:c9b24787d5e1 | 404 | joystick.direction = DOWN_LEFT; |
Nikollao | 2:c9b24787d5e1 | 405 | } else if (joystick.y < DIRECTION_TOLERANCE && joystick.x > DIRECTION_TOLERANCE) { |
Nikollao | 2:c9b24787d5e1 | 406 | joystick.direction = DOWN_RIGHT; |
Nikollao | 3:dd4eb355f8d9 | 407 | } |
Nikollao | 3:dd4eb355f8d9 | 408 | */ |
Nikollao | 2:c9b24787d5e1 | 409 | } |