初探物联网 - 基于Arduino的气象站和View and Data API的结合实例

如果你参加了上个月在北京的Autodesk 开发者日,你应该看到了我做的关于Arduino的物联网实例演示,如果你没看到,欢迎参加14号在上海的开发者日,到时候我会再演(xian)示(bai)一下。

这是个基于这样一个场景的简单演示。我的一个建筑物上面安装了这样一个温度传感器,随时把当前环境温度上传到云端,在浏览器端可以显示这个建筑物的三维模型和温度变化曲线图。如果温度到达一定的高温,比如大于40度,那可能是起火了,就需要发出高温报警,在三维模型中定位出报警的温度传感器的位置,并发出火警警报。

演示地址 : http://arduiview.herokuapp.com/

继续之前你可能需要阅读一下我前面的两篇文章:

迈出物联网的第一步,玩儿一下Arduino

使用 Arduino 和 LM35 温度传感器监测温度

下面简单介绍一下这个实例系统的实现。下图为系统的架构图, Arduino 和 Viewer都通过REST 的方式和云端的服务器进行通信。Arduino 定时把当前温度通过REST的方式上传,Viewer定时取得温度信息并绘制曲线图,如遇高温则报警。貌似相当简单,这种基于HTTP的REST API方式的一个缺点就是实时性不好,需要进行轮询。后面我做了改进,通过WebSocket和MQTT协议,可以实现更好的实时传输,这个我们后面再说。

下图就是Arduino 和LM 35温度传感器的链接情况。Arduino 本身并没有联网功能,所以还需要一个额外的设备,我采用了CC3000 WiFi Shield模块,在淘宝上也可以买到。把Arduino 和CC3000两个套在一起,然后按照前面文章中提到的方式把温度传感器连接起来即可。

然后我们需要写些代码驱动CC3300 WiFi模块联网。我们可以使用Adafruite CC3000 Library 。 在Arduino IDE里面,“Project” –> “Include Libraries” –> “Manage Libraries”, 搜索“CC3000”,找到这个类库安装。然后你可以阅读一下自带的例子。这一点Arduino 做的非常好,每个类库都有完备的实例,拿过来改一下就可以了。

下面我们需要创建云端的服务器,我用node.js来创建并且暴露了一些REST API。其中一个就是用来解释Arduino上传的温度数据的REST API。如下所示:

PUT /sensors/somesensorId/values

body:

{

value : 22

}

node.js中路由部分的代码实现为:

router.route(‘/sensors/:sensorId/values‘)
  .get(sensorController.getSensorValues)
  .put(sensorController.appendSensorValues);

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

下面是sensorController控制器的实现代码。这里没有列出的是,其实后端我还使用的mongoose和mongoDb以便把上传的温度数据保存起来,这样以后就可以做大数据分析了。不过这个例子只是为了演示,我也没保存全部数据,只是保存了最近50多个。

exports.appendSensorValues = function(req,res){  //append

    //we just save 50 + 1 values items to save db spaces
    var MAX_VAULE_ITEM_COUNT = 50;

    var sensorId = req.params.sensorId;

    Sensor.findById(sensorId, function(err, sensor){
      if(err)
        res.json(err);

      var sensorValueItem = {};
      sensorValueItem.timestamp = new Date().getTime();
      sensorValueItem.value = req.body.value;

      //console.log(sensorValueItem);
      var len = sensor.values.length;
      sensor.values = sensor.values.slice(len - MAX_VAULE_ITEM_COUNT );

      sensor.values = sensor.values.concat(sensorValueItem);

      sensor.save(function(err){

        if(err)
          res.send(err);

        res.json(sensorValueItem);
      })
    });

}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

这里的代码还是挂一漏万,如果大家感兴趣还是在github上看完整代码.https://github.com/duchangyu/project-arduivew/tree/v0.1,

