使用.NET IoT驱动超声波测距传感器

背景

最近买的一堆传感器到货了,先来把玩一下超声波测距传感器。超声波传感器一般用于机器人,小车的避障,物体的测距,液位检测,停车检测等领域。

188d4f39f9b76b9bfe81c4688da1770a.png

HC-SR04

知识回顾

开始之前我们先复习一下高中的物理知识。

a8d42a490603539793a2f8d5a6bafb95.png

原理

通过上图的原理图,又已知声波速度,这里取 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显示屏》。

1610bad15ef949cccbddd5298e3d6cc2.png

接线图

上图因为没找到 TX2 的图片所以用的 Nano。树莓派,Nano 和 TX2 的物理引脚功能一样,只是 PCM 编码和 GPIO 的编号是不一样的,代码有的情况下需要调整,后续会讲到。

接好线,我们先快速用 Python 验证下原理。

import RPi.GPIO as GPIO
import timeTRIG_PIN = 38
ECHO_PIN = 40def 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:passpulse_s = time.time()#等待高电平结束,再次记录时间while GPIO.input(ECHO_PIN) == GPIO.HIGH:passpulse_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 40using 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 40using 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);
}

最终效果如下:

2b38aad0bf67b05a4f4bf1fc01e7954c.png

最终效果图

References

[1] 支持的设备文档: https://github.com/dotnet/iot/blob/main/src/devices/README.md

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/285059.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2019-nCoV 全国新型肺炎疫情每日动态趋势可视图

传染源: 野生动物,可能为中华菊头蝠 病毒: 新型冠状病毒 2019-nCoV 传播途径: 经呼吸道飞沫传播,亦可通过接触传播 易感人群: 人群普遍易感。老年人及有基础疾病者感染后病情较重,儿童及婴幼儿也有发病 潜伏期: 一般为 3~7 天,最长…

C语言试题173之实现插入排序算法

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:实现排序…

【ArcGIS遇上Python】ArcGIS Python将多个文件夹内的分幅数据整合到同一个文件夹内——以Globeland30数据为例

文章目录 WinRAR解压缩ArcGIS Python批处理从Glabeland30官网下载的全球地覆盖数据包括3年(2000、2010、2020),每一年都是按图幅存储的tif格式栅格数据。以2000的数据为例,全球共812个图幅,每一个图幅对应一个压缩包,如下图所示。 WinRAR解压缩 在进行数据预处理时,必须…

Delphi中字符串比较大小 VS Oracle-SQL中字符串比较大小

重点注意Delphi和Oracle-SQL中比较字符串时空字符串的根本性的不同Delphi中的字符串比较 Delphi中字符串比较大小的规则:对应位置的字符按照字符编码值逐个对比,直到遇到可以确定大小关系的就结束比较参考《Delphi的Ord函数和ASCII码对照表》 常见的一些…

STM8S和STM8L调试串口中断的注意点

源:STM8S和STM8L调试串口中断的注意点

C语言试题174之实现快速排序算法

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:实现快速…

解决slideDown()、slideUp()执行结束后才执行下一次,导致鼠标离开后很久动画依然在执行的问题...

问题描述: 给一个容器设置了mouseenter时,一个隐藏的box通过slideDown()显示出来;mouseleave时,通过slideUp()隐藏。 当鼠标不断在容器上滑过时,会导致鼠标离开很久后,动画也在不断执行 解决方法&#xff…

Docker Compose 安装 Superset

前言动手学 dockerSuperset 是一个强大的在线 SQL 查询编辑工具,同时也是一个轻量级的 BI 工具,今天我们就来动手学一下用 docker compose 安装 Superset。安装动手学 docker安装 git 并克隆项目:yum install git -ygit clone https://github…

[转]再见 NoSQL!

为解决大规模数据集合多重数据种类带来的挑战,NoSQL 应运而生,但现在却也遇到了诸多问题,本文作者 Rick Negrin,曾在微软工作 12 年,并在 SQL Server 团队度过大部分光阴,他提出,是时候「和 NoS…

【ArcGIS Pro微课1000例】0008:ArcGIS Pro加载不同来源的在线底图数据

