C# 控制 GPIO

来源:https://www.cnblogs.com/JiuHuan/archive/2019/10/25/11740610.html
-Advertisement-
Play Games

控制 IO 有多種方式。 這裡說最簡單的方式。 Linux 下 一切皆文件。 所以 GPIO 也會是一個文件。通過操作文件,可以控制它。 貼入代碼。 1 using NewLife; 2 using NewLife.Log; 3 using System; 4 using System.Collec ...


控制 IO 有多種方式。

這裡說最簡單的方式。

  Linux 下 一切皆文件。 所以 GPIO 也會是一個文件。通過操作文件,可以控制它。

貼入代碼。

  1 using NewLife;
  2 using NewLife.Log;
  3 using System;
  4 using System.Collections.Generic;
  5 using System.IO;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Threading;
  9 using System.Threading.Tasks;
 10 
 11 namespace Linux
 12 {
 13     /// <summary>GPIO 組</summary>
 14     public enum PinGroup : int
 15     {
 16         PA = 0,
 17         PB = 1,
 18         PC = 2,
 19         PD = 3,
 20         PE = 4,
 21         PG = 5,
 22         PH = 6,
 23         PI = 7,
 24         PJ = 6,
 25     }
 26 
 27     /// <summary>引腳輸入輸出模式</summary>
 28     public enum PinDir
 29     {
 30         In = 0,
 31         Out = 1,
 32     }
 33 
 34     /// <summary>簡單實現 GPIO 的讀寫,不包含中斷處理</summary>
 35     public class SimpleGpio : DisposeBase
 36     {
 37         /// <summary> 保證 結尾有/ 的路徑</summary>
 38         private static String _GpioBasePath = @"/sys/class/gpio/";
 39 
 40         /// <summary>GPIO 的目錄</summary>
 41         public static String GpioBasePath
 42         {
 43             get { return _GpioBasePath; }
 44             set
 45             {
 46                 if (value == null) return;
 47                 if (value == "") return;
 48 
 49                 _GpioBasePath = value;
 50 
 51                 if (!_GpioBasePath.EndsWith("/")) _GpioBasePath += "/";
 52             }
 53         }
 54 
 55         /// <summary>方向</summary>
 56         public PinDir Dir;
 57 
 58         /// <summary>狀態</summary>
 59         public Boolean Opened { get; private set; } = false;
 60 
 61         /// <summary>名稱</summary>
 62         public String Name { get; set; }
 63 
 64 
 65         /// <summary>引腳編號</summary>
 66         private int _PinIdx = -1;
 67 
 68         /// <summary>引腳路徑</summary>
 69         private String pinPath;
 70 
 71 
 72         #region 構造
 73 
 74         public SimpleGpio() { }
 75 
 76         /// <summary></summary>
 77         /// <param name="gp">gpio 組</param>
 78         /// <param name="gpidx">組內編號</param>
 79         public SimpleGpio(PinGroup gp, int gpidx)
 80         {
 81             _PinIdx = (int)gp * 32 + gpidx;
 82 
 83             Name = "gpio" + _PinIdx;
 84         }
 85 
 86         /// <summary></summary>
 87         /// <param name="idx">全局gpio index</param>
 88         public SimpleGpio(int idx)
 89         {
 90             _PinIdx = idx;
 91 
 92             Name = "gpio" + _PinIdx;
 93         }
 94 
 95         /// <summary>析構</summary>
 96         protected override void OnDispose(bool disposing)
 97         {
 98             base.OnDispose(disposing);
 99 
100             UnexportPin();
101         }
102 
103         #endregion
104 
105         #region 基礎操作
106 
107         /// <summary></summary>
108         /// <param name="idx">全局gpio index</param>
109         public void SetPin(int idx)
110         {
111             _PinIdx = idx;
112 
113             Name = "gpio" + _PinIdx;
114         }
115 
116         /// <summary> </summary>
117         /// <param name="gp">gpio 組</param>
118         /// <param name="gpidx">組內編號</param>
119         /// <param name="dir">輸入/輸出</param>
120         public void SetPin(PinGroup gp, int gpidx, PinDir dir = PinDir.In)
121         {
122             _PinIdx = (int)gp * 32 + gpidx;
123             Dir = dir;
124 
125             Name = "gpio" + _PinIdx;
126         }
127 
128 
129         /// <summary>打開</summary>
130         /// <returns></returns>
131         public Boolean Open()
132         {
133             pinPath = GpioBasePath + Name + "/";
134             XTrace.WriteLine("打開 " + pinPath);
135 
136             if (!pinPath.AsDirectory().Exists)
137             {
138                 try
139                 {
140                     if (!ExportPin()) return false;
141                 }
142                 catch
143                 {
144                     XTrace.WriteLine(pinPath + "導出引腳出錯,請 檢查參數 和 許可權");
145                     return false;
146                 }
147             }
148 
149             // 寫入配置
150             var dir = new FileInfo(pinPath + "direction");
151             if (!dir.Exists) { XTrace.WriteLine("direction 文件呢?"); return false; }
152 
153             var str = Dir == PinDir.Out ? "out\n" : "in\n";
154             dir.WriteBytes(str.GetBytes());
155 
156             Opened = true;
157             return true;
158         }
159 
160         /// <summary>關閉</summary>
161         public void Close()
162         {
163             UnexportPin();
164 
165             Opened = false;
166         }
167 
168         /// <summary>寫引腳狀態</summary>
169         /// <param name="value"></param>
170         public void Write(bool value)
171         {
172             if (!Opened) return;
173 
174             if (Dir == PinDir.In) return;
175 
176             var fi = new FileInfo(pinPath + "value");
177             if (!fi.Exists) { XTrace.WriteLine("value 文件呢?"); return; }
178 
179             if (value)
180                 fi.WriteBytes("1\n".GetBytes());
181             else
182                 fi.WriteBytes("0\n".GetBytes());
183         }
184 
185         /// <summary>讀取狀態</summary>
186         /// <returns></returns>
187         public bool Read()
188         {
189             if (!Opened) return false;
190 
191             var fi = new FileInfo(pinPath + "value");
192             if (!fi.Exists) { XTrace.WriteLine("value 文件呢?"); return false; }
193 
194             var v = fi.ReadBytes(0, 1);
195             if (v == null) return false;
196             if (v.Length == 0) return false;
197             if (v[0] == '0') return false;
198 
199             return true;
200         }
201 
202         #endregion
203 
204         #region 輔助
205         /// <summary>導出引腳</summary>
206         /// <returns></returns>
207         public bool ExportPin()
208         {
209             if (!GpioBasePath.AsDirectory().Exists)
210             {
211                 XTrace.WriteLine("基礎目錄 {0} 不存在", GpioBasePath);
212                 return false;
213             }
214 
215             var export = new FileInfo(GpioBasePath + "export");
216             if (!export.Exists)
217             {
218                 XTrace.WriteLine("export 文件不存在,請確認gpio目錄是否正確");
219                 return false;
220             }
221 
222             var param = _PinIdx + "\n";
223             export.WriteBytes(param.GetBytes());
224             Thread.Sleep(100);
225 
226             if (!pinPath.AsDirectory().Exists)
227             {
228                 XTrace.WriteLine("導出失敗,請確認 Pin 是否正確");
229                 return false;
230             }
231 
232             // XTrace.WriteLine("導出 {0},成功", Name);
233             return true;
234         }
235 
236         /// <summary>取消導出引腳</summary>
237         public void UnexportPin()
238         {
239             var unexport = new FileInfo(GpioBasePath + "unexport");
240             if (!unexport.Exists)
241             {
242                 XTrace.WriteLine("unexport 文件不存在,請確認gpio目錄是否正確");
243                 return;
244             }
245 
246             var param = _PinIdx + "\n";
247             unexport.WriteBytes(param.GetBytes());
248         }
249         #endregion
250     }
251 }
View Code

 

