【Arduino开源项目】LCR(电感/电容/电阻)电桥测试仪

【Arduino开源项目】LCR(电感/电容/电阻)电桥测试仪


提供了不同驱动屏幕显示的Hex文件。以及源文件,不多介绍了,感兴趣的可以自行下载下来看,地址已经使用的镜像地址访问应该没有问题。

在这里插入图片描述
在这里插入图片描述

这次带来的是外网开源的LCD1602显示的简易版LRC,只能测试电电感,电容,电阻,电容的ESR值没法测试。与上面的开源项目不属于同一个项目。

在这里插入图片描述

原理图

在这里插入图片描述
在这里插入图片描述

  • 绘制了一张Proteus图作为使用说明
    在这里插入图片描述

程序代码

#include <LiquidCrystal.h>

LiquidCrystal lcd(13, 8, 7, 5, 4, 2);

#define R_1 A1
#define R_2 A2
#define IND_1 6
#define IND_2 12
#define fuente_pin 11
#define switch_pin 10
#define descarga_pin 9

#define PIN_1 A3
#define PIN_2 A4

//Variables leer pines
int pin_1;
int pin_2;

//Variables para inductometro
double pulso;
double frecuencia;
double capacitancia;
double inductancia;

//Capacimetro
float R = 1.0e6;
float C = 0;
float RC = 0;
unsigned long t_inicio = 0;//获取Arduino开机后运行的时间长度,单位为微秒
volatile long t_alto = 0;
long T = 0;
float VCC = 4.50;
float Vref = VCC / 2;
float V0 = 0;
float error_correccion = 40.;
int retardo_delay = 20;


//Variables resistometro
int vR_1 = 0;
int vR_2 = 0;
float Vin = 5;
float Vout = 0;
float Res_1 = 10000;
float Res_2 = 9000000;
float r_1 = 0;
float r_2 = 0;
float Resistor_1[8];
float Resistor_2[5];
float ResArreglo_1;
float ResArreglo_2;

void setup() {
  lcd.begin(16, 2);

  //Configuracion de pines
  pinMode(PIN_1, INPUT);
  pinMode(PIN_2, INPUT);
  //Configuracion Inductometro
  pinMode(IND_1, INPUT);
  pinMode(IND_2, OUTPUT);
  capacitancia = 0.000001021;
  //delay(200);
  //Configuracion de Resistometro
  pinMode(R_1, INPUT);
  pinMode(R_2, INPUT);

  //Configuracion Capacimetro
  attachInterrupt(3, stop, RISING);//上升沿触发,外部中断引脚改到3号引脚(2号引脚被LCD1602占用)
  Vref = VCC / 2;
  pinMode(fuente_pin, OUTPUT);
  digitalWrite(fuente_pin, LOW);
  pinMode(switch_pin, INPUT);
  pinMode(descarga_pin, INPUT);
}

