电流监测系统
材料准备
-
Arduino uno R4 wifi版开发板
-
杜邦线(公对公母对母公对母)若干
-
INA226模块(焊接好的)
想法
想实现对指定电路的电流实时监控,实时传输到远程设备上
整个设计思路就是通过电流模块去获取电流信息,arduino传输数据到远程。
最开始的想法是arduino获取电流信息,然后通过蓝牙传输到电脑端,电脑端写点脚本把信息分发出去。
后面拿到arduino发现有更简单的思路:arduino可以建立wifi热点,相当于路由器,然后创建网页,在网页端实时更新电流数据。
实践
-
vcc接3.3v gnd接gnd sda接sda scl接scl
-
根据测量的电路大小设置INA226模块参数
const float SHUNT_RESISTOR = 0.01; //设置为实际使用的分流电阻值 const float MAX_CURRENT = 0.005; //预期测量的最大电流值 const float ZERO_THRESHOLD = 0.005; //需要调整零点阈值,因为模块有一定的空载电流
#include "INA226.h" #include <Wire.h> #include <WiFiS3.h> INA226 INA(0x40); // WiFi配置 const char* ssid = "Current_Monitor"; const char* password = "12345678"; WiFiServer server(80); String response = ""; // INA226配置参数 const float SHUNT_RESISTOR = 0.01; const float MAX_CURRENT = 0.005; const float ZERO_THRESHOLD = 0.005; const float ERROR_THRESHOLD = -0.02; const float INVALID_THRESHOLD = 50.0; // 无效数据阈值 // 电流状态变量 float lastCurrent = 0; unsigned long lastChangeTime = 0; boolean currentState = false; float currentValue = 0; bool isValidData = true; // 异常计数器 int errorCount = 0; const int MAX_ERROR_COUNT = 3; // HTML页面模板 const char* htmlTemplate = R"( <!DOCTYPE html> <html> <head> <title>Current Monitor</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> body { font-family: Arial; text-align: center; margin: 0; padding: 20px; background-color: #f0f0f0; } .container { max-width: 600px; margin: 0 auto; padding: 15px; } h1 { color: #333; font-size: 1.8em; margin-bottom: 20px; } .status { font-size: 1.2em; margin: 15px auto; padding: 15px; border-radius: 15px; box-shadow: 0 2px 5px rgba(0,0,0,0.2); word-wrap: break-word; } .safe { background-color: #90EE90; color: #006400; } .warning { background-color: #FFB6C1; color: #8B0000; } .invalid { background-color: #D3D3D3; color: #696969; } .current-value { font-size: 2em; font-weight: bold; margin: 10px 0; } @media (max-width: 480px) { body { padding: 10px; } h1 { font-size: 1.5em; } .status { font-size: 1em; } .current-value { font-size: 1.5em; } } </style> <script> function updateCurrent() { fetch('/current', { cache: 'no-store', headers: { 'Cache-Control': 'no-cache' } }) .then(response => response.json()) .then(data => { const statusDiv = document.getElementById('status'); const current = data.current; const valid = data.valid; if (!valid) { statusDiv.innerHTML = '<div class="current-value">数据无效</div>电流值超过50mA,数据不可靠'; statusDiv.className = 'status invalid'; } else if (current <= 1) { statusDiv.innerHTML = '<div class="current-value">安全</div>无电流'; statusDiv.className = 'status safe'; } else if (current < 50) { statusDiv.innerHTML = '<div class="current-value">' + current.toFixed(3) + ' mA</div>' + '<div>警告:检测到电流!</div>'+ '<div class="warning-alert">⚠ 警告</div>'; statusDiv.className = 'status warning'; } }) .catch(error => { console.error('Error:', error); }); } setInterval(updateCurrent, 1000); </script> </head> <body> <div class="container"> <h1>电流监测系统</h1> <div id="status" class="status safe">加载中...</div> </div> </body> </html> )"; void initINA226() { Wire.begin(); if (!INA.begin()) { Serial.println("INA226 Init Failed!"); delay(1000); initINA226(); // 仅重试INA226初始化 } INA.setAverage(4); INA.setMaxCurrentShunt(MAX_CURRENT, SHUNT_RESISTOR); Serial.println("INA226 Init OK"); } void setup() { Serial.begin(115200); while (!Serial); // 初始化INA226 initINA226(); // 设置WiFi接入点模式 if (WiFi.status() == WL_NO_MODULE) { Serial.println("Communication with WiFi module failed!"); while (true); } // 创建接入点 WiFi.beginAP(ssid, password); delay(5000); // 等待AP启动 IPAddress ip = WiFi.localIP(); Serial.print("AP IP address: "); Serial.println(ip); // 启动服务器 server.begin(); Serial.println("Server started"); } void loop() { WiFiClient client = server.available(); if (client) { String currentLine = ""; String requestType = ""; // 读取HTTP请求头 while (client.connected()) { if (client.available()) { char c = client.read(); if (c == '\n') { // 如果是空行,说明请求头结束 if (currentLine.length() == 0) { // 根据请求类型发送响应 if (requestType.indexOf("GET /current") >= 0) { // 发送JSON数据 client.println("HTTP/1.1 200 OK"); client.println("Content-Type: application/json"); client.println("Access-Control-Allow-Origin: *"); client.println("Connection: close"); client.println(); // 构建JSON响应 String jsonResponse = "{\"current\":"; jsonResponse += String(currentValue, 3); jsonResponse += ",\"valid\":"; jsonResponse += isValidData ? "true" : "false"; jsonResponse += "}"; client.println(jsonResponse); } else { // 发送HTML页面 client.println("HTTP/1.1 200 OK"); client.println("Content-Type: text/html; charset=UTF-8"); client.println("Connection: close"); client.println(); client.println(htmlTemplate); } break; } else { // 保存第一行作为请求类型 if (requestType == "") { requestType = currentLine; } currentLine = ""; } } else if (c != '\r') { currentLine += c; } } } delay(10); // 给浏览器一点时间处理数据 client.stop(); } // 读取和处理电流数据 float current = INA.getCurrent_mA(); // 应用零点阈值 if(abs(current) < ZERO_THRESHOLD) { current = 0; } // 检测电流是否异常 if (current == ERROR_THRESHOLD) { errorCount++; if (errorCount >= MAX_ERROR_COUNT) { Serial.println("Error threshold reached. Restarting INA226..."); initINA226(); errorCount = 0; return; } } else { errorCount = 0; } // 更新电流值和有效性状态 if (current >= INVALID_THRESHOLD) { isValidData = false; } else { currentValue = current; isValidData = true; } // 状态变化检测和输出 boolean newState = current > ZERO_THRESHOLD && current < INVALID_THRESHOLD; if(newState != currentState) { unsigned long duration = millis() - lastChangeTime; Serial.print(millis()); Serial.print("\t"); Serial.print(current, 3); Serial.print("\t"); Serial.print(duration); Serial.print("\t"); Serial.println(newState ? "Current ON" : "Current OFF"); currentState = newState; lastChangeTime = millis(); } // 实时输出电流值到串口 Serial.print("Current: "); Serial.print(current, 3); Serial.println(" mA"); delay(100); }