profile

profile

0个粉丝

15

问答

0

专栏

20

资料

profile  发布于  2013-11-20 19:33:47
采纳率 0%
15个问答
3941

可视化网络电表搭建攻略

标题起得比较唬人,请无视。

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

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

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

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

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

先看看效果图(据说近期会有新版的展示界面) 在线链接: http://www.lewei50.com/u/g/1979 [attach]1153[/attach] [attach]1154[/attach] 看到下面的锯齿状图形了吗?那就是你的冰箱在努力保持西瓜的新鲜。 几个用电高峰,是空调们在为主人降温。 用电量怎么总是高于0呢?那是你的无线路由器在保持家里的网络时刻畅通。

现在分步骤来实现它: 1断电 要断开家里空气开关的总闸,如果有室外的总闸,那就拉室外的总闸,保证家里是没有电的。 操作时严禁一只手碰火线,一只手碰零线。 [attach]1155[/attach] 2接线 打开家里的配电箱,找到总的进户的火线,拆开,把电量测量模块的圈圈套在这个火线上,专业术语是“互感器”。并把火线按照原来的位置接回去。 [attach]1157[/attach] 按照接线说明图,连接好测量模块、通讯模块和arduino。 3通电 如果你的操作正确,这时候推上你家的空气开关总闸,是不会有任何反应的。如果有问题,会跳闸。 4注册网站及设置对应传感器 http://www.lewei50.com/ 注册及配置传感器过程不详细说明了。简单说下我的传感器的命名,你也可以有你自己的。 [attach]1156[/attach] 5刷代码 刷代码是为了从通讯模块里面把电量等数据读出来,并上传到乐联网上。

代码中使用了乐联网的类库,从这里下载: http://www.github.com/lewei50/LeWeiClient/ [code]// LeWei AC Power Meter trail success2013.06.25 // LeWei AC Power Meter (ZongBiao60A)trail syccess 2013.06.30 18:50pm // 4 Parameter: watt / kwh / Amp / Voltage / Pf

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

/*

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

int preset_multiple_registers(int slave, int start_addr, int reg_count, int *data);

/*

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

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

/ open.lewei50.com sensor client /

include

include

include

define USERKEY "Your API Key" // replace your key here

define LW_GATEWAY "Your Gateway No."

LeWeiClient *lwc;

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

int pin = 8; unsigned long duration; unsigned long starttime; unsigned long sampletime_ms = 30000; unsigned long lowpulseoccupancy = 0; float ratio = 0; double concentration = 0;

void setup() {

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

delay(10000);

lwc = new LeWeiClient(USERKEY, LW_GATEWAY);

starttime = millis(); } / filter program : 20130521 /

define FILTERLEN 10

unsigned long Array_Average( unsigned long* Array,int length) { int x; unsigned long returnVal; unsigned long result=0; for(x=0;x<length;x++) { result+=Array[x]; Serial.print("result="); Serial.println(result); } returnVal=result/length; return returnVal; }

unsigned long Filter1(unsigned long lowpulse) { static unsigned long sfiterArray[FILTERLEN]; static int sindex=0; int x; Serial.println("filter1 begin:"); if(FILTERLEN>sindex) { sindex++; Serial.println(sindex); sfiterArray[sindex]=lowpulse; Serial.println("filter1 END"); return lowpulse; } else { for(x=0;x<FILTERLEN-1;x++) { sfiterArray[x]=sfiterArray[x+1]; } sfiterArray[FILTERLEN-1]=lowpulse; for(x=0;x<FILTERLEN;x++) { Serial.println(sfiterArray[x]); } Serial.println("Aver:"); Serial.println(Array_Average(sfiterArray,FILTERLEN)); Serial.println("filter1 END"); return(Array_Average(sfiterArray,FILTERLEN));

}

} /END: filter program : 20130521 /

int x=0; //simulated sensor output int sampling=1; int transfering=0;

/ Modbus para / int retval; int data[10]; int tt[30]; //int changed to unsigned int

void loop() {

int i;
/ example, this will write some data in the first 10 registers of slave 1 / // retval = preset_multiple_registers(1,1,10, data);

// data[0] = retval; // data[1]++; // data[8]=0xdead; // data[9] = 0xbeaf; // delay(500); //int read_holding_registers(int slave, int start_addr, int count,int *dest, int dest_size);
// retval = read_holding_registers(2,1, 1,tt,6);
retval = read_holding_registers(1, 0x49, 6, tt, 1); // 1:5,2:7,3:9 // delay(1000); // Serial.print("receve flag=");
// Serial.println(retval);

int Voltage = tt[0]; Voltage = Voltage / 100; float Amp = tt[1]; Amp = Amp / 1000; int Watt = tt[2]; //long y=x065536+x1; unsigned int Kwhh = (unsigned int)tt[3]; //unsigned int Kwhh = (unsigned int)65535; //test maximum unsigned int Kwhl = (unsigned int)tt[4]; unsigned long kwhA = (unsigned long) Kwhh 65536 + Kwhl; // unsigned long kwhA = Kwhh <<16 + Kwhl; float Kwh = kwhA; Kwh = Kwh / 3200; // double Kwh = kwhA / 3200; //Kwh = kwh / 32; // int Kwh = tt[4]; float Pf = tt[5]; Pf = Pf / 1000; float Cabon = tt[5]; Cabon = Cabon / 1000;

Serial.print(Voltage); Serial.print(Amp); Serial.print(Watt); Serial.print(Kwh); Serial.print(Pf); Serial.print(Cabon);

// 4 Parameter: watt / kwh / Amp / Voltage / Pf // 这里的名字要跟你之前在网站上设置的对应起来

  lwc->append("kwh", Kwh);
  lwc->append("w", Watt);
  lwc->append("a", Amp); 
  lwc->append("v", Voltage); 
  lwc->append("pf", Pf); 

// lwc->append("06", Cabon);

    lwc->send();   
    delay(15000);

}

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

/****

  • BEGIN MODBUS RTU MASTER FUNCTIONS ****/

