搜索
bottom↓
回复: 2

转帖-可视化网络电表搭建攻略(基于arduino+w5100)

[复制链接]

出0入0汤圆

发表于 2013-9-1 09:24:26 | 显示全部楼层 |阅读模式
原文地址 :http://www.geek-workshop.com/thread-5649-1-1.html


×友情提示,修改电路前,一定要断开电源总开关×

你想象过看着家里的电器用电的样子吗?
你知道你每月那几天交的钱都去了哪里了吗?
你知道是什么东东在偷偷的用你的电吗?

如果你感兴趣,下面的文章适合你。

电,对于很多人来说是个很神秘,很危险,很神奇的东西。现在通过下面的攻略,你也可以拥有这样神奇的超能力,看到家里的电跑到哪里去了,是不是很想要?

====小广告====
你需要:
一个测电笔
一个十字口螺丝刀
一个平口螺丝刀
一把尖嘴钳
一个电量测量模块
一个通讯底板(我用的乐联网的E-KIT),你也可以使用任何一种arduino+w5100模块来搭建



====广告结束===

先看看效果图(据说近期会有新版的展示界面)
在线链接:
http://www.lewei50.com/home/gatewaystatus/1298



看到下面的锯齿状图形了吗?那就是你的冰箱在努力保持西瓜的新鲜。
几个用电高峰,是空调们在为主人降温。
用电量怎么总是高于0呢?那是你的无线路由器在保持家里的网络时刻畅通。

现在分步骤来实现它:
1断电
要断开家里空气开关的总闸,如果有室外的总闸,那就拉室外的总闸,保证家里是没有电的。
操作时严禁一只手碰火线,一只手碰零线。



2接线
打开家里的配电箱,找到总的进户的火线,拆开,把电量测量模块的圈圈套在这个火线上,专业术语是“互感器”。并把火线按照原来的位置接回去。


按照接线说明图,连接好测量模块、通讯模块和arduino。
3通电
如果你的操作正确,这时候推上你家的空气开关总闸,是不会有任何反应的。如果有问题,会跳闸。
4注册网站及设置对应传感器
http://www.lewei50.com/
注册及配置传感器过程不详细说明了。简单说下我的传感器的命名,你也可以有你自己的。



5刷代码
刷代码是为了从通讯模块里面把电量等数据读出来,并上传到乐联网上。

代码中使用了乐联网的类库,从这里下载:
http://www.github.com/lewei50/LeWeiClient/

