onenet 发表于 2015-8-26 10:43:00

【设备云】Arduino Leonardo+红外传感器+SIM900A 制作简易客流统计系统(二)

本帖最后由 迷你强 于 2015-8-28 14:57 编辑

完整的实例代码如下:

#include //JSON 数据封装库
#include //HTTP报头封装库

#define DEVICE_ID "Your device id"
#define HOSTADD "api.heclouds.com"
#define API_KEY"Your api key"
#define TRYTIMES 1
#define RET_OK   0
#define RET_ERR1

unsigned long timer1 = 0, timer2 = 0, comeIn = 0, goOut = 0;
char flag1 = 0, flag2 = 0;

void setup()
{
Serial1.begin(115200);//初始化硬件串口,该串口接SIM900A模块
Serial.begin(115200);//初始化USB虚拟串口,该串口作为打印调试用

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);//设置外部中断1触发模式和中断处理函数
attachInterrupt(1, getEventTime2, FALLING);/设置外部中断2触发模式和中断处理函数

while (1)
{
    Serial1.println("AT+COPS?\r");//查询运营商信号
    delay(200);

    if (Serial1.find("CHINA MOBILE") == true )//发现中国移动运营商信号
    {
      Serial.println("CHINA MOBILE");
      break;
    }
}
sendCmd("AT+CLPORT=\"TCP\",\"2000\"\r");//设置本地端口号为2000
}

void loop()
{

establishTCPConnect("AT+CIPSTART=\"TCP\",\"183.230.40.33\",\"80\"\r");//与服务器建立TCP连接
startSendData("AT+CIPSEND\r");//开启数据头程模式

/*运用SDK进行HTTP包封装*/
StaticJsonBuffer<200> jsonBuffer;//建立JSON字符串BUFFER
JsonObject& jsonData = jsonBuffer.createObject();

JsonArray& data = jsonData.createNestedArray("datastreams");
addJsonDataRecord("come_in", comeIn, data);//在JSON串中添加come_in数据流记录
addJsonDataRecord("Go_out", goOut, data);//在JSON串中添加Go_out数据流记录

HttpPacketHead packetHead;//HTTP报头

packetHead.setHostAddress(HOSTADD);//包头主机地址设置
packetHead.setDevId(DEVICE_ID);//设置报头设备ID
packetHead.setAccessKey(API_KEY);//设置API KEY
packetHead.createCmdPacket(POST, TYPE_DATAPOINT, jsonData);//生成HTTP报头,这里需要传入上面生成的JSON串对象,该函数会自动计算该JSON串的长度并设置content length字段。

Serial1.print(packetHead.content);//先发送报头数据

jsonData.printTo(Serial1);//再发送HTTP报所带的JSON内容
Serial1.println("�32");//结束数据传输

delay(200);
closeTCPConnect("AT+CIPCLOSE\r");//关闭TCP连接
}

/*外部中断1的中断处理函数,主要是记录中断发生的时间,判断人的行进方向*/
void getEventTime1(void)
{
timer1 = millis();//记录中断发生的时间
Serial.println(timer1);
flag1 = 1;

if (flag2)//中断2是否发生
{
    flag1 = 0;
    flag2 = 0;
    if (timer2 > timer1)//根据发生时间判断人的行进方向
    {
      comeIn ++;
    }
    else
    {
      goOut ++;
    }
}
}

/*外部中断2的中断处理函数,主要是记录中断发生的时间,判断人的行进方向*/
void getEventTime2(void)
{
timer2 = millis();
Serial.println(timer2);
flag2 = 1;

if (flag1)
{
    flag1 = 0;
    flag2 = 0;
    if (timer2 > timer1)
    {
      comeIn ++;
    }
    else
    {
      goOut ++;
    }
}
}

/*添加一条JSON数据流记录的处理函数*/
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(200);
    if ((Serial1.find(">") == true) || i > TRYTIMES)
    {
      Serial.println(data);
      break;
    }
    Serial1.println(data);
    i++;
}
return RET_OK;
}

/*向SIM900A发生AT指令的函数*/
char sendCmd(String data)
{
int i = 0;
Serial1.println(data);
while (1)
{
    delay(200);
    if ((Serial1.find("OK") == true) || i > TRYTIMES)
    {
      Serial.println(data);
      break;
    }
    Serial1.println(data);
    i++;
}
return RET_OK;
}

/*和服务器建立TCP连接得函数*/
char establishTCPConnect(String data)
{
int i = 0;
Serial1.println(data);
while (1)
{
    delay(200);
    if ((Serial1.find("CONNECT OK") == true) || i > TRYTIMES)
    {
      Serial.println("CONNECT OK");
      break;
    }
    Serial1.println(data);
    i++;
}
return RET_OK;
}

/*关闭和服务器的TCP连接*/
char closeTCPConnect(String data)
{
int i = 0;
Serial1.println(data);
while (1)
{
    delay(200);
    if ((Serial1.find("CLOSE OK") == true) || i > TRYTIMES)
    {
      Serial.println("CLOSE OK");
      break;
    }
    Serial1.println(data);
    i++;
}
return RET_OK;
}

将代码写入Ardiuno Leonardo开发板,就按照好红外传感器就可以进行简单客流统计了,本实例中的客流统计功能只针对简单的统计场合,由于原理所限,对多种复杂的情况未做特殊处理,会产生误差。比如:两人并排通过的情况,系统计数为加1。在此处不做过多研究。开发板启动以后可以通过OneNeT平台查看客流统计情况。如题:
注意:运用SDK封装HTTP包时,占用内存比不用SDK封装要多,由于Ardiuno Leonardo比较小,在编程时对内存使用要小心,内存占用过大会造成开发板程序崩溃或者死机。

迷你强 发表于 2015-8-28 14:58:26

文件头貌似缺东西

方恨少 发表于 2018-3-18 14:22:48

谢谢提供湖码,相当不错的设计
页: [1]
查看完整版本: 【设备云】Arduino Leonardo+红外传感器+SIM900A 制作简易客流统计系统(二)