电源设计技术信息网站

FAQ   订阅电子杂志   English   繁體中文   日本語   한국어

下载中心

TECH INFORaspberry Pi初学者指南

如何在Raspberry Pi上设置VNC服务器

这篇文章来源于DevicePlus.com英语网站的翻译稿。

用于OTG、被动冷却系统、LED心跳灯以及大容量电容的VNC

virtual network computing

profit_image – stock.adobe.com

什么是VNC?

VNC(虚拟网络计算)一种易于使用的工具软件,可以帮助您成功访问所连接到的任何设备上的图形用户界面(GUI)。它在带宽、延迟以及安全性方面灵活性很高。当您使用VNC时,设备在局域网或外网都可以。

您可以轻松并且安全地从Windows、macOS 或Linux连接到您的Pi。这是一款适用于共享远程计算的通用设备。但是,当使用微型服务器就足够时,就不要运行大型服务器。Raspberry Pi计算机的使用十分环保,如此一来您就可以为解决气候变化问题出一份力了!

安装和设置

该过程的实现不需要具备相关的网络知识,但是您需要准备好一个Pi。Raspberry Pi 2 B+及以上的任何版本都可以,版本1对于响应式VNC会话来说太慢了。

基本设置请参考本文 , 而关于如何配置您的Raspberry Pi来使用静态IP请参考此处

当您身在外地想要连接家里或实验室的设备时,才会需要静态IP,这可以保证Pi没有从DHCP获取别的IP地址,从而防止扰乱端口转发。

此处可用的所有Raspberry Pi Linux镜像都为您提供了RealVNC服务器的选项。您应该选择“Raspbian Buster with desktop”变体,并通过USB转microSD适配器,使用“dd”或您的Pi,将其闪存到microSD卡中。

sudo unzip -px raspbian_latest | dd bs=1M of=/dev/sdX

其中,“X”是相关磁盘,例如如果您使用的是一个Raspberry Pi,通过USB转microSD适配器进行闪存,“X”为/dev/sda。在这一点上请务必小心,否则将会写入错误位置。在您的Pi/Linux系统上使用“lsblk”找出您想要写入的磁盘。

例如:

pi@raspberry$ lsblk
NAME        MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda           8:0    1 30.2G  0 disk /media/pi/SANDISK_32GB
mmcblk0     179:0    0 29.8G  0 disk 
├─mmcblk0p1 179:1    0  256M  0 part /boot
└─mmcblk0p2 179:2    0 29.6G  0 part /
pi@raspberry$ sudo umount /media/pi/SANDISK_32GB
pi@raspberry$ sudo unzip -px raspbian_latest | dd bs=1M of=/dev/sda &;&; \
	      sync &;&; \
	      echo If Raspbian has automounted your disk (again), see it with 'ls_blk' &;&; \
	      echo and then unmount it ... again. 

一个更简单的方法是使用Etcher,它甚至可以帮助您直接解压所下载的文件。请点击此链接获取相关说明。

实例

完成microSD卡闪存后,您就可以启动Pi了。首先,您需要决定是否通过显示器进行操作。

一个无显示器操作的实例是如果您的Pi在机器人中,同时您希望在系统运行时使用一个GUI编辑器来对代码进行调整,而如果没有连接显示器,请使用“sudo raspi-config”指令。
-> ‘3 Boot Options’(三种启动选项)
-> ‘B1 Desktop / CLI’(B1 桌面 / CLI)
-> ‘B1 Console’ (B1控制台)来停止Xserver。这样做可以节省RAM和CPU的消耗。

通过LAN连接Raspberry Pi

如果要将Pi与显示器一起使用,需要连接HDMI线缆和USB键盘及鼠标。

然后,在您的Pi终端输入指令“sudo raspi-config”,接下来:
Boot to desktop step 1/3

然后 ……
Boot to desktop step 2/3

接下来 ……
Boot to desktop step 3/3

如果要求重新启动,点击“OK”,然后退出raspi-config。

