VNC伺服器可讓使用者從遠端以圖像介面操控Raspberry Pi,我在樹莓派一代安裝的是免費的TightVNC,它雖然可以被設定支援在遠端和本機電腦端進行文字剪貼,但是它僅支援Latin-1編碼,中文字在剪貼之後會變成??問號亂碼。
所以我改用RealVNC,它有分成免費、個人和商業版,最主要的差異在於免費版不支援加密(encryption)、也不具備檔案傳輸功能,但是剪貼中文沒問題。詳細的功能比較,請參閱realvnc.com的VNC產品頁面。
取得RealVNC的授權碼
啟動RealVNC伺服器需要輸入授權碼,安裝之前,請先連到Activate VNC頁面,點選“Free license only,…(僅免費授權)”選項、輸入你的大名、e-mail、確認e-mail、選擇國家,最後按下“Continue(繼續)”,即可收到授權碼。
安裝RealVNC
以下操作步驟節錄自RealVNC的Raspberry Pi產品頁面。
1. 在樹莓派的終端機執行底下兩行敘述,下載最新版的RealVNC軟體並解壓縮:
$ curl -L -o VNC.tar.gz https://www.realvnc.com/download/binary/latest/debian/arm/ tar xvf VNC.tar.gz
解壓縮之後可取得Server(伺服器)和Viewer(用戶端)兩個套件。目前的版本是5.2.3。
2. 只需要安裝VNC伺服器:
$ sudo dpkg -i VNC-Server-5.2.3-Linux-ARM.deb
3. 加入授權碼:
$ sudo vnclicense -add 授權碼
初次啟動RealVNC伺服器軟體時,它的操作視窗可能會要求我們輸入連線密碼,請在Users & Permissions(使用者和權限)畫面輸入密碼和確認密碼(按下右上角的Add鈕新增密碼):
啟動VNC伺服器:Service Mode
VNC伺服器有兩種啟動模式,我們可選用任一種:
- Service Mode(服務模式):VNC連線用戶的操作以及所見畫面,都和主機同步,相當於直接操作Pi。
- Virtual Mode(虛擬模式):VNC伺服器將為連線用戶建立「虛擬桌面」,因此VNC用戶的操作不影響同樣在操作Pi的用戶。
使用免費版初次啟動「服務模式」時,需要設定連線密碼。請執行底下的指令,然後跟著指示輸入兩次密碼:
$ sudo vncpasswd /root/.vnc/config.d/vncserver-x11
接著輸入底下的指令啟動VNC伺服器:
$ sudo /etc/init.d/vncserver-x11-serviced start
如果需要在開機時啟動VNC伺服器,請輸入:
$ sudo update-rc.d vncserver-x11-serviced defaults
日後若想要取消開機啟動VNC伺服器,請輸入:
$ sudo update-rc.d vncserver-x11-serviced remove
使用VNC Viewer(用戶端)連線Pi
預設的RealVNC伺服器埠號是5900,假設樹莓派的IP位址是192.168.1.11,從個人電腦或手機、平板的VNC Viewer軟體(如:Chrome線上應用商店的VNC Viewer)連線時,要輸入5900埠號,Picture quality(影像品質)選擇"Automatic"(自動)即可:
連線時,VNC會顯示底下的訊息,提示這是「未加密連線」(點選左下角的核取方塊,就不會再出現這個訊息了):
輸入密碼即可連線:
樹莓派本機的IP位址可透過ifconfig指令,或者按一下系統右上角的VNC選單圖示,即可從底下的畫面看到IP位址(註:在VNC選單按滑鼠右鍵,選擇Options指令,可設定VNC伺服器的參數)。
設定樹莓派的初始螢幕解析度(方法一):透過例行性工作排程(crontab)
如果沒有接上螢幕開機,樹莓派預設的螢幕解析度將是640×480,VNC用戶端的連線畫面也是不堪使用的640×480。在終端機執行xrandr(原意為X Rotate and Reflect Extension,改變大小與旋轉擴充),將能顯示當前的螢幕解析度:
$ xrandr xrandr: Failed to get size of gamma for output default Screen 0: minimum 640 x 480, current 640 x 480, maximum 640 x 480 default connected 640x480+0+0 0mm x 0mm
根據Raspberry Pi官方論壇的“X11VNC headless resolution”這一篇討論,透過底下的指令建立一個例行性工作排程(crontab)設定螢幕解析度:
$ crontab -e
然後在此排程最後加入這一行敘述:
@reboot /bin/fbset -g 1366 768 1366 768 16
按下Ctrl+O鍵寫入、Ctrl+X退出之後,重新啟動,就能獲得1366×768像素、16位元色彩深度的VNC畫面了。
註:fbset用於設定顯示卡的frame buffer(圖框緩衝區),參數-g代表geometry(尺寸),後面的數字分別代表“水平可見解析度(像素)”、“垂直可見解析度”、“虛擬水平解析度”、“虛擬垂直解析度”以及“色彩深度(亦即,每個像素的色彩位元數,16位元是數千色,24位元是全彩)”。
設定樹莓派的初始螢幕解析度(方法二):使用HDMI轉VGA接頭
有些電腦必須連接顯示器,顯示卡的GPU才會啟動,像Apple的Mac Mini就是一例。若需要在不連接螢幕的情況下,開啟GPU運算功能,可以購買一個像Headless Ghost的HDMI模擬器,將它插在電腦的HDMI座。
或者,依照macminicolo的方法(Build a Dummy Dongle for a headless Mac mini),準備一條HDMI轉VGA線,在VGA端子那一端的第1和6腳,插入一個電阻(原作者用的是85Ω,我用的是120Ω),也能騙過電腦。將此HDMI轉換線插在樹莓派上:
Pi的系統不需要任何設定,也不需要加上例行性工作排程,VNC連線的解析度就是1920×1080的Full HD解析度了。 當然,測試成功之後,我實際並沒有採用這種方式,用上一節的方法就行了。
啟動VNC伺服器:Virtual Mode
多數人都是使用Virtual Mode(虛擬模式)連接VNC。在終端機視窗輸入底下的指令,便能以「虛擬模式」啟動VNC伺服器:
$ vncserver
我們可以在指令後面加上解析度的參數,以1366×768解析度為例:
$ vncserver -geometry 1366x768
免費版的RealVNC伺服器最多可接受5個用戶端同時連線(亦即,虛擬5個螢幕)。虛擬模式的VNC埠號從5901~5905。假設樹莓派的IP位址是192.168.1.11,請在VNC用戶端使用5901埠號連線:
若要關閉此虛擬模式的VNC伺服器,請輸入(1代表虛擬的螢幕編號):
$ vncserver -kill :1
開機啟動虛擬模式的VNC伺服器
開機啟動虛擬模式的VNC伺服器的設定步驟,和其他VNC伺服器軟體大同小異,除了在 /etc/init.d/ 路徑下建立控制腳本(script)之外,比較簡單的方法是在家目錄底下的“.config(設置)”隱藏目錄裡面,存入開機設置程序,底下的步驟修改自Adafriut的TightVNC開機啟動設定:
切換到家目錄的.config目錄:
$ cd ~/.config
在此目錄底下新增一個autostart(自動啟動)資料夾:
$ mkdir autostart
使用nano文字編輯器,在autostart路徑底下新增一個“realvnc.desktop”檔:
$ nano autostart/realvnc.desktop
在此文字檔中輸入底下的內容:
[Desktop Entry] Type=Application Name=RealVNC Exec=vncserver -geometry 1366x768 StartupNotify=false
按下Ctrl+O寫入、Ctrl+X關閉檔案。
日後每次開機時,Pi都會啟動虛擬模式的VNC伺服器。
趙老師好久不見,來看看你新的技術,也恭喜你的新書擁有超高銷售量
拍謝~因為最近在忙一些事情,所以沒有更新文章。
thanks,
jeffrey
目前已經學不完了,老師在更新下去我可能要學到頭髮發白了ˇˇ
不會啦~一頭白髮更顯得睿智,不像我都禿光了……
thanks,
jeffrey
老師請問Arduino怎麼寫1個按鈕開關控制8燈跑馬燈?
按一下循環位移1燈,還要能保持狀態?
搞了2天了~先用8051那麼簡單的東西,發現難度超高,
再來用Arduino,翻了你的書沒範例,翻了另外一本揚明豐出的,有4燈的範例,但是是教錯誤的,上傳程式到晶片後,按鈕都還沒按就自己輪流在跑了T_T,搜遍網路居然找不到現成的範例,因為急用沒時間自己編譯.
hi dull-boy:
《超圖解Arduino互動設計入門》第四章有4個跑馬燈範例,你的需求可用「動手做4-4」單元的陣列範例,加上開關電路改寫。
「按一下循環位移1燈」指的是「假設現在亮LED1,按一下按鈕,亮LED2」嗎?這樣的話,你只需用一個變數紀錄LED陣列的索引值即可。每按一下,索引值加1;若索引值超出LED陣列範圍,就索引設成0。
如果是「按一下,先輪流點亮所有的LED一次,第一次停在LED1,第二次停在LED2…」,那就相當於「每次輪流點亮8個LED,只是起始點不同:第一次從LED1開始,第二次從LED2開始…」。這同樣也是設定一個「起始」索引值,每次循環之後,起始索引值加1…點亮LED的程式可以寫成一個函式,依照需求從loop()循環呼叫…這樣就行啦!
thanks,
jeffrey
LED亮燈順序就
00000000,
10000000,
01000000,
00100000,
00010000,
00001000,
00000100,
00000010,
00000001,
謝老師!
所以…你的程式碼完成了?
因為急用,後來讓我找到8051現成的範例,我用89S2051搞定了,
看似簡單的動作,如果不是老師這種等級,是寫不出來的.
沒有啦~如果所有我們想達成的功能,都有現成範例可以套用,那就不需要工程師了 :-p 寫程式初期,真正厲害的是筆和紙。底下是依照我上個留言,修改自書本4-4範例的程式碼:
thanks,
jeffrey
謝老師,不過我把他改成亮8燈後怪怪的,循環第一輪正常,第二輪就只跳固定2燈ˇˇ
拍謝,剛剛發現這一行程式碼錯了:
正確的寫法:
thanks,
jeffrey
老師我把接腳指定為const byte LEDs[] = {5,6,7,9,10,11,12,13};
可正常點燈;但是陣列只要放入接腳8,當燈跑到全熄,跑第2輪他就會和第5接腳的LED一起點亮,好奇怪喔
指定這樣const byte LEDs[] = {5,6,7,8,9,10,11,12,13};
第8腳卻可以照順序亮燈ˇˇ這是為何阿,老師這太深澳了吧
急用這程式的當天,我有不小心把4針的排針,放在板子USB下方4個接點+ D+ D- -的下方,會是板子短路嗎?
可若短路故障,為何還能寫入程式,就上述第8腳怪怪的.
本來嚇一跳以為電腦端USB燒了,我曾經不小心燒掉一個電腦端的USB孔T_T
試了一下,只要頭尾出現雙數腳位,第8腳輸出led燈就會不正常,
這需要老師開導了@_@
我是在紙上構想程式,沒有實際測試,會在「第二輪」時點亮第8腳,我也很納悶,請再試試看,把loop()當中的判斷條件式:
改成底下的敘述:
thanks,
jeffrey
改成老師的說明,怎麼試都正常了
老師真是太強大了
說真的`網上是很多範例,可是都是還沒按鈕就自己跑燈了,很難想像錯誤的資訊怎還PO上網ˇˇ
感謝告知!
thanks,
jeffrey
您好,請問一下:
WAMP,就是架站綜合包,可以「安裝」,也可以「portable可攜式」,請問,這兩個差在哪?網路上都找不到答案耶!請多講一點,越詳細越好,感恩不盡!
啊這不就像統一麵,看你要帶著直接乾吃,還是泡在湯碗裡面吃,反正都能解饞……
thanks,
jeffrey