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