现在,启用RealVNC服务器,再次在Pi终端输入指令“sudo raspi-config”。
Enable VNC server step 1/3

然后……
Enable VNC server step 2/3

接下来……
Enable VNC server step 3/3

选择“Yes”并再次退出raspi-config。如果系统发生更改时需要进行重新启动,您将会收到重启的提示,此时请选择“是”。

重新启动后,您可以使用用户名“pi”和密码进行连接。我们稍后将介绍客户端软件的安装。

如果您打算进行无显示器操作,请在“/etc/rc.local”文件种添加以下行。如果不是,请跳过本节。

# HEADLESS
if /usr/bin/pgrep -U pi vncserver >/dev/null ; then 
        /bin/sh -c '/usr/bin/sudo -u pi /usr/bin/vncserver -kill :1 >/dev/null 2>&;1 || :'
fi 
/bin/sh -c '/usr/bin/sudo -u pi /usr/bin/vncserver -depth 24 -geometry 1280x1024 :0 >/dev/null 2>&;1'

现在,您可以使用VNC客户端登录您的Pi了。目前为止我认为最好用的是Raspbian系统自带或已经安装好的一个软件:RealVNC Viewer。

它为macOS、Windows、Linux以及其他许多系统(包括Android和iPhone iOS)提供了客户端(预编译为二进制包)。您可以点击此处下载您所需要的客户端。在macOS 和Windows上并不需要什么特殊的操作,只需双击所要下载的软件即可。在Ubuntu或其他类似的基于Debian的发行版上,对于modern模式的设备,在终端窗口中使用以下指令下载“DEB x64”:

sudo dpkg -i VNC-Viewer-6.19.325-Linux-x64.deb

对于其他Linux系统,请根据需要使用RPM或者独立的BIN,或通用脚本。安装完成后,输入“vncviewer”并按下回车键。您将会看到一个高级的GUI界面。在顶部,您需要输入Pi的地址,您可以通过在Pi终端输入“hostname -I”来找到该地址信息。另一种选择是使用适用于iPhone iOS 或Android的免费Fing应用程序。

地址格式为IP:PORTl。例如,在这个网络中,10.0.9.116:5900是我的Pi上的“:0”实例,而“:1”实例将使用端口5901,因此我输入10.0.9.116:5901。

输入地址后,按下回车键,然后稍等片刻。系统会提示您进行身份验证,并且可以设置VNC Viewer来存储登录信息。然后,您将直接进入Pi的桌面环境中。

Welcome to Raspbian Desktop

Change ‘pi’ user password

RealVNC panel

通过网络/WAN连接Raspberry Pi

通过互联网连接到您的Pi这一过程有点复杂。您需要在路由器上设置端口转发,还需要将Pi设置为使用静态IP地址。使用安装或设置部分中的链接来设置一个静态IP地址,或者如果您的路由器包含此选项,可以在网络客户端列表中选择Pi,并设置DHCP地址保留。这样的话就可以保证Pi始终具有相同的IP地址了。

接下来,将外部端口20202/tcp通过端口转发传输到您的Pi端口22/tcp。如此一来就无需暴露VNC服务器,我们将能够确保与您的Pi之间的连接是尽可能安全的。RealVNC只为企业用户提供256位AES,但是我们暂时不需要购买,SSH可以提供很大的帮助。

将以下指令复制到Pi的终端窗口中:

sudo service ssh start
sudo systemctl enable ssh
sudo apt-get update
sudo apt-get -y install ufw
sudo ufw enable
sudo ufw default deny
sudo ufw logging low
sudo ufw allow log 5900/tcp
sudo ufw allow log 5901/tcp
sudo ufw allow log 22/tcp

请务必使用“sudo raspi-config”或“passwd pi”更改默认密码,千万不要在“raspberry”上公开SSH密钥。

需要明确的是,请确保您将通过端口转发将20202 _TCP_传输到了Pi静态IP地址—端口22 _TCP_。

动态DNS?