下面来实现Arduino的部分,获取温度并通过REST的方式上传。前面提到的CC3000提供的实例已经演示了怎么连接到WiFi并上网,这里略过,如果你感兴趣可以看我的完整代码。这里我们只说说Arduino怎么发送REST请求的部分。在Arduino里面,我没有找到好的REST 的client库,不过说起来也不复杂,就是按照HTTP的协议发送原生字符串即可。按照我们的REST接口的定义,上传的REST协议应该是这样的:

PUT /api/sensors/somesensorid/value HTTP/1.1

HOST: arduiview.heroku.com

content-type : application/json

Content-Length : 19

{

value : 22

}

下面就是构建这样的字符串,然后通过CC3000客户端发送出去即可,代码片段如下:

void postTemperatureToCloudServer() {

  //connectToCloudServer
  Serial.println(F("trying to connect to cloud server....."));
  //client.close();
  client = cc3000.connectTCP(ip, 80);

  Serial.println(F("connected to cloud server - "));
  Serial.println(WEBSITE );

  Serial.println(F("begin uploading..."));

  float temp = 0.0;
  // get the current temperature from sensor
  int reading = analogRead(0);
  temp = reading * 0.0048828125 * 100;
  Serial.print(F("Current temp"));
  Serial.println(temp);

  int length;
  char sTemp[5] = "";
  //convert float to char*,
  dtostrf(temp, 2, 2, sTemp); //val, integer part width, precise, result char array
  //itoa(temp, sTemp,10);
  Serial.println(sTemp);

  char sLength[3];

  //prepare the http body
  //
  //{
  //  "value" : 55.23
  //}
  //

  char httpPackage[20] = "";

  strcat(httpPackage, "{\"value\": \"");
  strcat(httpPackage, sTemp);
  strcat(httpPackage, "\" }");

  // get the length of data package
  length = strlen(httpPackage);
  // convert int to char array for posting
  itoa(length, sLength, 10);
  Serial.print(F("body lenght="));
  Serial.println(sLength);

  //prepare the http header
  Serial.println(F("Sending headers..."));

  client.fastrprint(F("PUT /api/sensors/"));
  char *sensorId = SENSOR_ID;
  client.fastrprint(sensorId);
  //client.fastrprint(SENSOR_ID);
  client.fastrprint(F("/values"));

  client.fastrprintln(F(" HTTP/1.1"));
  Serial.print(F("."));

  client.fastrprint(F("Host: "));
  client.fastrprintln(WEBSITE);
  Serial.print(F("."));

  client.fastrprint(F("content-type: "));
  client.fastrprintln(F("application/json"));
  Serial.print(F("."));

  client.fastrprint(F("Content-Length: "));
  client.fastrprintln(sLength);
  client.fastrprintln(F(""));
  Serial.print(F("."));

  Serial.println(F("header done."));

  //send data
  Serial.println(F("Sending data"));
  client.fastrprintln(httpPackage);

  Serial.println(F("===upload completed."));

  // Get the http page feedback

  unsigned long rTimer = millis();
  Serial.println(F("Reading Cloud Response!!!\r\n"));
  while (millis() - rTimer < 2000) {
    while (client.connected() && client.available()) {
      char c = client.read();
      Serial.print(c);
    }
  }
  delay(1000);             // Wait for 1s to finish posting the data stream
  client.close();      // Close the service connection

  Serial.println(F("upload completed\n"));

}

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

 
感兴趣还是看一下完整代码,在这里:
https://github.com/duchangyu/project-arduivew/blob/v0.1/arduino/arduiview-lm35-2/arduiview-lm35-2.ino 
时间: 2024-10-25 08:37:17

初探物联网 - 基于Arduino的气象站和View and Data API的结合实例的相关文章

Using View and Data API with Meteor

By Daniel Du I have been studying Meteor these days, and find that Meteor is really a mind-blowing framework, I can talk about this latter. I was inspired by this question on forum and started to looking at the possibilities of using View and Data AP

View and Data API tips: 缓存Access Token

