极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11784|回复: 2

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

[复制链接]
发表于 2015-8-26 10:43:00 | 显示全部楼层 |阅读模式
本帖最后由 迷你强 于 2015-8-28 14:57 编辑

完整的实例代码如下:

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

  3. #define DEVICE_ID "Your device id"
  4. #define HOSTADD "api.heclouds.com"
  5. #define API_KEY  "Your api key"
  6. #define TRYTIMES 1
  7. #define RET_OK   0
  8. #define RET_ERR  1

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

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

  15.   while (!Serial1)
  16.   {
  17.     ; // wait for serial port to connect. Needed for Leonardo only
  18.   }
  19.   while (!Serial)
  20.   {
  21.     ; // wait for serial port to connect. Needed for Leonardo only
  22.   }

  23.   attachInterrupt(0, getEventTime1, FALLING);//设置外部中断1触发模式和中断处理函数
  24.   attachInterrupt(1, getEventTime2, FALLING);/设置外部中断2触发模式和中断处理函数

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

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

  37. void loop()
  38. {

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

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

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

  47.   HttpPacketHead packetHead;//HTTP报头

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

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

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

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

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

  64.   if (flag2)//中断2是否发生
  65.   {
  66.     flag1 = 0;
  67.     flag2 = 0;
  68.     if (timer2 > timer1)//根据发生时间判断人的行进方向
  69.     {
  70.       comeIn ++;
  71.     }
  72.     else
  73.     {
  74.       goOut ++;
  75.     }
  76.   }
  77. }

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

  84.   if (flag1)
  85.   {
  86.     flag1 = 0;
  87.     flag2 = 0;
  88.     if (timer2 > timer1)
  89.     {
  90.       comeIn ++;
  91.     }
  92.     else
  93.     {
  94.       goOut ++;
  95.     }
  96.   }
  97. }

  98. /*添加一条JSON数据流记录的处理函数*/
  99. void addJsonDataRecord(char key[], int value, JsonArray& array)
  100. {
  101.   JsonObject& root = array.createNestedObject();
  102.   root.add("id", key);
  103.   JsonArray& data = root.createNestedArray("datapoints");
  104.   JsonObject& root1 = data.createNestedObject();
  105.   root1.add("value", value);
  106. }

  107. /*开启数据传送的处理函数*/
  108. char startSendData(String data)
  109. {
  110.   int i = 0;
  111.   Serial1.println(data);
  112.   while (1)
  113.   {
  114.     delay(200);
  115.     if ((Serial1.find(">") == true) || i > TRYTIMES)
  116.     {
  117.       Serial.println(data);
  118.       break;
  119.     }
  120.     Serial1.println(data);
  121.     i++;
  122.   }
  123.   return RET_OK;
  124. }

  125. /*向SIM900A发生AT指令的函数*/
  126. char sendCmd(String data)
  127. {
  128.   int i = 0;
  129.   Serial1.println(data);
  130.   while (1)
  131.   {
  132.     delay(200);
  133.     if ((Serial1.find("OK") == true) || i > TRYTIMES)
  134.     {
  135.       Serial.println(data);
  136.       break;
  137.     }
  138.     Serial1.println(data);
  139.     i++;
  140.   }
  141.   return RET_OK;
  142. }

  143. /*和服务器建立TCP连接得函数*/
  144. char establishTCPConnect(String data)
  145. {
  146.   int i = 0;
  147.   Serial1.println(data);
  148.   while (1)
  149.   {
  150.     delay(200);
  151.     if ((Serial1.find("CONNECT OK") == true) || i > TRYTIMES)
  152.     {
  153.       Serial.println("CONNECT OK");
  154.       break;
  155.     }
  156.     Serial1.println(data);
  157.     i++;
  158.   }
  159.   return RET_OK;
  160. }

  161. /*关闭和服务器的TCP连接*/
  162. char closeTCPConnect(String data)
  163. {
  164.   int i = 0;
  165.   Serial1.println(data);
  166.   while (1)
  167.   {
  168.     delay(200);
  169.     if ((Serial1.find("CLOSE OK") == true) || i > TRYTIMES)
  170.     {
  171.       Serial.println("CLOSE OK");
  172.       break;
  173.     }
  174.     Serial1.println(data);
  175.     i++;
  176.   }
  177.   return RET_OK;
  178. }
复制代码

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

本帖子中包含更多资源

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

x
回复

使用道具 举报

发表于 2015-8-28 14:58:26 | 显示全部楼层
文件头貌似缺东西
回复 支持 反对

使用道具 举报

发表于 2018-3-18 14:22:48 | 显示全部楼层
谢谢提供湖码,相当不错的设计
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-24 23:06 , Processed in 0.051651 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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