事前叮嚀:
- 電流偵測在搜尋資料時,請先確認該應用場合是直流還是交流?交流是正弦波,對於量測並不是直接取一次樣就可以搞定
- 目前看到網路影片資料,極大多數都沒有查看 datasheet ,在最大值輸出電壓全部都是錯的,5A 只到 3.5V,20A 30A 也只到 4.5V,所以計算公式全是錯的
- ACS712 只能使用 5V ,輸出自然也是 5V ,ESP8266 當然不支援,網路上看到可以使用電平轉換或是電阻分壓的方式接入,不過為了更精準的量測最後決定升級成「雙核」版本,使用 Arduino UNO + ESP8266 來達到 ACS712 + WiFi 的目的
- 有看到搭配 ADS1115 的使用方式,沒使用過不確定效果
--
什麼是 ACS712
- ACS712 - Allegro Microsystems
- Interfacing ACS712 Current Sensor with Arduino – Measure Current with Arduino
簡單說就是,一顆測量電流後轉換成電壓大小的 IC ,根據電壓大小即可換算用電
--
應用硬體線路
--
Datasheet 對於量測後輸出電壓的解釋
ACS712 有三個型號 5A, 20A, 30A 我們就看 5A 和 30A 就好了
先看 5A 的
當 Vcc 為 5V 時,輸出 2.5V 為 0 負載,滿負載是 3.5V
然後是 30A 的
一樣 Vcc 為 5V 時,2.5V 為 0 負載,滿負載 30A 時為 4.5V
無論哪個型號,輸出電壓結果都是線性的,換句話說就是可以直接把 「輸出電壓 - 2.5」 然後和極限電壓來做簡單的計算即可得到真正的負載電流
--
接上 Arduino 的情況
當我使用一顆 ACS712 30A 的偵測器時,接到 A0 的類比腳位,0 負載時理想值是收到 511 左右的值,這是因為 ACS712 0 負載時會輸出 2.5V 的電壓
換句話說,如果使用 30A 這顆 IC 的話,那就只能得到 408 ( (1024/5) * (4.5-2.5) = 408 ) 個取樣,每個取樣為 0.074A,接到 110V 交流電就是 8.1W
也就是說精度就是 0.074A,數值抖一下就是 8.1W 的差異,當然這樣 30A 的情況,如果是 5A 的話因為滿負載是 3.5V 所以就要自己換算一下 (等 Hoyo 自己有用到再換算更新上來 )
--
AC 交流電
- https://ngsir.netfirms.com/capplets/rms/rms.pdf
交流電負載的情況就是交流電「正弦波」的樣子,因此必須至少取樣一個以上的週期後的數據才能計算電流。
台灣交流電為 60HZ 所以一次的取樣至少不能低於 1/60 = 0.0167 秒 才是一個週期
--
週期取樣計算 Arduino 程式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
float value; // void setup() { Serial.begin(9600); } void loop() { unsigned long start_time = millis(); int i = 1; float total; float RMS; float W; while (1){ if ( millis() - start_time >= 166 ) break; // 60HZ = 1000/60=16.6 value = analogRead(A0) - 512; total += value*value; i++; } RMS = (sqrt(total/i) -1 ); // 1 是觀察後在無負載時出現的雜訊值 W = RMS*0.074*110; Serial.print(RMS); Serial.print(" "); Serial.print(W); Serial.println(); } |
--
SoftwareSerial - Arduino + ESP8266 雙核通訊
Arduino 和 ESP8266 使用 SoftwareSerial 達到雙向資訊交換,需要注意串列鮑率(Baud Rate) 不能設定太低,會掉資料
Arduino 端,接 ACS712
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
#include <SoftwareSerial.h> SoftwareSerial mySerial(10, 11); // RX, TX // 引入所需函式庫 // ACS712 float value; int i = 1; float total; float RMS; float W; unsigned char senBuf[9] = {0}; static int count = 0; // 繼電器設定 const int relayPin = 5; // 溫濕度設定 float t; float h; int w; void setup() { Serial.begin(57600); mySerial.begin(57600); delay(100); // 繼電器 pinMode(relayPin, OUTPUT); digitalWrite(relayPin, HIGH); // pinMode(16, INPUT); } void loop() { acs712(); } void acs712() { value = analogRead(A0); Serial.println( value ); unsigned long start_time = millis(); total = 0; i = 0; while (1) { if ( millis() - start_time >= 166 ) break; // 60HZ = 1000/60=16.6 value = analogRead(A0) - 512; total += value * value; i++; } RMS = (sqrt(total / i) - 1 ); // 1 是觀察後在無負載時出現的雜訊值 if ( RMS >= 0 ) { RMS = RMS; } else { RMS = 0; } W = RMS * 0.074 * 110; Serial.print("RMS: "); Serial.print(RMS); Serial.print(" W:"); Serial.print(W); Serial.println(); mySerial.print("{\"W\":\""); mySerial.print(RMS); mySerial.print("\",\"W\":\""); mySerial.print(W); mySerial.print("\"}"); mySerial.println(); delay(100); } |
ESP8266
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <SoftwareSerial.h> SoftwareSerial mySerial(13, 15); // RX, TX void setup() { Serial.begin(57600); mySerial.begin(57600); } void loop() { if ( mySerial.available() ) { Serial.println(mySerial.readStringUntil('\n')); } } |
--
ADS1115
更準的類比數位轉位器以及可應用在 ESP8266 上
--
12,415 total views, 7 views today