风筝
发表于: 2020-3-18 08:49:08 | 显示全部楼层

如果您曾经使用过电池、SMPS电路或其他电源电路,那么经常会发生这种情况,您必须通过加载负载来测试电源,以检查其在不同负载条件下的性能。通常用于执行此类测试的设备称为“恒定电流直流负载(Constant Current DC Load)”,它使我们能够调整电源的输出电流,然后保持恒定,直到再次调整为止。在本篇文章中,我们将学习如何使用Arduino开发板制作我们自己的可调电子负载,该负载可以接受24V的最大输入电压和高达5A的漏极电流。


在之前的压控电流源帖子中,我们已经说明了如何将运算放大器与MOSFET一起使用以及如何使用压控电流源电路。但是在本文中,我们将应用该电路制作一个数控电流源。显然,一个数字控制的电流源需要一个数字电路,因此使用了Arduino NANO。 Arduino NANO将提供直流负载所需的控件。


该电路包括三个部分。第一部分是Arduino Nano部分,第二部分是数模转换器,第三部分是纯模拟电路,使用双运算放大器来控制负载部分。


我们的电子负载具有以下输入和输出部分。

●    两个输入开关,用于增加和减少负载。

●    LCD将显示设置的负载,实际负载和负载电压。

●    最大负载电流限制为5A。

●    负载的最大输入电压为24V。


所需的组件

以下列出了制作直流电子负载所需的组件。

●    Arduino nano开发板

●    1602字符LCD

●    Mosfet irf540n

●    mcp4921数模转换器

●    5瓦并联电阻


Arduino直流电子负载电路图

在下面的示意图中,运算放大器具有两个部分。一部分是控制MOSFET,另一部分是放大检测到的电流。第一部分使用R12、R13和MOSFET。 R12用于减小反馈部分的负载效应,R13用作Mosfet栅极电阻。

Arduino-DC-Electronic-Load-Circuit-Diagram.png


电阻R8和R9用于感测此虚拟负载将承受的电源电压。根据分压器规则,这两个电阻最大支持24V。超过24V的电压会产生不适用于Arduino引脚的电压。因此请注意不要连接输出电压超过24V的电源。


电阻R7是此处的实际负载电阻。这是一个5W、0.1欧姆的电阻器。根据电源法则,它将支持最大7A(P = I2R),但是出于安全考虑,将最大负载电流限制为5A是比较明智​​的。因此,在目前最大24V的情况下,可以通过该虚拟负载设置5A负载。


放大器的另一部分配置为增益放大器。它将提供6倍的增益。在电流流动期间,将出现电压降。例如,当5A电流流经电阻时,根据欧姆定律,0.1欧姆分流电阻两端的电压降将为0.5V(V = I x R)。同相放大器会将其放大到x6,因此放大器第二部分的输出将为3V。该输出将由Arduino nano模拟输入引脚感测,并且将计算电流。


放大器的第一部分配置为电压跟随器电路,该电压跟随器电路将根据输入电压控制MOSFET,并由于流经分流电阻器的负载电流而获得所需的反馈电压。


MCP4921是数模转换器。 DAC使用SPI通信协议从任何微控制器单元获取数字数据,并根据其提供模拟电压输出。该电压是运算放大器的输入。


另一部分是Arduino Nano开发,它将通过SPI协议将数字数据提供给DAC并控制负载,并以1602字符显示屏显示数据。使用了另外减少和增加按钮,并没有连接到数字引脚,而是连接到模拟引脚。因此,可以将其更改为另一种类型的开关,例如滑块或模拟编码器。同样,通过修改代码,人们可以提供原始模拟数据来控制负载。这也避免了开关反跳问题。


最后,通过增加负载,Arduino nano将以数字格式将负载数据提供给DAC,DAC将向运算放大器提供模拟数据,并且运算放大器将根据运算放大器的输入电压控制MOSFET。 最后,根据流经分流电阻的负载电流,将出现压降,该压降将由LM358的第二个通道进一步放大并由Arduino nano获得。这将显示在字符显示屏上。当用户按下减少按钮时,将会发生同样的事情。