现在一切都准备好了,您可以在工作场所,或者任何其他地方连接到您的Pi了。如何连接?您的Pi所在网络的外部地址是什么?

通过动态DNS,您就可以使用“一般”名称进行连接,从而解决这个问题了。“Example.com”中包含了一个使用“一般”名称的示例,并且您无需记住IP地址就可以实现连接。想要记住IP地址“93.184.216.34”似乎有些麻烦,因为您有太多需要记住的事情了。

但是,您可以轻松记住诸如“risingsun.csproject.org”之类的地址。让我们在您的Pi上安装一个动态DNS客户端,这样就可以保证这个名称始终指向您的Pi的外部网络地址了。

请在您的Pi终端粘贴以下指令:

apt-get update
apt-get -y install inadyn

您需要选择一个动态DNS服务商。如果您想要免费的,请使用FreeDNS。注册并使用指令sudo nano /etc/inadyn.conf来编辑“/etc/inadyn.conf:”。为方便起见,此处列出了相关参数:

period = 300
# The FreeDNS username must be in lower case and
# the password (max 16 chars) is case sensitive
provider freedns.afraid.org {
    username = lower-case-username
    password = case-sensitive-pwd
    hostname = some.example.com
}

获取所有信息后,将这些指令粘贴到Pi的终端窗口:

# Start it now
sudo service inadyn start 
# Persist across reboots
sudo systemctl enable inadyn 

要连接到您的Pi,现在需要在您的工作站或者笔记本电脑上执行以下操作(这适用于macOS 和Linux,Windows上的SSH隧道不在本文讨论范围内):

ssh -l pi -p 20202 -L 5900:localhost:5900 \
risingsun.csproject.org

这将为您的VNC通讯创建一个SSH隧道。对于Raspberry 2 B+及更高版本的型号,SSH并不会造成CPU利用率增高的问题,所以不用担心。

为了通过隧道连接,请在VNC Viewer中输入地址“127.0.0.1:5900”,然后通过本地SSH隧道连接到Pi上的VNC服务。

如有必要,请输入您的凭据,然后您将会返回到Pi的桌面环境。即使您在一个咖啡厅或者机场使用公共Wi-Fi也不用担心了。

当然,您也可以仅通过SSH连接到Pi,然后使用以下指令启动VNC服务ad-hoc:

nohup vncserver :0

这将会持续运行,直到您杀死进程(例如用“pkill -9 -U pi vncserver”指令)。

提升您的VNC体验

您可以做一些事情来提升VNC性能。一种方法是将图形减少到16位或16位以下,以获得一个更加舒适的用户体验。

延迟是很大的问题,如果您将您的Pi通过以太网连接到本地网络,将会对缓解该问题有很大的帮助。

如果您的连接速度不够快(或者其他正在使用的用户占用了很大的资源空间),您可以安装speedtest-cli来发现这一情况。将以下行粘贴到您的终端中:

sudo apt update
sudo apt-get -y install speedtest-cli
speedtest-cli --bytes --simple

我的Pi上的输出如下:

Ping: 2.723 ms
Download: 9.96 Mbyte/s
Upload: 0.50 Mbyte/s

上传速度为0.5Mbyte/s,约等于4Mbit/s,对于24位、1280×1024分辨率的VNC来说勉强够用。

对于GUI,您应该改掉默认界面。该默认界适用于旧的512MB RAM Raspberry Pi,但是如果您想要一个常规、直观的界面,这就不是很好用了。

vanilla Raspberry Pi桌面主要由大量的功能包组成,这些包来自于元功能包集“raspberrypi-ui-mods”和“lxde-common”。它具有一个额外的功能,就是有助于向VNC用户提供LXPolkit错误信息。

如果您有一个16-32GB microSD卡和一个Raspberry Pi 2 B+(或更高版本),我强烈建议您安装MATE桌面环境。

The MATE desktop environment

MATE将能够大大提升您的整体使用体验!

请将以下命令行粘贴到您的Pi终端:

sudo apt-get update
sudo apt-get -y remove raspberrypi-uid-mods lxde\* 
sudo apt-get -y install mate-desktop-environment \
mate-themes mate-utils mate-tweak mate-terminal 

如果您安装了MATE,请将以下行粘贴到您的~/.vnc/xstartup文件中:

#! /bin/sh
if [ -r ${HOME}/.Xresources ] ; then
        xrdb ${HOME}/.Xresources 
fi
xsetroot -solid grey -cursor_name left_ptr &;
mate-session

然后,重新启动。如果您有了内存高达4GB的新版Raspberry Pi 4 B,这就更好了,您再也不会需要转换到您的microSD卡了。即使在我使用的Raspberry Pi 2 B+上,MATE也很少会需要我去转换。就是这么好用。

附加内容

为您的Pi添加被动冷却系统

Raspberry Pi before modification

在CPU上切一个大圆孔

对于Raspberry Pi 2 B+及更高版本的型号,都存在发热的问题。您可以通过指令“vcgencmd measure_temp”随时查看系统温度,如果温度达到了阈值80C/176F,您的Pi将会自动降低时钟频率,以避免发生过热导致的“未定义行为”。

因此,您的1.2GHz CPU有可能会以600MHz的频率运行一段时间,并且在热量消散之前不会恢复到全速运行。如果您将Pi放置在一个气流受限的机箱中,那么那些微型散热器将可能不会起到作用,而如果您使用了四个核,且负载均为100%,那这些散热器就真的一点作用也没有了。有一个名为gpio-fan的内置config.txt参数可用于驱动风扇(参见“/boot/overlays/README”),但是我们并不想在每次刷新microSD卡时都要对其进行设置。

这时候,我们可以采取另一种方法—使用介电温度开关。通过使用绝缘导热胶带将其连接到CPU散热器上,它将会接通5V轨道电源到一个5V风扇之间的电路。我使用了一个常开型,可以在温度达到华氏113度时接通电路。电路一旦接通,风扇就会驱散CPU中的热量。0.75W的迷你风扇是一个不错的选择,如果我们使用一个环流二极管(ROHM BAT86肖特基),就可以防止产生电压超过5V轨道电源的尖峰脉冲,这样风扇的使用就非常安全了。

BOM

您将会需要以下部件:

1x KSD9700 温度开关,常开,45C/113F https://www.aliexpress.com/item/10pcs-2500W-Temperature-control-switch-KSD9700-45-Degrees-Celsius-Normally-open-N-O-10A-250V-Thermal/32790498666.html
1x BAT86 肖特基二极管 https://www.newark.com/nexperia/bat86/rectifier-diode-single-50-v-200/dp/96K6771
1x 5V 风扇 https://www.banggood.com/5v-303010mm-3010-Cooling-Fan-with-2-Pin-Dupont-Wire-for-3D-Printer-Part-p-1421461.html?rmmds=buy&;cur_wbarehouse=CN
细绞线 https://www.daburn.com/2671UltraFlexibleSub-MiniatureWire-U/LSTYLE15681692.aspx
1x 40V/2200uF 电容,电解 https://www.newark.com/illinois-capacitor/228tta050m/aluminum-electrolytic-capacitor/dp/30K6693
导热胶带 https://www.adafruit.com/product/1468
2x Raspberry Pi 散热器 https://www.adafruit.com/product/3082

开始构建!

Reactive cooling diagram

实际上,只需将5V GPIO引脚上的一根电线(或一种会使保修失效的方式—在microUSB端口一边的大功率“D5”二极管上焊接一根线)连接到介质开关的一根电线上,然后再将其另一根电线连接到风扇的正极端子即可。

Creative 5V tap on RPi

将一个BAT86肖特基环流二极管按照从风扇负极端子到正极端子的方向进行正向偏置连接,然后将风扇的负极端子连接到GND来完成电路连接。您可以自行创建构成地面的条件,那么GND将是无处不在的。Pi功能性非常强,可以处理极微小的接地回路。

