2023-12-17 21:36:39 [显示全部楼层]
62682浏览
查看: 62682|回复: 0

[项目] 自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务

[复制链接]
本帖最后由 珠峰 于 2023-12-17 22:45 编辑

近日入手一块树莓派4B(4G版),打算用来做Siot服务器及jupyter写python程序,感觉如果一直开着风扇的话,会多少有点噪音而且浪费资源。不开风扇又怕太热,毕竟4B比3B+的发热量要大。随手拿来一些电子元件及PCB板,做一个自动温控系统给4B散热,用4B作为服务器,并增加开关机按键。(成品如图)自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图29
功能:
1.开机显示树莓派的IP地址,使得无显示器也可以轻松实现远程连接、使用SIOT、JUPYTER服务。
2.可以实时显示系统运行情况,显示时间、CPU使用率、CPU温度、风扇运行情况、内存使用情况、硬盘使用情况等。
3.还可以使用一个按钮实现重启、关机、取消操作功能,使得关闭树莓派不用直接断电,保护系统安全。
4.OLED屏幕具有无操作一定时间后自动熄屏,并可使用按钮唤醒,省电,还可以避免光污染,非常实用。

一、材料
    1. 128*64 IIC接口OLED显示屏*1
    2. 7*5cm双面喷锡洞洞板*1
    3. 红色LED灯*1
    4. S8050三极管*2
    5. 微动开关*2
    6. 排针(2.54mm)红、绿、黑各一排
    7. 弯排针一排
    8. 加长2*20P直插排针母座*1(这里我用了4 个1*10的代替)
    9. 2*20P直插排针母座*1
    10. 5*6六角塑料柱*2
    11. 0.5mm、0.3mm漆包线若干
    12. 电烙铁等焊接工具
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图1
二、电路图
[size=10.5000pt] 自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图2
[size=10.5000pt]
三、按电路图焊接到双面PBC板上
[size=10.5000pt] 自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图3自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图17自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图11