PCB设计和Gerber文件

由于该电路的电流较大,因此,使用适当的PCB设计策略来消除不希望的故障情况是一个明智的选择。因此,为此直流负载设计了一个PCB。我使用Eagle PCB设计软​​件来设计PCB。您可以选择任何PCB Cad软件。下图显示了CAD软件中最终设计的PCB:

Printed-Circuit-Board.png


在设计此PCB时要注意的一个重要因素是使用厚的电源层以确保整个电路中都有适当的电流通过。还有接地拼接VIAS,用于在上下两层中正确地接地。


您也可以从下面的链接下载此PCB的Gerber文件,并将其用于生产PCB:可调式电子直流负载的Gerber文件


可调直流负载的Arduino代码

代码很简单。首先,我们包含了SPI和LCD头文件,并设置了最大逻辑电压、芯片选择引脚等。

  1. #include <SPI.h>
  2. #include <LiquidCrystal.h>
  3. #define SS_PIN 10
  4. #define MAX_VOLT 5.0 // maximum logic voltage
  5. #define load_resistor 0.1 // shunt resistor value in Ohms
  6. #define opamp_gain 6 // gain of the op-amp
  7. #define average 10 // average time
复制代码

然后声明与程序流有关的整数和变量。此外,我们设置了Arduino Nano相关的外设引脚。

  1. const int slaveSelectPin = 10; // Chip select pin
  2. int number = 0;
  3. int increase = A2; // Increase pin
  4. int decrease = A3; //decrease pin
  5. int current_sense = A0; //current sense pin
  6. int voltage_sense = A1; // voltage sense pin
  7. int state1 = 0;
  8. int state2 = 0;
  9. int Set = 0;
  10. float volt = 0;
  11. float load_current = 0.0;
  12. float load_voltage = 0.0;
  13. float current = 0.0;
  14. float voltage = 0.0;
  15. LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // LCD pins
复制代码

在setup函数中设置于LCD和SPI的引脚方向。

  1. void setup() {
  2.   pinMode(slaveSelectPin, OUTPUT);
  3.   pinMode(increase, INPUT);  
  4.   pinMode(decrease, INPUT);  
  5.   pinMode(current_sense, INPUT);
  6.   pinMode(voltage_sense, INPUT);
  7.   // initialize SPI:
  8.   SPI.begin();
  9.   //set up the LCD's number of columns and rows:
  10.     lcd.begin(16, 2);
  11.   // Print a message to the LCD.
  12.     lcd.print("Digital Load");
  13.     lcd.setCursor(0, 1);
  14.     lcd.print("Circuit Digest");
  15.     delay (2000);
  16. }
复制代码

以下函数用于转换DAC值。

  1. void convert_DAC(unsigned int value)
  2. {
  3.    /*Step Size = 2^n, Therefore 12bit 2^12 = 4096
  4.      For 5V reference, the step will be 5/4095 = 0.0012210012210012V or 1mV (approx)*/
  5.   unsigned int container ;
  6.   unsigned int MSB;
  7.   unsigned int LSB;
  8.   /*Step: 1, stored the 12 bit data into the container
  9.    Suppose the data is 4095, in binary 1111 1111 1111*/
  10.   container = value;   
  11.   /*Step: 2 Creating Dummy 8 bit. So, by dividing 256, upper 4 bits are captured in LSB
  12.    LSB = 0000 1111*/
  13.   LSB = container/256;
  14.   /*Step: 3 Sending the configuration with punching the 4 bit data.
  15.    LSB = 0011 0000 OR 0000 1111. Result is 0011 1111 */
  16.   LSB = (0x30) | LSB;
  17.   /*Step:4 Container still has the 21bit value. Extracting the lower 8 bits.
  18.    1111 1111 AND 1111 1111 1111. Result is 1111 1111 which is MSB*/  
  19.   MSB = 0xFF & container;   
  20. /*Step:4 Sending the 16bits data by dividing into two bytes. */
  21.     digitalWrite(slaveSelectPin, LOW);
  22.     delay(100);      
  23.     SPI.transfer(LSB);
  24.     SPI.transfer(MSB);   
  25.     delay(100);
  26.     // take the SS pin high to de-select the chip:
  27.     digitalWrite(slaveSelectPin, HIGH);            
  28. }