問題1: 導出失敗,請確認 Pin 是否正確

問題有可能是沒有許可權導出。

  查看 /sys/class/gpio/export 文件所屬組

  

  只允許 root 用戶進行導出 IO 口。

  需要用 root 用戶運行導出函數 ExportPin() 。

解決辦法:  使用 root 許可權運行程式  sudo xxxxx.

  或者   切換到 root 用戶再執行。 su 

  註意: 一旦導出,直到關機,引腳文件都會一直存在。 即 多次運行不必每次都導出。

 

問題2: 沒有控制GPIO 的許可權。

解決辦法: 將當前用戶添加到 IO 用戶組。或者切換到 IO 用戶。方法同問題1.

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在CefSharp75版本,使用了WpfImeKeyboardHandler支持後,無法支持搜狗中文輸入法 其中的一個修複方案: 在ChrominumWebBrowser中,添加焦點事件的重寫,對InputMethod相關進行修改 SetIsInputMethodEnabled -- 是否可輸入中文 ...
  • /// <summary> /// 生成文件的 /// </summary> /// <param name="calssName"></param> public void create(string calssName) { //獲取程式集 var createClass = Assembly. ...
  • 1.關係 關係定義兩個實體之間的關係。在關係型資料庫中,這由外鍵約束表示。 2.術語定義 有許多術語用於描述關係:●相關實體:這是包含外鍵屬性的實體。有時稱為關係的"子級"。●主體實體:這是包含主/備用鍵屬性的實體。有時稱為關係的 "父項"。●外鍵:依賴實體中的屬性,用於存儲與實體相關的主體鍵屬性的 ...
  • 安裝WSL 1、打開WINDOWS功能,勾選子系統選項 2、打開商店搜索WSL,安裝ubuntu 我這裡的系統版本是:18.04 如何查看ubuntu系統版本 sudo lsb_release a 或 cat /etc/issue 3、打開ubuntu,設置賬號密碼 安裝.net core SDK ...
  • 因為nuget線上下載有時候很慢,所以下載nuget包,進行本地安裝 登陸nuget官網https://www.nuget.org/下載相關資源 選擇對應版本進行下載,同時需要下載相關依賴的包 ​ 最終下載的共4個包,cef.redist64,cef.redist86,cefsharp.common ...
  • .Net Core 3.0 IdentityServer4 快速入門 一、簡介 IdentityServer4是用於ASP.NET Core的OpenID Connect和OAuth 2.0框架。 將IdentityServer4部署到您的應用中具備如下特點: 1)、認證服務 2)、單點登陸 3)、 ...
  • 以前都是用的Windows系統,最近有被win10搞得有點煩,就入了manjaro的坑,windows下部分軟體在manjaro安裝記錄,留個記錄。 我的系統信息 下麵開始正式幹活。 一、準備步驟 下載Redis https://redis.io/ 二、安裝 1 當前目錄 /home/yzhl/Do ...
  • Ubuntu 18.04下 1、安裝python 2._版本,輸入 sudo apt install python 命令行輸入 python或python3會打開對應的版本。 輸入 exit()或Ctrl + D可以退出python的shell。 2、ipython 2._ 版本安裝,輸入 sudo ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...