void loop() {
  leerpines();
/***************A3=0且A4=0时, 测量电感值*********************/
  if (pin_1 == LOW && pin_2 == LOW) {
    digitalWrite(IND_2, HIGH);
    delay(5);
    digitalWrite(IND_2, LOW);

    delayMicroseconds(100);

    pulso = pulseIn(IND_1, HIGH, 5000);
    lcd.clear();
    if (pulso > 0.1) {
      frecuencia = 1.E6 / (2 * pulso);
      inductancia = 1. / (capacitancia * frecuencia * frecuencia * 4.*3.1459 * 3.14159);
      inductancia *= 1E6;

      lcd.setCursor(2, 0);
      lcd.print("INDUCTANCIA:");
      //delay(200);
      if (inductancia >= 1000) {
        lcd.setCursor(0, 1);
        int valor = (inductancia / 1000) - 0.5;
        lcd.print(valor);
        lcd.setCursor(6, 1);
        lcd.print("mH");
      } else {
        lcd.setCursor(0, 1);
        int valor_2 = inductancia + 10;
        lcd.print(valor_2);
        lcd.setCursor(6, 1);
        lcd.print("uH");
      }
    } else if (pulso < 0.1) {
      lcd.setCursor(2, 0);
      lcd.print("INSERTAR IND");
    }
    delay(300);

  }
/***************A3=0且A4=1时, 测量电阻值*********************/
  if (pin_1 == LOW && pin_2 == HIGH) {
    lcd.clear();
    for (int i = 0 ; i <= 7; i++) {
      Resistor_1[i] = analogRead(R_1);
      ResArreglo_1 = ResArreglo_1 + Resistor_1[i];
    }
    vR_1 = (ResArreglo_1 / 8.0);
    Vout = (Vin * vR_1) / 1023;
    r_1 = Res_1 * (1 / ((Vin / Vout) - 1));
    lcd.setCursor(2, 0);
    lcd.print("RESISTENCIA:");
    if (r_1 <= 999) {
      lcd.setCursor(0, 1);
      lcd.print(r_1);
      lcd.setCursor(9, 1);
      lcd.print("Omhs");
    } else if (r_1 >= 1000) {
      r_1 = r_1 / 1000;
      lcd.setCursor(0, 1);
      lcd.print(r_1);
      lcd.setCursor(9, 1);
      lcd.print("KOmhs");
    }
    delay(500);
    ResArreglo_1 = 0;
  }
/***************A3=1且A4=0时, 测量电容值*********************/
  if (pin_1 == HIGH && pin_2 == LOW) {
    lcd.clear();
 /***************同时按下switch_pin,才开始测量电容值*********************/  
    if (debounce(switch_pin) == LOW)
    {
      pinMode(descarga_pin, OUTPUT);
      digitalWrite(descarga_pin, LOW);
      delay(100);
      pinMode(descarga_pin, INPUT);
      digitalWrite(fuente_pin, HIGH);
      t_inicio = micros();

    }

    if (t_alto > 0 && t_inicio > 0 && (t_alto - t_inicio) > 0 )
    {
      T = (t_alto - t_inicio);
      RC = -T / log((Vref - VCC) / (V0 - VCC));
      //Vref = VCC/2
      //V0 = 0V
      C = RC / R;		//测量电容公式
      lcd.setCursor(0, 0);
      lcd.print("C:");
      lcd.setCursor(3, 0);
      lcd.print(C * 1000, 1);
      lcd.setCursor(13, 0);
      lcd.print("nF");
      lcd.setCursor(0, 1);
      lcd.print("C:");
      lcd.setCursor(3, 1);
      lcd.print(C * 1000000 - error_correccion , 0);
      lcd.setCursor(13, 1);
      lcd.print("pF");

      t_inicio = 0;
      t_alto = 0;

      digitalWrite(fuente_pin, LOW);
      delay(2000);
    }
  }
}
/***************读取A3和A4引脚值*********************/
void leerpines() {
  pin_1 = digitalRead(PIN_1);
  pin_2 = digitalRead(PIN_2);
}

void stop()
{
  t_alto = micros();
}

int debounce(int pin)
{
  int estado;
  int previo_estado;
  previo_estado = digitalRead(pin);
  for (int i = 0; i < retardo_delay; i++)
  {
    delay(1);
    estado = digitalRead(pin);
    if ( estado != previo_estado)
    {
      i = 0;
      previo_estado = estado;
    }
  }
  return estado;
}
LCD1602+PCF8574转I2C接口的程序

由于I2C接口的SDA和SCL接口与A4和A5,是共用的,所以将代码中的相关引脚定义改动了一下,将PIN_1和PIN_2引脚的定义换成其他未使用的引脚

#include <Wire.h>
#include <LiquidCrystal_I2C.h>//点击这里会自动打开管理库页面: http://librarymanager/All#LiquidCrystal_I2C

LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display


#define R_1 A1
#define R_2 A2
#define IND_1 6
#define IND_2 12
#define fuente_pin 11
#define switch_pin 10
#define descarga_pin 9

#define PIN_1 5
#define PIN_2 7

//Variables leer pines
int pin_1;
int pin_2;

//Variables para inductometro
double pulso;
double frecuencia;
double capacitancia;
double inductancia;