或者,选择一个不会出错的方法,即直接将其连接到一个GPIO GND引脚上。唯一要注意的细节是要确保导热胶带导热性能很好,需要事先用异丙醇对散热器和开关进行擦拭。一切准备就绪后,请使用一大块热胶将其固定在该位置上。

This RPi is packed

使用热胶将其固定

KSD9700被埋在热胶和Kapton胶带下面,位于上图中CPU的右侧。在运行过程中,当“vcgencmd measure_temp”返回53C/127.4F时,45C/113F开关将闭合,并持续驱动风扇,直到“vcgencmd measure_temp”保持返回38C/100.4F为止。即便是在CPU四核100%负载的情况下,也只有持续时间发生变化。这是因为开关本身必须吸收足够多的热量才会达到133F,而CPU传感器的读数会超前一些。

这种类型的开关可以使用十年,并且十分耐用,独立于config.txt 中的“gpio-fan”参数。同时,它也很容易制作。准备好您的热胶枪吧!

为您的Pi添加一个LED心跳灯电路

BOM

4x ROHM SLR343BC4TT32 3mm 蓝色 LEDs https://www.avnet.com/shop/us/products/rohm/slr343bc4tt32-3074457345627700657?CMP=EMA_ECIA_inventoryfeed_VSE?aka_re=1
1x 2N7000 N-通道 MOSFET https://www.oddwires.com/2n7000-2n7000ta-small-signal-mosfet-10-pack/
4x 330 ohm 电阻 https://www.sparkfun.com/products/14490
细绞线 https://www.daburn.com/2671UltraFlexibleSub-MiniatureWire-U/LSTYLE15681692.aspx
1x 4.7kOhm 电阻 https://www.adafruit.com/product/2783

开始构建!

LED heartbeat diagram

LED heartbeat board

一个小的Pi植入板可以成为一个真正的蓝色心跳灯。LED的万向性将会通过热胶和一些来自反编译笔记本电脑LCD的薄膜得到增强。

RPi &; BIG reservoir capacitor

关闭和启动性能良好!阳极氧化铝网可以保护风扇不受损伤,但是会减少约40%的气流流动。

那么,为什么这个Pi上有一个大容量2200uF电容呢?是的,这里有一个电容,并且直接连接到了5V/GND GPIO 引脚上。

这里使用电容的原因和低音喇叭中使用电容的原因相同。即使您已经一切准备就绪了,使用了官方Raspberry Pi 5.25V SMPS电源和低电阻线,但是如果您的电流消耗突然激增(比如电流需要快速从1A变为2A),可能还是会遇到问题。

对我来说,这种情况最常发生在我在写入一个USB硬盘的同时又执行大量CPU工作和网络工作的时候。这种时候我会收到严重的欠压警告。如果您的5V引脚上的电压约为4.65V或低于这个数值,就会遇到这种情况,这非常令人心烦。

那么,如果SMPS电源无法应对偶尔出现的尖峰电压或传输电压怎么办?您需要添加一个存储电容器,电容量越大越好,但是根据经验法则,系统每流入1A的电流需要1000uF,实际电容量要略大于这个值,所以为2200uF。Raspberry Pi 4 B的额定电流为3A,因此需要使用约3300uF的电容。您也可以选择更高性能的电容,比如使用一个超级电容肯定会进一步提高性能。电容的另一个优点是也可以用于点焊。

您可以在心跳灯电路中使用这个简单的Python 3脚本。
[ begin heartbeat.py ]

#! /usr/bin/env python3
import RPi.GPIO as GPIO   
from time import sleep
GPIO.setmode( GPIO.BCM ) # 
# Count 12 from the 3V3,5V pins at the top of the
# GPIO header
_led = 18  # BCM18/BOARD12/PWM0 pin 
GPIO.setup( _led , GPIO.OUT ) 
pwm = GPIO.PWM( _led, 100 ) 
pwm.start( 0 ) 
p=print
_step = 3

