maker_lin 发表于 2016-4-12 19:56:07

Arduino电量采集 TCP透传方式上传乐联

本帖最后由 maker_lin 于 2016-4-13 11:23 编辑

一、主要实现功能

   arduino 通过 软串口 连接方式读取 电量模块 的数据, 并将数据通过ESP8266 采用 TCP透传 方式上传至乐联。

二、主要配件:

   1. ocrobot HEKR物联网开发板(测试使用,稳定运行后会换 arduino mini + ESP8266 ,)
   2. LT-518 电量计量模块
   3. AC220-DC12 电源模块(非必要,手头有闲置,所以用上了)

三、数据查看地址

   http://www.lewei50.com/u/g/9131

四、相关资料说明及成品图片

拿吃完的巧克力盒子凑合先用着
http://image.geek-workshop.com/album/201604/12/204455gsbz88brc7reza01.png
http://image.geek-workshop.com/album/201604/12/204457ark0k6wcrk106ycz.png
直接挂办公室电箱旁
http://image.geek-workshop.com/album/201604/12/204459d4oeb3dmo64nms4n.png

这个是电量计量模块
http://image.geek-workshop.com/album/201604/12/204450gopszhf99111m8v6.png
http://image.geek-workshop.com/album/201604/12/204451dek4s0yygqju3k0j.png

模块的一些数据格式要求
http://image.geek-workshop.com/album/201604/12/204452mgefbsp42jsc4gj2.png
http://image.geek-workshop.com/album/201604/12/204454kp8ppgzzdn20029f.png

电量计量模块相对比较简单,就是发送一组数据向模块请求数据,然后模块会返回一组数据, 格式都差不多,按照资料解析下数据就好。


各部分功能(简易流程)
1.   Arduino            >>>查询数据>>> 电量模块>>>返回数据
      Arduino            >>>读取数据>>> 整理数据格式>>>发送到串口 ESP8266
2.   ESP8266         >>>读取串口数据>>>转发到乐联

ESP8266是使用 arduino的IDE 编写的代码,这个使用方法可以参考http://www.arduino.cn/thread-17895-1-1.html 这篇文章


五、代码部分
arduino 代码
#include <Wire.h>
#include<SoftwareSerial.h>



unsigned charTx_Buffer;
unsigned charRx_Buffer;
unsigned charread_enable, receive_finished, reveive_number;

floatVoltage_data, Current_data, Power_data, Energy_data, Pf_data, CO2_data;
floatVoltage,Current,Power,Energy,Pf,CO2;

SoftwareSerial softSerial(10, 11);


void setup() {

Serial.begin(115200);         
softSerial.begin(4800);
softSerial.listen();
}

void loop() {

write_data();
delay(100);
read_data();
delay(100);
   Analysis_data();
   delay(100);

    float Voltage= Voltage_data/10000;
    float Current= Current_data/10000;
    float Power= Power_data/10000;
    float Energy= Energy_data/10000;
    float Pf= Pf_data/1000;
    float CO2= CO2_data/10000;

Serial.println("{\"method\": \"update\",\"gatewayNo\": \"01\",\"userkey\": \"*****************************\"}&^!");
    delay(20000);
//向乐联注册

Serial.print("{\"method\": \"upload\",\"data\":[{\"Name\":\"DY\",\"Value\":\"");
Serial.print(Voltage);
Serial.print("\"},{\"Name\":\"DL\",\"Value\":\"");
Serial.print(Current);
Serial.print("\"},{\"Name\":\"GL\",\"Value\":\"");
Serial.print(Power);
Serial.print("\"},{\"Name\":\"YDL\",\"Value\":\"");
Serial.print(Energy);
Serial.print("\"},{\"Name\":\"GLYS\",\"Value\":\"");
Serial.print(Pf);
Serial.print("\"},{\"Name\":\"WD\",\"Value\":\"");
Serial.print(CO2);
Serial.println("\"}]}&^!");
delay(30000);

}

unsigned int calccrc(unsigned char crcbuf, unsigned int crc)
{
unsigned char i;
unsigned char chk;
crc = crc ^ crcbuf;
for (i = 0; i < 8; i++)
{
    chk = ( unsigned char)(crc & 1);
    crc = crc >> 1;
    crc = crc & 0x7fff;
    if (chk == 1)
      crc = crc ^ 0xa001;
    crc = crc & 0xffff;
}
return crc;
}

