Transistor Gijutsu, October 2014, Special Features Chapter 7,Software of the LCRmeter トランジスタ技術2014年10月号 特集第7章のソフトウェア,サバイバルLCRメータ
Dependencies: mbed
main.cpp
- Committer:
- Dance
- Date:
- 2014-08-28
- Revision:
- 0:b3e41ec91adf
File content as of revision 0:b3e41ec91adf:
// // Transistor Gijutu - LPC11U35 ARM Writer // LCR meter // #include "mbed.h" #include "parts.h" #include "lcd_P4bit.h" #define IPC 25 // interrupt per cycle #define PI 3.14159265358979 int ps1k = 0; // pre-scaler for measure freq. 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 }; double Vraw[IPC], Iraw[IPC]; // AD convert data int VorI; double vcalc[IPC], icalc[IPC]; // waveform buffer for calc. Ticker f25k; // interval timer - make sine wave and measure current and voltage DigitalOut sine0(P0_14); // R2R DAC bit 0 DigitalOut sine1(P0_2); // R2R DAC bit 1 DigitalOut sine2(P0_23); // R2R DAC bit 2 DigitalOut sine3(P0_17); // R2R DAC bit 3 DigitalOut ISRflag(P0_20); // interrupt service routine flag AnalogIn Voltage(p20); // Voltage ADC AnalogIn Current(p19); // Current ADC // 50KHz interval interrupt void interval_25k() { ISRflag = 1; ++ ps1k; if( IPC <= ps1k ) { ps1k = 0; VorI = !VorI; } sine0 = sintable[ps1k] & 0x01; // DAC output - each bit sine1 = sintable[ps1k] & 0x02; sine2 = sintable[ps1k] & 0x04; sine3 = sintable[ps1k] & 0x08; // if( VorI ) Vraw[ps1k] = Voltage.read(); // measure Voltage or Current else Iraw[ps1k] = Current.read(); ISRflag = 0; } int main() { int i; char s[10]; double vi, vq, ii, iq; // voltage/current, in-phase,quad-phase -> vi + jvq, ii + jiq double r, x; // register, reactance -> r + jx double a; // amplitude // work area initialize VorI = 0; for( i = 0; IPC > i; i ++ ) Vraw[i] = Iraw[i] = 0.0; // LCD module initialize LCD_iniz(); // start interval interrupt f25k.attach_us( &interval_25k, FREQ / IPC ); // LCD test LCD_cmd( 0x80 ); LCD_puts( "LCR Mete" ); LCD_cmd( 0xC0 ); LCD_puts( "r V0.0" ); // Main routine for( ; ; ) { // copy raw data to calc. buffer for( i = 0; IPC > i; i ++ ) vcalc[i] = Vraw[i], icalc[i] = Iraw[i]; // calc. in-phase and quad-phase vi = vq = ii = iq = 0.0; for( i = 0; IPC > i; i ++ ) { a = 2 * PI * (double)i / (double)IPC; vi = vi + vcalc[i] * sin( a ); vq = vq + vcalc[i] * cos( a ); ii = ii - icalc[i] * sin( a ); iq = iq - icalc[i] * cos( a ); } // gain calc. a = ( R3 * ( R4 + R5 ) ) / ( R4 * ( R2 + R3 ) ); vi /= a; // voltage real vq /= a; // voltage imaginary ii /= R1; // current real iq /= R1; // current immaginary // divide : Z = v / i if( 0.0 != ii || 0.0 != iq ) { a = ii * ii + iq * iq; r = ( ( vi * ii ) + ( vq * iq ) ) / a; x = ( ( vq * ii ) - ( vi * iq ) ) / a; } else { r = 999999.9, x = 999999.9; // hi-Z } // display R if( 1000.0 > r ) sprintf( s, "R%4.1f ", r ); else if( 10000.0 > r ) sprintf( s, "R%2.3fK ", r / 1000.0 ); else if( 100000.0 > r ) sprintf( s, "R%3.2fK ", r / 1000.0 ); else sprintf( s, "R ----- " ); LCD_cmd( 0x80 ); LCD_puts( s ); // display X if( 0 < x ) { // inductance x = x / ( 2.0 * PI * FREQ ); // H if( 1.0 > x ) sprintf( s, "L%4.1fm ", x * 1000.0 ); else if( 10.0 > x ) sprintf( s, "L%2.3f ", x ); else if( 100.0 > x ) sprintf( s, "L%3.2f ", x ); else sprintf( s, "L ----- " ); } else { // capacitance x = -1000000.0 / ( x * 2.0 * PI * FREQ ); // uF if( 1.0 > x ) sprintf( s, "C%4.1fn ", x * 1000.0 ); else if( 10.0 > x ) sprintf( s, "C%2.3fu ", x ); else if( 100.0 > x ) sprintf( s, "C%3.2fu ", x ); else sprintf( s, "C ----- " ); } LCD_cmd( 0xC0 ); LCD_puts( s ); } }