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.h@0:4e20939af8bb, 2017-08-21 (annotated)
- Committer:
- Nikollao
- Date:
- Mon Aug 21 11:22:14 2017 +0000
- Revision:
- 0:4e20939af8bb
- Child:
- 1:bf693859586c
LIA FAST DONE!
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Nikollao | 0:4e20939af8bb | 1 | /** |
Nikollao | 0:4e20939af8bb | 2 | @file main.h |
Nikollao | 0:4e20939af8bb | 3 | @brief Header file contains functions and variables |
Nikollao | 0:4e20939af8bb | 4 | @brief Fast Lock-In Amplifier - AC to DC converter |
Nikollao | 0:4e20939af8bb | 5 | @brief Revision 1.0 |
Nikollao | 0:4e20939af8bb | 6 | @author Nikollao Sulollari |
Nikollao | 0:4e20939af8bb | 7 | @Date 16/08/2017 |
Nikollao | 0:4e20939af8bb | 8 | */ |
Nikollao | 0:4e20939af8bb | 9 | |
Nikollao | 0:4e20939af8bb | 10 | #ifndef MAIN_H |
Nikollao | 0:4e20939af8bb | 11 | #define MAIN_H |
Nikollao | 0:4e20939af8bb | 12 | #include "mbed.h" |
Nikollao | 0:4e20939af8bb | 13 | |
Nikollao | 0:4e20939af8bb | 14 | #define DIRECTION_TOLERANCE 0.05 |
Nikollao | 0:4e20939af8bb | 15 | |
Nikollao | 0:4e20939af8bb | 16 | /** |
Nikollao | 0:4e20939af8bb | 17 | @namespace aout |
Nikollao | 0:4e20939af8bb | 18 | @brief Analog output DC filtered value |
Nikollao | 0:4e20939af8bb | 19 | */ |
Nikollao | 0:4e20939af8bb | 20 | AnalogOut aout(DAC0_OUT); |
Nikollao | 0:4e20939af8bb | 21 | |
Nikollao | 0:4e20939af8bb | 22 | /** |
Nikollao | 0:4e20939af8bb | 23 | @namespace gpo |
Nikollao | 0:4e20939af8bb | 24 | @brief Digital output set the D0 pin High/Low |
Nikollao | 0:4e20939af8bb | 25 | */ |
Nikollao | 0:4e20939af8bb | 26 | DigitalOut gpo(D0); |
Nikollao | 0:4e20939af8bb | 27 | |
Nikollao | 0:4e20939af8bb | 28 | /** |
Nikollao | 0:4e20939af8bb | 29 | @namespace ain |
Nikollao | 0:4e20939af8bb | 30 | @brief analog input which is the signal from the bolometer (THz detector) |
Nikollao | 0:4e20939af8bb | 31 | */ |
Nikollao | 0:4e20939af8bb | 32 | AnalogIn ain(A0); |
Nikollao | 0:4e20939af8bb | 33 | |
Nikollao | 0:4e20939af8bb | 34 | /** |
Nikollao | 0:4e20939af8bb | 35 | @namespace dref |
Nikollao | 0:4e20939af8bb | 36 | @brief event triggered interrupt used to calculate the reference frequency |
Nikollao | 0:4e20939af8bb | 37 | */ |
Nikollao | 0:4e20939af8bb | 38 | InterruptIn dref(D6); |
Nikollao | 0:4e20939af8bb | 39 | |
Nikollao | 0:4e20939af8bb | 40 | /** |
Nikollao | 0:4e20939af8bb | 41 | @namespace amp_ticker |
Nikollao | 0:4e20939af8bb | 42 | @brief time-triggered interrupt calculates the amplitude of the input signal |
Nikollao | 0:4e20939af8bb | 43 | */ |
Nikollao | 0:4e20939af8bb | 44 | Ticker offset_ticker; |
Nikollao | 0:4e20939af8bb | 45 | |
Nikollao | 0:4e20939af8bb | 46 | /** |
Nikollao | 0:4e20939af8bb | 47 | @namespace sample_ticker |
Nikollao | 0:4e20939af8bb | 48 | @brief time-triggered interrupt samples internal sine and cosine signals |
Nikollao | 0:4e20939af8bb | 49 | */ |
Nikollao | 0:4e20939af8bb | 50 | Ticker sample_ticker; |
Nikollao | 0:4e20939af8bb | 51 | |
Nikollao | 0:4e20939af8bb | 52 | /** |
Nikollao | 0:4e20939af8bb | 53 | @namespace output_ticker |
Nikollao | 0:4e20939af8bb | 54 | @brief time-triggered interrupt updates the output of Fast LIA |
Nikollao | 0:4e20939af8bb | 55 | */ |
Nikollao | 0:4e20939af8bb | 56 | Ticker output_ticker; |
Nikollao | 0:4e20939af8bb | 57 | |
Nikollao | 0:4e20939af8bb | 58 | /** |
Nikollao | 0:4e20939af8bb | 59 | @namespace period_timer |
Nikollao | 0:4e20939af8bb | 60 | @brief timer is used to calculate the frequency of the input square wave |
Nikollao | 0:4e20939af8bb | 61 | */ |
Nikollao | 0:4e20939af8bb | 62 | Timer period_timer; |
Nikollao | 0:4e20939af8bb | 63 | |
Nikollao | 0:4e20939af8bb | 64 | |
Nikollao | 0:4e20939af8bb | 65 | /** |
Nikollao | 0:4e20939af8bb | 66 | @namespace period_timer |
Nikollao | 0:4e20939af8bb | 67 | @brief timer updates the output of the LIA depending on the time constant |
Nikollao | 0:4e20939af8bb | 68 | */ |
Nikollao | 0:4e20939af8bb | 69 | Timer output_timer; |
Nikollao | 0:4e20939af8bb | 70 | /** |
Nikollao | 0:4e20939af8bb | 71 | @namespace lcd |
Nikollao | 0:4e20939af8bb | 72 | @brief object of the N5110 class |
Nikollao | 0:4e20939af8bb | 73 | */ |
Nikollao | 0:4e20939af8bb | 74 | //N5110 lcd(PTE26 , PTA0 , PTC4 , PTD0 , PTD2 , PTD1 , PTC3); |
Nikollao | 0:4e20939af8bb | 75 | |
Nikollao | 0:4e20939af8bb | 76 | |
Nikollao | 0:4e20939af8bb | 77 | /** |
Nikollao | 0:4e20939af8bb | 78 | @namespace pc |
Nikollao | 0:4e20939af8bb | 79 | @brief serial connection between mbed and pc |
Nikollao | 0:4e20939af8bb | 80 | */ |
Nikollao | 0:4e20939af8bb | 81 | Serial pc(USBTX,USBRX); |
Nikollao | 0:4e20939af8bb | 82 | |
Nikollao | 0:4e20939af8bb | 83 | /** |
Nikollao | 0:4e20939af8bb | 84 | @namespace DirectionName |
Nikollao | 0:4e20939af8bb | 85 | @brief define joystick's direction based on its x,y values |
Nikollao | 0:4e20939af8bb | 86 | */ |
Nikollao | 0:4e20939af8bb | 87 | enum DirectionName { |
Nikollao | 0:4e20939af8bb | 88 | UP, |
Nikollao | 0:4e20939af8bb | 89 | DOWN, |
Nikollao | 0:4e20939af8bb | 90 | LEFT, |
Nikollao | 0:4e20939af8bb | 91 | RIGHT, |
Nikollao | 0:4e20939af8bb | 92 | CENTRE, |
Nikollao | 0:4e20939af8bb | 93 | }; |
Nikollao | 0:4e20939af8bb | 94 | |
Nikollao | 0:4e20939af8bb | 95 | /** |
Nikollao | 0:4e20939af8bb | 96 | @namespace Joystick |
Nikollao | 0:4e20939af8bb | 97 | @brief create strcut Joystick |
Nikollao | 0:4e20939af8bb | 98 | */ |
Nikollao | 0:4e20939af8bb | 99 | typedef struct JoyStick Joystick; |
Nikollao | 0:4e20939af8bb | 100 | struct JoyStick { |
Nikollao | 0:4e20939af8bb | 101 | double x; /// current x value |
Nikollao | 0:4e20939af8bb | 102 | double x0; /// 'centred' x value |
Nikollao | 0:4e20939af8bb | 103 | double y; /// current y value |
Nikollao | 0:4e20939af8bb | 104 | double y0; /// 'centred' y value |
Nikollao | 0:4e20939af8bb | 105 | int button; /// button state (assume pull-down used, so 1 = pressed, 0 = unpressed) |
Nikollao | 0:4e20939af8bb | 106 | DirectionName direction; // current direction |
Nikollao | 0:4e20939af8bb | 107 | }; |
Nikollao | 0:4e20939af8bb | 108 | /// create struct variable |
Nikollao | 0:4e20939af8bb | 109 | Joystick joystick; |
Nikollao | 0:4e20939af8bb | 110 | |
Nikollao | 0:4e20939af8bb | 111 | /** |
Nikollao | 0:4e20939af8bb | 112 | set-up serial port |
Nikollao | 0:4e20939af8bb | 113 | */ |
Nikollao | 0:4e20939af8bb | 114 | void init_serial(); |
Nikollao | 0:4e20939af8bb | 115 | |
Nikollao | 0:4e20939af8bb | 116 | /** |
Nikollao | 0:4e20939af8bb | 117 | initialise lcd and serial |
Nikollao | 0:4e20939af8bb | 118 | */ |
Nikollao | 0:4e20939af8bb | 119 | void program_init(); |
Nikollao | 0:4e20939af8bb | 120 | |
Nikollao | 0:4e20939af8bb | 121 | /** |
Nikollao | 0:4e20939af8bb | 122 | use MCU in High Power Mode and set Core, ADC, and BUS clocks at max |
Nikollao | 0:4e20939af8bb | 123 | */ |
Nikollao | 0:4e20939af8bb | 124 | void setupK64Fclocks(); |
Nikollao | 0:4e20939af8bb | 125 | |
Nikollao | 0:4e20939af8bb | 126 | /** |
Nikollao | 0:4e20939af8bb | 127 | initialise DAC pin, otherwise AnalogOut (dac0_out) does not work |
Nikollao | 0:4e20939af8bb | 128 | */ |
Nikollao | 0:4e20939af8bb | 129 | void initDAC(); |
Nikollao | 0:4e20939af8bb | 130 | |
Nikollao | 0:4e20939af8bb | 131 | /** |
Nikollao | 0:4e20939af8bb | 132 | ISR sets flag to find Amplitude of bolometer signal |
Nikollao | 0:4e20939af8bb | 133 | */ |
Nikollao | 0:4e20939af8bb | 134 | void findAmplitude(); |
Nikollao | 0:4e20939af8bb | 135 | |
Nikollao | 0:4e20939af8bb | 136 | /** |
Nikollao | 0:4e20939af8bb | 137 | find the amplitude of the analog bolometer signal |
Nikollao | 0:4e20939af8bb | 138 | */ |
Nikollao | 0:4e20939af8bb | 139 | double max(int points); |
Nikollao | 0:4e20939af8bb | 140 | |
Nikollao | 0:4e20939af8bb | 141 | double mavg_filter(int filt_points); |
Nikollao | 0:4e20939af8bb | 142 | |
Nikollao | 0:4e20939af8bb | 143 | /** |
Nikollao | 0:4e20939af8bb | 144 | ISR sets flag to update LIA output |
Nikollao | 0:4e20939af8bb | 145 | */ |
Nikollao | 0:4e20939af8bb | 146 | void updateOutput(); |
Nikollao | 0:4e20939af8bb | 147 | |
Nikollao | 0:4e20939af8bb | 148 | /** |
Nikollao | 0:4e20939af8bb | 149 | ISR sets flag to mix signals |
Nikollao | 0:4e20939af8bb | 150 | */ |
Nikollao | 0:4e20939af8bb | 151 | void mixSignals(); |
Nikollao | 0:4e20939af8bb | 152 | |
Nikollao | 0:4e20939af8bb | 153 | /** |
Nikollao | 0:4e20939af8bb | 154 | performs digital mixing with refX and refY components |
Nikollao | 0:4e20939af8bb | 155 | */ |
Nikollao | 0:4e20939af8bb | 156 | void digitalMix(double remove_offset); |
Nikollao | 0:4e20939af8bb | 157 | |
Nikollao | 0:4e20939af8bb | 158 | /** |
Nikollao | 0:4e20939af8bb | 159 | moving average filter with n points (n = 17) |
Nikollao | 0:4e20939af8bb | 160 | */ |
Nikollao | 0:4e20939af8bb | 161 | void filterSignal(int averages); |
Nikollao | 0:4e20939af8bb | 162 | |
Nikollao | 0:4e20939af8bb | 163 | /** |
Nikollao | 0:4e20939af8bb | 164 | ISR calculates the DigitalIn signal frequency |
Nikollao | 0:4e20939af8bb | 165 | */ |
Nikollao | 0:4e20939af8bb | 166 | void voltageRise(); |
Nikollao | 0:4e20939af8bb | 167 | |
Nikollao | 0:4e20939af8bb | 168 | /** |
Nikollao | 0:4e20939af8bb | 169 | ISR calculates the offset of the bolometer signal |
Nikollao | 0:4e20939af8bb | 170 | */ |
Nikollao | 0:4e20939af8bb | 171 | void offset_isr(); |
Nikollao | 0:4e20939af8bb | 172 | |
Nikollao | 0:4e20939af8bb | 173 | void output_isr(); |
Nikollao | 0:4e20939af8bb | 174 | |
Nikollao | 0:4e20939af8bb | 175 | double calculate_constant(double freq_ref); |
Nikollao | 0:4e20939af8bb | 176 | |
Nikollao | 0:4e20939af8bb | 177 | /*!< used to assign the amplitude of the bolometer signal */ |
Nikollao | 0:4e20939af8bb | 178 | volatile double amplitude = 0; |
Nikollao | 0:4e20939af8bb | 179 | |
Nikollao | 0:4e20939af8bb | 180 | /*!< used to find the offset of the input signal */ |
Nikollao | 0:4e20939af8bb | 181 | volatile double outDC = 0; |
Nikollao | 0:4e20939af8bb | 182 | |
Nikollao | 0:4e20939af8bb | 183 | /*!< stores the period of the input digital signal */ |
Nikollao | 0:4e20939af8bb | 184 | volatile double ref_period = 0; |
Nikollao | 0:4e20939af8bb | 185 | |
Nikollao | 0:4e20939af8bb | 186 | /*!< stores the frequency of the input digital signal */ |
Nikollao | 0:4e20939af8bb | 187 | volatile double ref_freq = 0; |
Nikollao | 0:4e20939af8bb | 188 | |
Nikollao | 0:4e20939af8bb | 189 | /*!< counter is used to find take between two rises of digital signal*/ |
Nikollao | 0:4e20939af8bb | 190 | volatile int g_counter = 1; |
Nikollao | 0:4e20939af8bb | 191 | |
Nikollao | 0:4e20939af8bb | 192 | /*!< flag is set from ISR to find offset of the bolometer signal */ |
Nikollao | 0:4e20939af8bb | 193 | volatile int g_offset_flag = 0; |
Nikollao | 0:4e20939af8bb | 194 | |
Nikollao | 0:4e20939af8bb | 195 | /*!< sampling period to take n samples and find bolometer signal amplitude */ |
Nikollao | 0:4e20939af8bb | 196 | volatile double amplitude_delay = 0; |
Nikollao | 0:4e20939af8bb | 197 | |
Nikollao | 0:4e20939af8bb | 198 | /*!< flag used to update output */ |
Nikollao | 0:4e20939af8bb | 199 | volatile int g_output_flag = 0; |
Nikollao | 0:4e20939af8bb | 200 | |
Nikollao | 0:4e20939af8bb | 201 | /*!< flag used to sample internal sine/cosine signals */ |
Nikollao | 0:4e20939af8bb | 202 | volatile int g_sample_flag = 0; |
Nikollao | 0:4e20939af8bb | 203 | |
Nikollao | 0:4e20939af8bb | 204 | /*!< array stores the square root of X^2 and Y^2 */ |
Nikollao | 0:4e20939af8bb | 205 | volatile double R[16]; |
Nikollao | 0:4e20939af8bb | 206 | |
Nikollao | 0:4e20939af8bb | 207 | /*!< store the bolometer signal and find max value */ |
Nikollao | 0:4e20939af8bb | 208 | double bolometer_signal[8]; |
Nikollao | 0:4e20939af8bb | 209 | |
Nikollao | 0:4e20939af8bb | 210 | /*!< store the bolometer signal and find max value */ |
Nikollao | 0:4e20939af8bb | 211 | double bol_signal; |
Nikollao | 0:4e20939af8bb | 212 | //int size = 16; |
Nikollao | 0:4e20939af8bb | 213 | |
Nikollao | 0:4e20939af8bb | 214 | /*!< variable used if a sine/cosine of 8 discrete values is used */ |
Nikollao | 0:4e20939af8bb | 215 | int samples8 = 8; |
Nikollao | 0:4e20939af8bb | 216 | |
Nikollao | 0:4e20939af8bb | 217 | /*!< variable used if a sine/cosine of 17 discrete values is used */ |
Nikollao | 0:4e20939af8bb | 218 | int samples16 = 16; |
Nikollao | 0:4e20939af8bb | 219 | |
Nikollao | 0:4e20939af8bb | 220 | /*!< variable used if a sine/cosine of 32 discrete values is used */ |
Nikollao | 0:4e20939af8bb | 221 | int samples32 = 32; |
Nikollao | 0:4e20939af8bb | 222 | |
Nikollao | 0:4e20939af8bb | 223 | /*!< sampling frequency of the internal sine/cosine waves */ |
Nikollao | 0:4e20939af8bb | 224 | double sample_freq = 0; |
Nikollao | 0:4e20939af8bb | 225 | |
Nikollao | 0:4e20939af8bb | 226 | /*!< variable used to sample the internal sine/cosine waves */ |
Nikollao | 0:4e20939af8bb | 227 | double sample_time = 0; |
Nikollao | 0:4e20939af8bb | 228 | |
Nikollao | 0:4e20939af8bb | 229 | /*!< number of samples for the amplitude of the bolometer signal */ |
Nikollao | 0:4e20939af8bb | 230 | int amp_points = 32; |
Nikollao | 0:4e20939af8bb | 231 | |
Nikollao | 0:4e20939af8bb | 232 | /*!< sampling freq to find the amplitude of the bolomter signal */ |
Nikollao | 0:4e20939af8bb | 233 | double delay_freq = 0; |
Nikollao | 0:4e20939af8bb | 234 | |
Nikollao | 0:4e20939af8bb | 235 | /*!< read the timer and if it is equal to the time constant update output */ |
Nikollao | 0:4e20939af8bb | 236 | double time_out = 0; |
Nikollao | 0:4e20939af8bb | 237 | |
Nikollao | 0:4e20939af8bb | 238 | int filter_points = 500; |
Nikollao | 0:4e20939af8bb | 239 | |
Nikollao | 0:4e20939af8bb | 240 | double offset = 0; |
Nikollao | 0:4e20939af8bb | 241 | |
Nikollao | 0:4e20939af8bb | 242 | /*!< sine wave array with 32 values */ |
Nikollao | 0:4e20939af8bb | 243 | static double sin_array32[32] = {0, 0.1951, 0.3827, 0.5556, 0.7071, 0.8315, 0.9239, |
Nikollao | 0:4e20939af8bb | 244 | 0.9808, 1, 0.9808, 0.9239, 0.8315, 0.7071, 0.5556, |
Nikollao | 0:4e20939af8bb | 245 | 0.3827, 0.1951, 0, -0.1951, -0.3827, -0.5556, -0.7071, |
Nikollao | 0:4e20939af8bb | 246 | -0.8315, -0.9239, -0.9808, -1, -0.9808, -0.9239, -0.8315, |
Nikollao | 0:4e20939af8bb | 247 | -0.7071, -0.5556, -0.3827, -0.1951 |
Nikollao | 0:4e20939af8bb | 248 | }; |
Nikollao | 0:4e20939af8bb | 249 | |
Nikollao | 0:4e20939af8bb | 250 | /*!< cosine wave array with 32 values */ |
Nikollao | 0:4e20939af8bb | 251 | static double cos_array32[32] = {1, 0.9808, 0.9239, 0.8315, 0.7071, 0.5556, |
Nikollao | 0:4e20939af8bb | 252 | 0.3827, 0.1951, 0, -0.1951, -0.3827, -0.5556, -0.7071, |
Nikollao | 0:4e20939af8bb | 253 | -0.8315, -0.9239, -0.9808, -1, -0.9808, -0.9239, -0.8315, |
Nikollao | 0:4e20939af8bb | 254 | -0.7071, -0.5556, -0.3827, -0.1951, 0, 0.1951, 0.3827, |
Nikollao | 0:4e20939af8bb | 255 | 0.5556, 0.7071, 0.8315, 0.9239, 0.9808 |
Nikollao | 0:4e20939af8bb | 256 | }; |
Nikollao | 0:4e20939af8bb | 257 | |
Nikollao | 0:4e20939af8bb | 258 | /*!< sine wave array with 17 values */ |
Nikollao | 0:4e20939af8bb | 259 | static double sin_array16[16] = {0, 0.3827, 0.7071, 0.9239, 1, 0.9239, 0.7071, |
Nikollao | 0:4e20939af8bb | 260 | 0.3827, 0, -0.3827, -0.7071, -0.9239, -1, -0.9239 |
Nikollao | 0:4e20939af8bb | 261 | ,-0.7071, -0.3827, |
Nikollao | 0:4e20939af8bb | 262 | }; |
Nikollao | 0:4e20939af8bb | 263 | |
Nikollao | 0:4e20939af8bb | 264 | /*!< sine wave array with delay and 16 values, used for testing output */ |
Nikollao | 0:4e20939af8bb | 265 | static double sin_array16delay[16] = {0.7071, 0.9239, 1, 0.9239, 0.7071, |
Nikollao | 0:4e20939af8bb | 266 | 0.3827, 0, -0.3827, -0.7071, -0.9239, -1, -0.9239 |
Nikollao | 0:4e20939af8bb | 267 | ,-0.7071, -0.3827, 0, 0.3827 |
Nikollao | 0:4e20939af8bb | 268 | }; |
Nikollao | 0:4e20939af8bb | 269 | |
Nikollao | 0:4e20939af8bb | 270 | /*!< cosine wave array with 17 values */ |
Nikollao | 0:4e20939af8bb | 271 | static double cos_array16[16] = {1, 0.9239, 0.7071, |
Nikollao | 0:4e20939af8bb | 272 | 0.3827, 0, -0.3827, -0.7071, -0.9239, -1, -0.9239 |
Nikollao | 0:4e20939af8bb | 273 | ,-0.7071, -0.3827, 0, 0.3827, 0.7071, 0.9239, |
Nikollao | 0:4e20939af8bb | 274 | }; |
Nikollao | 0:4e20939af8bb | 275 | |
Nikollao | 0:4e20939af8bb | 276 | /*!< sine wave array with 8 values */ |
Nikollao | 0:4e20939af8bb | 277 | static double sin_array8[8] = {0, 0.7071, 1, 0.7071, 0, -0.7071, -1, -0.7071}; |
Nikollao | 0:4e20939af8bb | 278 | |
Nikollao | 0:4e20939af8bb | 279 | /*!< cosine wave array with 8 values */ |
Nikollao | 0:4e20939af8bb | 280 | static double cos_array8[8] = {1, 0.7071, 0, -0.7071, -1, -0.7071, 0, 0.7071}; |
Nikollao | 0:4e20939af8bb | 281 | |
Nikollao | 0:4e20939af8bb | 282 | #endif |