提交 7d0ed2f4 编写于 作者: 福明 提交者: skylarCai

IssueID:1683:Python example ultrasonic ranging

[Detail]
New Python example: ultrasonic ranging.

[Verified Cases]
Build Pass: <py_engine_demo>
Test Pass:  <py_engine_demo>
上级 f4cd40ef
# 超声测距仪
本案例通过一个超声测距传感器测量距离,测量值显示在液晶屏幕上,同时上送到云端。本案例是手持式超声测距仪的原型。
## 背景知识
由于超声波指向性强,能量消耗缓慢,在介质中传播的距离较远,因而超声波经常用于距离的测量,如测距仪和物位测量仪等都可以通过超声波来实现。利用超声波检测往往比较迅速、方便、计算简单、易于做到实时控制,并且在测量精度方面能达到工业实用的要求,因此在移动机器人研制上也得到了广泛的应用。
<br>
## 准备
1. M5Stack Core2开发板一套<br>
2. URM37超声测距传感器一个<br>
3. 母对母杜邦连接线若干<br>
涉及到的硬件购买链接如下,仅供参考,不负责商家发货的品质保障等问题!
<br>
| 名称 | 数量 | 参考链接 |
| --- | --- | --- |
| M5Stack Core2开发板 | 1 | [M5Stack Core2](https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-22404213529.17.732749d8usCqYX&id=625561056791) |
| URM37超声测距传感器 | 1 | [URM37超声测距传感器](https://wiki.dfrobot.com.cn/_SKU_SEN0001_URM37V5.0%E8%B6%85%E5%A3%B0%E6%B3%A2%E6%B5%8B%E8%B7%9D%E4%BC%A0%E6%84%9F%E5%99%A8) |
| 母对母杜邦线 | 4 | [母对母杜邦线](https://detail.tmall.com/item.htm?id=14466195609&ali_refid=a3_430582_1006:1104520036:N:MsF9mE9KLTC2IibWJh+K1A==:21c5b519e28c4b0cd17ec4383141281f&ali_trackid=1_21c5b519e28c4b0cd17ec4383141281f&spm=a230r.1.14.1&skuId=3108214440213) 请选用10cm长即可 |
### 硬件连线图
硬件连线图如下图所示:
<div align="center">
<img src=./../../../images/ultrasonic_ranging/hardware_connection.png width=100%/>
</div>
<br>
## 物联网平台开发
### 开通公共实例
对于第一次使用物联网平台的读者,需要开通实例以使用物联网平台的功能。这里可以使用免费的公共实例进行开发。
[物联网平台](https://iot.console.aliyun.com/lk/summary/new)中,左上角选择“华东2-上海”,点击“公共实例”,即可开通。
<div align="center">
<img src=./../../../images/sound_led/声控灯_物联网平台开发_物联网平台.png width=90%/>
</div>
开通物联网平台功能之后,需要完成下面的3个步骤完成云端设备的设定:
1. 创建云端产品
2. 创建产品属性(物模型)
3. 创建云端设备(获取三元组)
<br>
### 创建云端产品
点击上图中的“公共实例”,即可进入[控制台](https://iot.console.aliyun.com/lk/summary/new)进行产品创建。然后,点击创建产品按钮,如下图所示。
<div align="center">
<img src=./../../../images/ultrasonic_ranging/create.png
width=100%/>
</div>
选择之后,点击“确认”按钮,即可完成产品创建。如下图所示
<div align="center">
<img src=./../../../images/ultrasonic_ranging/create_1.png width=100%/>
</div>
### 创建产品属性(物模型)
按照如下步骤定义物模型。完成后点击“发布上线”。
<div align="center">
<img src=./../../../images/ultrasonic_ranging/product.png width=100%/>
</div>
<br>
<div align="center">
<img src=./../../../images/ultrasonic_ranging/product_1.png width=100%/>
</div>
<br>
<div align="center">
<img src=./../../../images/ultrasonic_ranging/product_2.png width=75%/>
</div>
### 创建云端设备(获取三元组)
按照如下步骤添加设备。
<div align="center">
<img src=./../../../images/ultrasonic_ranging/device.png width=100%/>
</div>
<br>
<div align="center">
<img src=./../../../images/ultrasonic_ranging/device_1.png width=75%/>
</div>
##### **获取设备三元组**
如下图所示,在设备列表中点击“查看”按钮,就可以看到设备的三元组信息。
设备三元组是指产品Key(productKey)、设备名称(DeviceName)、设备秘钥(DeviceSecret)。
三元组是物联网设备端和物联网云端设备相关联的唯一标识符,在设备端连接云端的时候会使用三元组信息和云端进行鉴权,鉴权通过之后云端会认为设备已激活并上线。设备三元组在后面设备端开发时会用到,请注意保存。
<div align="center">
<img src=./../../../images/ultrasonic_ranging/triple.png width=100%/>
</div>
<br>
## 设备端开发
### 开发环境
在进行下一步之前请确保M5StackCore2开发环境已经搭建完毕。详情请参考[M5StackCore2快速开始](../../../startup/M5StackCore2_startup.md)的说明。
<br>
### 创建解决方案
如下图所示,打开VSCode之后在新建一个基于helloworld的python工程,设定好工程名称(“ultrasonic_ranging”)及工作区路径之后,硬件类型选择M5Stack Core2,点击立即创建,创建一个Python轻应用的解决方案。
<div align="center">
<img src=./../../../images/classifying_rubbish/垃圾分类识别_创建工程.png width=80%/>
</div>
### 代码准备
[超声测距仪](./code/)目录下的所有脚本进行复制到“ultrasonic_ranging”工程根目录中,然后进行如下设定完成设备端代码的开发。
> Python脚本的详细说明请参考脚本内嵌的文字注释
### 修改路由器名称及密码
修改ultrasonic_ranging工程里main.py中SSID和PWD的值为读者实际要连接的路由器的名称及密码(请注意名称和密码都需要放在''符号中间)。
```python
# Wi-Fi SSID和Password设置
SSID='Your-AP-SSID'
PWD='Your-AP-Password'
```
修改完成之后connect_wifi函数就会连接读者自己设定的路由器。
### 修改设备的三元组信息
请参考“获取设备的三元组步骤”,把获取的三元组信息,填入main.py中:
```python
# HaaS设备三元组
productKey = "Your-ProductKey"
deviceName = "Your-devicename"
deviceSecret = "Your-deviceSecret"
```
### 运行结果
液晶屏幕上实时显示距离测量值,单位为厘米。
<div align="center">
<img src=./../../../images/ultrasonic_ranging/display.png width=50%/>
</div>
### 云端查看
进入阿里云官网,用阿里云账号[登录物联网平台](https://iot.console.aliyun.com/devices/)查看状态
<div align="center">
<img src=./../../../images/ultrasonic_ranging/result.png width=100%/>
</div>
<br>
到此为止,超声测距仪案例就已经完成了。如果想学习更多实验,请参考[HaaS案例实践详解](https://gitee.com/haasedu/haasedu/tree/release_2.0)
## 后记
本案例中使用的URM37超声波测距传感器还拥有舵机控制和温度采集功能,后续可尝试把这些功能加入案例中。
\ No newline at end of file
{
"name": "m5stackcore2",
"version": "1.0.0",
"io": {
"serial2": {
"type": "UART",
"port": 2,
"dataWidth": 8,
"baudRate": 9600,
"stopBits": 1,
"flowControl": "disable",
"parity": "none"
}
},
"debugLevel": "ERROR",
"repl": "disable"
}
# -*- encoding: utf-8 -*-
from aliyunIoT import Device # aliyunIoT组件是连接阿里云物联网平台的组件
import display
import utime
import ujson # json字串解析库
import netmgr as nm # netmgr是Wi-Fi网络连接的组件
import _thread
import urm37
from driver import UART
# 物联网平台连接标志位
iot_connected = False
# 三元组信息
productKey = "产品密钥"
deviceName = "设备名称"
deviceSecret = "设备密钥"
# Wi-Fi SSID和Password设置
wifiSsid = "请填写您的路由器名称"
wifiPassword = "请填写您的路由器密码"
# 物联网设备实例
device = None
dist = 65535
# 等待Wi-Fi成功连接到路由器
def get_wifi_status():
nm.init()
nm.disconnect()
wifi_connected = nm.getStatus()
print("start to connect " , wifiSsid)
nm.connect(wifiSsid, wifiPassword) # 连接到指定的路由器(路由器名称为wifiSsid, 密码为:wifiPassword)
while True :
if wifi_connected == 5: # nm.getStatus()返回5代表连线成功
break
else:
wifi_connected = nm.getStatus() # 获取Wi-Fi连接路由器的状态信息
utime.sleep(0.5)
print("Wi-Fi connected")
print('DeviceIP:' + nm.getInfo()['ip']) # 打印Wi-Fi的IP地址信息
# 物联网平台连接成功的回调函数
def on_connect(data):
global iot_connected
iot_connected = True
# 连接物联网平台
def connect_lk(productKey, deviceName, deviceSecret):
global device, iot_connected
key_info = {
'region': 'cn-shanghai',
'productKey': productKey,
'deviceName': deviceName,
'deviceSecret': deviceSecret,
'keepaliveSec': 60
}
# 将三元组信息设置到iot组件中
device = Device()
# 设定连接到物联网平台的回调函数,如果连接物联网平台成功,则调用on_connect函数
device.on(Device.ON_CONNECT, on_connect)
# 配置收到云端属性控制指令的回调函数,如果收到物联网平台发送的属性控制消息,则调用on_props函数
device.on(Device.ON_PROPS, on_props)
# 启动连接阿里云物联网平台过程
device.connect(key_info)
# 等待设备成功连接到物联网平台
while(True):
if iot_connected:
print('物联网平台连接成功')
break
else:
print('sleep for 1 s')
utime.sleep(1)
def networkThread():
get_wifi_status()
connect_lk(productKey, deviceName, deviceSecret)
old_dist = 65535
while True:
if dist != old_dist:
old_dist = dist
prop = ujson.dumps({
'distance': dist
})
upload_data = {'params': prop}
device.postProps(upload_data)
utime.sleep(1)
def main():
global dist
_thread.stack_size(20 * 1024)
_thread.start_new_thread(networkThread, ())
disp = display.TFT()
uart_dev = UART()
if uart_dev.open('serial2') != 0:
print('Error: UART init error.')
return
urm37_dev = urm37.URM37(uart_dev)
utime.sleep(1)
while True:
dist = urm37_dev.getRange()
disp.clear()
disp.font(disp.FONT_DejaVu40)
if dist == 65535:
disp.text(100, 100, 'NA', disp.RED)
else:
text = '%03d' %dist
disp.text(90, 100, text, disp.GREEN)
utime.sleep_ms(200)
if __name__ == '__main__':
main()
from driver import UART
import utime
class URM37(object):
def __init__(self, uart_obj):
self.uart_obj = None
if not isinstance(uart_obj, UART):
raise ValueError("parameter is not a UART object")
self.uart_obj = uart_obj
def getRange(self):
tx_buf = bytearray([0x22, 0x00, 0x00, 0x22])
rx_buf = bytearray(4)
while True:
if self.uart_obj.read(rx_buf) <= 0:
break
self.uart_obj.write(tx_buf)
utime.sleep_ms(300)
if self.uart_obj.read(rx_buf) != 4:
return 65535
return rx_buf[1] * 256 + rx_buf[2]
def getTemperature(self):
tx_buf = bytearray([0x11, 0x00, 0x00, 0x11])
rx_buf = bytearray(4)
while True:
if self.uart_obj.read(rx_buf) <= 0:
break
self.uart_obj.write(tx_buf)
utime.sleep_ms(300)
if self.uart_obj.read(rx_buf) != 4:
return -4095.0
ret = rx_buf[1] * 256 + rx_buf[2]
if (ret & 4096) == 0:
ret = (ret & 4095) * 0.1
else:
ret = (ret & 4095) * (-0.1)
return ret
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册