def get_load():
  _f = open( '/proc/loadavg', 'r' )
  _buf = _f.read( 30 )
  _f.close()
  return float ( _buf.split()[0] )

def get_delay():
  _load = get_load()
  _delay_base = 0.2
  if _load >= 0 and _load < 0.33: _delay = _delay_base 
  elif _load < 0.66 and _load >= 0.33: _delay = _delay_base / 2
  elif _load < 1 and _load >= 0.66: _delay = _delay_base / 3
  elif _load < 1.33 and _load >=1: _delay = _delay_base / 4
  elif _load < 1.66 and _load >= 1.33: _delay = _delay_base / 5
  elif _load < 2 and _load >= 1.66: _delay = _delay_base / 6
  elif _load < 2.33 and _load >= 2: _delay = _delay_base / 7
  elif _load < 2.66 and _load >= 2.33: _delay = _delay_base / 8
  elif _load < 3 and _load >= 2.66: _delay = _delay_base / 9
  elif _load < 3.33 and _load >= 3: _delay = _delay_base / 10
  elif _load < 3.66 and _load >= 3.33: _delay = _delay_base / 11
  elif _load < 4 and _load >= 3.66: _delay = _delay_base / 12
  else: _delay = _delay_base / 20 # GO FAST
  # ET CETERA
  return _delay

if __name__ == '__main__':
  try:
    while True:
      for _it in range( 20, 100, _step ):  
        pwm.ChangeDutyCycle( _it ) 
        sleep( get_delay() ) 
      sleep( 0.25 )
      for _it in range( 100, 20, -(_step) ): 
        pwm.ChangeDutyCycle( _it )
        sleep( get_delay() )
      sleep( 0.25 )
  except KeyboardInterrupt:
    print( "[!] Caught ^C, breaking ..." )
    # Stop the PWM now that we're leaving
    pwm.stop() 
    # Clean up pin states, bring them all low
    GPIO.cleanup()      
    exit()

[ end heartbeat.py ]
将脚本“heartbeat.py”放入“/home/pi”中,并使用如下指令确保在您的Pi启动时会开始运行脚本:

/bin/sh -c '/usr/bin/sudo -u pi /usr/bin/python3 \
/home/pi/heartbeat.py >/dev/null 2>&;1' &;

同样,请务必将其放置在“exit 0”行上方。
现在,当您的Pi没有负载时,您会看到稳定跳动的蓝光,中等负载时看到以更高的频率跳动的蓝光,并且每次您的Pi加载时都会出现快速跳动。

然而,在这么简单的一个事物上投入时间还有一个更重要的原因。

这是中等负载下的一张照片:
Raspberry Pi with LED heartbeat

一个舒缓的蓝光跳动节奏可以提示Pi操作者一切都在按照计划进行。

“我的PI崩溃了吗?”—设法了解这一问题的答案始终是必要的,尤其是当您在运行一个无显示器系统时。如果Pi真的崩溃了,心跳灯将会死机并停止跳动,或者直接熄灭。

为了给您的Pi生成负载,请将以下内容粘贴到您的终端中:

dd if=/dev/zero bs=1M of=/dev/zero &; 
dd if=/dev/zero bs=1M of=/dev/zero &;
dd if=/dev/zero bs=1M of=/dev/zero &;
dd if=/dev/zero bs=1M of=/dev/zero &;
# Let it load, let it load, let it load ...
sleep 120
kill $( jobs -p ) 

接下来请观看我的小型Raspberry Pi 2 B+在重负载下的视频剪辑(所有核的利用率均为100%):


冷却并不容易,但是是十分必要的!我们采用被动冷却的方式从Raspberry交换热量。

Lasse Efrayim Jespersen
Lasse Efrayim Jespersen

Lasse出生在以色列,后来移居到较冷的纬度地区。出于个人兴趣,他逐渐了解到了Perl的直接、C/C++的高效以及MicroPython的优雅。他喜欢用ESP8266/ESP32/Raspberry Pi和Arduino来制作机器。

分享到社交媒体