[size=10.5000pt]
四、python编写自动温控系统程序(自制扩展板)
python3输入以下内容并命名为Oled12864.py
  1. #!/usr/bin/env python3
  2. #OLED12864IP.py showTheTime.py
  3. # 程序功能:开机显示树莓派的IP地址,使得无显示器也可以轻松实现远程连接,
  4. # 同时可以实时显示系统运行情况,显示时间、CPU使用率、CPU温度、风扇运行
  5. # 情况、内存使用情况、硬盘使用情况等,非常实用。
  6. from luma.core.interface.serial import i2c, spi
  7. from luma.oled.device import ssd1306, ssd1325, ssd1331, sh1106
  8. from luma.core.render import canvas
  9. from PIL import ImageDraw, Image,ImageFont
  10. import time
  11. import datetime as datetime
  12. import socket
  13. import fcntl
  14. import struct
  15. import os,sys
  16. import RPi.GPIO as GPIO
  17. import signal
  18. # OLED显示带有树莓派logo的地址
  19. logo = Image.open('/home/pi/images/pi.png')
  20. GPIO.setmode(GPIO.BCM)# 使用BCM引脚编码
  21. #定义 GPIO pin
  22. pin_power_btn = 27# 开关按钮接BCM(下同)27引脚
  23. pin_led = 25# LED接25引脚
  24. pin_oled_btn = 26# 唤醒OLED屏按钮接26引脚
  25. pin_fan_1 = 24# 风扇1接24引脚
  26. pin_fan_2 = 23# 风扇2接23引脚
  27. my_oled_show=1# OLED状态
  28. my_oled_show_count=0
  29. fan_1_run = "0"# 风扇1状态
  30. fan_2_run = "0"# 风扇1状态
  31. GPIO.setup(pin_power_btn,GPIO.IN,pull_up_down=GPIO.PUD_UP)
  32. GPIO.setup(pin_led,GPIO.OUT,initial=GPIO.LOW)
  33. GPIO.setup(pin_oled_btn,GPIO.IN,pull_up_down=GPIO.PUD_UP)
  34. GPIO.setup(pin_fan_1,GPIO.OUT,initial=GPIO.LOW)
  35. GPIO.setup(pin_fan_2,GPIO.OUT,initial=GPIO.LOW)
  36. press_time = 0#按钮计数
  37. count_down = 10# 倒计时10秒
  38. led_on = 1
  39. #clean the GPIO sources
  40. def cleanup():
  41.     GPIO.cleanup()
  42. def handleSIGTERM(signum,frame):
  43.     sys.exit()#raise an exception of type SystemExit
  44. #定义按钮功能
  45. def onPress(channel):
  46.     global press_time,count_down
  47.     press_time += 1
  48.     if press_time > 3:
  49.         press_time = 1
  50.     if press_time == 2:
  51.         GPIO.output(pin_led,1)
  52. #
  53.     elif press_time == 3:
  54.         GPIO.output(pin_led,0)
  55.         count_down = 10
  56. # 获取CPU温度
  57. def getCPUtemperature():
  58.     res = os.popen('vcgencmd measure_temp').readline()
  59.     return(res.replace("temp=","").replace("'C\n",""))
  60. # 获取内存信息
  61. def getRAMinfo():
  62.     p = os.popen('free')
  63.     i = 0
  64.     while 1:
  65.         i = i + 1
  66.         line = p.readline()
  67.         if i==2:
  68.             return(line.split()[1:4])
  69. # 获取CPU使用率
  70. def getCPUuse():
  71.     return(str(os.popen("sudo top -n1 | grep load | awk '/Cpu\(s\):/ {print $2}'").readline().strip()))
  72. # 获取SD卡使用率
  73. def getDiskSpace():
  74.     p = os.popen("df -h /")
  75.     i = 0
  76.     while 1:
  77.         i = i +1
  78.         line = p.readline()
  79.         if i==2:
  80.             return(line.split()[1:5])
  81. #显示时间
  82. def Show(d,fullDt):
  83.     y =  fullDt.strftime('%Y')
  84.     dt = fullDt.strftime('%m-%d')
  85.     tm = fullDt.strftime('%H:%M:%S')
  86. # 获取系统IP地址
  87. def getIP(ifname):
  88.     s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  89.     return socket.inet_ntoa(fcntl.ioctl(
  90.         s.fileno(),
  91.         0x8915,  # SIOCGIFADDR
  92.         struct.pack('256s', ifname[:15].encode('utf-8'))
  93.     )[20:24])
  94. # OLED显示函数
  95. def stats(oled,fullDt):
  96.     global my_oled_show,my_oled_show_count,fan_1_run,fan_2_run
  97.     y =  fullDt.strftime('%Y')
  98.     dt = fullDt.strftime('%m-%d')
  99.     tm = fullDt.strftime('%H:%M:%S')
  100.     # CPU 信息
  101.     CPU_temp = getCPUtemperature()
  102.     CPU_usage = getCPUuse()
  103.     #CPU 风扇运行情况
  104.     if float(CPU_temp) >= 49.0:
  105.         GPIO.output(pin_fan_1,1)
  106.         fan_1_run = "1"
  107.     if float(CPU_temp) <=45.0:
  108.         GPIO.output(pin_fan_1,0)
  109.         fan_1_run = "0"
  110.     if float(CPU_temp) >= 52.0:
  111.         GPIO.output(pin_fan_2,1)
  112.         fan_2_run = "1"
  113.     if float(CPU_temp) <=45.0:
  114.         GPIO.output(pin_fan_2,0)
  115.         fan_2_run = "0"
  116.     # 内存使用情况
  117.     RAM_stats = getRAMinfo()
  118.     RAM_total = round(int(RAM_stats[0]) / 1000,1)
  119.     RAM_used = round(int(RAM_stats[1]) / 1000,1)
  120.     RAM_free = round(int(RAM_stats[2]) / 1000,1)
  121.     # SD卡使用情况
  122.     DISK_stats = getDiskSpace()
  123.     DISK_total = DISK_stats[0]
  124.     DISK_used = DISK_stats[1]
  125.     DISK_perc = DISK_stats[3]
  126.     font = ImageFont.load_default()
  127.     font2 = ImageFont.truetype('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 12)
  128.     with canvas(oled) as draw:
  129.         if my_oled_show == 1:
  130.             #可选择显示有线网络或者无线网络IP
  131.             draw.text((0, 0), "IP: " + getIP("wlan0"), font=font2, fill=255)
  132.             #draw.text((0, 0), "IP: " + getIP("eth0"), font=font2, fill=255)
  133.             draw.text((0, 13), y+"-"+dt+" "+tm, font=font2, fill=255)
  134.             draw.bitmap((98, 28), logo, fill=1)
  135.             
  136.             draw.text((0, 26), "CPU:"+CPU_temp+"`C"+"  "+fan_1_run + fan_2_run, font=font2, fill=255)
  137.             draw.text((0, 39), "R:"+ str(RAM_used) +" / "+str(RAM_total ), font=font2, fill=255)
  138.             draw.text((0, 52), "D:"+ str(DISK_used) +" / "+str(DISK_total), font=font2, fill=255)
  139.         else:
  140.             draw.text((0, 0), "..." , font=font2, fill=255)
  141. # OLED显示唤醒按钮函数
  142. def oled_onPress(channel):
  143.     global my_oled_show,my_oled_show_count
  144.     my_oled_show = 1
  145.     my_oled_show_count = 0
  146. # 主函数
  147. def main():
  148.     my_gettime_count = 0
  149.     global press_time,count_down,led_on
  150.     global my_oled_show,my_oled_show_count
  151.     nowDt = datetime.datetime.now() + datetime.timedelta(hours=0)
  152.     GPIO.add_event_detect(pin_power_btn, GPIO.FALLING, callback = onPress,bouncetime = 500)
  153.     GPIO.add_event_detect(pin_oled_btn, GPIO.FALLING,callback = oled_onPress,bouncetime=500)
  154.     while True:
  155.         stats(oled,nowDt)
  156.         if my_gettime_count < 3600:
  157.             nowDt = nowDt + datetime.timedelta(seconds=1)
  158.             my_gettime_count += 1
  159.         else:
  160.             nowDt = datetime.datetime.now() + datetime.timedelta(hours=0)
  161.             my_gettime_count = 0
  162.         if my_oled_show == 1:
  163.             if my_oled_show_count <100:
  164.                 my_oled_show_count += 1
  165.             else:
  166.                 my_oled_show = 0
  167.                 my_oled_show_count = 0
  168.         else:
  169.             my_oled_show_count = 0
  170.         if press_time == 1:
  171.             if count_down == 0:
  172.                 os.system("sudo reboot")
  173.                 sys.exit()
  174.             led_on = not led_on
  175.             GPIO.output(pin_led,led_on)
  176.         if press_time == 2 and count_down == 0:
  177.             os.system("sudo halt")
  178.             sys.exit()
  179.         if press_time == 1 or press_time == 2:
  180.             count_down -= 1
  181.         time.sleep(1)
  182. if __name__ == "__main__":
  183.     try:
  184.         serial = i2c(port=1,address=0x3C)
  185.         oled = ssd1306(serial)
  186.         main()
  187.     except KeyboardInterrupt:
  188.         pass
  189.     finally:
  190.         cleanup()
复制代码


将以上文件上传到/home/pi目录下,并新建一个image文件夹,放上Python文件中的图片

自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图4
开启i2c功能自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图5
安装Luma.oled库终端输入下面命令。
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图6
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图7
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图8
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图9
[size=10.5000pt]
改变权限
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图10
设置自动启动服务
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图12
加入以下两行
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图13
[size=10.5000pt]
五、安装jupyter
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图14
漫长的等待…………
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图15
安装成功。
[size=10.5000pt]
输入jupyter --version查看版本信息,显示ipythonjupyter labipywidgets未安装,但是查询IPython版本却说已存在。
输入sudo pip3 install --upgrade IPython升级
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图16
输入sudo pip3 install jupyterlab安装jupyterlab
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图18
安装完成后,再次检查jupyter的版本,成功!
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图19


配置Jupyter
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图21
通过Ctrl+w快速定位c.NotebookApp.ip = ‘0.0.0.0’
c.NotebookApp.open_browser = False
c.NotebookApp.port = 8888
c.NotebookApp.notebook_dir = ‘/home/pi’


修改jupyter Notebook 密码

启动jupyter notebook

自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图20
配置自动服务自动启动。
1)编辑服务文件
pi@raspberrypi:~ $ sudo nano /etc/init.d/JupyterNB

  1. #!/bin/sh
  2. #/etc/init.d/JyputerNB
  3. ### BEGIN INIT INFO
  4. # Provides:JyputerNB
  5. # Required-Start:$remote_fs $syslog
  6. # Required-Stop:$remote_fs $syslog
  7. # Default-Start:2 3 4 5
  8. # Default-Stop:0 1 6
  9. # Short-Description: JyputerNB
  10. # Description: This service is used to start my applaction
  11. ### END INIT INFO
  12. case "$1" in
  13.     start)
  14.     echo "start your app here."
  15.     su pi -c "jupyter notebook"
  16.     ;;
  17.     stop)
  18.     echo "stop your app here."
  19.     ;;
  20.     *)
  21.     echo "Usage:service JyputerNotebook start|stop"
  22.     exit 1
  23.     ;;
  24. esac
  25. exit 0