//Capacimetro
float R = 1.0e6;
float C = 0;
float RC = 0;
long t_inicio = 0;
volatile long t_alto = 0;
long T = 0;
float VCC = 4.50;
float Vref = VCC / 2;
float V0 = 0;
float error_correccion = 40.;
int retardo_delay = 20;


//Variables resistometro
int vR_1 = 0;
int vR_2 = 0;
float Vin = 5;
float Vout = 0;
float Res_1 = 10000;
float Res_2 = 9000000;
float r_1 = 0;
float r_2 = 0;
float Resistor_1[8];
float Resistor_2[5];
float ResArreglo_1;
float ResArreglo_2;

void setup() {
    lcd.init();
  lcd.backlight();

  //Configuracion de pines
  pinMode(PIN_1, INPUT);
  pinMode(PIN_2, INPUT);
  //Configuracion Inductometro
  pinMode(IND_1, INPUT);
  pinMode(IND_2, OUTPUT);
  capacitancia = 0.000001021;
  //delay(200);
  //Configuracion de Resistometro
  pinMode(R_1, INPUT);
  pinMode(R_2, INPUT);

  //Configuracion Capacimetro
  attachInterrupt(3, stop, RISING);
  Vref = VCC / 2;
  pinMode(fuente_pin, OUTPUT);
  digitalWrite(fuente_pin, LOW);
  pinMode(switch_pin, INPUT);
  pinMode(descarga_pin, INPUT);
}

void loop() {
  leerpines();

  if (pin_1 == LOW && pin_2 == LOW) {
    digitalWrite(IND_2, HIGH);
    delay(5);
    digitalWrite(IND_2, LOW);

    delayMicroseconds(100);

    pulso = pulseIn(IND_1, HIGH, 5000);
    lcd.clear();
    if (pulso > 0.1) {
      frecuencia = 1.E6 / (2 * pulso);
      inductancia = 1. / (capacitancia * frecuencia * frecuencia * 4.*3.1459 * 3.14159);
      inductancia *= 1E6;

      lcd.setCursor(2, 0);
      lcd.print("INDUCTANCIA:");
      //delay(200);
      if (inductancia >= 1000) {
        lcd.setCursor(0, 1);
        int valor = (inductancia / 1000) - 0.5;
        lcd.print(valor);
        lcd.setCursor(6, 1);
        lcd.print("mH");
      } else {
        lcd.setCursor(0, 1);
        int valor_2 = inductancia + 10;
        lcd.print(valor_2);
        lcd.setCursor(6, 1);
        lcd.print("uH");
      }
    } else if (pulso < 0.1) {
      lcd.setCursor(2, 0);
      lcd.print("INSERTAR IND");
    }
    delay(300);

  }

  if (pin_1 == LOW && pin_2 == HIGH) {
    lcd.clear();
    for (int i = 0 ; i <= 7; i++) {
      Resistor_1[i] = analogRead(R_1);
      ResArreglo_1 = ResArreglo_1 + Resistor_1[i];
    }
    vR_1 = (ResArreglo_1 / 8.0);
    Vout = (Vin * vR_1) / 1023;
    r_1 = Res_1 * (1 / ((Vin / Vout) - 1));
    lcd.setCursor(2, 0);
    lcd.print("RESISTENCIA:");
    if (r_1 <= 999) {
      lcd.setCursor(0, 1);
      lcd.print(r_1);
      lcd.setCursor(9, 1);
      lcd.print("Omhs");
    } else if (r_1 >= 1000) {
      r_1 = r_1 / 1000;
      lcd.setCursor(0, 1);
      lcd.print(r_1);
      lcd.setCursor(9, 1);
      lcd.print("KOmhs");
    }
    delay(500);
    ResArreglo_1 = 0;
  }

  if (pin_1 == HIGH && pin_2 == LOW) {
    lcd.clear();
    if (debounce(switch_pin) == LOW)
    {
      pinMode(descarga_pin, OUTPUT);
      digitalWrite(descarga_pin, LOW);
      delay(100);
      pinMode(descarga_pin, INPUT);
      digitalWrite(fuente_pin, HIGH);
      t_inicio = micros();

    }

    if (t_alto > 0 && t_inicio > 0 && (t_alto - t_inicio) > 0 )
    {
      T = (t_alto - t_inicio);
      RC = -T / log((Vref - VCC) / (V0 - VCC));
      //Vref = VCC/2
      //V0 = 0V
      C = RC / R;				//Valor en uF



      lcd.setCursor(0, 0);
      lcd.print("C:");
      lcd.setCursor(3, 0);
      lcd.print(C * 1000, 1);
      lcd.setCursor(13, 0);
      lcd.print("nF");
      lcd.setCursor(0, 1);
      lcd.print("C:");
      lcd.setCursor(3, 1);
      lcd.print(C * 1000000 - error_correccion , 0);
      lcd.setCursor(13, 1);
      lcd.print("pF");

      t_inicio = 0;
      t_alto = 0;

      digitalWrite(fuente_pin, LOW);
      delay(2000);
    }
  }
}