//#define TIMEOUT 1000 / 1 second /

define TIMEOUT 10000 / 10 second /

define MAX_READ_REGS 125

define MAX_WRITE_REGS 125

define MAX_RESPONSE_LENGTH 256

define PRESET_QUERY_SIZE 256

/ errors /

define PORT_ERROR -5

/* CRC

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

unsigned int crc(unsigned char *buf, int start, int cnt) { int i, j; unsigned temp, temp2, flag;

temp = 0xFFFF;

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

for (j = 1; j <= 8; j++) {
  flag = temp & 0x0001;
  temp = temp >> 1;
  if (flag)
    temp = temp ^ 0xA001;
}

}

/ Reverse byte order. /

temp2 = temp >> 8; temp = (temp << 8) | temp2; temp &= 0xFFFF;

return (temp); }

/*** *

  • The following functions construct the required query into
  • a modbus query packet.
  • ***/

define REQUEST_QUERY_SIZE 6 / the following packets require /

define CHECKSUM_SIZE 2 / 6 unsigned chars for the packet plus /

/ 2 for the checksum. /

void build_request_packet(int slave, int function, int start_addr, int count, unsigned char *packet) { packet[0] = slave; packet[1] = function; start_addr -= 1; packet[2] = start_addr >> 8; packet[3] = start_addr & 0x00ff; packet[4] = count >> 8; packet[5] = count & 0x00ff;

//below test only // packet[0] =0x01; // packet[1] = 0x03; // packet[2] = 0; // packet[3] = 0x48; // packet[4] = 0; // packet[5] = 0x02; }

/***** *

  • modbus_query( packet, length)
  • Function to add a checksum to the end of a packet.
  • Please note that the packet array must be at least 2 fields longer than
  • string_length. **/

void modbus_query(unsigned char *packet, size_t string_length) { int temp_crc;

temp_crc = crc(packet, 0, string_length);

packet[string_length++] = temp_crc >> 8; packet[string_length++] = temp_crc & 0x00FF; packet[string_length] = 0; }

/*** *

  • send_query(query_string, query_length )
  • Function to send a query out to a modbus slave. ****/

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

int i;

modbus_query(query, string_length); string_length += 2;

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

} /* without the following delay, the reading of the response might be wrong

  • apparently, / delay(200); / FIXME: value to use? */

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

/*** *

  • receive_response( array_for_data )
  • Function to monitor for the reply from the modbus slave.
  • This function blocks for timeout seconds if there is no reply.
  • Returns: Total number of characters received. ***/

