|
|
本帖最后由 gpwang2000 于 2013-8-29 18:14 编辑
乐联的家庭能耗活动搞得如火如荼, 利用手里现成的模块搭了一套系统,在群里得到廋网虫、小叶子、老顽童等的帮助。
移动端包括BMP085 + DSM501A + LCD5110 + 电量模块 + ArduinoNano + 433M发射,无线网关包括433M超再生接收 + ArduinoUno + ENC28J60,无线数据传输以最常见价格最低廉的433M收发模块为基础,利用VirtualWire库实现了无线数据的单向传送,一次最大可传80个字节,另外为了方便系统串口调试, 与电量模块的通信使用了软件串口。
无线网关部分程序, 主要完成数据接收并上传到乐为物联
- #include <VirtualWire.h>
- #include <EtherCard.h>
- #define INTEGER(x) (long) x
- #define DECIMAL(x) (long)(abs(x)*100L+0.5) % 100
- #define DATA_COUNT 9
- // ethernet interface mac address
- static byte mymac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 };
- uint8_t Ethernet::buffer[700];
- // lewei50
- //char lwSite[] PROGMEM = "192.168.1.148";
- char lwSite[] PROGMEM = "www.lewei50.com";
- char lwUrl[] PROGMEM = "/api/V1/gateway/UpdateSensors/01";
- char lwKey[] PROGMEM = "userkey: xxxxxxxxxxxxxxxxxxxxxxxxxx";
- char *lwSensor[DATA_COUNT]={"T", "P", "PM10", "PM25", "V", "KWH", "W", "A", "PF"};
- union DATA{
- float value[DATA_COUNT];
- struct{
- float Temperature; //温度
- float Pressure; //气压
- float Pm10; //1um粒子
- float Pm25; //2.5um粒子
- float Voltage; //电压
- float Kwh; //电量
- float Watt; //功率
- float Amp; //电流
- float Pf; //功率因素
- }item;
- }data;
- uint8_t lwSend = 0;
- uint8_t lwCount = 0;
- uint32_t sendTime;
- // called when the client request is complete
- static void my_result_cb (byte status, word off, word len) {
- Serial.print("<<< reply ");
- Serial.print(millis() - sendTime);
- Serial.println(" ms");
- Serial.println((const char*) Ethernet::buffer + off);
- }
- void setup() {
- Serial.begin(9600);
-
- // 初始化接收模块,速率为1200bps
- vw_setup(1200);
- vw_rx_start();
- //初始化以太网卡
- Serial.println("ethercard");
- while(ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0) {
- Serial.println( "Failed");
- delay(2000);
- }
-
- //初始化IP地址
- Serial.println("dhcp");
- while (!ether.dhcpSetup()) {
- Serial.println("failed");
- delay(2000);
- }
- ether.printIp("My IP: ", ether.myip);
- ether.printIp("GW IP: ", ether.gwip);
- ether.printIp("DNS IP: ", ether.dnsip);
- //网址预处理
- ether.dnsLookup(lwSite);
- }
-
- void loop() {
- uint8_t buf[VW_MAX_MESSAGE_LEN];
- uint8_t buflen = VW_MAX_MESSAGE_LEN;
- char str[50];
- ether.packetLoop(ether.packetReceive());
- //无线数据接收
- if (vw_get_message(buf, &buflen)) {
- if (buflen != sizeof(data)){
- Serial.println("recv error");
- return;
- }
-
- //处理收到的数据
- float *p = (float *)buf;
- for (int i=0; i<DATA_COUNT; i++){
- //记录传输间隔内的最大值
- if (p[i] > data.value[i]) data.value[i] = p[i];
- }
- lwSend = 1;
- }
- //数据分批发送至乐联网,每个数据约5分钟传一次
- if (lwSend == 1){
- sprintf(str,"[{"Name":"%s","Value":"%ld.%ld"}]", lwSensor[lwCount], INTEGER(data.value[lwCount]),DECIMAL((data.value[lwCount])));
- Serial.println(str);
- ether.dnsLookup(lwSite);
- ether.printIp("Server: ", ether.hisip);
- sendTime = millis();
- ether.httpPost (lwUrl, lwSite, lwKey, str, my_result_cb);
- data.value[lwCount] = 0;
- if (++lwCount >= DATA_COUNT) lwCount = 0;
- lwSend = 0;
- }
- }
复制代码
移动采集部分程序, 主要收集各个模块的数据从433M一并发送,约30秒发送一次
- #include <Wire.h>
- #include <ModbusMaster.h>
- #include <Adafruit_BMP085.h>
- #include <SoftwareSerial.h>
- #include <VirtualWire.h>
- #include <lcd5110.h>
- #include <dsm501a.h>
- #include <AcMeter.h>
- #define INTEGER(x) (long) x
- #define DECIMAL(x) (long)(abs(x)*100L+0.5) % 100
- #define DATA_COUNT 9
- Adafruit_BMP085 bmp;
- DSM501A dsm(A2, A3);
- ACMETER meter;
- union{
- float value[DATA_COUNT];
- struct{
- float Temperature; //温度
- float Pressure; //气压
- float Pm10; //1um粒子
- float Pm25; //2.5um粒子
- float Voltage; //电压
- float Kwh; //电量
- float Watt; //功率
- float Amp; //电流
- float Pf; //功率因素
- }item;
- }data;
- void setup()
- {
- //初始化串口
- Serial.begin(9600);
-
- // 初始化发送模块,速率为1200bps
- Serial.println("vm");
- vw_setup(1200);
- // 初始化5110液晶模块
- Serial.println("lcd5110");
- LCD_init();
- //初始化bmp085模块
- Serial.println("bmp085");
- while(!bmp.begin()){
- Serial.println("Fialed!");
- delay(2000);
- }
- // 启动粉尘检测
- Serial.println("dsm start");
- dsm.begin();
- }
- void loop()
- {
- uint8_t i, result;
- //dsm.loop == 1, 处于粉尘采样阶段
- if (dsm.loop() == 1) return;
- //提取粉尘数据
- data.item.Pm10 = dsm.pm10;
- data.item.Pm25 = dsm.pm25;
- //提取bmp085温度和气压数据
- data.item.Temperature = bmp.readTemperature();
- data.item.Pressure = bmp.readPressure();
- //提取电量信息
- if (meter.read() == 0){
- data.item.Voltage = meter.Voltage;
- data.item.Amp = meter.Amp;
- data.item.Watt = meter.Watt;
- data.item.Pf = meter.Pf;
- data.item.Kwh = meter.Kwh;
- }
- //LCD显示数据
- char str[30];
- LCD_clear();//清屏
- sprintf(str, "TIME: %ld", millis());
- LCD_write_english_string(0,0,str);
- sprintf(str, "PM10: %ld.%ld", INTEGER(data.item.Pm10), DECIMAL(data.item.Pm10));
- LCD_write_english_string(0,1,str);
- sprintf(str, "PM25: %ld.%ld", INTEGER(data.item.Pm25), DECIMAL(data.item.Pm25));
- LCD_write_english_string(0,2,str);
- sprintf(str, "TEMP: %ld.%ld", INTEGER(data.item.Temperature), DECIMAL(data.item.Temperature));
- LCD_write_english_string(0,3,str);
- sprintf(str, "PRES: %ld", INTEGER(data.item.Pressure));
- LCD_write_english_string(0,4,str);
- sprintf(str, "VOLT: %ld", INTEGER(data.item.Voltage), DECIMAL(data.item.Voltage));
- LCD_write_english_string(0,5,str);
- //数据发送至无线网关
- vw_send((uint8_t *)&data, sizeof(data));
- vw_wait_tx(); // Wait until the whole message is gone
-
- //再次启动粉尘检测
- Serial.println("dsm start");
- dsm.begin();
- }
复制代码
硬件连接情况
以下是一些参考库
乐联电量:http://www.lewei50.com/event/detail/1
BMP085:https://github.com/adafruit/Adafruit-BMP085-Library
虚拟串口:http://www.arduino.cc/en/Reference/SoftwareSerial
MODBUS:http://playground.arduino.cc/Code/ModbusMaster
ViturlWire:http://www.geeetech.com/wiki/index.php/433Mhz_RF_link_kit
28J60:https://github.com/jcw/ethercard
LCD5110:http://www.geek-workshop.com/thread-713-2-1.html
DSM501A:http://www.geek-workshop.com/forum.php?mod=viewthread&tid=1747
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
|