第十二次培训:考虑真实环境,测量流浪狗数据,初步制定数据上传
第十二次培训:考虑真实环境,测量流浪狗数据,初步制定数据上传
第十二次培训:考虑真实环境,测量流浪狗数据,初步制定数据上传策略14年研发的esp8266尺寸5mm*5mm,配合dht11(23.5mm*12mm*5.5mm),可以嵌套在为流浪狗(考虑小型犬类,活动范围广,可以提供多组数据)准备的项圈上面。
基于Arduino的温湿度上传OneNET,同时SIM900A短信报警(1)相似项目
[var1]
Arduino判断,DHT11温湿度传感器采集的数据,ESP8266模块连接WiFi,将数据按网关通信协议+mqtt协议上传至OneNET服务器(或别的云服务平台),使用者可在平台实时查看温湿度数据。设定温湿度值上限与下限,若温湿度数据超过设定范围(流浪狗因室外温度变化出现生命危险),则立即向手机发送警报,同时触发蜂鸣器(引起小狗附近的人查看),用SIM900A模块发送短信到指定的手机号。同时心率传感器测量心跳,设定心跳下限,心跳过慢同样发送警报。一般的幼年狗比成年狗心跳速率要快,大约为115—zhi100/S,成年狗心跳速率大约为85—100之间;正常情况下狗的心率在每分钟90次左右,犬种越大,心率越低。
实际数据传输过程中,如果中间节点出现什么故障是难以知道的。更要命的是,有的节点(防火墙)会自动把一定时间之内没有数据交互的连接给断掉。在这个时候,就需要我们的心跳包了,用于维持长连接,保活。
心跳机制?/数据上传频率(相关详解-里面有实例、源码,接入到阿里云)
就是每隔几分钟发送一个固定信息给服务端,服务端收到后回复一个固定信息如果服务端几分钟内没有收到客户端信息则视客户端断开。一般的应用下,判定时间在30-40秒比较不错。如果实在要求高,那就在6-9秒。
在室外温度严重影响流浪狗,也就是小狗体温过高时,启用风扇帮助降温,但是风扇可能增加项圈重量,平时对小型犬类造成负担。所以在考虑要不要加风扇。
[var1]
● Arduino UNO开发板
● ESP8266 Wi-Fi模块
● MQ-2气体传感器
● 蜂鸣器
● 连接导线
● 面包板
[var1]
Arduino Uno:
可通过USB连接或者外部电源供电。外部(非USB)电源可以是AC-DC适配器,也可以是电池。电路板可由6-20V外部电源供电。然而,如果电源电压低于7V,那么5V引脚可能会提供低于5V的电压,电路板也许会不稳定。如果电源电压超过12V,稳压器可能会过热,从而损坏电路板。电压范围建议为7~12V。
温湿度传感器:
Arduino单片机和DHT11传感器之间只要连一个数字口,DATA接11口就可以了(随便你定义)。DHT11传感器的引脚VCC可以接Arduino 的5V供电,GND脚接Arduino的地,空脚悬空不接。
#include "dht11.h" DHT11 myDHT11(11); int temp=1; int humi=1; myDHT11.DHT11_Read(); //读取温湿度值
这是部分代码,dht11的库是网上找的一个,调用就可以了。
esp8266模块:
将WiFi模块的VCC和CH_PD端共接电源5V,将WiFi模块的GND接GND。模块URXD接Arduino开发板的TXD,UTXD接Arduino开发板的RXD。自带有一个信号指示灯和一个电源指示灯。在接上正确的电源后,红灯长亮,表示模块已经开始工作。在串口发送AT指令或者数据时,WiFi模块的蓝色指示灯会轻微的闪烁后熄灭。
串口初始化需要对相应的寄存器进行初始化,在这里设置其串口波特率为115200
Serial.begin(115200);
向OneNET云平台发送HTTP数据包时,要包含设备ID和APIKEY,这里可在程序开始就设置,而不是在post请求中就是为了方便修改。用如下函数即可:
#define DevicesID 516128482 char APIkey[] = "wsZg=kanSndl6XnjadWqwbgDi=E=";
编辑函数set_ESP8266(),由AT命令使WiFi连接路由器和OneNET云平台
void set_ESP8266(void) { Serial.println("AT"); //判断模块是否正常 Serial.println("AT+CWMODE=3"); //设置WIFI应用模式 Serial.println("AT+RST"); //重置WIFI模块 Serial.print("AT+CWJAP=\""); //连接无线路由器 Serial.print(ssid); Serial.print("\",\""); Serial.print(password); Serial.println("\""); Serial.println("AT+CIPSTART=\"TCP\",\"183.230.40.33\",80"); //和服务器建立TCP连接 Serial.println("AT+CIPMODE=1"); //进入透明传输模式 Serial.println("AT+CIPSEND"); //开始传输 }
合成POST请求。固定的POST头部加之前设定的设备ID和APIKEY,然后调用温度函数,把温度加进请求。最后要注意的是预先设定整个POST包的长度,长度错误是传不上去数据的。
void ESP8266_SendMessage(void){ Serial.print("POST /devices/"); Serial.print(DevicesID); Serial.println("/datapoints HTTP/1.1"); Serial.print("api-key:"); Serial.println(APIkey); Serial.println("Host:api.heclouds.com"); Serial.println("Content-Length: 59"); Serial.println(""); Serial.print("{\"datastreams\":[{\"id\":\"Temp\",\"datapoints\":[{\"value\":"); Serial.print(myDHT11.TEM_Buffer_Int); Serial.println("}]}]}"); }
代码中的POST包的长度是写死的59位,传的是两位的温度和湿度,如果传一位数会传不上。可以自己改改加个计算长度的
int chang; String fa; fa = "{\"X_Acceleration\": " + APIkey + ",\"Y_Acceleration\": " +String(AngleY)+",\"Z_Acceleration\": "+String(AngleZ)+"}";//定义发送数据格式 chang = fa.length();//获取发送数据长度
SIM900A短信模块:
模块使用的SIM卡是标准大小,也就是俗称的大卡其它的型号可以使用SIM卡卡套。
模块需要5V供电,本设计USB提供5V电源和接地。接线引脚:
Arduino SIM900A
5V -> 5V 供电
GND -> GND 电源地
TXD -> 5VRXD 模块接收
RXD -> 5VTXD 模块发送
主循环中使用if函数判断温湿度值是否超限,超限就调用SIM900A_SendMessage()函数发送短信报警。因网络延迟和处理速度,每次命令发送后应该延时几秒等待响应。
mySerial.begin(9600); //设置sim900a波特率为9600 if(myDHT11.TEM_Buffer_Int>30 || myDHT11.HUMI_Buffer_Int>50) { SIM900A_SendMessage(); } void SIM900A_SendMessage() { mySerial.print("AT+CSCS=\"GSM\"\r\n"); //设置GSM字符集 mySerial.print("AT+CMGF=1\r\n"); //设置为文本模式 mySerial.print("AT+CMGS=\"18888888888\"\r\n"); //设置手机号 mySerial.print("HUMI = "); mySerial.print(myDHT11.HUMI_Buffer_Int); mySerial.println(" %RH"); mySerial.print("TMEP = "); mySerial.print(myDHT11.TEM_Buffer_Int); mySerial.println(" ℃"); mySerial.write(0x1A); //“CTRL+Z”的键值,执行发送操作 (HEX)格式单独发送 }
蜂鸣器模块:
通过驱动电路控制蜂鸣器,使用的材料有1K欧姆电阻、PNP型三极管(型号8550)和有源蜂鸣器。三极管的B脚,就是基极通过一个1K欧姆电阻接到Arduino开发板的输出端口10,A脚是集电极要接地,C脚发射极接有源蜂鸣器的负极,而蜂鸣器的正极接5V供电。
- 三极管就相当于电路开关,当Arduino的10口输出高电平,三极管A极与C极间没有电压差,三极管A极与C极间不通,电流不通过有源蜂鸣器,蜂鸣器不响。
- 当开发板输出低电平,三极管A极与C极间就会形成电压差,令A极与C极导通,电流就会通过有源蜂鸣器,并立即发声。
[var1]
接入百度地图。要考虑定位耗电。
百度地图开放平台:http://lbsyun.baidu.com/products/location,在页面底部有下载,以下内容可免费使用
参考:html调用百度地图api
具体代码 <!DOCTYPE html> <head> <meta charset="utf-8" /> <title>百度地图API</title> <script type="text/javascript" src="http://api.map.baidu.com/api?key=&v=1.1&services=true"></script> </head> <body> <!--百度地图容器--> <div style="width:697px;height:550px;border:#ccc solid 1px;" id="dituContent"></div> </body> <script type="text/javascript"> //创建和初始化地图函数: function initMap(){ createMap();//创建地图 setMapEvent();//设置地图事件 addMapControl();//向地图添加控件 } //创建地图函数: function createMap(){ var map = new BMap.Map("dituContent");//在百度地图容器中创建一个地图 var point = new BMap.Point(104.081592,30.655831);//定义一个中心点坐标 map.centerAndZoom(point,12);//设定地图的中心点和坐标并将地图显示在地图容器中 window.map = map;//将map变量存储在全局 } //地图事件设置函数: function setMapEvent(){ map.enableDragging();//启用地图拖拽事件,默认启用(可不写) map.enableScrollWheelZoom();//启用地图滚轮放大缩小 map.enableDoubleClickZoom();//启用鼠标双击放大,默认启用(可不写) map.enableKeyboard();//启用键盘上下左右键移动地图 } //地图控件添加函数: function addMapControl(){ //向地图中添加缩放控件 var ctrl_nav = new BMap.NavigationControl({anchor:BMAP_ANCHOR_TOP_LEFT,type:BMAP_NAVIGATION_CONTROL_LARGE}); map.addControl(ctrl_nav); //向地图中添加缩略图控件 var ctrl_ove = new BMap.OverviewMapControl({anchor:BMAP_ANCHOR_BOTTOM_RIGHT,isOpen:1}); map.addControl(ctrl_ove); //向地图中添加比例尺控件 var ctrl_sca = new BMap.ScaleControl({anchor:BMAP_ANCHOR_BOTTOM_LEFT}); map.addControl(ctrl_sca); } initMap();//创建和初始化地图 </script> </html> 如果引入简单地图,将以上代码复制即可。
步骤分解
1,想要在HTML中加载百度地图,使用js形式,先去申请个秘钥
<script type="text/javascript" src="http://api.map.baidu.com/api?key=&v=1.1&services=true"></script>
2,创建一个map地图实例,放进div中:
<div id="example">
var map1=new Bmap.map("example");
3,创建地图起始点和显示级别(此例地图放大级别是11):
map1.centerAndZoom(new Bmap.point(120,30),11)
4.设置当前城市:
map.setCurrentCity("广州")
5,对地图拖拽,缩放等进行配置,直接调用内置api:
enableDragging() none 启用地图拖拽。
disableDragging() none 禁用地图拖拽。
enableScrollWheelZoom() none 启用滚轮放大缩小。
disableScrollWheelZoom() none 禁用滚轮放大缩小。
enableDoubleClickZoom() none 启用双击放大。
disableDoubleClickZoom() none 禁用双击放大。
enableKeyboard() none 启用键盘操作。键盘的上、下、左、右键可连续移动地图。同时按下其中两个键可使地图进行对角移动。PgUp、PgDn、Home和End键会使地图平移其1/2的大小。+、-键会使地图放大或缩小一级。
disableKeyboard() none 禁用键盘操作。
enableInertialDragging() none 启用地图惯性拖拽
disableInertialDragging() none 禁用地图惯性拖拽。
enableContinuousZoom() none 启用连续缩放效果
disableContinuousZoom() none 禁用连续缩放效果。
enablePinchToZoom() none 启用双指操作缩放
disablePinchToZoom() none 禁用双指操作缩放
e
nableAutoResize() none 启用自动适应容器尺寸变化
disableAutoResize() none 禁用自动适应容器尺寸变化。
setDefaultCursor(cursor:String) none 设置地图默认的鼠标指针样式。参数cursor应符合CSS的cursor属性规范
getDefaultCursor() String 返回地图默认的鼠标指针样式。
setDraggingCursor(cursor:String) none 设置拖拽地图时的鼠标指针样式。参数cursor应符合CSS的cursor属性规范。
getDraggingCursor() String 返回拖拽地图时的鼠标指针样式
setMinZoom(zoom:Number) none 设置地图允许的最小级别。取值不得小于地图类型所允许的最小级别。
setMaxZoom(zoom:Number) none 设置地图允许的最大级别。取值不得大于地图类型所允许的最大级别。
6,添加事件监听:
map.addEventListener("operate",function(e){doSomething})
事件类型:
click {type, target, point, pixel, overlay} 左键单击地图时触发此事件。
dblclick {type, target, pixel, point} 鼠标双击
rightclick {type, target, point, pixel, overlay} 右键单击
rightdblclick {type, target, point, pixel, overlay} 右键双击
maptypechange {type, target} 地图类型发生变化时。
mousemove {type, target, point, pixel, overlay} 鼠标在地图区域移动过程中
mouseover {type, target} 鼠标移入地图区域时
mouseout {type, target} 鼠标移出地图区域时
movestart {type, target} 地图移动开始时
moving {type, target} 地图移动过程中触发此事件。
moveend {type, target} 地图移动结束时
zoomstart {type, target} 地图更改缩放级别开始时
zoomend {type, target} 地图更改缩放级别结束时
addoverlay {type, target} 当使用Map.addOverlay()方法向地图中添加单个覆盖物时
。 addcontrol {type, target} 当使用Map.addControl()方法向地图中添加单个控件时
removecontrol {type, target} 当使用Map.removeControl()方法移除单个控件时
removeoverlay {type, target} 当使用Map.removeOverlay()方法移除单个覆盖物时
clearoverlays {type, target} 当使用Map.clearOverlays()方法一次性移除全部覆盖物时
dragstart {type, target, pixel, point} 开始拖拽地图时
dragging {type, target, pixel, point} 拖拽地图过程中
dragend {type, target, pixel, point} 停止拖拽地图时
addtilelayer {type, target} 添加一个自定义地图图层时
。 removetilelayer {type, target} 移除一个自定义地图图层时
load {type, target, pixel, point, zoom} 调用Map.centerAndZoom()方法时。这表示位置、缩放层级已经确定,但可能还在载入地图图块。
resize {type, target, size} 地图可视区域大小发生变化时
hotspotclick {type, target, hotspots} 点击热区时
hotspotover {type, target, hotspots} 鼠标移至热区时
hotspotout {type, target, hotspots} 鼠标移出热区时
tilesloaded {type, target} 当地图所有图块完成加载时
touchstart {type, target, point,pixel} 触摸开始时,仅适用移动设备
touchmove {type, target, point,pixel} 触摸移动,仅适用移动设备
touchend {type, target, point,pixel} 触摸结束时】,仅适用移动设备
longpress {type, target, point,pixel} 长按事件,仅适用移动设备。
以上的参数指在操作事件之后可以获取到的参数,传给function(e)的e对象,可以通过e.params来取,比如输出单击的经度:
map.addEventListener("click",function(e){ alert(e.point.lng); });
添加控件:
比如添加2D,3D卫星地图类型控件:
map.addControl(new BMap.MapTypeControl());
添加和删除右下角缩略图(小地图)控件:
var c = new BMap.OverviewMapControl() ;
map.addControl(c);
map.removeControl(c);
设定特定的控件的类型:
var opts1={ type:BMAP_MAPTYPE_CONTROL_MAP }
map.addControl(new BMap.MapTypeControl(opts1));
还有其他控件或类型:
Control ScaleControlOptions ControlAnchor OverviewMapControl LengthUnit MapTypeControl NavigationControl CopyrightControl(版权控件) NavigationControlType ScaleControl(比例尺控件) Copyright MapTypeControlType(控件样式类型) GeolocationControl(定位控件) StatusCode PanoramaControl(看全景控件)
其他的应用:
比较好的博主专栏https://blog.csdn.net/lmj623565791/category_2392939.html
Android 百度地图 SDK v3.0.0 (一)
1.把百度地图导入app
申请密钥
a、申请密钥,到百度API控制台的页面:http://lbsyun.baidu.com/apiconsole/key
输入要应用名称,选择应用类型,输入安全码。
b、关于安全码 ( 数字签名;包名 ) 的获取:
打开IDE:
黑框框住的就是数字签名,然后包名就是咱们应用的包名,直接用分号连接:例如:F5:10:39:D9:81:57:BD:2E:A0:CD:E3:EB:5E:C4:CC:E0:E0:0D:41:56;com.zhy.zhy_baidu_ditu_demo03
最后点击完成,就能获取密钥了:
3、第一个baidu map应用
下载就不多说了,直接点击官网的相关下载就行选择就可,后面我也会贴上源码。
配置:
第一步:在工程里新建libs文件夹,将开发包里的baidumapapi_vX_X_X.jar拷贝到libs根目录下,将libBaiduMapSDK_vX_X_X.so拷贝到libs\armeabi目录下(官网demo里已有这两个文件,如果要集成到自己的工程里,就需要自己添加),拷贝完成后的工程目录如下图所示;
注:liblocSDK3.so和locSDK_3.1.jar为百度定位SDK所使用资源,开发者可根据实际需求自行添加。
android_dev1.png
第二步:在工程属性->Java Build Path->Libraries中选择“Add External JARs”,选定baidumapapi_vX_X_X.jar,确定后返回。
通过以上两步操作后,您就可以正常使用百度地图SDK为您提供的全部功能了。
注意:由于adt插件升级,若您使用Eclipse adt 22的话,需要对开发环境进行相应的设置,方法如下:
1). 在Eclipse 中选中工程,右键选 Properties->Java Build Path->Order and Export 使 Android Private Libraries处于勾选状态;
2). Project -> clean-> clean all .
a、在application中添加开发密钥
<application <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="开发者 key" /> </application>
b、添加所需权限
<uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" /> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.BROADCAST_STICKY" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
c、布局文件中添加地图控件
<com.baidu.mapapi.map.MapView android:id="@+id/id_bmapView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:clickable="true" />
d、在应用程序创建时初始化 SDK引用的Context 全局变量:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); // 在使用SDK各组件之前初始化context信息,传入ApplicationContext // 注意该方法要再setContentView方法之前实现 SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity_main); }
好了,经过这四步就能显示地图了
e、不过地图很耗电,所以有必要管理其声明周期(耗电)
package com.zhy.zhy_baidu_ditu_demo00; import android.app.Activity; import android.os.Bundle; import android.view.Window; import com.baidu.mapapi.SDKInitializer; import com.baidu.mapapi.map.MapView; public class MainActivity extends Activity { private MapView mMapView = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); // 在使用SDK各组件之前初始化context信息,传入ApplicationContext // 注意该方法要再setContentView方法之前实现 SDKInitializer.initialize(getApplicationContext()); setContentView(R.layout.activity_main); // 获取地图控件引用 mMapView = (MapView) findViewById(R.id.id_bmapView); } @Override protected void onDestroy() { super.onDestroy(); // 在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理 mMapView.onDestroy(); mMapView = null; } @Override protected void onResume() { super.onResume(); // 在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理 mMapView.onResume(); } @Override protected void onPause() { super.onPause(); // 在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理 mMapView.onPause(); } }
as在百度官网有