电源/新能源
如果您曾经使用过电池、SMPS 电路或其他电源电路,那么通常会发生您必须通过加载来测试您的电源,以检查它在不同负载条件下的性能。通常用于执行此类测试的设备称为恒流直流负载,它允许我们调整电源的输出电流,然后使其保持恒定,直到再次调整为止。在本教程中,我们将学习如何使用 Arduino 构建我们自己的可调电子负载,最大输入电压为 24V,漏极电流高达 5A。
该电路由三部分组成。第一部分是Arduino Nano部分,第二部分是数模转换器,第三部分是纯模拟电路,其中使用单个封装的双运算放大器来控制负载部分。这个项目的灵感来自于Arduino上的一篇文章,然而,为了降低复杂性,电路进行了更改,每个人都可以构建它的基本功能。
我们的电子负载设计有以下输入和输出部分。
两个输入开关,用于增加和减少负载。
显示设定负载、实际负载和负载电压的 LCD。
最大负载电流限制为 5A。
负载的最大输入电压为 24V。
所需材料
下面列出了构建直流电子负载所需的组件。
Arduino纳米
16x2 字符 LCD
两桶插座
MOSFET irf540n
麦克普4921
LM358
5 瓦分流电阻 0.1 欧姆
1k
10k - 6 个
散热器
.1uF 50v
2k - 2 个
Arduino直流电子负载电路图
在下面的示意图中,运算放大器有两个部分。一种是控制 MOSFET,另一种是放大感应电流。您还可以查看本页底部的视频,该视频解释了电路的完整工作。第一部分具有 R12、R13 和 MOSFET。R12 用于降低反馈部分的负载效应,R13 用作 Mosfet 栅极电阻。
额外的两个电阻器 R8 和 R9 用于检测将由该虚拟负载施加压力的电源的电源电压。根据分压器规则,这两个电阻最大支持 24V。超过 24V 会产生不适合 Arduino 引脚的电压。所以请注意不要连接输出电压超过 24V 的电源。
电阻 R7 是这里的实际负载电阻。它是一个 5 瓦、0.1 欧姆的电阻器。根据幂律,它将支持最大 7A (P = I 2 R),但为了安全起见,将最大负载电流限制为 5A 更为明智。因此,目前最大24V、5A的负载可以通过这个假负载来设置。
另一部分放大器被配置为增益放大器。它将提供 6 倍的增益。在电流流动期间,会出现电压降。例如,当 5A 电流流过电阻器时,根据欧姆定律,0.1 欧姆分流电阻器 (V = I x R) 两端的电压降将为 0.5V 。同相放大器会将其放大到 x6,因此 3V 将是放大器第二部分的输出。该输出将由 Arduino nano 模拟输入引脚感应,并计算电流。
放大器的第一部分配置为电压跟随器电路,它将根据输入电压控制 MOSFET,并由于流过分流电阻的负载电流而获得所需的反馈电压。
MCP4921是数模转换器。DAC 使用 SPI 通信协议从任何微控制器单元获取数字数据,并根据它提供模拟电压输出。该电压是运算放大器的输入。我们之前还学习了如何将这个MCP4921 DAC 与 PIC一起使用。
另一方面,有一个 Arduino Nano,它将通过SPI 协议将数字数据提供给 DAC并控制负载,同时以 16x2 字符显示屏显示数据。使用了两个额外的东西,即减少和增加按钮。它不是连接到数字引脚,而是连接到模拟引脚。因此,可以将其更改为另一种类型的开关,例如滑块或模拟编码器。此外,通过修改代码,可以提供原始模拟数据来控制负载。这也避免了开关抖动问题。
最后,通过增加负载,Arduino nano会将负载数据以数字格式提供给DAC,DAC将模拟数据提供给运放,运放根据运放的输入电压控制MOSFET 。 最后,根据流过分流电阻的负载电流,会出现一个电压降,该电压降将被 LM358 的第二通道进一步放大,并由 Arduino nano 得到。这将显示在字符显示屏上。当用户按下减少按钮时,也会发生同样的事情。
PCB 设计和 Gerber 文件
由于该电路具有高电流路径,因此使用适当的 PCB 设计策略来消除不需要的故障情况是一个更明智的选择。因此,为这种直流负载设计了 PCB。我使用 Eagle PCB 设计软件来设计我的 PCB。您可以选择任何 PCB Cad 软件。CAD软件中最终设计的PCB如下图所示,
在设计此 PCB 时需要注意的一个重要因素是使用厚电源层以使电流在整个电路中流动。还有接地缝合VIAS(接地平面中的随机过孔),用于在到顶部和底部的两层中实现适当的接地流。
拿到电路板后,您可以继续组装所有组件。我完成的电路板如下所示。
接下来,您可以上传代码并启动模块以检查它是如何工作的。该项目的完整代码在本页底部给出。代码解释如下。
可调直流负载的 Arduino 代码
代码非常简单。首先,我们包含了 SPI 和 LCD 头文件以及设置最大逻辑电压、片选引脚等。
#include#include #define SS_PIN 10 #define MAX_VOLT 5.0 // 最大逻辑电压 #define load_resistor 0.1 // 以欧姆为单位的分流电阻值 #define opamp_gain 6 // 运算放大器的增益 #define average 10 // 平均时间
本节包含所需的与程序流相关的整数和变量声明。此外,我们使用 Arduino Nano 设置关联的外围设备引脚。
常量 int slaveSelectPin = 10; // 片选引脚 int number = 0; int 增加 = A2; // 增加 pin int 减少 = A3; //减少引脚 int current_sense = A0; //电流检测引脚 int voltage_sense = A1; // 电压检测引脚 int state1 = 0; int state2 = 0; 诠释集= 0; 浮动电压 = 0; 浮动负载电流 = 0.0; 浮动负载电压= 0.0; 浮动电流 = 0.0; 浮动电压 = 0.0; 液晶液晶(7、6、5、4、3、2);// LCD 引脚
这用于 LCD 和 SPI 的设置。此外,引脚方向设置在这里。
void setup() { pinMode(slaveSelectPin, OUTPUT); pinMode(增加,输入); pinMode(减少,输入); pinMode(current_sense,输入); pinMode(电压感应,输入); // 初始化 SPI: SPI.begin(); //设置LCD的列数和行数: lcd.begin(16, 2); // 向 LCD 打印一条消息。 lcd.print("数字负载"); lcd.setCursor(0, 1); lcd.print("电路文摘"); 延迟(2000 年); }
它用于转换 DAC 值。
void convert_DAC(unsigned int value) { /*步长 = 2^n, 因此 12bit 2^12 = 4096 对于 5V 参考,步长将是 5/4095 = 0.0012210012210012V 或 1mV(大约)*/ unsigned int container ; 无符号整数 MSB; 无符号整数 LSB; /*步骤:1、将12位数据存入容器 假设数据为4095,二进制1111 1111 1111*/ container = value; /*步骤:2 创建虚拟 8 位。因此,通过除以 256,在 LSB 中捕获高 4 位 LSB = 0000 1111*/ LSB = container/256; /*Step: 3 发送配置打孔4位数据。 LSB = 0011 0000 或 0000 1111。结果为 0011 1111 */ LSB = (0x30) | 低位; /*Step:4 容器仍然有 21bit 的值。提取低 8 位。 1111 1111 和 1111 1111 1111。结果是 1111 1111,即 MSB*/ MSB = 0xFF & 容器; /*Step:4 将16bits的数据分成两个字节发送。*/ digitalWrite(slaveSelectPin, LOW); 延迟(100); SPI.传输(LSB); SPI.传输(MSB); 延迟(100); // 将 SS 引脚拉高以取消选择芯片: digitalWrite(slaveSelectPin, HIGH); }
本部分用于电流检测相关操作。
浮动 read_current (void){ load_current = 0; for (int a = 0; a <平均值; a++){ load_current = load_current + analogRead(current_sense); } 负载电流 = 负载电流 / 平均值; load_current = (load_current* MAX_VOLT) / 1024; load_current = (load_current / opamp_gain) / load_resistor; 返回负载电流; }
这用于读取负载电压。
浮动读取电压(无效){ load_voltage = 0; for (int a = 0; a <平均值; a++){ load_voltage = load_voltage + analogRead(voltage_sense); } 负载电压 = 负载电压 / 平均值; load_voltage = ((load_voltage * MAX_VOLT)/1024.0)*6; 返回负载电压; }
这是实际的循环。在这里,测量开关步骤并将数据发送到 DAC。传输数据后,正在测量实际电流和负载电压。这两个值也最终打印在 LCD 上。
无效循环(){ 状态1 =模拟读取(增加); if (state1 > 500){ 延迟(50); state1 = 模拟读取(增加); 如果 (state1 > 500){ 伏特 = 伏特+0.02; } } state2 = 模拟读取(减少); if (state2 > 500){ 延迟(50); state2 = 模拟读取(减少); if (state2 > 500){ if (volt == 0){ volt = 0; } 其他{ 伏 = 伏-0.02; } } } 数字 = 伏特 / 0.0012210012210012; convert_DAC(数字); 电压 = 读取电压(); 当前 = 读取电流(); lcd.setCursor(0, 0); lcd.print("设置值"); lcd.print("="); 设置=(伏特/2)*10000; lcd.print(设置); lcd.print("毫安"); lcd.setCursor(0, 1); lcd.print("我"); lcd.print("="); lcd.print(当前); lcd.print("一个"); lcd.print("V"); lcd.print("="); lcd.print(电压); // lcd.print(load_voltage); //lcd.print("mA"); // 延迟(1000); //lcd.clear(); }
测试我们的可调直流负载
数字负载电路采用 12V 电源焊接并通电。我在电源侧使用了我的 7.4V 锂电池,并连接了一个钳形表来检查它是如何工作的。正如您所看到的,当设定电流为 300mA 时,电路从电池中汲取 300mA 电流,该电流也由钳形表测量为 310mA。
#include
#include
#define SS_PIN 10
#define MAX_VOLT 5.0
#define load_resistor 0.1
#define opamp_gain 6
#define average 10
const int slaveSelectPin = 10;
整数 = 0;
int 增加 = A2;
int减少= A3;
诠释 current_sense = A0;
诠释电压感应= A1;
诠释状态1 = 0;
int state2 = 0;
诠释集= 0;
浮动电压 = 0;
浮动负载电流 = 0.0;
浮动负载电压= 0.0;
浮动电流 = 0.0;
浮动电压 = 0.0;
液晶液晶(7、6、5、4、3、2);
void setup() {
// 将 slaveSelectPin 设置为输出:
pinMode(slaveSelectPin,输出);
pinMode(增加,输入);// 声明 LED 为输出
pinMode(decrease, INPUT); // 将按钮声明为输入
pinMode(current_sense, INPUT); //
pinMode(voltage_sense, INPUT); //
// 初始化 SPI:
SPI.begin();
//设置LCD的列数和行数:
lcd.begin(16, 2);
// 向 LCD 打印一条消息。
lcd.print("数字负载");
lcd.setCursor(0, 1);
lcd.print("电路文摘");
延迟(2000 年);
}
void convert_DAC(unsigned int value)
{
/*步长 = 2^n, 因此 12bit 2^12 = 4096
对于 5V 参考,步长为 5/4095 = 0.0012210012210012V 或 1mV(大约)*/
unsigned int container ;
无符号整数 MSB;
无符号整数 LSB;
/*步骤:1、将12位数据存入容器
假设数据为4095,二进制1111 1111 1111*/
container = value;
/*步骤:2 创建虚拟 8 位。因此,通过除以 256,在 LSB 中捕获高 4 位
LSB = 0000 1111*/
LSB = container/256;
/*Step: 3 发送配置打孔4位数据。
LSB = 0011 0000 或 0000 1111。结果为 0011 1111 */
LSB = (0x30) | 低位;
/*Step:4 容器仍然有 21bit 的值。提取低 8 位。
1111 1111 和 1111 1111 1111。结果是 1111 1111,即 MSB*/
MSB = 0xFF & 容器;
/*Step:4 将16bits的数据分成两个字节发送。*/
digitalWrite(slaveSelectPin, LOW);
延迟(100);
SPI.传输(LSB);
SPI.传输(MSB);
延迟(100);
// 将 SS 引脚拉高以取消选择芯片:
digitalWrite(slaveSelectPin, HIGH);
}
浮动 read_current (void){
load_current = 0;
for (int a = 0; a <平均值; a++){
load_current = load_current + analogRead(current_sense);
}
负载电流 = 负载电流 / 平均值;
load_current = (load_current* MAX_VOLT) / 1024;
load_current = (load_current / opamp_gain) / load_resistor;
返回负载电流;
}
浮动读取电压(无效){
load_voltage = 0;
for (int a = 0; a <平均值; a++){
load_voltage = load_voltage + analogRead(voltage_sense);
}
负载电压 = 负载电压 / 平均值;
load_voltage = ((load_voltage * MAX_VOLT)/1024.0)*6;
返回负载电压;
}
无效循环() {
state1 = 模拟读取(增加);
如果(状态 1 > 500){
延迟(50);
state1 = 模拟读取(增加);
如果 (state1 > 500){
伏特 = 伏特+0.02;
}
}
state2 = 模拟读取(减少);
if (state2 > 500){
延迟(50);
state2 = 模拟读取(减少);
if (state2 > 500){
if (volt == 0){
volt = 0;
}
其他{
伏 = 伏-0.02;
}
}
}
数 = 伏特 / 0.0012210012210012;
convert_DAC(数字);
电压 = 读取电压();
当前 = 读取电流();
lcd.setCursor(0, 0);
lcd.print("设置值");
lcd.print("=");
设置=(伏特/2)*10000;
lcd.print(设置);
lcd.print("毫安");
lcd.setCursor(0, 1);
lcd.print("我");
lcd.print("=");
lcd.print(当前);
lcd.print("一个");
lcd.print("V");
lcd.print("=");
lcd.print(电压);
lcd.print("V");
// 液晶显示器。打印(负载电压);
//lcd.print("mA");
// 延迟(1000);
//lcd.clear();
}
全部0条评论
快来发表一下你的评论吧 !