對已經具備一定Linux基礎的人來說,樹莓派學習起來應該非常簡單自然。在他們眼中,樹莓派就是一個簡易版的,卡通版的Linux而已。但是對我這樣一個早已習慣微軟技術生態系統的人或者初學者來說,要實現一個簡單程序的編寫、編譯到運行,還是不太容易的。

上圖是我搭建的一個相對完整的樹莓派開發環境,有顯示(HDMI轉VGA->7寸顯示屏800*480),有鍵盤和鼠標等,當然這些不是必須的,只是對初學者來說,顯的比較直觀。
為了降低學習和開發難度,樹莓派上提供多種編程語言選擇,比如Python、Java、C/C++等linux可支持的開發語言。在圖形界面下,可以在IDE環境相對簡單的進行Python編程、調試、運行等。如果基於第三方支持庫,還可以用Python操控GPIO等。
出於對C/C++語言的熱愛,我還是選擇了基於GNU C進行程序開發,下圖是已經安裝到智能小車上的樹莓派。我們需要搭建一個沒有顯示、鼠標和鍵盤下的編程、部署、運行調試環境。

至於如何燒寫樹莓派的系統到SD卡上,我們這里就不再熬敘了,已有很多入門文章進行了相關的講解和說明。本篇文章主要介紹,搭建一個便於和Windows平台交互的編程平台,借助wiringPi C/C++庫,操作GPIO和串口通信。
第一步:遠程登錄樹莓派
我們選擇安裝的樹莓派系統鏡像為Raspbian,系統默認啟動后,就是支持遠程SSH連接的。我們可以下載一個免費的PuTTY工具軟件進行遠程連接。

打開連接,輸入用戶名:pi 密碼:raspberry(默認) 會出現如下畫面。

第二步:安裝簡易FTP服務
為了便於把Windows系統中已經寫好的C文件部署到樹莓派中,我們安裝一個簡單的FTP服務。我們選擇的是一個開源的比較輕量級的FTP服務器vsftpd,下面簡單說一下安裝步驟:
1、 安裝vsftpd服務
sudo apt-get install vsftpd
2、 開啟vsftpd服務
sudo service vsftpd start
3、 修改配置文件
sudo nano /etc/vsftpd.conf
找到並修改
anonymous_enable=NO //不允許匿名訪問
local_enable=YES //允許本地用戶訪問
write_enable=YES //允許寫
local_umask=022 //設定上傳后文件權限掩碼
存盤退出。
4、 重啟vsftpd服務
sudo service vsftpd restart
打開windows上任意一款FTP客戶端軟件(我一直使用的是FlashFXP),配置相關IP、用戶和密碼(用戶名:pi 密碼:raspberry)。

連接成功后,會出現如下畫面:

第三步:安裝wiringPi庫
WiringPi是第三方封裝的一個針對樹莓派平台的GPIO控制庫函數,WiringPi遵守GUN Lv3。wiringPi使用C或者C++開發並且可以被其他語言轉包應用。
詳情請參見這篇文章:http://blog.csdn.net/xukai871105/article/details/17737005
有了以上三步的准備,我們就可以在Windows編寫開發C語言代碼,遠程部署到樹莓派,通過樹莓派上的GCC工具進行編譯,然后執行。編寫代碼之前,我們先了解一下樹莓派的GPIO接口,如下圖所示:

我們需要完成三個功能,一、GPIO控制一個LED閃爍;二、通過串口和凌霄板進行通信;三、輸出PWM信號控制舵機。
下面我們將一一介紹上面三個功能的實現。
1、GPIO控制LED燈閃爍
硬件接線:我們選擇一個LED發光二極管,焊接一個1K左右的電阻,把一根杜邦線剪開,分別焊接到二極管兩個管腳上(其中一個焊接在電阻另外一端)。LED較長的管腳為正極,我們接在樹莓派第11管腳上,也就是GPIO0上。另外一端,我們接在25管腳上(可任意接在一個標有0V的管腳上)。
我們在記事本(推薦使用EverEdit)編寫相關代碼,如下圖所示:

把LED.C文件通過FlashFXP上傳到樹莓派上去。用GCC進行編譯,然后執行,如下圖所示:

如果硬件沒有問題,那么你應該可以看到LED燈在閃爍了。
2、樹莓派和凌霄開發板串口通信
2.1 關閉串口調試功能
串口還不能直接使用,因為默認是綁定調試端口的,所以我們必須先關閉該功能。
命令行中輸入如下命令:
sudo nano /boot/cmdline.txt
將以下內容
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
改為
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait
輸入如下命令:
sudo nano /etc/inittab
將以下內容
#Spawn a getty on Raspberry Pi serial line
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
改為
#Spawn a getty on Raspberry Pi serial line
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100
然后重啟樹莓派。
2.2 硬件接線
8號管腳為TX,10號管腳為RX,是TTL電平的,我們和凌霄開發板的子板接口19和20管腳進行連接。
樹莓派 8 (TX) -- 凌霄開發板19(RX)
樹莓派 10 (RX) -- 凌霄開發板20(TX)
樹莓派 6 (0v) -- 凌霄開發板03(GND)
2.3 .NET Micro Framework串口編程
我們要求的功能相對簡單,並不要求雙向通信,凌霄開發板接收到控制攝像頭雲台的按鍵信息后,直接發送給樹莓派(如果通過網絡遠程控制小車,則可以由樹莓派通過wifi socket編程獲取遠程的按鍵控制信息,然后通過串口發給凌霄開發板,由后者控制小車,后續如果有時間,可以做一個這方面的功能)。
串口定義:
static SerialPort piPort = new SerialPort("COM4", 9600);
在Main函數中,進行串口打開操作:
piPort.Open();
在按鍵事件中發送按鍵信息:
static void ps2_Click(object sender, PS2.ButtonArgs e)
{
if (e.key == PS2.Key.RRocker)
{
PS2 ps2 = (PS2)sender;
PS2.ButtonArgs button = ps2.GetButton(PS2.Key.L2);
if (button.state == 1) //按下L2按鍵,我們才發送搖桿的信息
{
byte[] buffer = new byte[] { 0xAA, (byte)e.x, (byte)e.y, 0x55 };
piPort.Write(buffer, 0, 4);
piPort.Flush();
}
}
}
2.4 樹莓派串口編程
打開串口:
if ((fd = serialOpen ("/dev/ttyAMA0", 9600)) < 0)
{
fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
return 1;
}
接收數據:
while(1)
{
if(serialDataAvail (fd)>=4) //判斷接收緩沖區的個數
{
if (read (fd, buffer, 4) == 4)
{
if(buffer[0]==0xAA && buffer[3]==0x55)
{
printf("x:%d y:%d\r\n",buffer[1],buffer[2]);
}
}
}
else
{
delay (10) ;
}
}
注:WiringPi對外封裝並沒有提供串口read函數,只提供了單個字符的獲取,我們直接采用linux本身提供的read函數。
2.5 通信測試
編寫相關文件,傳輸到樹莓派,然后進行編譯。運行程序后,我們操作Sony PS2按鍵,應該可以看到如下信息輸出:

3、樹莓派PWM輸出控制
樹莓派僅提供一個物理硬件PWM輸出IO,也就是GPIO1,第12管腳。實際測試發現,其周期為6.64us左右,WiringPi封裝的接口還不能修改該周期的大小(后續有時間可以研究一下底層相關代碼),這不符合舵機控制的需要,舵機一般要求20ms左右的周期。另外攝像頭雲台是控制兩路舵機,所以一個物理硬件PWM也不夠。所以我們采用軟PWM,也就是用普通的GPIO,通過時鍾中斷,模擬PWM方波輸出。
我們用GPIO1(12管腳)和GPIO2(13管腳)來模擬PWM輸出,所以硬件接線也是舵機的PWM信號輸入管腳和樹莓派的這兩個管腳相連(舵機5V的供電專門供,不要直接從樹莓派5V管腳上取)。
PWM初始化代碼:
#define PWM1 1
#define PWM2 2
softPwmCreate (PWM1, pwmV1, 200) ; //1=100us 7~28
softPwmCreate (PWM2, pwmV2, 200) ; //1=100us 7~28
在串口的信息接收中,輸出PWM,從而控制舵機。
if (read (fd, buffer, 4) == 4)
{
if(buffer[0]==0xAA && buffer[3]==0x55)
{
pwmV1 = 7 + (int)(buffer[1]*21.0/255.0); //x
pwmV2 = 7 + (int)(buffer[2]*21.0/255.0); //y
softPwmWrite(PWM1, pwmV1);
softPwmWrite(PWM2, pwmV2);
}
}
部署到樹莓派,編譯,運行,如果我們手頭有示波器,我們應該可以看到GPIO1和GPIO2輸出的波形。
以上程序如果和凌霄板共同運行,應該可以看到如下效果:
視頻鏈接:http://v.youku.com/v_show/id_XNjY2MTE1NjQ0.html
文章導航:
2、【樹莓派+.NET MF打造視頻監控智能車】控制篇(.NET MF)
3、【樹莓派+.NET MF打造視頻監控智能車】控制篇(樹莓派)
4、【樹莓派+.NET MF打造視頻監控智能車】視頻篇
小結:
1、 樹莓派硬件設計小巧,會讓一些人因為樹莓派而喜歡上Linux。
2、 Linux畢竟不是一個實時系統,在做軟PWM的時候,你會發現舵機會抖動,並且幅度還不小(由於凌霄系統已經提供了16路PWM,所以后續還是由凌霄系統控制所有的舵機)
3、 Linux系統的鏡像大概2.8G左右,和凌霄系統的幾百K相比,還是挺重量級的,並且啟動時間會比較長一些。
