前言
畢設需要測量一個電路的電壓和電流,從而計算出來功率。這個電路是和移動設備綁在一起的,所以測量的信號要通過WiFi傳遞出來。而接收信號的方法,可以是網頁接收或者app,app太復雜了,所以寫一個前端小網頁要簡單得多。
1. 硬件設計
1.1. 采樣電路
這個采樣電路的作用就是讓需要采樣的數據從它流過,然后采集返回數據。
電路圖的上半部分就是對經過的電壓電流采樣的電路。P1輸入的電壓范圍為010V,所以在紅框1中使用兩個20kΩ的分壓電阻使得采樣的電壓范圍為05V,為什么分壓到這個范圍,是因為之后的ADS1115只能采樣到0~VCC的電壓,而該芯片的電壓在該電路中設計為5V。如果輸入電壓范圍更寬的話,可以適當調整分壓電阻的大小。
紅框1中還有一個電流采樣點R3,它是0.2Ω的采樣電阻,這樣會將電流轉化為電壓信號,傳遞給ADS1115采樣。在這個電路中,如果過3A的電流,采樣電阻上就有0.6V的電壓傳遞給ADS1115。采樣電阻可以更大,這樣采得的電流數據就更準確。但是,電阻太大導致損耗也會增大,同時壓降也會很大。主電路是要給后續設備供電的,采樣壓降太大,后續設備也會受影響。
紅框2中就是采樣信號的芯片:ADS1115,它有四個采樣腳,可以差分采樣和單獨采樣。通過SCL和SDA兩個管腳以I2C的方式和單片機連接,從而將采樣的信號傳輸出去。在本文中,單片機用的是NodeMCU。
采樣電路通過穩壓芯片產生一路5V輸出給NodeMCU供電,同時SCL、SDA兩個管腳接受NodeMCU的控制,將采樣數據傳遞出去。
1.2. NodeMCU
NodeMCU是一個開源的物聯網平臺。它使用Lua腳本語言編程。該平臺基于eLua開源項目,底層使用ESP8266 sdk 0.9.5版本。該平臺使用了很多開源項目,例如 lua-cjson,spiffs。NodeMCU包含了可以運行在esp8266 WiFi SoC芯片之上的固件,以及基于ESP-12模組的硬件。
本文中使用的是D1 mini版的NodeMCU,該開發板上集成了esp8266芯片,它可以用來產生熱點或者連接WiFi,從而構成一個服務器。這個開發板可以讓開發者以arduino的方式進行編程設計,只不過需要在arduino IDE上導入對應的開發板即可。
2. 軟件設計
2.1. arduino ide添加開發板
進入arduino ide的首選項
回到主面板,進入"工具->開發板->開發板管理器",在如下圖中輸入esp:
安裝即可實現新開發板的添加。
在開發板中就可以看到NodeMCU的選擇。
2.2. 建立網絡
arduino有相關的ESP8266WIFI庫來操作WiFi,建立網絡。
首先,這個開發板既可以連接WiFi,也可以創建熱點讓其他設備連接。兩種方式都可以為之后的服務器做準備。
2.2.1. 連接WiFi
首先導入ESP8266WiFi.h頭文件,該文件可以在庫管理中添加WiFi庫獲得。
在setup
函數中通過WiFi.begin(ssid, password);
發起連接WiFi的調用,然后通過while
不斷輪詢WiFi.status()
檢測是否連接成功。
如果連接成功,在串口上打印出它獲得的IP。
// Import required libraries
#include < ESP8266WiFi.h >
// WiFi parameters
const char* ssid = "MI8pro";
const char* password = "12345600";
void setup(void)
{
// Start Serial
Serial.begin(115200);
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Print the IP address
Serial.println(WiFi.localIP());
}
void loop() {
}
2.2.2. 開啟熱點
使用NodeMCU產生一個熱點,因為NodeMCU沒有和外部網絡連接,所以這個熱點是局域網式的。
很簡單,就是在setup
中通過WiFi.softAP
函數來開啟熱點。
在此基礎上可以進一步實現網絡的連接??梢栽?.2.1節代碼中添加重試次數,如果重試多次還無法連接到對應WiFi,就自己建立熱點。
不過后期,為了便捷開發,只是使用WiFi連接來建立網絡。
#include < ESP8266WiFi.h >
IPAddress local_IP(192,168,0,100);
IPAddress gateway(192,168,0,100);
IPAddress subnet(255,255,255,0);
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.print("Setting soft-AP configuration ... ");
Serial.println(WiFi.softAPConfig(local_IP, gateway, subnet) ? "Ready" : "Failed!");
Serial.print("Setting soft-AP ... ");
Serial.println(WiFi.softAP("ESPsoftAP", "12345600", 1, false, 10) ? "Ready" : "Failed!");
Serial.print("Soft-AP IP address = ");
Serial.println(WiFi.softAPIP());
}
void loop() {}
2.3. 服務器
arduino也有相應的庫來建立HTTP服務器。
這個服務器主要處理兩個路徑的請求:/
和/get
。其中,根目錄就是返回給瀏覽器一個網頁,而網頁中會通過js不停向/get
發送請求,獲取采集的電壓電流等數據。
網頁如下。
< !DOCTYPE html >
< script src='https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js' >< /script >
< h1 >current and voltage sample< /h1 >
< br/ >
< body >
< script type='text/javascript' >
$(function () {
setInterval(reflush, 1000)
})
function reflush() {
$.getJSON('./get', function(json) {
//解決原生js更新數據產生頁面閃爍的問題
$('#tmp')[0].innerHTML = json.voltage
$('#voltage').html($('#tmp').html())
$('#tmp')[0].innerHTML = json.current
$('#current').html($('#tmp').html())
$('#tmp')[0].innerHTML = json.power
$('#power').html($('#tmp').html())
$('#tmp')[0].innerHTML = json.serial
$('#serial').html($('#tmp').html())
})
}
< /script >
< label id='tmp' hidden >< /label >
< label >voltage: < /label >
< b >
< i >
< label id='voltage' >0.00< /label >
< /i >
< /b >
V< br/ >
< label >current: < /label >
< b >
< i >
< label id='current' >0.00< /label >
< /i >
< /b >
A< br/ >
< label >power: < /label >
< b >
< i >
< label id='power' >0.00< /label >
< /i >
< /b >
W< br/ >
< label >serial-number: < /label >
< b >
< i >
< label id='serial' >0.00< /label >
< /i >
< /b >
< /body >
首先導入頭文件,并定義全局變量server并定義對應的handler。在handleRoot
中會直接將上述網頁返回,而在handleGet
中會將電壓、電流、功率等數據通過json的形式返回給客戶端。為了表示數據的實時性,還附帶了一個序列號,序列號在網頁上的變化,表示了數據是實時接收的。
#include < ESP8266WebServer.h >
#include < ArduinoJson.h >
//Web Server
ESP8266WebServer server(8080);
void handleRoot() {
server.send(200, "text/html", rootpage);
}
void handleGet() {
StaticJsonDocument< 100 > json;
json["voltage"] = voltage;
json["current"] = current;
json["power"] = power;
char serial[100];
sprintf(serial, "0x%x", millis());
json["serial"] = serial;
char msg[measureJson(json) + 1];
serializeJson(json, msg, measureJson(json) + 1);
server.send(200, "text/plain", msg);
Serial.printf("handleGet: %sn", msg);
}
然后在setup()
函數中配置對應的handler。
server.on("/", HTTP_GET, handleRoot);
server.on("/get", HTTP_GET, handleGet);
server.begin();
在loop()
函數中處理客戶端的請求,其實也就是調用一個函數,在loop這個死循環中不停處理請求。
//server處理客戶端的請求
server.handleClient();
2.4. 采樣
采樣是通過arduino的一個ADS1115庫來實現的,也是很簡單。
首先導入需要的庫,并實例化一些對象。
#include < Adafruit_ADS1015.h >
// 電壓電流測量
Adafruit_ADS1115 ads(0x48);
float voltage = 5.00;
float current = 1.11;
float power = voltage * current;
在setup()
函數中開啟ADS芯片,這個是很重要的。
ads.begin();
然后在loop()
函數中,獲取硬件電路中的ADS1115芯片四個采樣腳的電壓,進一步獲得電壓和電流值,0.1875是電壓因數。
因為ADS采樣腳的輸入阻抗問題,測得的電壓值和實際的電壓值是有偏移的,不過是線性偏移。只要求兩組采樣值x和實際值y,然后通過y=ax+b來求得其系數。
//ADC電壓電流采集,功率計算
int16_t adc0, adc1, adc2, adc3;
adc0 = ads.readADC_SingleEnded(0);
adc1 = ads.readADC_SingleEnded(1);
adc2 = ads.readADC_SingleEnded(2);
adc3 = ads.readADC_SingleEnded(3);
// AD測得的值
voltage = ((adc0 - adc1) * 0.1875) / 1000;
current = (adc3 - adc2)*0.1875 / 1000;
//矯正,通過取兩個點求斜率y=ax+b,a=2.028,b=1.1568,x是測量值,y是實際輸入電壓值
voltage = 2.028 * voltage + 1.1568;
//current就是測得的電壓除以采樣電阻0.2
current = current * 5;
power = voltage * current;
-
采樣電路
+關注
關注
10文章
64瀏覽量
28283 -
SDA
+關注
關注
0文章
124瀏覽量
28115 -
分壓電阻
+關注
關注
0文章
18瀏覽量
11579 -
ESP8266
+關注
關注
50文章
962瀏覽量
44829 -
NODEMCU
+關注
關注
13文章
289瀏覽量
21299
發布評論請先 登錄
相關推薦
評論