9976浏览
查看: 9976|回复: 14

[项目] 又酷又迷你的DIY服务器---bbServer 制作过程与经验分享

[复制链接]
bbServer 制作过程与经验分享

【简介】

bbServer 是一台高性能、低功耗、酷炫的家用服务器,通过单板电脑特有的 GPIO 完成屏幕和灯带的控制,配合单面镜和半透镜形成深渊灯的效果。作者的个人应用场景是用来运行 Minecraft 服务器,让游戏内的活动与服务器外围设备产生联动,例如当有玩家进入服务器时,会在 OLED 屏幕上显示,并且伴随着光效。

又酷又迷你的DIY服务器---bbServer 制作过程与经验分享图1

开源链接:
https://github.com/RealCorebb/bbServer

视频链接:
https://www.bilibili.com/video/BV1j24y1a7Ut/

【故事起因】

我一直想 DIY 一台能够放在家里 24 小时开机的服务器。我希望这台服务器功耗足够低,这样就不会被妈妈打。因为我想用它来运行 Minecraft 服务器,所以性能也需要稍微好一点。然而,低功耗和高性能之间存在着矛盾,我只有选择能耗比更高的芯片。
所以,我选择了香橙派5这类 ARM 架构的单板电脑,因为它省电、体积小,性能也高,而且可以像单片机一样控制一些电子元件。因此,我在服务器上添加 OLED 屏幕和 WS2812 RGB 灯带,借助 CircuitPython 就可以根据自己的想法尽情发挥,制作出这样一台低功耗、迷你、又好玩又酷炫的服务器。

【bbServer制作步骤】

1.购买所需物料
在开始制作bbServer之前,您需要准备以下物料:

又酷又迷你的DIY服务器---bbServer 制作过程与经验分享图2

(1)香橙派5,这是一款性价比非常高的RK3588S单板电脑,RK3588S是一个8nm制程ARM架构的SOC,有8核心(6大核+2小核),用来开中小型Minecraft服务器是非常稳妥且省电的。
(2)2.42寸OLED屏幕 (4PIN I2C版本)
(3)WS2812-2020 寻址RGB灯带(90LEDS/M)
(4)3D打印外壳
(5)单面镜+30%半透镜
(6)M2硬盘(2230或2242尺寸)
(7)散热片(19*19*5mm)
(8)3007涡轮散热风扇
(9)5V4A电源适配器

2.组装硬件
将M.2硬盘插入香橙派5上的M.2插槽中。

又酷又迷你的DIY服务器---bbServer 制作过程与经验分享图3

将散热片安装在香橙派5的芯片上,然后将其插入3D打印的外壳中,并将四周的固定螺丝扭紧。香橙派5本身侧边有一个开关机的按键,如果需要使用的话也可以3D打印一个较大的按钮模型,卡在外壳与开关按键之间。

又酷又迷你的DIY服务器---bbServer 制作过程与经验分享图4

安装3007涡轮散热风扇,可以装在芯片旁边,出气口朝外,将正负极分别接到5V和GND。如果想要更安静一点,也可以接到3.3V。

又酷又迷你的DIY服务器---bbServer 制作过程与经验分享图5

将WS2812-2020 RGB灯带与OLED屏幕连接到香橙派5的GPIO引脚上,确保连接正确。因为设计的外壳想尽量保持小巧、紧凑,所以用一般的2.54间距的杜邦线会太高,装不进去。解决办法就是将杜邦线的胶壳去掉(用镊子撬开卡口,把线拿出来即可),可以用热缩管或胶布套住端子部分,避免相互之间接触导电。

又酷又迷你的DIY服务器---bbServer 制作过程与经验分享图6

具体的IO引脚和接线图如下:

又酷又迷你的DIY服务器---bbServer 制作过程与经验分享图7

又酷又迷你的DIY服务器---bbServer 制作过程与经验分享图8

又酷又迷你的DIY服务器---bbServer 制作过程与经验分享图9

安装好之后可以跳到第3大步:安装系统、环境,测试一下LED和屏幕是否正常点亮,然后接着完成最后的组装。
在验证硬件正常后,将单面镜和30%半透镜组装到3D打印的外壳中,注意尽量戴上干净的手套,避免手指印。