ArcGIS Pro可以很方便的选择不同来源的在线底图数据,如中国地图彩色版、各种形式的天地图等。 打开ArcGIS Pro,点击左下角的【设置】。 点击【选项】。 ArcGIS Pro提供了三种形式的底图:组织的默认底图、自定义底图<

ORA-16198: LGWR received timedout error from KSR

ORA-16198: LGWR received timedout error from KSRORA-16198 意味着主库上的LOG_ARCHIVE_DEST_2的NET_TIMEOUT设置的太小&#xff0c;导致LNS不能在设置的时间内将日志传输到备库。解决方法是提高NET_TIMEOUT的值到15-20 秒&#xff0c;SQL>ALTER SYSTEM SET LOG_ARCHIVE_D…

php+mysql实现数据分批插入

上周需要将云端的数据有条件的录入到mysql中&#xff0c;最开始是使用遍历数据然后一条条的插入的笨方法&#xff0c;结果速度慢的要死&#xff0c;所以又随便写了个笨方法2.0&#xff0c;记录一下自己菜鸟的成长历程。同时这也是在博客园的第一篇文章&#xff0c;目的仅仅是单…

RIL接听电话没有声音的问题 [ RIL_Answer | RIL_SetAudioDevices ]

没有什么好说明的&#xff0c;直接上代码&#xff1a; RIL_Answer(m_hRil); RILAUDIODEVICEINFO audioDeviceInfo; audioDeviceInfo.cbSize sizeof(audioDeviceInfo); audioDeviceInfo.dwParams RIL_PARAM_ADI_ALL; audioDeviceInfo.dwRxDevic…

[转]敏捷开发之Scrum扫盲,及敏捷开发中XP与SCRUM的区别

敏捷开发之Scrum扫盲篇 现在敏捷开发是越来越火了&#xff0c;人人都在谈敏捷&#xff0c;人人都在学习Scrum和XP… 为了不落后他人&#xff0c;于是我也开始学习Scrum&#xff0c;今天主要是对我最近阅读的相关资料&#xff0c;根据自己的理解&#xff0c;用自己的话来讲述S…

C语言试题175之实现选择排序算法

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:实现选择…

最流行的 .NET 反编译工具合集

编译和反编译 .NET 中的编译是把开发人员写的 C# 代码转化为计算机可理解的代码的过程&#xff0c;也就是中间语言代码&#xff08;IL代码&#xff09;。在这个过程中&#xff0c;C# 源代码被转换为可执行文件&#xff08;exe或者dll 文件&#xff09;。反编译则和编译相反&am…

【ArcGIS Pro微课1000例】0009:ArcGIS Pro地理配准完整教程(建议收藏)

扫描得到的地图数据通常不包含空间参考信息,航片和卫片的位置精度也往往较低,这就需要通过具有较高位置精度的控制点将这些数据匹配到用户指定的地理坐标系中,这个过程称为地理配准。 地理配准即就是通过建立数学函数将栅格数据集(扫描后的图像)中各点的位置与标准空间参…

Intent跳转传list集合

先把List<>改为ArrayList<> ArrayList<Good> listnew ArrayList<Good>(); Intent intent new Intent(MainActivity.this,InfoActivity.class); intent.putExtra("list", list); startActivity(intent); Intent intent get…

Linux中的selinux

#1.selinux内核级加强型防火墙1&#xff09;针对文件&#xff0c;会对系统中每个文件添加安全上下文&#xff08;context&#xff09;2)针对进程&#xff0c;会对系统中的每个进程添加安全上下文&#xff08;context&#xff09;3&#xff09;会在系统服务上设定sebool开关4&am…

C语言试题176之实现归并排序算法

📃个人主页:个人主页 🔥系列专栏:C语言试题200例 💬推荐一款刷算法、笔试、面经、拿大公司offer神器👉 点击跳转进入网站 ✅作者简介:大家好,我是码莎拉蒂,CSDN博客专家(全站排名Top 50),阿里云博客专家、51CTO博客专家、华为云享专家 1、题目 题目:实现归并…