2015年1月19日

arduino測試電池電壓與內阻

週末看到SciCore社團裡,江老師出了一道問題,要用SciCore量測電池電量


一般大家家裡都有很多充電電池,乾電池,相機電池,如果能夠準確知道電量就可以更方便使用跟掌握充電時機。電池電量的量測不只是電壓還包括內阻的大小,本周使用SciCore有能力量出電池的狀態而也可以完美的顯示出來,期待有巧思跟願意解救大家的朋友能來解決這問題!


先前在《Arduino自造指南:從65個專案玩透Arduino》這本書裡看過量電池電壓的方式,基本上照著作就行,比較麻煩的是要量電池內阻,這我就從來沒經驗,因此上網找了一些資料。


1.電壓源內阻測量儀
2.電池內阻測試儀
第一篇和第二篇作的方法類似,就是先直接測量電池電壓(開路電壓),再把電池和一個電阻串聯之後再量電池有負載的時候的電壓(負載電壓)。因為那個電阻是已知的,所以就可以用這樣的公式去求得。

電池內阻=(開路電壓-負載電壓)/(負載電壓/負載電阻)


3.簡易電池內阻測試儀製作
而這第三篇是使用交流阻抗的方式來測電池。零件為555IC加上LM317定電流給予50mA,1K Hz的交流訊號,使用電錶的交流200mV檔,測量電池兩端的電壓降,如果測得10mV,則電阻就是100毫歐。不過我還不知道arduino怎麼測得交流電壓,所以就先記著,以後再做。


現在就來看成品,測量的結果會輸出到LCD上面,分別顯示電壓和電池內阻。電池老化,或是沒電,電池內阻就會越大。

電池測試


配線則是這樣,會用到的零件包括
10歐姆、1k歐姆、2.2k歐姆、10k歐姆兩個、一個2n2222的電晶體,還有一個100nF的電容

arduino製作電池測試器


這個電路分三個部份來看

分壓電路
右邊的部份是用兩個10k歐姆的電阻作分壓電路,目的在提供外部參考電壓2.5v給arduino(連接AREF)。因為arduino預設都是用5v來作參考電壓,把參考電壓減少,就可以增加解析度。兩個電阻務必用電錶先量過,確定兩個都一樣電阻。理論上我這樣作可以提供2.5v的電壓,不過我這樣分出來的電壓卻不到2.5v

液晶螢幕
使用I2C的LCD,連接SDA、SCL、VCC和GND

電池測量
一般使用A0的腳位測量開路電壓,當D13送出高電位的訊號後,會讓電晶體像開關一樣,讓電池和10歐姆的電阻串聯,這時候A0測的電壓就是負載電壓了。


Arduino的程式
就直接貼這了

************************************************
#include <LiquidCrystal_I2C.h>


//液晶顯示螢幕
LiquidCrystal_I2C lcd(0x27, 16, 2); // set the LCD address to 0x27 for a 16 chars and 2 line display


int controlPin = 13;  //電晶體開關pin
int analogValue = 0;
int sumOpen = 0;  //開路電壓多次計算總和
int sumLoad = 0;  //負載電壓多次計算總和
float voltageOpen = 0; //開路電壓
float voltageLoad = 0; //負載電壓
int loadR = 10; //負載的電阻值


void setup()
{
  //使用外部參考電壓
  analogReference(EXTERNAL);
  lcd.begin();

  Serial.begin(9600);

  lcd.backlight();
  pinMode(controlPin, OUTPUT);

}

void loop()
{
  sumOpen = 0;
  sumLoad  = 0;
  digitalWrite(controlPin, LOW);

  //重複測量五次開路電壓
  for (int i = 1; i < 6; i++) {
    analogValue = analogRead(0);
    sumOpen = analogValue + sumOpen;
  }

  //參考電壓為5/2=2.5v    2.5/1024=0.0024  因此將測量的類比值乘0.0024得到測量電壓
  voltageOpen = 0.0024 * (sumOpen / 5);
  delay(100);

  digitalWrite(controlPin, HIGH);
  delay(4000);

  //重複測量五次負載電壓
  for (int i = 1; i < 6; i++) {
    analogValue = analogRead(0);
    sumLoad = analogValue + sumLoad;
  }
  voltageLoad = 0.0024 * (sumLoad / 5);
  digitalWrite(controlPin, LOW);

  //電池內阻的計算方式為(開路電壓-負載電壓)/通過電流
  float InR = 1000 * (voltageOpen - voltageLoad) / (voltageLoad / loadR);

  delay(1000);

  lcd.setCursor(0, 0);
  lcd.print(voltageOpen);
  lcd.print(" V                   ");
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print(InR);
  lcd.print("  mOhm               ");
}

************************************************

搞這東西跟生物有關嗎?喔,當然有的,我學到了交流阻抗的測量方式,這可以用來測細胞膜的阻抗耶,之後就可以來玩玩囉。