复制代码


自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图22
2)修改服务文件的权限
pi@raspberrypi:~ $ sudo chmod 777 /etc/init.d/JupyterNB
3)设置服务启动
pi@raspberrypi:~ $ sudo update-rc.d JupyterNB defaults
4)重启测试
pi@raspberrypi:~ $ sudo reboot
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图23

安装启动成功
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图24

六、安装SIoT并配置服务自启
SIoT为一个为教育定制的跨平台的MQTT服务器程序,S指科学(Science)、简单(simple)的意思。SIoT支持Win10Win7MacLinux等操作系统,一键启动,无需注册即可使用。

SIoT为“虚谷物联”项目的核心软件,是为了帮助中小学生理解物联网原理,并且能够基于物联网技术开发各种创意应用,尤其是用于科学数据采集。

SIoT最新版本为1.2,仅有1.1版本支持在树莓派上使用,其下载地址为:

https://github.com/liliang9693/mindplus-docs/tree/master/SIOT

1.在电脑中下载到1.1版本的SIoT之后,打开发现压缩包中siot文件夹的名字为“SIoT raspberryPi”,中间有空格,为了不必要的麻烦,建议将压缩包里面的文件夹的名字改为SIoT,压缩包也改名为SIoT

2.然后将SIoT压缩包通过ftp上传到树莓派的/Home/pi/中 ,打开命令窗口,运行以下命令进行安装。