又酷又迷你的DIY服务器---bbServer 制作过程与经验分享图10

OLED屏幕可以一边用胶布固定在RJ45网口上,另一边用杜邦线顶着。摆放在正中间靠后的位置,然后将单面镜卡进OLED屏幕与LED之间。

又酷又迷你的DIY服务器---bbServer 制作过程与经验分享图11

接着,再盖上半透镜就大功告成啦。

又酷又迷你的DIY服务器---bbServer 制作过程与经验分享图12

3.安装系统
香橙派5官方提供了Ubuntu、Debian、Android系统,也有在单板电脑上比较出名的Armbian系统。但目前的情况Armbian有一些BUG,导致I2C和SPI功能不正常,无法使用LED和OLED。所以这里选择的是官方的Ubuntu系统。

完整的文档可以参考官方的使用说明书:
http://www.orangepi.cn/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-pi-5.html

大致步骤如下:

(1)准备一张TF卡,使用balenaEtcher软件将官网下载的Ubuntu镜像写入TF卡中
(2)插入TF卡、M2硬盘,开机。连接网线,使用Xshell连接香橙派或使用HDMI连接显示器操作。默认用户名为:root,密码为:orangepi
(3)在终端控制台输入指令nand-sata-install,选择Install the bootloader on SPI Flash,等待几分钟直至出现Done

又酷又迷你的DIY服务器---bbServer 制作过程与经验分享图13

(4)将镜像写入M2硬盘中,指令如下:
dd bs=1M if=<镜像路径> of=/dev/nvme0n1 status=progress
例如:
dd bs=1M if=Orangepi5_x.x.x_ubuntu.img of=/dev/nvme0n1 status=progress
(5)写入完成后,就可以输入poweroff指令关机,拔掉TF卡,再开机,以后就都是用M2硬盘作为系统盘开机啦。M2硬盘比起TF卡更耐用,更适合长时间运行,速度也更快。

4.配置环境
在完成以上步骤后,这就是一台arm架构的Ubuntu系统的电脑了,你可以使用绝大多数能在Linux上运行的软件,例如假设Mumble语音服务器、Minecraft服务器、Apache网站服务器等等……

除此之外,还可以利用上面的GPIO,让它能够像单片机一样控制一些电子零件。

安装必要的软件包:Python、pip、CircuitPython。前面两个大家都很熟悉,最后一个CircuitPython就是一个能在Linux板子上运行类似单片机功能的框架,是由电子界著名的Adafruit出品的。

因为具体的步骤有点复杂,想要研究的可以参考官方的文档:
https://learn.adafruit.com/circuitpython-on-orangepi-linux/circuitpython-orangepi
官方文档使用的是Armbian系统以及较老的香橙派,不过大致是一样的,需要修改一些东西让CircuitPython能够识别到我们使用的板子型号。

为此,我写了一个脚本,可以一键在香橙派Ubuntu系统下安装好CircuitPython以及我们使用的OLED屏幕和WS2812 LED灯带相应的依赖库。

脚本地址:
https://raw.githubusercontent.com/RealCorebb/bbServer/master/bbServer.sh

可以使用以下方式安装:
wget https://raw.githubusercontent.co ... /master/bbServer.sh
chmod 777 bbServer.sh
./bbServer.sh

在安装好后,需要重启一次。安装好后会把bbServer的demo示例程序设为开机自启,所以重启后会看到LED灯带动画以及OLED屏幕显示时间、CPU、内存信息了。

