本帖最后由 robert_jw 于 2016-1-20 16:34 编辑
前言:
OneNET是中移物联网有限公司基于开放、共赢的理念,面向公共服务自主研发的开发云平台,为各种跨平台物联网应用、行业解决方案提供简便的云端接入、海量存储、计算和大数据可视化服务,从而降低物联网企业和个人(创客)的研发、运营和运维费用,使物联网企业和个人(创客)更加专注于应用,共建以OneNET设备云为中心的物联网生态环境。 OneNET支持多种接入协议,包括:EDP、Restful、MQTT、Modbus、JT/T808-2011等,具体接入文档请到OneNET官方网站进行下载: http://open.iot.10086.cn/download
本文将采用Restful(HTTP),利用arduino+SIM900A+红外传感器,将数据上传到OneNET平台,形成一个简易的客流量统计方案。
——————————————————————————————————————————————————
所用到的器材如下所示:
Arduino Leonardo开发板
SIM900A模块
漫反射光电开关
实验原理 Ardiuno Leonardo的Pin2/Pin3为外部中断输入口,本实例采用外部中断的形式采集红外检测信号,对于NPN型红外传感器,没有人通过的时候输出高电平,有人通过的时候输出低电平。在Ardiuno Leonardo中利用中断的方式进行信号检测,有人通过的时候就会触发中断进行计数。 除此之外,可以用两个红外传感器检测信号,根据产生信号的先后顺序识别行人通行的方向。客流统计的测量方法示意图: 客流统计的测量方法示意图 两个对射式红外传感器可以判断物体进出状态。将A、A',C、C'两对对射式红外传感器平行安装在场所的出入口内、外两侧,当A、A'先于C、C'检测到屏蔽信号时,表明所测物体为离开;当C、C'先于A、A'检测到屏蔽信号时物体为进入。程序大致逻辑流程: 方法实现逻辑流程图 Step1 平台端准备工作 首先是做好在OneNET平台端的准备工作,包括申请账号、创建设备、创建数据流、创建并关联ApiKey。这里需要创建两个数据流,一个统计进入人数,一个统计走出人数。因为是使用RestFul API接入,设备类型选择HTTP。
Step2 硬件连线 硬件接线示意图如下所示: 其中,两个红外传感器数据线分别接arduino板的数字2 3引脚 实物连接图如下:
Step3 编写代码 硬件和OneNET平台端的准备工作都做好了,需要完成Arduino硬件板上的代码编写,对于GPRS模块操作,ArduinoIDE中没有通用的库可供使用,需要根据模块使用手册自行编写代码。针对RestFul API的数据报文封装,OneNET官方也开发了相关的Arduino库,该库的头文件为HttpPacket.h。源代码如下所示: [mw_shl_code=c,true]#include <ArduinoJson.h>
#include <HttpPacket.h>
#define DEVICE_ID "78488"
#define HOSTADD "api.heclouds.com"
#define API_KEY "B4ZGKmtaL5eJw6NIpjEEI+kULqQ="
#define TRYTIMES 3
#define RET_OK 0
#define RET_ERR 1
unsigned long timer1 = 0, timer2 = 0, comeIn = 0, goOut = 0;
char flag1 = 0, flag2 = 0;
StaticJsonBuffer<200> jsonBuffer;
char jsonStr[200] = {0};
HttpPacketHead packetHead;
void setup()
{
Serial1.begin(115200);
Serial.begin(115200);
while (!Serial1)
{
; // wait for serial port to connect. Needed for Leonardo only
}
while (!Serial)
{
; // wait for serial port to connect. Needed for Leonardo only
}
attachInterrupt(0, getEventTime1, FALLING);
attachInterrupt(1, getEventTime2, FALLING);
while (1)
{
Serial1.println("AT+COPS?\r");
delay(200);
if (Serial1.find("CHINA") == true )
{
Serial.println("CHINA MOBILE");
break;
}
}
sendCmd("AT+CLPORT=\"TCP\",\"2000\"\r");
}
void loop()
{
establishTCPConnect("AT+CIPSTART=\"TCP\",\"183.230.40.33\",\"80\"\r");
startSendData("AT+CIPSEND\r");
JsonObject &jsonData = jsonBuffer.createObject();
JsonArray &data = jsonData.createNestedArray("datastreams");
addJsonDataRecord("come_in", comeIn, data);
addJsonDataRecord("Go_out", goOut, data);
jsonData.printTo(jsonStr, 200);
packetHead.setHostAddress(HOSTADD);
packetHead.setDevId(DEVICE_ID);
packetHead.setAccessKey(API_KEY);
packetHead.createCmdPacket(POST, TYPE_DATAPOINT, jsonStr);
Serial1.print(packetHead.content);
jsonData.printTo(Serial1);
Serial1.println("");
delay(500);
closeTCPConnect("AT+CIPCLOSE\r");
delay(1000);
}
void getEventTime1(void)
{
timer1 = millis();
Serial.println(timer1);
flag1 = 1;
if (flag2)
{
flag1 = 0;
flag2 = 0;
if (timer2 > timer1)
{
comeIn ++;
}
else
{
goOut ++;
}
}
}
void getEventTime2(void)
{
timer2 = millis();
Serial.println(timer2);
flag2 = 1;
if (flag1)
{
flag1 = 0;
flag2 = 0;
if (timer2 > timer1)
{
comeIn ++;
}
else
{
goOut ++;
}
}
}
void addJsonDataRecord(char key[], int value, JsonArray &array)
{
JsonObject &root = array.createNestedObject();
root.add("id", key);
JsonArray &data = root.createNestedArray("datapoints");
JsonObject &root1 = data.createNestedObject();
root1.add("value", value);
}
char startSendData(String data)
{
int i = 0;
Serial1.println(data);
while (1)
{
delay(1000);
if ((Serial1.find(">") == true) || i > TRYTIMES)
{
Serial.println(data);
break;
}
Serial1.println(data);
i++;
}
return RET_OK;
}
char sendCmd(String data)
{
int i = 0;
Serial1.println(data);
while (1)
{
delay(1000);
if ((Serial1.find("OK") == true))//|| i > TRYTIMES)
{
Serial.println(data);
break;
}
Serial1.println(data);
i++;
}
return RET_OK;
}
char establishTCPConnect(String data)
{
int i = 0;
Serial1.println(data);
while (1)
{
delay(1000);
if ((Serial1.find("CONNECT OK") == true) || i > TRYTIMES)
{
//LedFlash();
Serial.println("CONNECT OK");
break;
}
Serial1.println(data);
i++;
}
return RET_OK;
}
char closeTCPConnect(String data)
{
int i = 0;
Serial1.println(data);
while (1)
{
delay(1000);
if ((Serial1.find("CLOSE OK") == true) || i > TRYTIMES)
{
Serial.println("CLOSE OK");
break;
}
Serial1.println(data);
i++;
}
return RET_OK;
}
[/mw_shl_code]
step4 运行程序 将以上代码在IDE中编译并下载到开发板中。运行程序后,在平台端查看数据上传情况,运用应用孵化器生成客流统计应用展示曲线,如下图所示:
|