本帖最后由 cyrs 于 2019-12-11 16:53 编辑
2014年9月9日进行的主要更正和补充 在http://www.green-trust.org/jmc上查看经过改进的2015年新版本。
对于离网的Ham Radio和Solar项目,我需要一种测量电压,安培,瓦特,安培小时和瓦特小时的方法。有几种商业产品可以做到这一点,但是却没有我想要的灵活性。我设计了一个基于Arduino微控制器的解决方案,该解决方案非常可扩展。现在,它监视上述附加设备的值,并且我正在考虑添加Web监视和用于数据收集的SD卡。好吧,让我们开始吧。
步骤1:分压器
首先,我们访问我们友好的分压器计算器。我输入20v作为输入,输入5v作为输出,并为R2输入10k(使用小于10k的电阻进行实验,直到获得可能的对)。计算得出R1为30K。 R1 = 30k欧姆 R2 = 10k欧姆 Vout =(R2 / R1 + R2)* Vin Vout =(10000 /(30000 + 10000))* 20v Vout =(10000/40000)* 20v Vout = .25 * 20v Vout = 5v 比例= Vin / Vout 比例= 4 由于Arduino具有10位ADC,因此对于0-5v输入,其输出0-1023(1024步)。这是0.00488v /步。 对于R1 = 30k Ohm和R2 = 10k Ohm的分压器,一个12v电池的计算如下: A4引脚上的12v /比率= 3v。 3v / .00488 = 615(ADC读数向上取整) 因此A4引脚电压= .00488 * ADC读数(在这种情况下为615)或3.00伏。 然后电池电压= A4引脚电压*比率(3 * 4 = 12) 读取该值的代码如下: ADCVal = AnalogRead(batMonPin); //读取A4引脚上分压器上的电压
pinVoltage = ADCVal * 0.00488; //计算A / D引脚上的电压// // A / D
的读数为0.00488mV
// //如果将A / D读数乘以0.00488,则
//得到引脚上的电压。
batteryVoltage = pinVoltage *比率; //使用为分压器
计算的比率//计算电池电压,比率= Vin / Vout 步骤2:电流监控
下一步是跟踪负载消耗的电流或电源产生的电流。我们正在使用ACS715霍尔效应传感器来跟踪通过的电流。
更新!ACS714双向电流传感器现已部署。这将为“ AH IN-AH OUT = AMP Remaining”类型的监视启用电池“电量计”。http://www.hacktronics.com/Sensors/Current-Sensor-30-to-30-Amp/flypage.tpl.html
更新!ACS712 5amp传感器项目,网址为
http://arduinotronics.blogspot.com/2014/01/volt-amp-watt-hour-meter-shield.html
//读取模拟量值:
sensorValue = AnalogRead(analogInPin);
//转换为
毫安培outputValue =(((long)sensorValue * 5000/1024)-500)* 1000/133;
安培=(浮点)outputValue / 1000;
第3步:数学警报!
要计算瓦特数(伏特*安培),安培小时数(安培*小时)和瓦特时数(瓦特*小时),需要跟踪时间分量,并执行一些数学运算:
浮动瓦特=安培*电池电压;
样本=样本+ 1;
毫秒= millis();
时间=(浮动)毫秒/ 1000.0;
totalCharge = totalCharge +安培;
averageAmps = totalCharge /样本;
ampSeconds = averageAmps * time;
ampHours = ampSeconds / 3600;
瓦特小时=电池电压*安培小时;
步骤4:串行输出
现在,我们可以使用以下代码将计算结果输出到串行端口:
Serial.print(“ Volts =”);
Serial.print(电池电压);
Serial.print(“ \ t Current(amps)=”);
Serial.print(amps);
Serial.print(“ \ t功率(瓦)=”);
Serial.print(瓦特);
Serial.print(“ \ t时间(小时)=”);
Serial.print(时间/ 3600);
Serial.print(“ \ t安培小时数(ah)=”);
Serial.print(ampHours);
Serial.print(“ \ t瓦特小时(wh)=”);
Serial.println(wattHours);
步骤5:
LCD显示
一直保持计算机连接不便,因此我在项目中添加了4针液晶显示器。
lcd.setCursor(0,0);
lcd.print(batteryVoltage);
lcd.print(“ V”);
lcd.print(amps);
lcd.print(“ A”);
lcd.setCursor(0,1);
lcd.print(瓦特);
lcd.print(“ W”);
lcd.print(时间/ 3600);
lcd.print(“ H”);
lcd.setCursor(0,2);
lcd.print(ampHours);
lcd.print(“ Ah”);
lcd.print(wattHours);
lcd.print(“ Wh”);
步骤6:原始码
* /
整数Vin = 20; int Vout = 5; 整数比= Vin / Vout; //根据Vin / Vout计算 int batMonPin = A4; //分压器的输入引脚
int ADCVal = 0; // A / D值的变量
float pinVoltage = 0; //变量以保存计算出的电压
float batteryVoltage = 0;
int AnalogInPin = A0; //载体板OUT连接到
int sensorValue = 0的模拟输入引脚;//从载板读取的值
int outputValue = 0; //输出以毫安为单位的
无符号长毫秒= 0;
浮动时间= 0.0;
int样本= 0;
float totalCharge = 0.0;
float averageAmps = 0.0;
float ampSeconds = 0.0;
浮动ampHours = 0.0;
浮动瓦特小时= 0.0;
浮动安培= 0.0;
整数R1 = 9000; // R1的电阻,单位为欧姆
int R2 = 3000; // R2的电阻,以ohm
int ratio = 0; //通过Vin / Vout计算得出
void setup(){
//以9600 bps初始化串行通信:
Serial.begin(9600);
lcd.begin(20,4);
}
void loop(){
int sampleADCVal = 0;
int avgADCVal = 0;
int sampleAmpVal = 0;
int avgSAV = 0;
for(int x = 0; x <10; x ++){//通过循环10x
// //读取模拟量值:
sensorValue = AnalogRead(analogInPin);
sampleAmpVal = sampleAmpVal + sensorValue; //将样本加在一起
ADCVal = AnalogRead(batMonPin); //读取分压器上的电压
sampleADCVal = sampleADCVal + ADCVal; //将样本加在一起
延迟(10); //让ADC在下一个样本之前稳定
}
avgSAV = sampleAmpVal / 10;
//转换为毫安
输出值=(((long)avgSAV * 5000/1024)-500)* 1000/133;
/ *传感器在静止时输出约100。
模拟读取产生的值为0-1023,等于0v至5v。
“((long)sensorValue * 5000/1024)”是以毫伏为单位的传感器输出电压。
要减去500mv的偏移量。
该单元每安培电流产生133mv,因此
除以0.133可将mv转换为ma
* /
avgADCVal = sampleADCVal / 10; //除以10(样本数)以获得稳定的读数
pinVoltage = avgBVal * .00488; //计算A / D引脚上的电压
/ *
如果将A / D读数乘以0.00488,则A / D的读数为1 = 0.0048mV ,然后
得到引脚上的电压。
同样,根据接线和
读取电压的位置,在
重负载下显示的电压也可能
恰好在电源电压下。监视
负载或供应并做出决定。
* /
batteryVoltage = pinVoltage *比率;//使用为分压器计算的比率
//计算电池电压
安培=(float)outputValue / 1000;
浮动瓦特=安培*电池电压;
Serial.print(“ Volts =”);
Serial.print(电池电压);
Serial.print(“ \ t Current(amps)=”);
Serial.print(amps);
Serial.print(“ \ t功率(瓦)=”);
Serial.print(瓦特);
样本=样本+ 1;
毫秒= millis();
时间=(浮动)毫秒/ 1000.0;
totalCharge = totalCharge +安培;
averageAmps = totalCharge /样本;
ampSeconds = averageAmps * time;
ampHours = ampSeconds / 3600;
瓦特小时=电池电压*安培小时;
Serial.print(“ \ t时间(小时)=”);
Serial.print(时间/ 3600);
Serial.print(“ \ t安培小时数(ah)=”);
Serial.print(ampHours);
Serial.print(“ \ t瓦特小时(wh)=”);
Serial.println(wattHours);
lcd.setCursor(0,0);
lcd.print(batteryVoltage);
lcd.print(“ V”);
lcd.print(amps);
lcd.print(“ A”);
lcd.setCursor(0,1);
lcd.print(瓦特);
lcd.print(“ W”);
lcd.print(时间/ 3600);
lcd.print(“ H”);
lcd.setCursor(0,2);
lcd.print(ampHours);
液晶显示器
lcd.print(wattHours);
lcd.print(“ Wh”);
lcd.setCursor(0,3);
lcd.print(ratio,5);
lcd.print(“”);
lcd.print(avgBVal);
//在下一个循环之前等待10毫秒
//使模数转换器
在上一次读取之后稳定下来//
delay(10);
}
第7步:未来扩展
对于扩展该项目,我的一些想法是通过通信进行的,例如wifi或以太网,板载Web服务器或附加到Pachube / Cosm / Xively(https://xively.com/),用于数据记录的SD卡,以及今天,我想到增加一个低压隔离开关来保护电池免受过度放电的影响。我还设计了一个混合继电器,它消除了MOSFET开关的发热以及继电器触点的电弧。我将很快为该项目开发代码。
混合继电器可实现诸如风力涡轮机的卸载负载控制器之类的衍生产品,以及用于多级掉电或基于电池电压或负载优先级的受控功率使用的减载。
步骤8:Protoboard
我们已经将电流和电压传感器从免焊面包板上移到了Radio Shack原型板上。这更加坚固和“永久”。
附件:
|