設備與材料
個人電腦 × 1
arduino Uno × 1
OLED 128*64 × 1
PB 按鈕 × 1
1/4W 1kΩ× 1
1/4W 1MΩ× 1
1/4W 10MΩ× 1
連接線 若干
實體接線圖
原理
利用電容充電時間常數 τ=R×C,利用 arduino millis() 與 micros() 計時功能,計算多久會充電到1個時間常數 (充電到 0.632 * 電壓最大值 ) 。
1kΩ充電:
計時是用 millis() ,單位是 ms
τ = 1k × C
C = τ / 1k
C = τ μF
1MΩ充電:
計時是用 micros() ,單位是 =μs
τ = 1M × C
C = τ / 1M
C = τ pF
10MΩ充電:
計時是用 micros() ,單位是 =μs
τ = 10M × C
C = τ / 10M
C = τ/10 pF
參考程式
/*
* arduino 電容測試程式
*
*/
int Out1k = 12; //1k電阻的充電腳
int Out1M = 11; //1M電阻的充電腳
int Out10M = 10; //10M電阻的充電腳
int ReadPin = A0; //類比讀取電容電壓腳位
int PB=9; //按鈕開關
unsigned long runTime; //計算執行時間
byte step=12; //執行狀態 12 不執行
void setup() {
pinMode(PB,INPUT_PULLUP);
pinMode(ReadPin,INPUT);
//開啟串例傳輸
Serial.begin(9600);
}
void loop() {
//檢測是否按鈕,如果按下就可以測量
if(!digitalRead(PB)){
//開始測量
step=0;
}
switch(step){
case 0:
//充電前先將電容電壓放電
//Out1M Out1M 高組態,不影響 Out1k 充電
pinMode(Out1M,INPUT);
pinMode(Out10M,INPUT);
pinMode(Out1k,OUTPUT);
digitalWrite(Out1k,LOW);
step=1;
break;
case 1:
//檢測放電是否完成
if(analogRead(ReadPin)<35){
step=2;
}
break;
case 2:
//用 1kΩ 開始充電
digitalWrite(Out1k,HIGH);
runTime = millis();
step = 3;
break;
case 3:
//檢測充電電壓 1023*0.632 63.2% 是1個充電時間常數
if(analogRead(ReadPin)>646){
runTime = millis()-runTime;
if(runTime>2){
//測量結束
Serial.print(runTime);
Serial.println("μF");
step=12;
digitalWrite(Out1k,LOW);
}else{
//數值太低,用 1M 電阻來充電
step=4;
}
}
break;
case 4:
//充電前先將電容電壓放電
pinMode(Out1k,OUTPUT);
digitalWrite(Out1k,LOW);
step=5;
break;
case 5:
//檢測放電是否完成
if(analogRead(ReadPin)<35){
step=6;
}
break;
case 6:
//Out1k 高阻態,不影響 Out1M 充電
pinMode(Out1k,INPUT);
pinMode(Out1M,OUTPUT);
digitalWrite(Out1M,HIGH);
runTime = micros();
step = 7;
break;
case 7:
//1023*0.632=646
if(analogRead(ReadPin)>646){
runTime = micros()-runTime-420;
if(runTime>1000){
//測量結束
Serial.print(runTime);
Serial.println("pF");
digitalWrite(Out1M,LOW);
step=12;
}else{
//數值太低,用 10M 電阻來充電
step=8;
}
}
break;
case 8:
//充電前先將電容電壓放電
pinMode(Out1k,OUTPUT);
digitalWrite(Out1k,LOW);
step=9;
break;
case 9:
//檢測放電是否完成
if(analogRead(ReadPin)<35){
step=10;
}
break;
case 10:
//Out1k Out1M 高阻態,不影響 Out10M 充電
pinMode(Out1k,INPUT);
pinMode(Out1M,INPUT);
pinMode(Out10M,OUTPUT);
digitalWrite(Out10M,HIGH);
runTime = micros();
step = 11;
break;
case 11:
//1023*0.632=646
if(analogRead(ReadPin)>646){
runTime = micros()-runTime-420;
Serial.print(runTime/10);
Serial.println("pF");
digitalWrite(Out10M,LOW);
step=12;
}
break;
}
}
輸出畫面
測試結果
待測電容從2200μF ~ 220pF 都能測量,小於100pF測量會有點問題,因為用麵包板製作,當沒有待測電容時,測出的電容值會有 40幾pF,因為指令執行本身就需要時間。因此決定修正程式,測得的執行時間會減掉 420μS 來修正誤差。
修正前拿1個10pF的電容器去測量時,測出的結果約50幾pF,誤差有點大,修正後結果比較正常。
功能要求
範例程式是將電容測量結果傳回電腦,請結合 OLED 實習,將測量電容大小顯示在 OLED 上。程式中並沒有對空接,或測試端直接短路做判斷,請自行加上判斷(當待測端直接短路時,電壓是無法到達充電電壓,所以當測試時間超過多久之後,就可以判定待測端短路)
相關知識
Arduino 輸出實習(單燈閃爍)
Arduino 輸出實習(跑馬燈-愚公移山)
Arduino 輸出實習(跑馬燈-for迴圈)
Arduino 數位輸入實習
Arduino 數位輸入實習(INPUT_PULLUP)
Arduino 類比輸入實習
Arduino PWM 實習 (呼吸燈)
Arduino PWM 實習 (光感應調光燈)
Arduino 8×8 LED Matrix MAX7219 實習
Arduino 紅綠燈小綠人 實習
Arduino 計時器 實習
Arduino 音樂盒
Arduino 電子琴(鍵盤掃描)
Arduino DHT11 溫濕度感應器
Arduino OLED 顯示
Arduino 超音波測距模組 HC-SR04
Arduino 執行時間實習
Arduino 電容測試器
Arduino 紅外線接收實習
Arduino 紅外線發射實習 EPSON 投影機控制
ESP-12F 網路智慧開關(MQTT)
ESP-12F 雲端記錄型 K-Type 溫度計(MQTT ThingSpeak)
ESP-12F 手機雲端紅外線控制
ESP-12F 網路電台收音機
ESP-12F 電子鼓