unsigned int chkcrc(unsigned char *buf, unsigned char len)
{
unsigned char hi, lo;
unsigned int i;
unsigned int crc;
crc = 0xFFFF;
for (i = 0; i < len; i++)
{
    crc = calccrc(*buf, crc);
    buf++;
}
hi = ( unsigned char)(crc % 256);
lo = ( unsigned char)(crc / 256);
crc = (((unsigned int)(hi)) << 8) | lo;
return crc;
}

void write_data(void)
{
union        crcdata
{
    unsigned int word16;
    unsigned charbyte;
} crcnow;
read_enable = 1;
if (read_enable == 1)
{
    read_enable = 0;
    Tx_Buffer = 0x01;
    Tx_Buffer = 0x03;
    Tx_Buffer = 0x00;
    Tx_Buffer = 0x48;
    Tx_Buffer = 0x00;
    Tx_Buffer = 0x06;
    crcnow.word16 = chkcrc(Tx_Buffer, 6);
    Tx_Buffer = crcnow.byte;
    Tx_Buffer = crcnow.byte;
    softSerial.write(Tx_Buffer, 8) ;          
}
}

void read_data()
{

if ( softSerial.available() > 0 )
{
   softSerial.readBytes(Rx_Buffer,34) ;
    delay(10);
   
}

}

void Analysis_data(void)
{
unsigned char i;
union        crcdata
{
    unsigned int word16;
    unsigned charbyte;
} crcnow;
receive_finished=1;
if (receive_finished == 1)
{
    receive_finished = 0;
    unsigned char reveive_numbe = 34;
    if (Rx_Buffer == 0x01);
    {
      crcnow.word16 = chkcrc(Rx_Buffer, reveive_numbe - 2);
      if ((crcnow.byte == Rx_Buffer) && (crcnow.byte == Rx_Buffer))
      {
      Voltage_data = (((unsigned long)(Rx_Buffer)) << 24) | (((unsigned long)(Rx_Buffer)) << 16) | (((unsigned long)(Rx_Buffer)) << 8) | Rx_Buffer;
      Current_data = (((unsigned long)(Rx_Buffer)) << 24) | (((unsigned long)(Rx_Buffer)) << 16) | (((unsigned long)(Rx_Buffer)) << 8) | Rx_Buffer;
      Power_data = (((unsigned long)(Rx_Buffer)) << 24) | (((unsigned long)(Rx_Buffer)) << 16) | (((unsigned long)(Rx_Buffer)) << 8) | Rx_Buffer;
      Energy_data = (((unsigned long)(Rx_Buffer)) << 24) | (((unsigned long)(Rx_Buffer)) << 16) | (((unsigned long)(Rx_Buffer)) << 8) | Rx_Buffer;
      Pf_data = (((unsigned long)(Rx_Buffer)) << 24) | (((unsigned long)(Rx_Buffer)) << 16) | (((unsigned long)(Rx_Buffer)) << 8) | Rx_Buffer;
      CO2_data = (((unsigned long)(Rx_Buffer)) << 24) | (((unsigned long)(Rx_Buffer)) << 16) | (((unsigned long)(Rx_Buffer)) << 8) | Rx_Buffer;
   
      }
    }
}
}

esp8266 透传代码
#include <ESP8266WiFi.h>
const char *ssid   = "wifi ssid";//这里是我的wifi,你使用时修改为你要连接的wifi ssid
const char *password = "password";//你要连接的wifi密码
const char *host = "42.121.128.216";//修改为手机的的tcpServer服务端的IP地址,即手机在路由器上的ip
WiFiClient client;
const int tcpPort = 9960;//修改为你建立的Server服务端的端口号


void setup()
{
Serial.begin(115200);
delay(10);

Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED)//WiFi.status() ,这个函数是wifi连接状态,返回wifi链接状态
   
{
    delay(500);
    Serial.print(".");
}//如果没有连通向串口发送.....

Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());//WiFi.localIP()返回8266获得的ip地址
}


void loop()
{
while (!client.connected())//几个非连接的异常处理
{
    if (!client.connect(host, tcpPort))
    {
      Serial.println("connection....");
      //client.stop();
      delay(500);

    }
}

while (client.available())//无线读取到的数据转发到到串口
    {
      uint8_t c = client.read();
      Serial.write(c);
    }


    if (Serial.available())//串口读取到的转发到wifi,因为串口是一位一位的发送所以在这里缓存完再发送
    {
      size_t counti = Serial.available();
      uint8_t sbuf;
      Serial.readBytes(sbuf, counti);
      client.write(sbuf, counti);

    }

}



爱上即可 发表于 2016-4-12 21:13:26

赞用的MODBUS协议啊,楼主 留个QQ吧,有问题请教
页: [1]
查看完整版本: Arduino电量采集 TCP透传方式上传乐联