Transistor Gijutsu, October 2014, Special Features Chapter 7,Software of the LCRmeter トランジスタ技術2014年10月号 特集第7章のソフトウェア,サバイバルLCRメータ

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //
00002 // Transistor Gijutu - LPC11U35 ARM Writer
00003 // LCR meter
00004 //
00005 #include "mbed.h"
00006 #include "parts.h"
00007 
00008 #include "lcd_P4bit.h"
00009 
00010 #define IPC 25 // interrupt per cycle
00011 #define PI 3.14159265358979
00012 
00013 int ps1k = 0;   // pre-scaler for measure freq.
00014 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 };
00015 double Vraw[IPC], Iraw[IPC];    // AD convert data
00016 int VorI;
00017 double vcalc[IPC], icalc[IPC];  // waveform buffer for calc.
00018 
00019 Ticker f25k;    // interval timer - make sine wave and measure current and voltage
00020 
00021 DigitalOut sine0(P0_14);    // R2R DAC bit 0
00022 DigitalOut sine1(P0_2);     // R2R DAC bit 1
00023 DigitalOut sine2(P0_23);    // R2R DAC bit 2
00024 DigitalOut sine3(P0_17);    // R2R DAC bit 3
00025 DigitalOut ISRflag(P0_20);  // interrupt service routine flag
00026 
00027 AnalogIn Voltage(p20);  // Voltage ADC
00028 AnalogIn Current(p19);  // Current ADC
00029 
00030 // 50KHz interval interrupt
00031 void interval_25k() {   
00032   ISRflag = 1;
00033   ++ ps1k;
00034   if( IPC <= ps1k ) {
00035     ps1k = 0;
00036     VorI = !VorI;
00037   }
00038   sine0 = sintable[ps1k] & 0x01;    // DAC output - each bit
00039   sine1 = sintable[ps1k] & 0x02;
00040   sine2 = sintable[ps1k] & 0x04;
00041   sine3 = sintable[ps1k] & 0x08;
00042 //
00043   if( VorI ) Vraw[ps1k] = Voltage.read();    // measure Voltage or Current
00044   else       Iraw[ps1k] = Current.read();
00045   ISRflag = 0;
00046 }
00047 
00048 int main() {
00049   int i;
00050   char s[10];
00051   double vi, vq, ii, iq;    // voltage/current, in-phase,quad-phase -> vi + jvq, ii + jiq
00052   double r, x;      // register, reactance -> r + jx
00053   double a;     // amplitude
00054   
00055   // work area initialize
00056   VorI = 0;
00057   for( i = 0; IPC > i; i ++ ) Vraw[i] = Iraw[i] = 0.0; 
00058   // LCD module initialize
00059   LCD_iniz();
00060   // start interval interrupt
00061   f25k.attach_us( &interval_25k, FREQ / IPC );
00062   // LCD test
00063   LCD_cmd( 0x80 );
00064   LCD_puts( "LCR Mete" );
00065   LCD_cmd( 0xC0 );
00066   LCD_puts( "r V0.0" );
00067   // Main routine
00068   for( ; ; ) {
00069     // copy raw data to calc. buffer
00070     for( i = 0; IPC > i; i ++ ) vcalc[i] = Vraw[i], icalc[i] = Iraw[i];
00071     // calc. in-phase and quad-phase
00072     vi = vq = ii = iq = 0.0;
00073     for( i = 0; IPC > i; i ++ ) {
00074       a = 2 * PI * (double)i / (double)IPC;
00075       vi = vi + vcalc[i] * sin( a );
00076       vq = vq + vcalc[i] * cos( a );
00077       ii = ii - icalc[i] * sin( a );
00078       iq = iq - icalc[i] * cos( a );
00079     }
00080     // gain calc.
00081     a = ( R3 * ( R4 + R5 ) ) / ( R4 * ( R2 + R3 ) );
00082     vi /= a;    // voltage real
00083     vq /= a;    // voltage imaginary
00084     ii /= R1;   // current real
00085     iq /= R1;   // current immaginary
00086     // divide : Z = v / i
00087     if( 0.0 != ii || 0.0 != iq ) {
00088       a = ii * ii + iq * iq;
00089       r = ( ( vi * ii ) + ( vq * iq ) ) / a;
00090       x = ( ( vq * ii ) - ( vi * iq ) ) / a;
00091     }
00092     else {
00093       r = 999999.9, x = 999999.9;   // hi-Z
00094     }
00095     //  display R
00096     if( 1000.0 > r )        sprintf( s, "R%4.1f  ", r );
00097     else if( 10000.0 > r )  sprintf( s, "R%2.3fK ", r / 1000.0 );
00098     else if( 100000.0 > r ) sprintf( s, "R%3.2fK ", r / 1000.0 );
00099     else sprintf( s, "R ----- " );
00100     LCD_cmd( 0x80 );
00101     LCD_puts( s );
00102     // display X
00103     if( 0 < x ) {
00104       // inductance
00105       x = x / ( 2.0 * PI * FREQ );  // H
00106       if( 1.0 > x )        sprintf( s, "L%4.1fm ", x * 1000.0 );
00107       else if( 10.0 > x )  sprintf( s, "L%2.3f  ", x );
00108       else if( 100.0 > x ) sprintf( s, "L%3.2f  ", x );
00109       else sprintf( s, "L ----- " );
00110     }
00111     else {
00112       // capacitance
00113       x = -1000000.0 / ( x * 2.0 * PI * FREQ );    // uF
00114       if( 1.0 > x )        sprintf( s, "C%4.1fn ", x * 1000.0 );
00115       else if( 10.0 > x )  sprintf( s, "C%2.3fu ", x );
00116       else if( 100.0 > x ) sprintf( s, "C%3.2fu ", x );
00117       else sprintf( s, "C ----- " );
00118     }
00119     LCD_cmd( 0xC0 );
00120     LCD_puts( s );
00121   }
00122 }
00123