#1.利用unzip解压zip文件,将SIoT.zip直接解压到/home/pi/中,
unzip SIoT.zip

#2.先修改SIoT目录的权限,不然进去之后不能运行。
sudo chmod -R 777 SIoT

#3.转到SIoT1的目录中
cd SIoT

#4.运行siot服务
sudo ./SIoT_Raspbian

自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图25

自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图26
到此,siot已完成,访问  树莓派地址:8080 即可登陆siot,帐号:siot 密码:dfrobot

3.最后,配置一下开机启动:
配置自动服务自动启动。

1)编辑服务文件

pi@raspberrypi:~ $ sudo nano /etc/init.d/SIoT

  1. #!/bin/sh
  2. #/etc/init.d/SIoT
  3. ### BEGIN INIT INFO
  4. # Provides:SIoT
  5. # Required-Start:$remote_fs $syslog
  6. # Required-Stop:$remote_fs $syslog
  7. # Default-Start:2 3 4 5
  8. # Default-Stop:0 1 6
  9. # Short-Description: SIoT
  10. # Description: This service is used to start my applaction
  11. ### END INIT INFO
  12. case "$1" in
  13. start)
  14. echo "start your app here."
  15. su pi -c "exec /home/pi/SIoT/SIoT_Raspbian"
  16. ;;
  17. stop)
  18. echo "stop your app here."
  19. ;;
  20. *)
  21. echo "Usage: service SIoT start|stop"
  22. exit 1
  23. ;;
  24. esac
  25. exit 0
复制代码


自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图27
2)修改服务文件的权限

pi@raspberrypi:~ $ sudo chmod 777 /etc/init.d/SIoT

3)设置服务启动

pi@raspberrypi:~ $ sudo update-rc.d SIoT defaults

4)重启测试

pi@raspberrypi:~ $ sudo reboot
自制树莓派4B自动温控+IP显示系统并配置Siot、jupyter服务图28


至此,树莓派4B温控+IP显示系统及服务器就制作完毕。



图片 22.png
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

硬件清单

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

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

mail