复制代码

read_current()函数用于读取感测到的电流。

  1. float read_current (void){
  2.           load_current = 0;         
  3.           for (int a = 0; a < average; a++){
  4.           load_current = load_current + analogRead(current_sense);               
  5.         }
  6.         load_current = load_current / average;
  7.         load_current = (load_current* MAX_VOLT) / 1024;
  8.         load_current = (load_current / opamp_gain) / load_resistor;
  9.         return load_current;
  10. }
复制代码

read_voltage()函数用于读取负载电压。

  1. float read_voltage (void){
  2.           load_voltage = 0;         
  3.           for (int a = 0; a < average; a++){
  4.           load_voltage = load_voltage + analogRead(voltage_sense);               
  5.         }
  6.         load_voltage = load_voltage / average;
  7.         load_voltage = ((load_voltage * MAX_VOLT)/1024.0)*6;
  8.         return load_voltage;
  9. }
复制代码

以下是loop函数的代码。在这里,测量开关,并将数据发送到DAC。传输数据后,将测量实际电流和负载电压。这两个值最终也都打印在LCD上。

  1. void loop () {
  2.         state1 = analogRead(increase);
  3.         if (state1 > 500){
  4.           delay(50);
  5.            state1 = analogRead(increase);
  6.            if (state1 > 500){
  7.               volt = volt+0.02;
  8.            }                  
  9.         }
  10.          state2 = analogRead(decrease);
  11.         if (state2 > 500){
  12.           delay(50);
  13.            state2 = analogRead(decrease);
  14.            if (state2 > 500){
  15.               if (volt == 0){
  16.                 volt = 0;
  17.               }
  18.             else{
  19.                 volt = volt-0.02;
  20.             }            
  21.            }
  22.         }
  23.         number = volt / 0.0012210012210012;
  24.         convert_DAC (number);        
  25.         voltage = read_voltage();
  26.         current = read_current();      
  27.          lcd.setCursor(0, 0);
  28.          lcd.print("Set Value");      
  29.         lcd.print("=");
  30.         Set = (volt/2)*10000;
  31.         lcd.print(Set);      
  32.         lcd.print("mA    ");
  33.         lcd.setCursor(0, 1);        
  34.         lcd.print("I");      
  35.         lcd.print("=");
  36.         lcd.print(current);      
  37.         lcd.print("A ");
  38.         lcd.print(" V");  
  39.         lcd.print("=");
  40.         lcd.print(voltage);      
  41.         lcd.print("V");              
  42.        // lcd.print(load_voltage);
  43.         //lcd.print("mA    ");
  44.        // delay(1000);
  45.         //lcd.clear();
  46. }
复制代码

测试我们的可调直流负载

数字负载电路使用12V电源焊接并上电。 我在电源侧使用了7.4V锂电池,并连接了钳型表以检查其工作情况。 如您所见,当设定电流为300mA时,电路将从电池中汲取300mA电流,该电流也由钳形表测量为310mA。

Arduino-based-Electronic-DC-Load-Working.jpg

希望您理解该项目,如果您有任何疑问,可以在本帖下面留言。


代码

以下是本文使用的完整代码: main.rar (1.46 KB, 下载次数: 25)

跳转到指定楼层
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 700 | 回复: 1479



手机版|

GMT+8, 2024-3-29 12:56 , Processed in 0.095590 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表