【.NET 与树莓派】使用 GPIO 库
上回老周在说准备工作的时候,提到过树莓派用金属盒散热的事情。有朋友会说,加了金属盒子接线不方便,就算用了“T”形板,毕竟是把导线延长了的。其实扩展板就是把原有的引脚引出(类似于延长),有的引出后使用并联电路来“复制”出几套接口。所以你买一块插孔多的面包板,自己也可以并联出许多扩展接口来,何况树莓派好一点的扩展板也比较贵。
如果你不运行桌面,不看岛国片,只是执行命令和运行代码,完全不用散热措施。老周直接用裸板试验过,只是运行程序的话,温度平均在 40 度上下,受室温影响不是很大,夏天的时候会高2度。这个温度问题不大,挂不了。70 度以上才要考虑散热。
最简单的散热方案是贴散热片,不过你不要贴歪了,想撕下来再贴一次好像不那么容易,弄不好可能会把芯片扯坏。曾经还听说有人把处理器扯下来的,不知道是真是假。另外,加个小风扇的方式应该挺好,有点噪音也没关系的(不要像轰炸机就行)。
好,现在说正题。我们知道,树莓派有许多 GPIO 引脚,通用方式是发出,或者接收电平信号。信号就是两种——高电平 or 低电平。我们可以简单地认为,高电平是 3.3 V 电压,低电平是 0V 电压,更深层的电路原理你可以不理会,不影响你编程。
为什么是高电平和低电平两个信号呢?嗯,问得真TM地好。你想一下啊,计算机只认识两个数字,哪两个呢?0 和 1,你给计算机下命令时,其实只要 0 和 1 组合就行。1 开灯,0 关灯;1 向左转,0 向右转;0 翻墙,1 撞墙;0 引爆火药,1 引爆自己……
哟西,这么一来,两个电平就可以对应两个二进制数字:高电平—— 1,低电平—— 0,完事。
有了两个明确的值,还需要明确方向。树莓派自身把电平拉高或者拉低,以此来告诉连接的电子模块要干什么活,这是发送信号;当一个触摸开关被你的娇美的小手触碰后,模块把电平拉高(高电平状态),告诉树莓派有人按了按钮,这时候树莓派的接口就是接收状态,然后树莓派可以控制另一个设备去做其他事情(比如,冲马桶)。
由于树莓派带有 Linux 操作系统,所以,GPIO 接口的操作方法很多,可以直接调用相关的 lib,也可以用一些封装好的库。不过,系统集成了一种简单的操作方法,类似于文件的方式,你只需要读写对应的路径就能控制 IO 接口。
启动系统后,你可以进入以下目录:
- cd /sys/class/gpio
然后执行 ls 命令,你会看到目录下有两个文件:
1、export:向这个文件写入 GPIO 口的编号,就可以打开相关接口;
2、unexport:向这个文件写入 GPIO 口的编号,关闭对应的接口。
你如果看到这两个文件,就可以试验一下了。不过在试之前,你还要做这件事:
- sudo raspi-config
sudo 是为了防止权限不够,raspi-config,是树莓派系统专用的配置程序,在命令模式下也是图形化操作的。
选第3项,接口选项,回车。
用上下箭头键移到最下面的 P8,回车。
用 Tab 键选中 Yes,默认会选中,然后回车确认,收工。按 Esc 可以退出配置程序(或者选 Finish)。
Remote GPIO 选项必须打开的,不然你连接的电子模块是没有反应的。
接下来,老周用这个激光模块来做演示。
这个模块上面有一个激光头,跟我们小时候在路边买的装钮扣电池的差不多,发出的激光比小时候买的玩具还差。那这个模块有什么鸟用。其实这个模块真没什么鸟用,不过用来学习演示挺不错,现实用途可以拿来逗猫,不过注意不要让猫碰到单片机。
这个模块有三个引脚,PCB板上只标注了两侧的引脚。
为了提升拍照效果,我在下面垫了一张厕纸。最左边的引脚旁标注了“-”,意思是接电源负极,即接树莓派上的 GND 引脚。树莓派有八个 GND 引脚,你可以随便接;最右边的引脚标注了“S”,表示这是信号脚,接树莓派的 GPIO 脚,这个有很多了,当然了,最好选默认没有分配功能的 GPIO 接口。比如下图中画了蓝线的。
左右两边的引脚都知道用处了,所以,中间那个引脚就是接电源正极的,可以接树莓派的 5V,上面的图上你也看到了,树莓派两个 5V 脚都放在了一起(第2、4脚)。
下面开始接线,由于树莓派没有在板子印有引脚符号(无丝印),所以在接线时要小心,不要接错。
信号线老周选用了 GPIO 17,在树莓派上是 11 号引脚,也就是左边一排,往下顺数第六个脚。
接好线之后,我们回到终端,还记得前面提到的那两个文件吗?先用 cd 命令定位到 /sys/class/gpio 目录,然后向 export 文件输入文本“17”。
- cd /sys/class/gpio
- echo 17 > export
然后用 ls 列出一下 gpio 下的子项,你是不是发现多了个子目录?叫 gpio17。
这说明 GPIO 的第17口已经准备就绪,可以通信了。
注意一下,这里的 GPIO 编号不是树莓派板子上的顺序,而是BCM编号,刚刚接线时接的是左排的第六脚,可以上 pinout.xyz 查看,这个脚的编号是17。
然后,cd gpio17,进入这个目录,看看里面有什么。
这里面有两个文件我们需要用到的。
1、direction:配置 GPIO 口的通信方向。向其中写入“in”为输入,写入“out”为输出。
2、value:GPIO 口输出的值,0 为低电平,1 为高电平。
激光头模块是收到高电平时发射激光的,所以这里要把通信方向设为 out。
- echo out > direction
向 value 写入“1”,输出高电平,发射激光,开始逗猫。
- echo 1 > value
逗久了猫也觉得不好玩了,你手也累了,这时向 value 写入“0”,输出低电平,关闭激光发射。
- echo 0 > value
最后,向 /sys/class/gpio/unexport 写入GPIO口编号 17,就可以关闭这个接口了。这时候,gpio17 子目录就不见了。
有了上面的试验,我们可以开始使用微软封装的 GPIO 库了。
这个 Nuget 库叫 System.Device.Gpio,它已经封装好了GPIO操作常用的类型。
1、对于Windows平台,用的是 UWP 的库;
2、对于类 Unix 平台,封装了以下几种版本:
1) LibGpio;
2)SysFsDriver,这个就是上面举例用的方式,以文件方式操作 /sys/class/gpio 路径下的文件。
3)Raspberry Pi 专版。
另外,还有 HummingBoard 版本。
我们在使用时,其实并不需要去思考使用哪个平台的类型,在实例化 GpioController 类的时候,会自动选用合适的类型。
使用以下命令,在.NET项目中添加 System.Device.gpio 库的引用。
- dotnet add package system.device.gpio
在VS2019 中,你也可以用非常熟悉的 Nuget 包管理器来添加,操作方法省略,老周相信你会用的了。
在代码中引入 System.Device.Gpio 命名空间,然后就可以欢畅地撸代码了。
- using System;
- using static System.Threading.Thread;
- using static System.Console;
- using System.Device.Gpio;
- namespace testA
- {
- class Program
- {
- static void Main(string[] args)
- {
- int pin = 17;
- GpioController gpio = new GpioController();
- // 打开接口
- gpio.OpenPin(pin);
- // 设置通信方向
- gpio.SetPinMode(pin, PinMode.Output);
- gpio.Write(pin, PinValue.Low); //先置低电平
- // 也可以这样写
- //gpio.Write(pin, 0);
- // 发送信号
- int x = 20;
- while (x-- > 0)
- {
- WriteLine("打开激光头");
- gpio.Write(pin, 1);
- Sleep(1000);
- WriteLine("关闭激光头");
- gpio.Write(pin, 0);
- Sleep(1000);
- }
- // 关闭接口
- gpio.ClosePin(pin);
- gpio.Dispose();
- // 退出
- WriteLine("3166");
- }
- }
- }
变量 pin 的值是17,前面接线的时候接的是 GPIO 17 引脚。
- dotnet publish -r linux-arm -c release --no-self-contained
-r linux-arm,就是指定目标的运行时为 arm (32)的 Linux 系统。
-c 指定生成方案,有 Debug 和 Release,这个老周就不多解释了,.NET 程序习惯模式。
--no-self-contained 表示不包含运行时库,因为老周已在树莓派的系统上装了 dotnet 运行时;如果你不想在上面安装运行时,可以去掉 --on-self-contained 选项,这样默认会包含运行时库。上传到树莓派上面,执行 chmod u+x xxxx 提升权限,然后就可以直接运行了。
要在树莓派上安装.NET 运行时也很简单。
1、执行 cd /tmp 转到临时目录。
2、下载时可以选择 .NET runtime,或 ASP.NET Core Runtime。后者包含运行Web应用的库。使用 wget 下载压缩包(选择 arm32 的 Linux 包)。
- wget https://download.visualstudio.microsoft.com/download/pr/7aa18d1a-1c9a-4571-9668-3d76b5cda367/41a75d18282fa815c548be4dbc9dd55f/aspnetcore-runtime-5.0.2-linux-arm.tar.gz
3、在 /usr/local 目录下创建一个目录,叫 dotnet。
- sudo mkdir /usr/local/dotnet
这个地方要加上 sudo ,不然权限不够。/usr/local 这个目录很适合,它就是让我们安装自己需要的第三方软件用的。
4、解压刚刚下载的压缩包,放到 /usr/local/dotnet 目录下面。
- sudo tar -zxf aspnetcore-runtime-5.0.2-linux-arm.tar.gz -C /usr/local/dotnet
-z 参数表示使用 gz 算法,-x 表示解压,-f 表示要解压的文件,三个参数合起来就是 -zxf。注意 -C 参数是大写的,表示工作目录,也就是你要解压到哪个目录,此处解压到 /usr/local/dotnet 目录下。
5、在 /etc/profile 文件中加入以下内容。
- # /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
- # and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
- if [ "`id -u`" -eq 0 ]; then
- PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
- else
- PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games"
- fi
- # .NET 的运行路径
- if [ -d /usr/local/dotnet ]; then
- PATH=$PATH:/usr/local/dotnet
- fi
- export PATH
- ……
位置是在 PATH 环境变量导出之前,将 dotnet 运行时的路径追加上去。即在 export 命令之前。保存并退出就OK了。
设置 PATH 变量放在 /etc/profile 中比放在 bash 的资源文件中好一些。放在bash资源中需要你登录终端时才执行,而且只在当前会话期间可用。放在 /etc/profile 中就成了“全局”了,只要顺利登入系统都有效。
在任意路径下执行 dotnet --info,如果有以下输出,那就成功了。
好了,现在可以把我们已经发布的程序上传到树莓派了。Win 10 自带 scp 命令,不需要安装传输工具。
在树莓派上 cd 到 pi 用户目录下(如果你改了用户名,可能是其他名字,可以用“~”代替)。
- cd ~
创建一个新目录,叫 app
- mkdir app
回到 Windows 上,打开命令提示符窗口,cd 到程序发布的目录。
- cd C:\Users\<用户名>\...\testA\bin\release\net5.0\linux-arm\publish
执行 scp 命令上传文件。
- scp ** pi@192.168.200.15:/home/pi/app
其中,**(用一个星号也可以,通配符)表示把发布目录下的所有文件上传到树莓派;冒号后面是树莓派上的路径,把文件放到前面创建的 app 目录下面,注意要用绝对路径,不能用“~”。
用终端登入树莓派,cd 到app下,能看到刚上传的文件。
无比紧张的时刻来临,执行我们写好的程序。
- dotnet testA.dll
如果没有出其他问题的话,你会看到激光头一开一关(其间暂停1秒)。
示例的源代码可以点这里下载:拼命点这里
这个 System.device.gpio 库还封装了 i2c、SPI 等常见的硬件通信方式,后续文章中老周还会介绍。
【.NET 与树莓派】使用 GPIO 库的更多相关文章
- 树莓派高级GPIO库,wiringpi2 for python使用笔记(三)GPIO操作
GPIO库的核心功能,当然就是操作GPIO了,GPIO就是"通用输入/输出"接口,比如点亮一个LED.继电器等,或者通过iic spi 1-wire等协议,读取.写入数据,这都是G ...
- 树莓派高级GPIO库,wiringpi2 for python使用笔记(一)安装
网上的教程,一般Python用RPi.GPIO来控制树莓派的GPIO,而C/C++一般用wringpi库来操作GPIO,RPi.GPIO过于简单,很多高级功能不支持,比如i2c/SPI库等,也缺乏高精 ...
- 树莓派高级GPIO库,wiringpi2 for python使用笔记(四)实战DHT11解码
DHT11是一款有已校准数字信号输出的温湿度传感器. 精度湿度+-5%RH, 温度+-2℃,量程湿度20-90%RH, 温度0~50℃. 我买的封装好的模块,上边自带了上拉电阻,直接查到树莓派上即可灰 ...
- 树莓派高级GPIO库,wiringpi2 for python使用笔记(五)i2c读取测试
wiringpi2显然也把i2c驱动带给了Python,手头上正巧有一个DS3231的模块,上边带了一个DS3231 RTC(实时时钟),与一片24C32,两个芯片均为iic总线设备,与树莓派接线如下 ...
- 树莓派高级GPIO库,wiringpi2 for python使用笔记(二)高精度计时、延时函数
学过单片机的同学应该清楚,我们在编写传感器驱动时,需要用到高精度的定时器.延时等功能,wiringpi提供了一组函数来实现这些功能,这些函数分别是: micros() #返回当前的微秒数,这个数在调用 ...
- 树莓派的GPIO编程
作者:Vamei 出处:http://www.cnblogs.com/vamei 严禁转载. 树莓派除了提供常见的网口和USB接口 ,还提供了一组GPIO(General Purpose Input/ ...
- 逗比学树莓派之GPIO
wiringPi适合那些具有C语言基础,在接触树莓派之前已经接触过单片机或者嵌入式开发的人群.wiringPi的API函数和arduino很相似,这也使得它广受欢迎.作者给出了大量的说明 ...
- 树莓派 - RPi.GPIO
RPi.GPIO是通过Python/C API实现的,C代码操作底层寄存器, python通过Python/C API调用这些C接口. 这是关于RPi.GPIO项目的介绍. 其中提到了有python ...
- 树莓派控制GPIO(Python)
如果你的raspi没有安装python那么先 sudo apt-get update sudo apt-get install python-dev 例如想要控制35管脚的亮灭: 先建一个文本 ...
随机推荐
- C++ 消失的析构函数 —— virtual 实现的动态析构
在C++类的结构中可以使用类方法创建内存,使用类的析构函数去施放内存,但有这么一种情况会导致:即使在析构函数中释放了内存,但由于析构函数没有被调用而导致内存泄漏,如下代码. 1 #include &l ...
- C++异常之四 异常类型的生命周期
异常类型的生命周期 1. throw 基本类型: int.float.char 这三种类型的抛出和函数的返回传值类似,为参数拷贝的值传递. 1 int test_1(int num) throw (i ...
- Vue3源码解析(computed-计算属性)
作者:秦志英 前言 上一篇文章中我们分析了Vue3响应式的整个流程,本篇文章我们将分析Vue3中的computed计算属性是如何实现的. 在Vue2中我们已经对计算属性了解的很清楚了,在Vue3中提供 ...
- JavaSE18-字节缓冲流&字符流
1.字节缓冲流 1.1 字节缓冲流构造方法 字节缓冲流介绍 BufferOutputStream:该类实现缓冲输出流. 通过设置这样的输出流,应用程序可以向底层输出流写 入字节,而不必为写入的每个字节 ...
- [日常摸鱼]bzoj1444 [JSOI2009]有趣的游戏——AC自动机+矩阵
今天学校跳蚤市场摆摊聚众吸毒打call,东西卖了一百多好开心_(:з」∠)_ (然后大家中午就去吃了一顿好的x) 下午听演讲然后现在来填坑orz(其实是昨晚的坑) 题目:bzoj1444 先用字符串构 ...
- [BUUCTF] MISC-九连环
0x01 知识点 伪加密 steghide提取信息 0x02 伪加密的判断 首先,在winhex分析,发现有4个zip文件的文件头和2个文件尾,有完整文件头尾那么可以直接修改后缀为zip解压, 查看一 ...
- CentOS 8 部署 ASP.NET Core 3.1 应用程序 kestrel+Nginx IIS+kestrel
vs2019发布到IIS 下载文档https://files.cnblogs.com/files/netlock/%E4%BD%BF%E7%94%A8VS2019%E5%8F%91%E5%B8%83 ...
- 用git上传项目到GitHub或者码云全过程
用git上传项目到GitHub或者码云全过程 1. 会生成一个隐藏文件夹".git".这是一个不可删文件,因为暂存区和历史区还有一些其他的信息都在这里,删掉就不是一个完整的仓库了 ...
- 认识ollydbg
四个区域:汇编区:虚拟地址,机器码,汇编指令,注释: 寄存器区:寄存器,数据: 数据区, 栈. 这是上面按钮的作用 热键: Ctrl+F2 - 重启程序. Alt+F2 - 关闭被调试程序. F3 - ...
- 【mysql】- Expalin篇
简介 id:在一个大的查询语句中每个 SELECT 关键字都对应一个唯一的id 与查询优化器有关,假如被优化过,那么可能是上下两个的id都是一样的 select_type:SELECT 关键字对应的那 ...