以下是demo的程序,可以看到使用CircuiPython是比较容易上手,发挥自己的想法的。有丰富的库,能够立马上手。

  1. 1.import threading
  2. 2.import board
  3. 3.import neopixel_spi
  4. 4.from PIL import Image, ImageDraw, ImageFont
  5. 5.from adafruit_led_animation.animation.blink import Blink
  6. 6.from adafruit_led_animation.animation.sparklepulse import SparklePulse
  7. 7.from adafruit_led_animation.animation.comet import Comet
  8. 8.from adafruit_led_animation.animation.chase import Chase
  9. 9.from adafruit_led_animation.animation.pulse import Pulse
  10. 10.from adafruit_led_animation.animation.sparkle import Sparkle
  11. 11.from adafruit_led_animation.animation.rainbowchase import RainbowChase
  12. 12.from adafruit_led_animation.animation.rainbowsparkle import RainbowSparkle
  13. 13.from adafruit_led_animation.animation.rainbowcomet import RainbowComet
  14. 14.from adafruit_led_animation.animation.solid import Solid
  15. 15.from adafruit_led_animation.animation.colorcycle import ColorCycle
  16. 16.from adafruit_led_animation.animation.rainbow import Rainbow
  17. 17.from adafruit_led_animation.animation.customcolorchase import CustomColorChase
  18. 18.from adafruit_led_animation.sequence import AnimationSequence
  19. 19.from adafruit_led_animation.color import PURPLE, WHITE, AMBER, JADE, MAGENTA, ORANGE , BLACK , RED
  20. 20.import adafruit_ssd1306
  21. 21.import time
  22. 22.import psutil
  23. 23.import pathlib
  24. 24.dirPath = str(pathlib.Path(__file__).parent.resolve())
  25. 25.font = ImageFont.truetype(dirPath+'/fonts/Jorolks.ttf',24)
  26. 26.smallJorolks = ImageFont.truetype(dirPath+'/fonts/Jorolks.ttf',12)
  27. 27.seledom = ImageFont.truetype(dirPath+'/fonts/Seledom.otf',14)
  28. 28.bigSeledom = ImageFont.truetype(dirPath+'/fonts/Seledom.otf',33)
  29. 29.pixelCorebb = ImageFont.truetype(dirPath+'/fonts/PixelCorebb.ttf',15)
  30. 30.pixelCorebbBig = ImageFont.truetype(dirPath+'/fonts/PixelCorebb.ttf',14)
  31. 31.player = Image.open(dirPath+'/icons/steve24.png')
  32. 32.player16 = Image.open(dirPath+'/icons/steve16.png')
  33. 33.performance = Image.open(dirPath+'/icons/performance.png')
  34. 34.
  35. 35.
  36. 36.# ------------------- WS2812 RGB LED  -_,- ------------------
  37. 37.
  38. 38.# Update to match the pin connected to your NeoPixels
  39. 39.pixel_pin = board.SPI()
  40. 40.# Update to match the number of NeoPixels you have connected
  41. 41.pixel_num = 40
  42. 42.
  43. 43.pixels = neopixel_spi.NeoPixel_SPI(pixel_pin, pixel_num, brightness=0.1, auto_write=False)
  44. 44.
  45. 45.blink = Blink(pixels, speed=0.5, color=JADE)
  46. 46.redFastBlink = Blink(pixels, speed=0.1, color=RED)
  47. 47.colorcycle = ColorCycle(pixels, speed=0.4, colors=[MAGENTA, ORANGE])
  48. 48.comet = Comet(pixels, speed=0.01, color=PURPLE, tail_length=10, bounce=True)
  49. 49.chase = Chase(pixels, speed=0.1, size=3, spacing=6, color=WHITE)
  50. 50.pulse = Pulse(pixels, speed=0.1, period=3, color=AMBER)
  51. 51.sparkle = Sparkle(pixels, speed=0.1, color=PURPLE, num_sparkles=10)
  52. 52.solid = Solid(pixels, color=JADE)
  53. 53.black = Solid(pixels, color = BLACK)
  54. 54.rainbow = Rainbow(pixels, speed=0.1, period=2)
  55. 55.sparkle_pulse = SparklePulse(pixels, speed=0.1, period=3, color=JADE)
  56. 56.rainbow_comet = RainbowComet(pixels, speed=0.05, tail_length=15, bounce=True)
  57. 57.rainbow_chase = RainbowChase(pixels, speed=0.1, size=3, spacing=2, step=8)
  58. 58.rainbow_sparkle = RainbowSparkle(pixels, speed=0.1, num_sparkles=15)
  59. 59.custom_color_chase = CustomColorChase(
  60. 60.    pixels, speed=0.1, size=2, spacing=3, colors=[ORANGE, WHITE, JADE]
  61. 61.)
  62. 62.
  63. 63.
  64. 64.animations = AnimationSequence(
  65. 65.    comet,
  66. 66.    blink,
  67. 67.    rainbow_sparkle,
  68. 68.    chase,
  69. 69.    pulse,
  70. 70.    sparkle,
  71. 71.    rainbow,
  72. 72.    solid,
  73. 73.    rainbow_comet,
  74. 74.    sparkle_pulse,
  75. 75.    rainbow_chase,
  76. 76.    custom_color_chase,
  77. 77.    advance_interval=5,
  78. 78.    auto_clear=True,
  79. 79.)
  80. 80.
  81. 81.# ------------------------------------
  82. 82.
  83. 83.# ------------------- SSD1306/SSD1309 OLED  -_,- ------------------
  84. 84.oled = None
  85. 85.
  86. 86.# Create blank image for drawing.
  87. 87.image = Image.new("1", (128, 64))
  88. 88.draw = ImageDraw.Draw(image)
  89. 89.
  90. 90.def clear():
  91. 91.    global image
  92. 92.    #image = Image.new("1", (oled.width, oled.height))
  93. 93.    draw.rectangle((0, 0, 128, 64), fill="black")
  94. 94.    oled.fill(0)
  95. 95.
  96. 96.def bootLogo():
  97. 97.    draw.text((5, 20), "bbServer", fill="white", font = font)
  98. 98.    oled.image(image)
  99. 99.    oled.show()
  100. 100.
  101. 101.def updateInfo():
  102. 102.    global oled
  103. 103.    i2c = board.I2C()  # uses board.SCL and board.SDA
  104. 104.    attempts = 0
  105. 105.    while attempts < 5:
  106. 106.        try:
  107. 107.            oled = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c)
  108. 108.            break
  109. 109.        except:
  110. 110.            attempts += 1
  111. 111.            print('OLED not found, retrying...')
  112. 112.            time.sleep(1)
  113. 113.        
  114. 114.    # Clear display.
  115. 115.    oled.fill(0)
  116. 116.    oled.rotate(False)
  117. 117.    oled.show()
  118. 118.    clear()
  119. 119.    bootLogo()
  120. 120.    time.sleep(1)
  121. 121.    while True:
  122. 122.        cpu = int(psutil.cpu_percent(interval=1))
  123. 123.        ram = int(psutil.virtual_memory().percent)
  124. 124.        timeNow = time.strftime("%H:%M")
  125. 125.        
  126. 126.        clear()
  127. 127.        draw.rounded_rectangle((2,2,28,12), radius=3, fill="white")
  128. 128.        draw.text((5,3), "CPU", fill="black", font = smallJorolks)
  129. 129.        draw.text((32,0), str(cpu)+"%", fill="white",font = pixelCorebb)
  130. 130.        draw.rounded_rectangle((67,2,96,12), radius=3, fill="white")
  131. 131.        draw.text((70,3), "RAM", fill="black", font = smallJorolks)
  132. 132.        draw.text((100,0), str(ram)+"%", fill="white",font = pixelCorebb)
  133. 133.        draw.text((2,24), timeNow, fill="white",font = bigSeledom)
  134. 134.        oled.image(image)
  135. 135.        oled.show()
  136. 136.        time.sleep(1)
  137. 137.# ------------------------------------
  138. 138.
  139. 139.if __name__ == "__main__":
  140. 140.    oledThread = threading.Thread(target=updateInfo)
  141. 141.    oledThread.start()
  142. 142.    while True:
  143. 143.        time.sleep(0.01)
  144. 144.        animations.animate()
