使用.NET IoT驱动超声波测距传感器
背景
最近买的一堆传感器到货了,先来把玩一下超声波测距传感器。超声波传感器一般用于机器人,小车的避障,物体的测距,液位检测,停车检测等领域。
HC-SR04
知识回顾
开始之前我们先复习一下高中的物理知识。
原理
通过上图的原理图,又已知声波速度,这里取 340 m/s (空气中的音速在1个标准大气压和15℃的条件下约为340m/s)。
那么,我们通过记录发射时间和接收时间,计算出间隔,然后距离根据(声波速度 * 时间间隔)/ 2 就可以得到。
模块介绍
我使用这个模块是宽压的 3.3v -5 v,探测距离:2cm-450cm,有2cm的超近盲区。精度0.3cm。
使用的方式也很简单,一个控制口发出一个10US以上的高电平,就可以在接收口等待高电平输出。一有输出就记录一个开始时间,当此口变为低电平时再记录一个结束时间,他们的间隔时间就为此次测距的时间,根据公式便可算出距离。
接线测试
在这里我用的 Jetson TX2 开发版套件测试,针脚使用的 38,和40。
38脚连 Trig ,设为输出模式;40 脚连 Echo,设为输入模式。
其上还连接了 I2C 设备,一个SSD1306 OLED 显示屏,作为后续的距离展示,更详细的介绍可以看我之前的文章《使用.Net驱动Jetson Nano的OLED显示屏》。
接线图
上图因为没找到 TX2 的图片所以用的 Nano。树莓派,Nano 和 TX2 的物理引脚功能一样,只是 PCM 编码和 GPIO 的编号是不一样的,代码有的情况下需要调整,后续会讲到。
接好线,我们先快速用 Python 验证下原理。
import RPi.GPIO as GPIO
import time
TRIG_PIN = 38
ECHO_PIN = 40
def main():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(TRIG_PIN, GPIO.OUT)
GPIO.setup(ECHO_PIN, GPIO.IN)
print("Demo running. Press CTRL+C to exit.")
try:
while True:
time.sleep(1)
distance = StartModule()
print("Distance: {}cm".format(distance))
finally:
GPIO.cleanup()
def StartModule():
# 发送 trig 信号,持续 10us 的方波脉冲
GPIO.output(TRIG_PIN,GPIO.HIGH)
# 单位为 s ,10us 需转换
time.sleep(0.00001)
GPIO.output(TRIG_PIN,GPIO.LOW)
#等待低电平结束,记录时间
while GPIO.input(ECHO_PIN) == GPIO.LOW:
pass
pulse_s = time.time()
#等待高电平结束,再次记录时间
while GPIO.input(ECHO_PIN) == GPIO.HIGH:
pass
pulse_e = time.time()
# 测得距离(单位:m) = (pulse_end - pulse_start) * 声波速度 / 2
return round((pulse_e - pulse_s) * 17000,2)
if __name__ == '__main__':
main()
.NET 实现
.NET IoT 库由两个 NuGet 包组成:
•System.Device.Gpio•Iot.Device.Bindings
System.Device.Gpio
支持使用各种协议来与低级别硬件引脚交互,以控制设备。我编写的 Sang.IoT.SSD1306
就使用了这个库。
Iot.Device.Bindings
提供了各种常用的设备绑定,当然里面其实也是有 SSD13xx 的,如果不是想了解原理,可以不用重复造轮子,先前往支持的设备文档[1]里面查询。
1.新建项目
dotnet new console -o ultrasonic
2.进入项目目录
cd ultrasonic
3.安装依赖库
dotnet add package Iot.Device.Bindings
4.修改代码
using System;
using System.Device.Gpio;
using System.Threading;
using Iot.Device.Hcsr04;
Console.WriteLine("Test sensor. Press Ctrl+C to end.");
// 此处注意 使用的是TX2设备,其他设备需查阅转换
int TRIG_GPIO = 394; //Pin 38
int ECHO_GPIO = 393; //Pin 40
using var controller = new GpioController();
using var sensor = new Hcsr04(controller,TRIG_GPIO,ECHO_GPIO);
while (true)
{
if(sensor.TryGetDistance(out _)){
Console.WriteLine($"Distance: {sensor.Distance}");
}
Thread.Sleep(1000);
}
5.运行测试
dotnet run
以上便是 .NET 中的实现,如果你想验证下驱动原理,可以自行尝试用 .NET 编码实现。
这里需要注意的是,传入的 triggerPin 和 echoPin 是所用设备的 GPIO 编号,不是物理的针脚号,需要查阅资料获取。
针对本案例,使用的 38 和 40针脚,在树莓派中 GPIO 编号分别是 20和21,在 Jetson Nano 中分别是 77和78 ,在 Jetson TX2 中分别是 394和393。
接入显示屏
基于以上代码,我们引入包Sang.IoT.SSD1306
。
dotnet add package Sang.IoT.SSD1306
修改代码
using System;
using System.Device.Gpio;
using System.Threading;
using Iot.Device.Hcsr04;
using Sang.IoT.SSD1306;
using SkiaSharp;
Console.WriteLine("Test sensor. Press Ctrl+C to end.");
// 此处注意 使用的是TX2设备,其他设备需查阅转换
int TRIG_GPIO = 394; //Pin 38
int ECHO_GPIO = 393; //Pin 40
using var controller = new GpioController();
using var sensor = new Hcsr04(controller,TRIG_GPIO,ECHO_GPIO);
// 显示准备
using var oled = new SSD1306_128_64(1);
SKPaint paint = new SKPaint() {
Color = new SKColor(255, 255, 255),
StrokeWidth = 1,
TextSize = 13,
Style = SKPaintStyle.Fill,
};
oled.Begin();
oled.Clear();
while (true)
{
if(sensor.TryGetDistance(out _)){
Console.WriteLine($"Distance: {sensor.Distance}");
// OLED 显示
using(var bitmap = new SKBitmap(128, 64, true)){
SKCanvas canvas = new SKCanvas(bitmap);
paint.TextSize = 13;
canvas.DrawText(DateTime.Now.ToString(), 0, 13, paint);
paint.TextSize = 30;
canvas.DrawText(sensor.Distance.ToString(), 0, 50, paint);
oled.Image(bitmap.Encode(SKEncodedImageFormat.Png, 100).ToArray());
}
oled.Display();
}
Thread.Sleep(1000);
}
最终效果如下:
最终效果图
References
[1]
支持的设备文档: https://github.com/dotnet/iot/blob/main/src/devices/README.md
相关文章
- 用.NET开发的磁力搜索引擎——btbook.net「建议收藏」
- 不安装运行时运行.NET程序
- 使用.Net驱动Jetson Nano的OLED显示屏
- [接上篇]在Window10/11的Linux子系统Docker上部署VB.NET Asp.Net Core WebAPI应用
- .net 温故知新:【10】.NET ORM框架EFCore使用入门之CodeFirs、DBFirst
- 【愚公系列】2023年01月 .NET CORE工具案例-RedLock.net实现分布式锁
- net掌握Linux环境下的.NET开发(linuxdot)
- MongoDB 使用.NET开发充分利用数据库性能(mongodb.net)
- 数据库使用.NET连接MySQL数据库(net连接mysql)
- 开发积极探索Mysql.Net 开发之路(mysql.net)
- .net让Oracle与ASP.NET实现无缝连接(oracleasp)
- 联手开发:.NET与Oracle的合作之路(.net和oracle)
- 华云斥资千万收购 huayun.com/net/org 等域名
- Oracle Database: The Ultimate Connection Guide for .NET Developers(net连接oracle)
- .net下的数据库连接SQLServer驱动在.NET平台下的数据库连接简明介绍(sqlserver驱动在)
- CMySQL与NET技术融会贯通(c mysql .net)
- NET与MySQL的无限结合(.net 连接mysql)
- Net环境下MySQL数据库驱动的研究与应用(.net的mysql驱动)
- 使用NET来连接MySQL数据库的简单方法(.net怎么连mysql)
- 网上解决Net环境下MySQL数据库的同步问题(.net 同步mysql)
- Net中连接MySQL技术简述(.net中引用mysql)
- NET 与 MySQL 结合能实现优雅的数据事务处理(.net MySQL事物)
- Oracle Net服务重新上线,确保数据安全(oracle net重启)
- 使用Oracle64位Net突破技术极限(oracle64位net)
- asp.net下用Aspose.Wordsfor.NET动态生成word文档中的数据表格的方法
- ASP.NET站点地图(sitemap)简明教程
- .Net中导出数据到Excel(asp.net和winform程序中)
- ASP.NET中在一般处理程序中使用session的简单介绍
- .net/c#memcached缓存获取所有缓存键的方法步骤
- ASP.NET使用Subtract方法获取两个日期之间的天数
- asp.net截屏功能实现截取web页面