小白使用ESP8266 IM1266 电量计数模块获取数据通过websocket发送服务器
前言
心血来潮突然想做个检测插座电压,功率,电量等信息,然后上传服务器,随时监控这些信息。
硬件采用Esp8266模块和IM1266 电量计数模块,并用Arduino IDE开发代码部分。下文中代码可以直接复制编译使用。
一、说明
开发过程中有些小bug:无法使用软件模拟串口和 IM1266 电量计数模块通信,但是又不知道是否能获取到数据。所以我是通过连接wifi然后使用websocket协议通信来实现的。
二、详细过程
1.ESP8266和IM1266 电量计数模块连线
通信:esp8266的RX接IM1266的TX (ESP8266的TX接IM1266的RX)
IM1266供电:esp8266的3v接IM1266的V+,GND接IM1266的V-(esp8266的vcc是5v电压也可以接IM1266的V+ ,IM1266V+ 支持5V)
暂时不接其他的,先测试,通过测试其他的
Arduino 代码:
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WebSocketsClient.h>
ESP8266WiFiMulti WiFiMulti; //wifi
WebSocketsClient webSocket; //websocket
unsigned char USART_TX_BUF[8]={0x01,0x03,0x00,0x48,0x00,0x08,0xC4,0x1A};
void setup() {
Serial.begin(4800); //IM1266通信默认波特率4800
//连接wifi
WiFiMulti.addAP("wifi名称", "wifi密码");
while(WiFiMulti.run() != WL_CONNECTED) {
delay(100);
}
//开启websocket
webSocket.begin("192.168.2.160", 2345, "/"); //websocket 通信目标ip地址 端口号 路径
webSocket.onEvent(webSocketEvent);
webSocket.setReconnectInterval(5000);
webSocket.enableHeartbeat(15000, 3000, 2);
}
void loop() {
webSocket.loop();
}
// //WebSocket客户端 处理
void webSocketEvent(WStype_t type, uint8_t * payload, size_t length) {
switch(type) {
case WStype_DISCONNECTED:
break;
case WStype_CONNECTED: {
while(1){
//发送数据
String result =""; //完整信息数据
String VStr,v1,v2,v3,v4 = ""; //存电压信息字符串
String IStr,i1,i2,i3,i4 = ""; //电流字符串
String PStr,p1,p2,p3,p4 = ""; //功率字符串
String QStr,q1,q2,q3,q4 = ""; //电量字符串
webSocket.sendTXT("发送数据=》");
Serial.write(USART_TX_BUF,8);
delay(500);
//开始读数据
for(int i = 0; i<37;i++){
String byteData = "";
byteData = String(Serial.read(),HEX); //第i+1个字节数据
result += byteData;
//第4~7个字节是电压信息
if(i == 3)v1=byteData;
if(i == 4)v2=byteData;
if(i == 5)v3=byteData;
if(i == 6)v4=byteData;
//第8~11个字节是电流信息
if(i == 7)i1=byteData;
if(i == 8)i2=byteData;
if(i == 9)i3=byteData;
if(i == 10)i4=byteData;
//第12~15个字节是功率信息
if(i == 11)p1=byteData;
if(i == 12)p2=byteData;
if(i == 13)p3=byteData;
if(i == 14)p4=byteData;
//第16~19个字节是电能信息
if(i == 15)q1=byteData;
if(i == 16)q2=byteData;
if(i == 17)q3=byteData;
if(i == 18)q4=byteData;
}
webSocket.sendTXT(result);//websocket 发送完整的字节
//IM1266文档 发送的第一个字节是01 用于判断接受的数据是否有效
if(result.charAt(0)== '1'){
//将4位拼接在一起 组成一个完整的信息
VStr =v1+v2+v3+v4;
IStr =i1+i2+i3+i4;
PStr =p1+p2+p3+p4;
QStr =q1+q2+q3+q4;
//拼接json数据发送给服务器
String data = "{";
data += "\"v\":\"";
data += VStr;
data += "\",";
data += "\"i\":\"";
data += IStr;
data += "\",";
data += "\"p\":\"";
data += PStr;
data += "\",";
data += "\"q\":\"";
data += QStr;
data += "\"}";
webSocket.sendTXT(data);
delay(1000);
}
}
break;
case WStype_TEXT:
break;
case WStype_BIN:
break;
case WStype_PING:
break;
case WStype_PONG:
break;
}
}
}
直接复制代码可以正常运行
2.代码解读
这是IM1266的文档。通过下列文档可知道需要先发送给IM1266发送数据01,03,00,48,00,08,C4,1A
然后IM1266会返回37个字节的数据。每个字节代表的数据可以在下面图片看到:
发送给IM1266数据
unsigned char USART_TX_BUF[8]={0x01,0x03,0x00,0x48,0x00,0x08,0xC4,0x1A}; //发送给IM1266的数据
Serial.write(USART_TX_BUF,8);//串口发送
delay(500);//延迟 IM1266数据的读取频率是250ms
IM1266会返回37个字节的数据,串口每次读取一个字节的数据。写个循环读取每个字节的信息,将对应的几个字节信息拼接在一起组成原始的数据信息,然后发送给服务器(如:第4~7个字节是电压信息,将4-7个字节拼接在一起,就是电压的16进制信息),下列是代码说明:
for(int i = 0; i<37;i++){
String byteData = "";
byteData = String(Serial.read(),HEX); //第i+1个字节数据
result += byteData;
//第4~7个字节是电压信息
if(i == 3)v1=byteData;
if(i == 4)v2=byteData;
if(i == 5)v3=byteData;
if(i == 6)v4=byteData;
//第8~11个字节是电流信息
if(i == 7)i1=byteData;
if(i == 8)i2=byteData;
if(i == 9)i3=byteData;
if(i == 10)i4=byteData;
//第12~15个字节是功率信息
if(i == 11)p1=byteData;
if(i == 12)p2=byteData;
if(i == 13)p3=byteData;
if(i == 14)p4=byteData;
//第16~19个字节是电能信息
if(i == 15)q1=byteData;
if(i == 16)q2=byteData;
if(i == 17)q3=byteData;
if(i == 18)q4=byteData;
}
webSocket.sendTXT(result);//websocket 发送完整的字节
//IM1266文档 发送的第一个字节是01 用于判断接受的数据是否有效
if(result.charAt(0)== '1'){
//将4位拼接在一起 组成一个完整的信息
VStr =v1+v2+v3+v4;
IStr =i1+i2+i3+i4;
PStr =p1+p2+p3+p4;
QStr =q1+q2+q3+q4;
//拼接json数据发送给服务器
String data = "{";
data += "\"v\":\"";
data += VStr;
data += "\",";
data += "\"i\":\"";
data += IStr;
data += "\",";
data += "\"p\":\"";
data += PStr;
data += "\",";
data += "\"q\":\"";
data += QStr;
data += "\"}";
webSocket.sendTXT(data);
delay(1000);
}
接下来是websocket服务端获取数据并显示,我这里是使用php的webman框架写的websocket服务:
完整的电压电流信息是16进制的数据除以1000
然后启动websocket服务,给esp8266通电:
电能390是之前接吹风机然后的数据,第一次应该都是0;
这样我们完整的数据测试通过了,然后下期我们接上插座正常测试下数据信息。
总结
如上,我们完整的使用ESP8266和IM1266通过Uart接口通信读取IM1266的电压,电流,功率和电量信息。虽然只是简单的一次测试,但可获取相关数据,成就感十足!