复制代码

【一些可能遇到的问题】


1.在烧写系统进TF卡后,在Windows 的资源管理器里就找不到这张TF卡了。这是正常的,因为写入了Linux系统后,Windows是读不了的。所以只能在像是Balenaetcher等烧写软件中看到,如果想变回原来的样子,在这类软件中点一下格式化即可。不要以为是TF卡坏了(作者以前就以为是TF卡坏了)

2.不知道怎么连接服务器。官方的镜像中是有桌面版和服务器版的,主要的差别在于前者有图形化的操作界面,也可以用HDMI连接显示器,后者只能连网线,用其它电脑通过SSH控制。如果作为服务器使用的话,其实一般的使用场景是类似于后者的,但对于新手来说,建议安装桌面版的,更容易上手。想了解的话,可以参考云服务器、普通Linux电脑的连接方式和工具,常用免费工具的有:Xshell,通过SSH,输入IP、用户名、密码,即可连上服务器的终端控制台。Xftp,通过SSH,可以在本地电脑与服务器之间传输文件。

3.OLED屏幕不亮。请注意,在某宝上有几款2.42寸OLED屏幕模块,请确保购买的是4/5 PIN的I2C的版本,而不是7PIN的SPI版本。另外,作者有试过在几家店里买过,实际上它们是不一样的,请认准接线图上的那一款,四个孔都在板子边缘的,且是有RES引脚的,这一款非常稳定,没遇到过什么问题。另外有一款是比较高一点,无法装进3D打印外壳里的,这款没有RES引脚,并且可能板子设计有问题,经常识别不到I2C,屏幕不亮。

