? 部落格連結:用 Node.js 給樹莓派寫了個控制檯 | Amber
大一的時候就買了很多樹莓派,因為那時候還啥也不會,就大部分時間放在角落裡吃灰。最近考古看到一篇外國老哥用樹莓配搭建 Hadoop 叢集的文章,就把樹莓派拿出來重新改造了一下,作為智慧家居中心使用。好在當初就是用 lego 搭的外殼,現在要翻修也很容易,已經搗鼓之後看起來就像下面那樣。為了能在 iOS
上用 HomeKit
控制家裡的幾個小米的智慧燈,我選擇了 HomeAssistant 作為智慧家居中心,但樹莓派的散熱就成了個問題。
雪乃坐鎮保佑不出 bug
本來買樹莓派的時候就帶了風扇,但都是直接插在樹莓派的供電介面上的,也就是說,3.3v
供電的 GPIO
引腳是沒法驅動 5v
工作電壓的風扇的,而且另一方面這小風扇非常吵,而且整天整晚的開著承軸受不了(已經掛了一個了),所以我就去萬能的某寶買了一個建準的磁懸浮風扇,6cm
的風徑可以給兩個樹莓派同時散熱。事實證明磁懸浮風扇果然名不虛傳,風量大還真的一點聲音都沒有。但為了延長承軸壽命,還是要設計一套可以通過程式設計控制的風扇控制程式。
經過一番搜尋,我參考了這篇文章。上面已經說過了,3.3v
的 GPIO
是沒法直接給風扇供電的,所以我選擇了博文中的三極體方案,設計了這樣的電路:
線上的 CircuteLab 沒有
motor
,用lamp
將就一下吧
我和博文中一樣選擇了 S9012
的 PNP
型三極體,風扇正極與樹莓派 5v
引腳相連,負極與三極體發射極相連,三極體基極與你想要使用的 GPIO
引腳(比如我這裡就是 8
號引腳 (GPIO 14
)) 相連,集電極接地即可。參考下面的樹莓派引腳圖:
⚠️ 注意
rpio
的引腳編號和實際的gpio
埠號不完全對應,下面會講到
接下來,通過 node.js
程式設計控制風扇自動停啟。使用 node.js
是為了下面和控制檯對接方便,示例程式碼如下:
const GPIO = require('rpio')
const PIN = 8 // 這裡的 8 號引腳對應 gpio 14,其餘請查閱 rpi gpio 手冊:https://pinout.xyz/
const TEMP_LOW = 38 // 低於 38 攝氏度則停止執行
const TEMP_HIGH = 42 // 高於 42 攝氏度則開啟風扇
const TEMP_FILE = '/sys/class/thermal/thermal_zone0/temp'
/**
* 讀取樹莓派當前溫度
* return {Number} 當前溫度
*/
function cpuTemp () {
return parseFloat(require('fs').readFileSync(TEMP_FILE)) / 1000
}
setInterval(function () {
temp = cpuTemp()
console.log(`Current temp is ${temp}`)
if (isClose) {
if (temp > TEMP_HIGH) {
GPIO.write(PIN, GPIO.LOW)
console.log('Open air cooler')
isClose = false
}
} else {
if (temp < TEMP_LOW) {
GPIO.write(PIN, GPIO.HIGH)
console.log('Close air cooler')
isClose = true
}
}
}, 2000) // 每 2s 重新整理一次
複製程式碼
對了,這裡有個坑忘了說。包括我參考的那篇部落格在內,大部分網路上的資料都是通過給介面高電平來開啟風扇的,但事實上這是以
NPN
型三極體計算的結果,要使得PNP
工作於放大狀態應該使發射結正偏而集電結反偏,如果GPIO
引腳這時給高電平是沒法使三極體正常工作的,所以這裡給低電平才對。
為了驗證這個我還把塵封的模電書找了出來好好複習了一下。
用 Node
編寫控制檯後端還比較簡單,主要架構就是 express
做服務端,bootstrap materialize design
+ d3.js
做前端頁面,再通過 socket.io
作為 WebSocket
通訊就行了。雖然簡單但程式碼比較繁瑣,就不在這裡貼出來了,給幾個截圖意思一下:
性感風扇線上調戲
搭配 HomeAssistant 食用風味更佳
不過我不清楚是不是 d3.js
的鍋,反正現在效能不是很好,長時間執行後樹莓派倒是不燙了,電腦的 CPU 卻下不來了大霧,估計反覆操作 DOM
效能開銷還是太大了,等明年再用 Vue
重構吧。