Transistor Gijutsu, October 2014, Special Features Chapter 7,Software of the LCRmeter トランジスタ技術2014年10月号 特集第7章のソフトウェア,サバイバルLCRメータ
Dependencies: mbed
main.cpp@0:b3e41ec91adf, 2014-08-28 (annotated)
- Committer:
- Dance
- Date:
- Thu Aug 28 07:09:42 2014 +0000
- Revision:
- 0:b3e41ec91adf
????????2014?10?????7????????
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Dance | 0:b3e41ec91adf | 1 | // |
Dance | 0:b3e41ec91adf | 2 | // Transistor Gijutu - LPC11U35 ARM Writer |
Dance | 0:b3e41ec91adf | 3 | // LCR meter |
Dance | 0:b3e41ec91adf | 4 | // |
Dance | 0:b3e41ec91adf | 5 | #include "mbed.h" |
Dance | 0:b3e41ec91adf | 6 | #include "parts.h" |
Dance | 0:b3e41ec91adf | 7 | |
Dance | 0:b3e41ec91adf | 8 | #include "lcd_P4bit.h" |
Dance | 0:b3e41ec91adf | 9 | |
Dance | 0:b3e41ec91adf | 10 | #define IPC 25 // interrupt per cycle |
Dance | 0:b3e41ec91adf | 11 | #define PI 3.14159265358979 |
Dance | 0:b3e41ec91adf | 12 | |
Dance | 0:b3e41ec91adf | 13 | int ps1k = 0; // pre-scaler for measure freq. |
Dance | 0:b3e41ec91adf | 14 | int sintable[] = { 8, 9, 11, 12, 13, 14, 14, 14, 14, 13, 12, 10, 8, 7, 5, 3, 2, 1, 1, 1, 1, 2, 3, 4, 6 }; |
Dance | 0:b3e41ec91adf | 15 | double Vraw[IPC], Iraw[IPC]; // AD convert data |
Dance | 0:b3e41ec91adf | 16 | int VorI; |
Dance | 0:b3e41ec91adf | 17 | double vcalc[IPC], icalc[IPC]; // waveform buffer for calc. |
Dance | 0:b3e41ec91adf | 18 | |
Dance | 0:b3e41ec91adf | 19 | Ticker f25k; // interval timer - make sine wave and measure current and voltage |
Dance | 0:b3e41ec91adf | 20 | |
Dance | 0:b3e41ec91adf | 21 | DigitalOut sine0(P0_14); // R2R DAC bit 0 |
Dance | 0:b3e41ec91adf | 22 | DigitalOut sine1(P0_2); // R2R DAC bit 1 |
Dance | 0:b3e41ec91adf | 23 | DigitalOut sine2(P0_23); // R2R DAC bit 2 |
Dance | 0:b3e41ec91adf | 24 | DigitalOut sine3(P0_17); // R2R DAC bit 3 |
Dance | 0:b3e41ec91adf | 25 | DigitalOut ISRflag(P0_20); // interrupt service routine flag |
Dance | 0:b3e41ec91adf | 26 | |
Dance | 0:b3e41ec91adf | 27 | AnalogIn Voltage(p20); // Voltage ADC |
Dance | 0:b3e41ec91adf | 28 | AnalogIn Current(p19); // Current ADC |
Dance | 0:b3e41ec91adf | 29 | |
Dance | 0:b3e41ec91adf | 30 | // 50KHz interval interrupt |
Dance | 0:b3e41ec91adf | 31 | void interval_25k() { |
Dance | 0:b3e41ec91adf | 32 | ISRflag = 1; |
Dance | 0:b3e41ec91adf | 33 | ++ ps1k; |
Dance | 0:b3e41ec91adf | 34 | if( IPC <= ps1k ) { |
Dance | 0:b3e41ec91adf | 35 | ps1k = 0; |
Dance | 0:b3e41ec91adf | 36 | VorI = !VorI; |
Dance | 0:b3e41ec91adf | 37 | } |
Dance | 0:b3e41ec91adf | 38 | sine0 = sintable[ps1k] & 0x01; // DAC output - each bit |
Dance | 0:b3e41ec91adf | 39 | sine1 = sintable[ps1k] & 0x02; |
Dance | 0:b3e41ec91adf | 40 | sine2 = sintable[ps1k] & 0x04; |
Dance | 0:b3e41ec91adf | 41 | sine3 = sintable[ps1k] & 0x08; |
Dance | 0:b3e41ec91adf | 42 | // |
Dance | 0:b3e41ec91adf | 43 | if( VorI ) Vraw[ps1k] = Voltage.read(); // measure Voltage or Current |
Dance | 0:b3e41ec91adf | 44 | else Iraw[ps1k] = Current.read(); |
Dance | 0:b3e41ec91adf | 45 | ISRflag = 0; |
Dance | 0:b3e41ec91adf | 46 | } |
Dance | 0:b3e41ec91adf | 47 | |
Dance | 0:b3e41ec91adf | 48 | int main() { |
Dance | 0:b3e41ec91adf | 49 | int i; |
Dance | 0:b3e41ec91adf | 50 | char s[10]; |
Dance | 0:b3e41ec91adf | 51 | double vi, vq, ii, iq; // voltage/current, in-phase,quad-phase -> vi + jvq, ii + jiq |
Dance | 0:b3e41ec91adf | 52 | double r, x; // register, reactance -> r + jx |
Dance | 0:b3e41ec91adf | 53 | double a; // amplitude |
Dance | 0:b3e41ec91adf | 54 | |
Dance | 0:b3e41ec91adf | 55 | // work area initialize |
Dance | 0:b3e41ec91adf | 56 | VorI = 0; |
Dance | 0:b3e41ec91adf | 57 | for( i = 0; IPC > i; i ++ ) Vraw[i] = Iraw[i] = 0.0; |
Dance | 0:b3e41ec91adf | 58 | // LCD module initialize |
Dance | 0:b3e41ec91adf | 59 | LCD_iniz(); |
Dance | 0:b3e41ec91adf | 60 | // start interval interrupt |
Dance | 0:b3e41ec91adf | 61 | f25k.attach_us( &interval_25k, FREQ / IPC ); |
Dance | 0:b3e41ec91adf | 62 | // LCD test |
Dance | 0:b3e41ec91adf | 63 | LCD_cmd( 0x80 ); |
Dance | 0:b3e41ec91adf | 64 | LCD_puts( "LCR Mete" ); |
Dance | 0:b3e41ec91adf | 65 | LCD_cmd( 0xC0 ); |
Dance | 0:b3e41ec91adf | 66 | LCD_puts( "r V0.0" ); |
Dance | 0:b3e41ec91adf | 67 | // Main routine |
Dance | 0:b3e41ec91adf | 68 | for( ; ; ) { |
Dance | 0:b3e41ec91adf | 69 | // copy raw data to calc. buffer |
Dance | 0:b3e41ec91adf | 70 | for( i = 0; IPC > i; i ++ ) vcalc[i] = Vraw[i], icalc[i] = Iraw[i]; |
Dance | 0:b3e41ec91adf | 71 | // calc. in-phase and quad-phase |
Dance | 0:b3e41ec91adf | 72 | vi = vq = ii = iq = 0.0; |
Dance | 0:b3e41ec91adf | 73 | for( i = 0; IPC > i; i ++ ) { |
Dance | 0:b3e41ec91adf | 74 | a = 2 * PI * (double)i / (double)IPC; |
Dance | 0:b3e41ec91adf | 75 | vi = vi + vcalc[i] * sin( a ); |
Dance | 0:b3e41ec91adf | 76 | vq = vq + vcalc[i] * cos( a ); |
Dance | 0:b3e41ec91adf | 77 | ii = ii - icalc[i] * sin( a ); |
Dance | 0:b3e41ec91adf | 78 | iq = iq - icalc[i] * cos( a ); |
Dance | 0:b3e41ec91adf | 79 | } |
Dance | 0:b3e41ec91adf | 80 | // gain calc. |
Dance | 0:b3e41ec91adf | 81 | a = ( R3 * ( R4 + R5 ) ) / ( R4 * ( R2 + R3 ) ); |
Dance | 0:b3e41ec91adf | 82 | vi /= a; // voltage real |
Dance | 0:b3e41ec91adf | 83 | vq /= a; // voltage imaginary |
Dance | 0:b3e41ec91adf | 84 | ii /= R1; // current real |
Dance | 0:b3e41ec91adf | 85 | iq /= R1; // current immaginary |
Dance | 0:b3e41ec91adf | 86 | // divide : Z = v / i |
Dance | 0:b3e41ec91adf | 87 | if( 0.0 != ii || 0.0 != iq ) { |
Dance | 0:b3e41ec91adf | 88 | a = ii * ii + iq * iq; |
Dance | 0:b3e41ec91adf | 89 | r = ( ( vi * ii ) + ( vq * iq ) ) / a; |
Dance | 0:b3e41ec91adf | 90 | x = ( ( vq * ii ) - ( vi * iq ) ) / a; |
Dance | 0:b3e41ec91adf | 91 | } |
Dance | 0:b3e41ec91adf | 92 | else { |
Dance | 0:b3e41ec91adf | 93 | r = 999999.9, x = 999999.9; // hi-Z |
Dance | 0:b3e41ec91adf | 94 | } |
Dance | 0:b3e41ec91adf | 95 | // display R |
Dance | 0:b3e41ec91adf | 96 | if( 1000.0 > r ) sprintf( s, "R%4.1f ", r ); |
Dance | 0:b3e41ec91adf | 97 | else if( 10000.0 > r ) sprintf( s, "R%2.3fK ", r / 1000.0 ); |
Dance | 0:b3e41ec91adf | 98 | else if( 100000.0 > r ) sprintf( s, "R%3.2fK ", r / 1000.0 ); |
Dance | 0:b3e41ec91adf | 99 | else sprintf( s, "R ----- " ); |
Dance | 0:b3e41ec91adf | 100 | LCD_cmd( 0x80 ); |
Dance | 0:b3e41ec91adf | 101 | LCD_puts( s ); |
Dance | 0:b3e41ec91adf | 102 | // display X |
Dance | 0:b3e41ec91adf | 103 | if( 0 < x ) { |
Dance | 0:b3e41ec91adf | 104 | // inductance |
Dance | 0:b3e41ec91adf | 105 | x = x / ( 2.0 * PI * FREQ ); // H |
Dance | 0:b3e41ec91adf | 106 | if( 1.0 > x ) sprintf( s, "L%4.1fm ", x * 1000.0 ); |
Dance | 0:b3e41ec91adf | 107 | else if( 10.0 > x ) sprintf( s, "L%2.3f ", x ); |
Dance | 0:b3e41ec91adf | 108 | else if( 100.0 > x ) sprintf( s, "L%3.2f ", x ); |
Dance | 0:b3e41ec91adf | 109 | else sprintf( s, "L ----- " ); |
Dance | 0:b3e41ec91adf | 110 | } |
Dance | 0:b3e41ec91adf | 111 | else { |
Dance | 0:b3e41ec91adf | 112 | // capacitance |
Dance | 0:b3e41ec91adf | 113 | x = -1000000.0 / ( x * 2.0 * PI * FREQ ); // uF |
Dance | 0:b3e41ec91adf | 114 | if( 1.0 > x ) sprintf( s, "C%4.1fn ", x * 1000.0 ); |
Dance | 0:b3e41ec91adf | 115 | else if( 10.0 > x ) sprintf( s, "C%2.3fu ", x ); |
Dance | 0:b3e41ec91adf | 116 | else if( 100.0 > x ) sprintf( s, "C%3.2fu ", x ); |
Dance | 0:b3e41ec91adf | 117 | else sprintf( s, "C ----- " ); |
Dance | 0:b3e41ec91adf | 118 | } |
Dance | 0:b3e41ec91adf | 119 | LCD_cmd( 0xC0 ); |
Dance | 0:b3e41ec91adf | 120 | LCD_puts( s ); |
Dance | 0:b3e41ec91adf | 121 | } |
Dance | 0:b3e41ec91adf | 122 | } |
Dance | 0:b3e41ec91adf | 123 |