4.WS2812 LED不亮。这个唯一的可能性就是接线有问题了,请注意引脚定义,不要正负极接反了。

5.安装固定不合适问题。如上文所述,杜邦线需要去壳,OLED屏幕模块确保同款,散热风扇不能太高,需要使用7mm以下的,不然会撞到屏幕。

【总结】

所以,这就是bbServer的制作过程及经验分享啦。通过制作bbServer,我们可以学到:

1.如何使用单板电脑和CircuitPython来控制电子元件。
2.如何使用Linux系统和搭建自己想要的服务。
3.还可以用Python简单、快速入门单片机领域。
在制作过程中,我们会了解一些基础知识,如单板电脑和CircuitPython的使用,GPIO引脚的控制,3D打印的设计和制作等等。同时,我们也需要有耐心和耐心来调试和解决一些问题。

总之,bbServer是一个非常有趣和有用的项目,通过它我们可以学到很多东西,并且可以用它来运行自己喜欢的应用程序,通过编写代码发挥自己无限的创意。

想更了解它,请看:
开源链接:
https://github.com/RealCorebb/bbServer
视频链接:
https://www.bilibili.com/video/BV1j24y1a7Ut/

花生编程  中级技匠

发表于 2023-1-22 18:10:34

厉害厉害
回复

使用道具 举报

花生编程  中级技匠

发表于 2023-1-22 18:11:38

好赞啊!
回复

使用道具 举报

三春牛-创客  初级技神

发表于 2023-1-22 18:51:06

厉害厉害
回复

使用道具 举报

三春牛-创客  初级技神

发表于 2023-1-22 18:53:23

支持,赞!
回复

使用道具 举报

JVUm7ppJGaRK  高级技师

发表于 2023-1-28 15:29:10

厉害厉害,请问一下服务器端口号是多少,我想进那个MC服务器试试,谢谢!
回复

使用道具 举报

aYYSW8AepLLd  高级技师

发表于 2023-1-28 20:16:00

厉害厉害
回复

使用道具 举报

盐焗海盐  见习技师

发表于 2023-3-5 15:12:45

太帅了啊


回复

使用道具 举报

Amos Young  中级技师

发表于 2023-7-4 17:03:09

好东西,泰裤辣,学习到了。
回复

使用道具 举报

快看擎天猪  中级技师

发表于 2023-7-31 12:01:28

666666666666
回复

使用道具 举报

花生编程  中级技匠

发表于 2023-8-19 10:34:59

泰裤辣!
回复

使用道具 举报

花生编程  中级技匠

发表于 2023-8-19 10:36:01

不错不错!
回复

使用道具 举报

派大星ym  初级技匠

发表于 2023-8-22 00:16:58

      
回复

使用道具 举报

派大星ym  初级技匠

发表于 2023-8-22 00:19:17

6666666666666
回复

使用道具 举报

Amos Young  中级技师

发表于 2023-8-22 15:41:03


好技术,厉害。做的很棒
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4

© 2013-2024 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail