Go实现树莓派超声波测距

后面发现调用的两个Go的库进行测算还是没办法读到好的超声波值, 所以放弃

公式

距离(cm)=((声速(m/s)×时间(ms))/ 2) *10

代码

ultrasonicSensor.go

package mainimport ("context""errors""fmt""periph.io/x/conn/v3/gpio""periph.io/x/conn/v3/gpio/gpioreg""time"
)var (TimeoutError = errors.New("timeout error")
)const (SpeedOfSound = 34300.0 // cm/s
)type UltrasonicSensor struct {triggerIO gpio.PinIOechoIO    gpio.PinIOstarted  boolcanceled chan struct{}
}func NewUltrasonicSensor(triggerPinName, echoPinName string) (*UltrasonicSensor, error) {var (us = &UltrasonicSensor{canceled: make(chan struct{}),}err error)us.triggerIO = gpioreg.ByName(triggerPinName)if nil == us.triggerIO {return nil, errors.New("can't find trigger pin")}us.echoIO = gpioreg.ByName(echoPinName)if nil == us.echoIO {return nil, errors.New("can't find echo pin")}return us, err
}func (u *UltrasonicSensor) Init() error {err := u.triggerIO.Out(gpio.Low)if nil != err {return err}err = u.echoIO.In(gpio.PullDown, gpio.NoEdge)return nil
}func (u *UltrasonicSensor) Destroy() error {return nil
}func (u *UltrasonicSensor) Start(detectInterval time.Duration, onDistanceChanged func(cm float64, err error) error) error {go u.run(detectInterval, onDistanceChanged)return nil
}func (u *UltrasonicSensor) run(detectInterval time.Duration, onDistanceChanged func(cm float64, err error) error) {if u.started {return}u.started = truedefer func() {select {case <-u.canceled:default:}u.started = false}()var (err          errordistance     float64distanceTemp float64/*声速大约是343米/秒, 超声波模块最大测量是2m ~ 6m时间(s) = 2*距离(m)/声速(m/s) = 2 * 6 / 343 ≈ 0.035*/maxWaitTime = time.Millisecond * 35 //35parentCtx   = context.Background()ctx         context.Context)for {err = u.ultrasonicPulseOut() // 发送超声波if nil != err {onDistanceChanged(0, err)return}ctx, _ = context.WithTimeout(parentCtx, maxWaitTime)distanceTemp, err = u.getDist(ctx)if nil != err {if TimeoutError != err {onDistanceChanged(0, err)return}fmt.Println("read timeout")time.Sleep(detectInterval)continue}if distance != distanceTemp {distance = distanceTempif err = onDistanceChanged(distance, nil); nil != err {return}}time.Sleep(detectInterval)}
}func (u *UltrasonicSensor) ultrasonicPulseOut() (err error) {if err = u.triggerIO.Out(gpio.High); nil != err {return err}time.Sleep(time.Microsecond * 10) // 10usif err = u.triggerIO.Out(gpio.Low); nil != err {return err}time.Sleep(time.Microsecond * 1)return
}func (u *UltrasonicSensor) getDist(ctx context.Context) (float64, error) {var (startDateTime time.Time // 开启超声波计时)waitForNext := func() error {select {case <-ctx.Done():return TimeoutErrorcase <-u.canceled:return errors.New("cancel error")case <-time.After(time.Nanosecond * 1): // 读取引脚延时,也是软件最大误差}return nil}/* wait for start */for gpio.Low == u.echoIO.Read() {if err := waitForNext(); nil != err {return 0, err}}startDateTime = time.Now()/* wait for end */for gpio.High == u.echoIO.Read() {if err := waitForNext(); nil != err {return 0, err}}return time.Since(startDateTime).Seconds() * SpeedOfSound / 2.0, nil
}func (u *UltrasonicSensor) Stop() error {if !u.started {return nil}select {case u.canceled <- struct{}{}:case <-time.After(time.Second * 2):return errors.New("cancel timeout")}return nil
}

main.go

package mainimport ("fmt""log""periph.io/x/host/v3""sync""time"
)func main() {var (waiter sync.WaitGroup)// 初始化硬件if _, err := host.Init(); err != nil {log.Fatal(err)}sensor, err := NewUltrasonicSensor("GPIO17", "GPIO27")if nil != err {fmt.Println(err)return}if err = sensor.Init(); nil != err {fmt.Println("sensor init fail, ", err.Error())return}defer sensor.Destroy()waiter.Add(1)sensor.Start(time.Second, func(cm float64, err error) error {if nil != err {waiter.Done()fmt.Println(err)return err}fmt.Println("Distance ", cm, "(cm)")return nil})waiter.Wait()
}

Note

注意电源一定要选对, 否则输出功率不够无法准确测量距离…

参考

树莓派|超声波传感器

GPIO-ZERO DistanceSensor

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

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

相关文章

设计模式——组合模式(Composite)

组合模式&#xff08;Composite Pattern&#xff09; 是一种结构型设计模式&#xff0c;它将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 特点 表示整体与部分&#xff1a;组合模式允许你将对象组合成树形结构…

MacOS miniconda安装方法

打开macos “终端” 应用 执行命令 mkdir -p ~/miniconda3curl https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-latest-MacOSX-arm64.sh -o ~/miniconda3/miniconda.shbash ~/miniconda3/miniconda.sh -b -u -p ~/miniconda3rm -rf ~/miniconda3/mini…

腾讯云CVM服务器数据盘挂载

背景&#xff1a;新开腾讯云服务器挂载数据盘。 在腾讯云服务器上挂载数据盘通常涉及以下几个步骤&#xff0c;这里以Linux系统为例进行说明。如果您的服务器是Windows系统&#xff0c;操作界面会有所不同&#xff0c;但原理相似。1. 登录入腾讯云控制台首先&#xff0c;登录腾…

【35分钟掌握金融风控策略16】贷前风控策略详解-1

目录 贷前风控策略详解 贷前风控目标 精准审核申请贷款客户资质 对申请贷款客户进行合理定额 对申请贷款客户进行合理定价 推动实现利润最大化 贷前风控数据源 客户贷款时提供的数据 贷前风控策略详解 俗话说&#xff0c;良好的开端是成功的一半&#xff0c;而贷前是风…

SpringCloud面试题

SpringCloud常见组件有哪些 注册中心组件&#xff1a;Eureka、Nacos 负载均衡组件&#xff1a;Ribbon 远程调用组件&#xff1a;OpenFeign 网关组件&#xff1a;Zuul、Gateway 服务保护组件&#xff1a;Hystrix、Sentinel 服务配置管理组件&#xff1a;SpringCloudConfig、Nac…

docker 部署etcd集群

docker 部署etcd集群 往期内容 ETCD 简介 前言 上期我们对于分布式kv存储中间件有了简单的认识&#xff0c;本期简单介绍docker-compose 部署etcd集群以及可视化工具 etcd Keeper 1-etcd docker 部署 看了很多网上部署的教程&#xff0c;要么超级简陋&#xff0c;要么搞一堆…

VBScript与文件的编码

首先&#xff0c;VBScript的脚本源文件得是ANSI编码的&#xff0c;如果保存为UTF-8格式的&#xff0c;执行时可能会报错&#xff0c;比如你语法什么的都没有问题&#xff0c;不过代码中包含汉字串&#xff0c;那么可能执行时就会出现“未结束的字符串常量”之类的错误。 VBScri…

kubernetes附加组件—图形化管理工具Dashboard

一、介绍 Dashboard是k8s集群管理的一个WebUi&#xff0c;它是k8s的一个附加组件&#xff0c;需要单独部署。 我们可以通过图形化的方法&#xff0c;创建、删除、修改、查询k8s资源。 二、安装部署dashboard组件 Github地址&#xff1a;GitHub - kubernetes/dashboard: Gen…

centos8.5 安装 redis 7.2.4 详细步骤

1 下载Index of /releases/ (redis.io) 通过xftp等方式上传到服务器&#xff0c;安装依赖包 yum install gcc gcc-c make tcl -y [rootlocalhost software]# ll total 3308 -rw-r--r--. 1 root root 3386861 May 3 21:56 redis-7.2.4.tar.gz [rootlocalhost software]# ll…

基于STM32F103ZE平台分析FreeRtos(九)——协程

目录 一、协程简介 二、协程工作机制 2.1 协程控制块结构 2.2 协程管理方式 2.3 协程调度方式 2.4 协程通信机制 三、协程状态及状态切换 3.1 协程状态 3.2 状态切换 四、协程创建 五、协程调度分析 5.1 源码分析 5.2 逻辑图分析 六、协程通信 6.1 协程发送消息…

如何评估大模型音频理解能力-从Gemini说起

Gemini家族包含Ultra、Pro和Nano三种大小的模型是谷歌开发的大型多模态人工智能模型&#xff0c;它在人工智能的多模态领域实现了重大突破&#xff0c;结合了语言、图像、音频和视频的理解能力。 Gemini的性能评估情况如下&#xff1a; Gemini模型的评估的具体指标从文本理解能…

CSS:display作用

display作用 介绍常用的属性值及其作用1. block - 该值将元素设置为块级元素举例分析 2. inline - 将元素设置为内联元素举例分析 3. inline-block - 将元素设置为内联块级元素举例分析 4. flex - 将元素定义为弹性容器&#xff0c;为其子元素提供灵活的布局能力举例分析 5. gr…

WiFi客户问题:kernel crash,PCI中断丢失,根本原因是中断类型错误

客户问题&#xff1a;kernel crash 问题描述&#xff1a; 在AML平台上&#xff0c;加载WiFi6 driver&#xff0c;几秒钟之后&#xff0c;kernel crash。 复现&#xff1a; 本地实验室容易复现。 分析Triage&#xff1a; 软件系统分析&#xff1a; WiFi driver 等待event t…

Sqli-labs第一关到第四关

目录 一&#xff0c;了解PHP源代码 二&#xff0c;破解第一关 2.1在了解完源码之后&#xff0c;我们重点看一下 2.2破解这道题表中有几列 2.3查看表中哪一列有回显 2.4查询库&#xff0c;表&#xff0c;列信息 三&#xff0c;总结 前提&#xff1a; 之所以把1234关…

gpt_academic的使用——含一键安装和接入其他API以及本地模型

https://github.com/binary-husky/gpt_academic/releases/ https://github.com/binary-husky/gpt_academic/wiki 安装

测试平台开发:Django开发实战之注册界面实现(上)

实现注册功能&#xff0c;大概包括以下几个步骤 1、设计ui ##字段 通过看数据库里面的user表里面的字段&#xff0c;可以大概知道需要几个字段&#xff1a; emailusernamepasswordpassword_confirm 生成简单的ui界面&#xff0c;复制这个html代码 然后在项目路径下面创建一…

鸿蒙 DevEcoStudio:简单实现网络请求登录案例

使用http或axios实现登录案例 在entry/src/main/ets/pages路径下新建Page9.ets文件&#xff1a; import http from ohos.net.http import router from ohos.router Entry Component struct Page9 {State message: string Hello WorldState username: string State password:…

数据结构(十二)----查找

目录 一.查找的概念 二.查找算法 1.顺序查找 顺序查找的查找效率&#xff1a; 顺序查找的优化&#xff1a; •有序表的优化&#xff08;缩短查找失败的平均查找长度&#xff09; •被查概率不相等的表的优化&#xff08;缩短查找成功的平均查找长度&#xff09; 2.折半…

2024年钉钉群直播回放怎么保存

钉钉群直播回放下载插件我已经打包好了&#xff0c;有需要的自己下载一下 小白钉钉工具打包链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;1234 --来自百度网盘超级会员V10的分享 1.首先解压好我给大家准备好的压缩包 2.再把逍遥一仙下载器解压出来&#xff0…

CentOS 重启网络失败service network restart

命令 service network restart 提示 Job for network.service failed because the control process exited with error code. See “systemctl status network.service” and “journalctl -xe” for details. 原因分析 使用journalctl -xe命令查看日志后的具体错误 -- Un…