实现代码:
  1. // LeWei AC Power Meter trail success2013.06.25
  2. // LeWei AC Power Meter (ZongBiao60A)trail syccess 2013.06.30 18:50pm
  3. // 4 Parameter: watt / kwh / Amp / Voltage / Pf

  4. /* FIXME: not yet being used */
  5. unsigned long interframe_delay = 2;  /* Modbus t3.5 = 2 ms */

  6. /*
  7. * preset_multiple_registers: Modbus function 16. Write the data from an
  8. * array into the holding registers of a slave.
  9. * INPUTS
  10. * slave: modbus slave id number
  11. * start_addr: address of the slave's first register (+1)
  12. * reg_count: number of consecutive registers to preset
  13. * data: array of words (ints) with the data to write into the slave
  14. * RETURNS: the number of bytes received as response on success, or
  15. *         0 if no bytes received (i.e. response timeout)
  16. *        -1 to -4 (modbus exception code)
  17. *        -5 for other errors (port error, etc.).
  18. */

  19. int preset_multiple_registers(int slave, int start_addr,
  20. int reg_count, int *data);

  21. /*
  22. * read_holding_registers: Modbus function 3. Read the holding registers
  23. * in a slave and put the data into an array
  24. * INPUTS
  25. * slave: modbus slave id number
  26. * start_addr: address of the slave's first register (+1)
  27. * count: number of consecutive registers to read
  28. * dest: array of words (ints) on which the read data is to be stored
  29. * dest_size: size of the array, which should be at least 'count'
  30. * RETURNS: the number of bytes received as response on success, or
  31. *         0 if no valid response received (i.e. response timeout, bad crc)
  32. *        -1 to -4 (modbus exception code)
  33. *        -5 for other errors (port error, etc.).
  34. */

  35. int read_holding_registers(int slave, int start_addr, int count,
  36. int *dest, int dest_size);


  37. /*
  38.    open.lewei50.com  sensor  client
  39. */



  40. #include
  41. #include
  42. #include

  43. #define USERKEY          "Your API Key" // replace your key here
  44. #define LW_GATEWAY       "Your Gateway No."
  45.   
  46. LeWeiClient *lwc;


  47. unsigned long lastConnectionTime = 0;          // last time you connected to the server, in milliseconds
  48. boolean lastConnected = false;                 // state of the connection last time through the main loop
  49. const unsigned long postingInterval = 30*1000; //delay between updates to cosm.com


  50. int pin = 8;
  51. unsigned long duration;
  52. unsigned long starttime;
  53. unsigned long sampletime_ms = 30000;
  54. unsigned long lowpulseoccupancy = 0;
  55. float ratio = 0;
  56. double concentration = 0;

  57. void setup() {

  58.    // start serial port:
  59.    Serial.begin(4800);
  60.    pinMode(8,INPUT);

  61.   delay(10000);               
  62.    
  63.    lwc = new LeWeiClient(USERKEY, LW_GATEWAY);

  64.    starttime = millis();
  65. }
  66. /* filter program : 20130521 */
  67. #define FILTERLEN 10

  68. unsigned long Array_Average( unsigned long* Array,int length)
  69. {
  70.     int x;
  71.     unsigned long returnVal;
  72.     unsigned long result=0;
  73.     for(x=0;xsindex)
  74.   {
  75.       sindex++;
  76.       Serial.println(sindex);
  77.       sfiterArray[sindex]=lowpulse;
  78.          Serial.println("filter1 END");
  79.       return lowpulse;
  80.   }
  81.   else
  82.   {
  83.       for(x=0;xappend("w", Watt);
  84.       lwc->append("a", Amp);
  85.       lwc->append("v", Voltage);
  86.       lwc->append("pf", Pf);
  87. //      lwc->append("06", Cabon);
  88.       
  89.      
  90.         lwc->send();   
  91.         delay(15000);
  92. }

  93. // this method makes a HTTP connection to the server:


  94. /****************************************************************************
  95. * BEGIN MODBUS RTU MASTER FUNCTIONS
  96. ****************************************************************************/

  97. //#define TIMEOUT 1000          /* 1 second */
  98. #define TIMEOUT 10000          /* 10 second */
  99. #define MAX_READ_REGS 125
  100. #define MAX_WRITE_REGS 125
  101. #define MAX_RESPONSE_LENGTH 256
  102. #define PRESET_QUERY_SIZE 256
  103. /* errors */
  104. #define PORT_ERROR -5

  105. /*
  106. CRC

  107. INPUTS:
  108. buf   ->  Array containing message to be sent to controller.           
  109. start ->  Start of loop in crc counter, usually 0.
  110. cnt   ->  Amount of bytes in message being sent to controller/
  111. OUTPUTS:
  112. temp  ->  Returns crc byte for message.
  113. COMMENTS:
  114. This routine calculates the crc high and low byte of a message.
  115. Note that this crc is only used for Modbus, not Modbus+ etc.
  116. ****************************************************************************/

  117. unsigned int crc(unsigned char *buf, int start, int cnt)
  118. {
  119.   int i, j;
  120.   unsigned temp, temp2, flag;

  121.   temp = 0xFFFF;

  122.   for (i = start; i < cnt; i++) {
  123.     temp = temp ^ buf[i];

  124.     for (j = 1; j <= 8; j++) {
  125.       flag = temp & 0x0001;
  126.       temp = temp >> 1;
  127.       if (flag)
  128.         temp = temp ^ 0xA001;
  129.     }
  130.   }

  131.   /* Reverse byte order. */

  132.   temp2 = temp >> 8;
  133.   temp = (temp << 8) | temp2;
  134.   temp &= 0xFFFF;

  135.   return (temp);
  136. }


  137. /***********************************************************************
  138. *
  139. *      The following functions construct the required query into
  140. *      a modbus query packet.
  141. *
  142. ***********************************************************************/

  143. #define REQUEST_QUERY_SIZE 6     /* the following packets require          */
  144. #define CHECKSUM_SIZE 2          /* 6 unsigned chars for the packet plus   */
  145. /* 2 for the checksum.                    */

  146. void build_request_packet(int slave, int function, int start_addr,
  147. int count, unsigned char *packet)
  148. {
  149.   packet[0] = slave;
  150.   packet[1] = function;
  151.   start_addr -= 1;
  152.   packet[2] = start_addr >> 8;
  153.   packet[3] = start_addr & 0x00ff;
  154.   packet[4] = count >> 8;
  155.   packet[5] = count & 0x00ff;

  156.   //below test only
  157.   //        packet[0] =0x01;
  158.   //        packet[1] = 0x03;
  159.   //        packet[2] = 0;
  160.   //        packet[3] = 0x48;
  161.   //        packet[4] = 0;
  162.   //        packet[5] = 0x02;
  163. }

  164. /*************************************************************************
  165. *
  166. * modbus_query( packet, length)
  167. *
  168. * Function to add a checksum to the end of a packet.
  169. * Please note that the packet array must be at least 2 fields longer than
  170. * string_length.
  171. **************************************************************************/

  172. void modbus_query(unsigned char *packet, size_t string_length)
  173. {
  174.   int temp_crc;

  175.   temp_crc = crc(packet, 0, string_length);

  176.   packet[string_length++] = temp_crc >> 8;
  177.   packet[string_length++] = temp_crc & 0x00FF;
  178.   packet[string_length] = 0;
  179. }



  180. /***********************************************************************
  181. *
  182. * send_query(query_string, query_length )
  183. *
  184. * Function to send a query out to a modbus slave.
  185. ************************************************************************/

  186. int send_query(unsigned char *query, size_t string_length)
  187. {

  188.   int i;

  189.   modbus_query(query, string_length);
  190.   string_length += 2;

  191.   for (i = 0; i < string_length; i++) {
  192.     //                Serial.print(query[i], HEX); //Orginal
  193.     Serial.write(query[i]); //JingLi

  194.   }
  195.   /* without the following delay, the reading of the response might be wrong
  196.    * apparently, */
  197.   delay(200);            /* FIXME: value to use? */

  198.   return i;           /* it does not mean that the write was succesful, though */
  199. }


  200. /***********************************************************************
  201. *
  202. *      receive_response( array_for_data )
  203. *
  204. * Function to monitor for the reply from the modbus slave.
  205. * This function blocks for timeout seconds if there is no reply.
  206. *
  207. * Returns:     Total number of characters received.
  208. ***********************************************************************/

  209. int receive_response(unsigned char *received_string)
  210. {

  211.   int bytes_received = 0;
  212.   int i = 0;
  213.   /* wait for a response; this will block! */
  214.   while(Serial.available() == 0) {
  215.     delay(1);
  216.     if (i++ > TIMEOUT)
  217.       return bytes_received;
  218.   }
  219.   delay(200);
  220.   /* FIXME: does Serial.available wait 1.5T or 3.5T before exiting the loop? */
  221.   while(Serial.available()) {
  222.     received_string[bytes_received] = Serial.read();
  223.     //                Serial.print(bytes_received);                       //only test
  224.     //                Serial.print("-");                                //only test
  225.     //                Serial.println(received_string[bytes_received]);  //only test
  226.     bytes_received++;
  227.     if (bytes_received >= MAX_RESPONSE_LENGTH)
  228.       return PORT_ERROR;
  229.   }   
  230.   //Serial.print("bytes_received=");
  231.   //Serial.println(bytes_received);
  232.   return (bytes_received);
  233. }


  234. /*********************************************************************
  235. *
  236. *      modbus_response( response_data_array, query_array )
  237. *
  238. * Function to the correct response is returned and that the checksum
  239. * is correct.
  240. *
  241. * Returns:     string_length if OK
  242. *           0 if failed
  243. *           Less than 0 for exception errors
  244. *
  245. *      Note: All functions used for sending or receiving data via
  246. *            modbus return these return values.
  247. *
  248. **********************************************************************/

  249. int modbus_response(unsigned char *data, unsigned char *query)
  250. {
  251.   int response_length;
  252.   int i;
  253.   unsigned int crc_calc = 0;
  254.   unsigned int crc_received = 0;
  255.   unsigned char recv_crc_hi;
  256.   unsigned char recv_crc_lo;

  257.   do {        // repeat if unexpected slave replied
  258.     response_length = receive_response(data);
  259.   }
  260.   while ((response_length > 0) && (data[0] != query[0]));
  261.   //      for (i = 0; i  0)
  262.     raw_response_length -= 2;

  263.   if (raw_response_length > 0) {
  264.     /* FIXME: data[2] * 2 ???!!! data[2] isn't already the byte count (number of registers * 2)?! */
  265.     for (i = 0;
  266.                i < (data[2] * 2) && i < (raw_response_length / 2);
  267.                i++) {

  268.       /* shift reg hi_byte to temp */
  269.       temp = data[3 + i * 2] << 8;
  270.       /* OR with lo_byte           */
  271.       temp = temp | data[4 + i * 2];

  272.       dest[i] = temp;
  273.     }
  274.   }
  275.   return (raw_response_length);
  276. }


  277. /***********************************************************************
  278. *
  279. *      preset_response
  280. *
  281. *      Gets the raw data from the input stream.
  282. *
  283. ***********************************************************************/

  284. int preset_response(unsigned char *query)
  285. {
  286.   unsigned char data[MAX_RESPONSE_LENGTH];
  287.   int raw_response_length;

  288.   raw_response_length = modbus_response(data, query);

  289.   return (raw_response_length);
  290. }


  291. /************************************************************************
  292. *
  293. *      read_holding_registers
  294. *
  295. *      Read the holding registers in a slave and put the data into
  296. *      an array.
  297. *
  298. *************************************************************************/

  299. int read_holding_registers(int slave, int start_addr, int count,
  300. int *dest, int dest_size)
  301. {
  302.   int function = 0x03;      /* Function: Read Holding Registers */
  303.   int ret;

  304.   unsigned char packet[REQUEST_QUERY_SIZE + CHECKSUM_SIZE];

  305.   if (count > MAX_READ_REGS) {
  306.     count = MAX_READ_REGS;
  307.   }

  308.   build_request_packet(slave, function, start_addr, count, packet);

  309.   if (send_query(packet, REQUEST_QUERY_SIZE) > -1) {
  310.     ret = read_reg_response(dest, dest_size, packet);
  311.   }
  312.   else {

  313.     ret = -1;
  314.   }

  315.   return (ret);
  316. }


  317. /************************************************************************
  318. *
  319. *      preset_multiple_registers
  320. *
  321. *      Write the data from an array into the holding registers of a
  322. *      slave.
  323. *
  324. *************************************************************************/

  325. int preset_multiple_registers(int slave, int start_addr,
  326. int reg_count, int *data)
  327. {
  328.   int function = 0x10;      /* Function 16: Write Multiple Registers */
  329.   int byte_count, i, packet_size = 6;
  330.   int ret;

  331.   unsigned char packet[PRESET_QUERY_SIZE];

  332.   if (reg_count > MAX_WRITE_REGS) {
  333.     reg_count = MAX_WRITE_REGS;
  334.   }

  335.   build_request_packet(slave, function, start_addr, reg_count, packet);
  336.   byte_count = reg_count * 2;
  337.   packet[6] = (unsigned char)byte_count;

  338.   for (i = 0; i < reg_count; i++) {
  339.     packet_size++;
  340.     packet[packet_size] = data[i] >> 8;
  341.     packet_size++;
  342.     packet[packet_size] = data[i] & 0x00FF;
  343.   }

  344.   packet_size++;
  345.   if (send_query(packet, packet_size) > -1) {
  346.     ret = preset_response(packet);
  347.   }
  348.   else {
  349.     ret = -1;
  350.   }

  351.   return (ret);
  352. }

复制代码
6将电量可视化、数字化之后,你可以做很多的事情,自己琢磨吧~

Enjoy it~

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2013-9-1 09:57:06 | 显示全部楼层
挺好的,支持

出0入0汤圆

发表于 2013-11-26 09:58:43 | 显示全部楼层
mark 网络电表
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 03:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表