int receive_response(unsigned char *received_string) {

int bytes_received = 0; int i = 0; / wait for a response; this will block! / while(Serial.available() == 0) { delay(1); if (i++ > TIMEOUT) return bytes_received; } delay(200); / FIXME: does Serial.available wait 1.5T or 3.5T before exiting the loop? / while(Serial.available()) { received_string[bytes_received] = Serial.read(); // Serial.print(bytes_received); //only test // Serial.print("-"); //only test // Serial.println(received_string[bytes_received]); //only test bytes_received++; if (bytes_received >= MAX_RESPONSE_LENGTH) return PORT_ERROR; }
//Serial.print("bytes_received="); //Serial.println(bytes_received); return (bytes_received); }

/***** *

  • modbus_response( response_data_array, query_array )
  • Function to the correct response is returned and that the checksum
  • is correct.
  • Returns: string_length if OK
  • 0 if failed
  • Less than 0 for exception errors
  • Note: All functions used for sending or receiving data via
  • modbus return these return values.
  • **/

int modbus_response(unsigned char data, unsigned char query) { int response_length; int i; unsigned int crc_calc = 0; unsigned int crc_received = 0; unsigned char recv_crc_hi; unsigned char recv_crc_lo;

do { // repeat if unexpected slave replied response_length = receive_response(data); } while ((response_length > 0) && (data[0] != query[0])); // for (i = 0; i <response_length; i++) { Serial.print(data[i]);Serial.print("---"); Serial.println(query[i]);} //only test

if (response_length) {

crc_calc = crc(data, 0, response_length - 2);

recv_crc_hi = (unsigned) data[response_length - 2];
recv_crc_lo = (unsigned) data[response_length - 1];

crc_received = data[response_length - 2];
crc_received = (unsigned) crc_received << 8;
crc_received =
  crc_received | (unsigned) data[response_length - 1];

/*********** check CRC of response ************/

if (crc_calc != crc_received) {
  response_length = 0;
  //                       Serial.println("CRC erro");                       //only test
}

/********** check for exception response *****/

if (response_length && data[1] != query[1]) {
  response_length = 0 - data[2];
}

} return (response_length); }

/**** *

  • read_reg_response
  • reads the response data from a slave and puts the data into an
  • array.
  • ****/

int read_reg_response(int dest, int dest_size, unsigned char query) {

unsigned char data[MAX_RESPONSE_LENGTH]; int raw_response_length; int temp, i;

raw_response_length = modbus_response(data, query); if (raw_response_length > 0) raw_response_length -= 2;

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

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

  dest[i] = temp;
}

} return (raw_response_length); }

/*** *

  • preset_response
  • Gets the raw data from the input stream.
  • ***/

int preset_response(unsigned char *query) { unsigned char data[MAX_RESPONSE_LENGTH]; int raw_response_length;

raw_response_length = modbus_response(data, query);

return (raw_response_length); }

/**** *

  • read_holding_registers
  • Read the holding registers in a slave and put the data into
  • an array.
  • *****/

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

unsigned char packet[REQUEST_QUERY_SIZE + CHECKSUM_SIZE];

if (count > MAX_READ_REGS) { count = MAX_READ_REGS; }

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

if (send_query(packet, REQUEST_QUERY_SIZE) > -1) { ret = read_reg_response(dest, dest_size, packet); } else {

ret = -1;

}

return (ret); }

/**** *

  • preset_multiple_registers
  • Write the data from an array into the holding registers of a
  • slave.
  • *****/

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

unsigned char packet[PRESET_QUERY_SIZE];

if (reg_count > MAX_WRITE_REGS) { reg_count = MAX_WRITE_REGS; }

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

for (i = 0; i < reg_count; i++) { packet_size++; packet[packet_size] = data[i] >> 8; packet_size++; packet[packet_size] = data[i] & 0x00FF; }

packet_size++; if (send_query(packet, packet_size) > -1) { ret = preset_response(packet); } else { ret = -1; }

return (ret); } [/code] 6将电量可视化、数字化之后,你可以做很多的事情,自己琢磨吧~

Enjoy it~ 原帖地址 http://www.geek-workshop.com/thread-5649-1-1.html

我来回答
回答1个
时间排序
认可量排序

perseverance

0个粉丝

8

问答

0

专栏

13

资料

perseverance 2013-11-24 23:01:40
认可0
用现成的东西搭建,会比较节省时间
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
相关问答
无更多相似问答 去提问
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区