上回老周在說準備工作的時候,提到過樹莓派用金屬盒散熱的事情。有朋友會說,加了金屬盒子接線不方便,就算用了“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 等常見的硬體通訊方式,後續文章中老周還會介紹。