void leerpines() {
  pin_1 = digitalRead(PIN_1);
  pin_2 = digitalRead(PIN_2);
}

void stop()
{
  t_alto = micros();
}

int debounce(int pin)
{
  int estado;
  int previo_estado;
  previo_estado = digitalRead(pin);
  for (int i = 0; i < retardo_delay; i++)
  {
    delay(1);
    estado = digitalRead(pin);
    if ( estado != previo_estado)
    {
      i = 0;
      previo_estado = estado;
    }
  }
  return estado;
}
该音频数字电桥,比较简单,但设计这个电路并不断改进,前后花费了近一个月时间。 数字电桥电路设计基本状况: 工作频率: 100Hz,1kHz,7.813kHz 最小分辨:最小分辨0.5毫欧,0.03uH,0.02pF 最大分辨:G欧 基本量程精度:1kHz基本量程精度,0.5%,选好电阻,精心制作,可以轻松达到0.25%精度 AD非线性误差小于0.05%,AD零点误差采用直流偏置消除 信号源:软件合成正弦DDS、软件合成方波DDS 显示:4LED 单片机:STC12C5A60S2 该LCR表的具体特性: AD转换器的字数:约1000字,采用了过采样技术,有效分辨力约为2000字 测量方法:准桥式测定,测量原理类似于比例法测电阻。 主要测量范围:1欧至0.5兆欧,精度0.5%(理论),阻抗实测比对,均未超过0.3% 有效测量范围:2毫欧至10兆欧,最小分辨力1毫欧 串联残余误差:2毫欧,低阻测量时此误差不可忽略 并联残余误差:50M欧,高阻测量时此误差不可忽略 Q值误差:±0.003(Q2,相对误差,简易算法),其它按0.5%左右估算 D值误差:±0.003(D2,相对误差,简易算法),其它按0.5%左右估算 注意:Q = 1/D 测试信号幅度:峰值200mV(100Hz),180mV(1kHz),140mV(7.8kHz) 电感:0.02uH分辨力,测量范围0.1uH至500H,超出500H未测试(因为我没有更大的电感器)。 电容:分辨力与夹具有关。夹具好的话,分辨0.1pF或0.05pF,不屏蔽只能分辨到0.2pF,甚至只有1pF。上限测量,没有测试,只测过10000uF电容,手上没有更大的电容。 实测误差,比上述精度指标好许多。 本表基准源:分别为4个基准电阻,一个时间基准。电阻基准就是电桥的4个下臂电阻,要求精度达到0.1%,对1%精度的金属膜电阻筛选即可。时间基准用32MHz石英晶振得到,精度可以满足电桥要求的。如果电阻达不到要求,可以使用软件校准。 频率精度:实际频率为99.18Hz、999.45Hz、7812.5Hz,简写为(100Hz、1kHz、7.8kHz)。由于DDS的频率分辨力有限,所以不采用整数频率。频率精度约为0.02%(由石英晶振决定)。 信号源失真度:没有专用仪器测试,只做估测。对输出信号做一次高通滤波后,用示波器观察,未发现可觉察失真。如果有可觉察失真,对D值测量有小量一些影响。 LCR开关式相敏检波器的检波效率分析图: 高精度音频数字电桥PCB截图: LCR表驱动程序部分展示:
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值