对于云API服务,常见的方式就是按照API调用次数收费,某些API调用也就有某些限制,比如在特定时间内只允许调用指定的次数以免造成滥用.虽然Autodesk的view and Data API目前还没有应用这样的限制,但我们最好也能实现这样的机制,比如对于或者Access Token这样的操作,一个Access Token是有一定的有效期的,在这个token的有效期内,我们就没必要重复发出API调用获取新的Acces Token,只有返回仍然有效的token就可以了.下面是c#实现的简单的逻辑,

View and Data API Tips: how to make viewer full screen

By Daniel Du If you have not heard of View and Data API, here is the idea, the View & Data API enables web developers to very easily display 3D (and 2D) models on a WebGL-enabled browser. please read this one first and get a key from http://developer

View and Data API Tips : Conversion between DbId and node

By Daniel Du In View and Data client side API, The assets in the Autodesk Viewer have an object tree, a tree structure that represents the model hierarchy. Each element in model can be representing as a node of model tree. Each node has a dbId, this

Autodesk View and Data API用户调查

相信大家已经听过Autodesk View and Data Web Service (API) 了吧,还没有? 下面这个就是用Autodesk View and Data Web Service嵌入的模型哦,先玩儿玩儿吧 :)   你也可以把这个模型嵌入到你自己的网站中. 我在和客户交流的时候,很多人都反应云服务器在国外,中国用户使用上就比较犹豫,那么如果把服务器架设在国内,你会用吗?做一下调查吧,让Autodesk听到你的声音.常言道,会哭的孩子有奶吃,不会哭的孩子被饿死啊,5555~  

Autodesk View and Data API练练手

大家如果参加过我们的活动,你应该已经听过看过不少关于View and Data Web Service的例子里,如果还没有的话,请看看下面这几篇: http://www.cnblogs.com/junqilian/category/594048.html 如果你已经了解了Viewer,那有没有兴趣练练手,把这样酷的三维模型嵌入到你自己的网页中呢?那么开始练练手吧. ?体验代码资料下载:http://pan.baidu.com/s/15zZMQ 在下载解压缩后你应该可以看到下面的目录结构,其中ha

基于arduino+web的物联网demo,web和微信控制

视频效果: 基于arduino+web的物联网demo,web和微信控制 基于arduino + web的物联网demo,实现了web和微信的多方式控制,折腾了好几周,终于完美解决了. 配件清单: Arduino uno3(主板) HLK-RM04(Uart串口转Wifi) 主板程序源码: String strs = ""; int led = 6; void setup() {    pinMode(led, OUTPUT);   Serial.begin(115200);//设置串

基于arduino的红外传感系统

一.作品背景 在这个科技飞速发展的时代,物联网已经成为了我们身边必不可少的技术模块,我这次课程设计做的是一个基于arduino+树莓派+OneNet的红外报警系统,它主要通过识别人或者动物的运动来判断是否有人在附近再通过蜂鸣器的响叫来实现报警功能. 红外报警系统在生活中的应用也很广泛,例如博物馆的展品,家里的安防系统,公司的安防系统等,但是如何准确的报警,保证红外线的正确识别是这个系统的主要问题,本次的实践综合这些因素提出了比较靠谱的解决方案,用智能网关解决这一系列的问题. 二.元件原理 热释电

ABP 初探 之基于EasyUI的CURD

ABP 初探 之基于EasyUI的CURD 结束了天天加班的项目,项目虽然结束,但还是有点小问题,只能在后期优化当中完成了,本次做项目采用了,MVC.Webapi.Entityframework,在园了里看到了有关ABP的介绍,同样ABP也是最新技术集合,就加入了 ABP架构设计交流群 134710707,一起探讨.学习与进步. ABP的技术文档全是英文资料,不过现在不用担心了,群里的热心朋友已翻译成能看的懂语言了,详情 ABP 源代码地址 https://github.com/aspnetbo