轉載請注明:@小五義http://www.cnblogs.com/xiaowuyi QQ群:64770604
一、家庭服務器實現的主要功能
1、流媒體播放服務:利用DLNA實現電視、手機、電腦播放其上面的媒體文件。
2、文件共享:利用samba實現手機、電腦等終端與服務器的文件共享。
3、自動下載:利用aria2c實現自動下載。
先上幾張效果圖:
用orico的包裝盒做了個機箱。
內部效果,線還是有些凌亂
放在桌上,感覺還不錯,呵呵
二、准備工作
1、樹莓派B+
2、安裝raspbian系統,具體安裝方法見:樹莓派學習筆記(1):入手樹莓派。
3、設置固定IP為192.168.1.120,設置方法見:樹莓派學習筆記(3):利用VNC遠程控制樹莓派。
4、安裝vnc軟件,安裝方法見:樹莓派學習筆記(3):利用VNC遠程控制樹莓派。
5、准備了一塊舊移動硬盤(80G)
6、准備了可外接供電的usb hub一個,樹莓派本身輸出電流較小,很難保證移動硬盤的運行,所以加了一個可外接供電的usb hub。
三、安裝samba實現文件共享
1、准備硬盤
硬盤進行分區和格式化,這里我直接就分了一個區,格式化為ext4格式,據網上介紹說如果是fat或者ntfs等格式可能會出現權限問題,於是干脆直接格式化為ext4格式。硬盤在樹莓派上格式化會比較慢,我就在電腦上進行了格式化。電腦操作系統是windows7,利用軟件MiniTool Partition Wizard Home Edition 8.0,下載地址:http://www.partitionwizard.com/download.html。具體使用方法是先將原分區刪除,然后點擊creat,在格式那里選ext4,類型我選的primary,label用的nas,然后點擊apply就開始格式化硬盤了。(如果用容量較小的U盤,可以直接用樹莓派格式化,命令為:mkfs -t ext4 /dev/sdb1)
2、將硬盤掛載到樹莓派上
樹莓派開機后,用putty連接(連接方法見樹莓派學習筆記(1):入手樹莓派)后,為方便操作直接進行root用戶(具體方法見http://www.cnblogs.com/xiaowuyi/p/3980037.html一樓評論處),然后運行df –h,查看硬盤掛載情況。
root@raspberrypi:/home/pi# df -h
Filesystem Size Used Avail Use% Mounted on
rootfs 2.9G 2.4G 387M 87% /
/dev/root 2.9G 2.4G 387M 87% /
devtmpfs 183M 0 183M 0% /dev
tmpfs 38M 792K 37M 3% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 75M 0 75M 0% /run/shm
/dev/mmcblk0p1 56M 9.7M 47M 18% /boot
/dev/sda1 70G 24M 67G 1% /media/nas
最后一行/dev/sda1說明硬盤已經掛載。為下一步安裝samba,將共享文件夾設為/samba。於是新建文件夾:
mkdir /samba
設置訪問權限:shmod 777 /samba
將硬盤掛載到/samba文件夾,具體步驟:
umount /dev/sda1 #取消掛載
mount /dev/sda1 /samba
這里再查看df -h,結果為:
這里表示已掛載成功。
3、解決硬盤的自動掛載
每次樹莓派重啟或者硬盤插拔都需要對硬盤進行重新掛載,比較麻煩,因此需要自動掛載。這里要修改/etc/fstab文件。有人喜歡用vi進行編輯,我比較喜歡直接vnc連接上后,用編輯器進行編輯。
可以看到,fstab文件其實就是一個表格,表格各列的含意如下:
第一列:磁盤分區名/卷標,一般是/dev/sdaN(N表示正整數)
第二列:掛載點,我們在這里把/dev/sda1掛到/samba上。
第三列:缺省設置,一般用defautls。
第四列:是否備份:0——表示不做 dump 備份;1——表示要將整個 <fie sysytem> 里的內容備份;2 也表示要做 dump 備份,但該分區的重要性比 1 小。
第五列:檢測順序:0——不進行檢測;根分區(/),必須填寫 1,其它的都不能填寫 1。如果有分區填寫大於 1 的話,則在檢查完根分區后,從小到大依次檢查下去。
具體填寫方法在圖中已注明。
4、安裝samba
更新一下源:
sudo apt-get update
安裝samba
sudo apt-get install samba samba-common-bin
安裝完成后,配置/etc/samba/smb.conf文件
在其最后添加以下命令:
#================================================
#轉載請注明:@小五義http://www.cnblogs.com/xiaowuyi QQ群:64770604
[share] #共享文件的名稱,將在網絡上以此名稱顯示
path = /samba #共享文件的路徑
valid users = root pi #允許訪問的用戶,這里我用的是root 和 pi 兩個用戶
browseable = yes #允許瀏覽
public = yes #共享開放
writable = yes #可寫
#================================================
保存后,重啟samba服務,輸入
/etc/init.d/samba restart
最后添加共享用戶:
smbpasswd –a pi #這里我用的pi。
設置開機自啟動,編輯/etc/rc.loca,如下
5、測試samba安裝效果
在windows計算機上,打開我的電腦,在左下角網絡點右鍵,選映射網絡驅動器
點擊完成會提示輸入用戶名和密碼,這里輸入設置的共享用戶名和密碼。
最后在計算機下會出現共享的文件夾,點開文件夾,新建test.txt文件進行一下測試,如果能正常建立,就說明ok了,如果不行,應該是權限問題,可再重新設置一下/samba文件夾權限。這里注意,如果在/samba文件夾下新建新的文件夾,也需要設置權限,可以用vnc連接后,用管理員瀏覽,點右鍵設置文件夾權限為read and write,也可以用chmod命令設置。
四、安裝DLNA實現流媒體服務器
DLNA主要面向媒體資源(比如視頻、音樂)實現網內共享,具體步驟如下:
1、安裝minidlna
更新一下安裝源
sudo apt-get update
安裝minidlna
sudo apt-get install minidlna
2、設置配置文件
設置/etc/minidlna.conf文件,在文件尾部添加如下內容:
#===================================================================================
#轉載請注明:@小五義http://www.cnblogs.com/xiaowuyi QQ群:64770604
media_dir=A,/samba/DLNA/Music #A表示這個目錄是存放音樂的,當minidlna讀到配置文件時,它會自動加載這個目錄下的音樂文件
media_dir=P,/samba/DLNA/Picture
media_dir=V,/samba/DLNA/Video
db_dir=/samba/DLNA/db #配置minidlna的數庫數據的存放目錄
log_dir=/samba/DLNA/log #配置日志目錄
#=======================================================================================
3、建立文件夾
在/samba文件夾下,建立以上文件夾,並設置好權限為read and write。
4、重啟minidlna
/etc/init.d/minidlna restart
測試:
/etc/init.d/minidlna status
返回如下結果為正常。
5、在電腦上進行播放
先在樹莓派以上對應的video等文件夾內存上一些文件(可利用samba直接從電腦上考入),然后返回到計算機進行操作。
點擊我的電腦下面的網絡,出現媒體設備
雙擊進入媒體播放器,在左邊的列表欄下方其它媒體庫中出現raspberrypi:root,點擊后,可選擇音樂,視頻等。
這時雙擊就可以欣賞了。
6、手機上進行播放
手機上實現網絡共享,可安裝es file explorer軟件,在其網絡處進行設置,設置方法與電腦基本一樣,這里不再詳述。設置后,文件均可瀏覽,媒體文件雙擊可以在線播放。
也可以直接使用updp播放器,這里我安裝的是moliplayer,可以在其附近設備里,直接找到raspberrypi:root,訪問其媒體問題,注意,這里是訪問的DLNA共享,所以不需要再輸入密碼。
7、智能電視進行播放
智能電視一般都是用的android系統,與手機基本一樣。
五、安裝aria2實現下載機功能
1、安裝aria2
更新一下安裝源
sudo apt-get update
安裝aria2
sudo apt-get install aria2
2、創建配置文件
在/etc目錄下創建aria2目錄用來存放配置文件:
sudo mkdir /etc/aria2
創建空白的aria2.session文件:
sudo touch /etc/aria2/aria2.session
創建配置文件
sudo nano /etc/aria2/aria2.conf
在該文件中輸入以下內容:
#=========文件保存目錄自行修改
dir=/samba
disable-ipv6=true
#打開rpc的目的是為了給web管理端用
enable-rpc=true
rpc-allow-origin-all=true
rpc-listen-all=true
#rpc-listen-port=6800
continue=true
input-file=/etc/aria2/aria2.session
save-session=/etc/aria2/aria2.session
max-concurrent-downloads=3
這里為了方便共享,我直接設置將文件下載到samba共享文件夾。
3、啟動aria2
sudo aria2c --conf-path=/etc/aria2/aria2.conf
如果沒有提示任何錯誤信息,那就按ctrl+c停止上面的語句,轉為后台運行:
sudo aria2c --conf-path=/etc/aria2/aria2.conf -D
同時其此句寫到開機啟動中,編輯/etc/rc.loca,如下
4、安裝appache
為了能web管理aria2進行下載,需要安裝yaaw和apache環境。
安裝appach
sudo apt-get install apache2
修改/var/www的權限
chmod 777 /var/www
5、安裝yaaw
從https://github.com/binux/yaaw下載yaaw,點擊右下角的 ,下載后將解壓后的文件夾內內容拷貝到/var/www文件夾下。這時輸入樹莓派IP,如果出現以下頁面,則表示已經正常工作了。
這里可以點add添加下載任務,具體方法不再詳述。
6、實現迅雷的離線下載
很多網站都介紹了aria2實現迅雷離線下載的方法,這里也做一下描述。我以firefox瀏覽器為例,chrome瀏覽器本身有一個迅雷離線增加插件,可以從https://chrome.google.com/webstore/detail/mbl%E8%BF%85%E9%9B%B7%E7%A6%BB%E7%BA%BF%E5%A2%9E%E5%BC%BA%E8%84%9A%E6%9C%AC/bcbkegabebafalcgckcdphlpainejkja進行安裝,安裝后就和firefox基本一樣了。
在firefox里添加一個書簽:
具體為:
===========================================================
名稱為:ThunderLixianExporter
地址為:javascript:void((function(){var d=document;var s=d.createElement('script');s.src='http://s.binux.me/tle.js';s.id='TLE_script';d.body.appendChild(s)})())
==================================================================
登錄迅雷離線網站:lixian.xunlei.com,登錄后,點一下書簽中的ThunderLixianExporter,然后點擊迅雷頁面右上角的配置按鈕(小齒輪)。
在上面的窗口中填寫aria2.json-RPC Path,這個值來自於yaaw那個頁面,具體方法是,輸入樹莓派IP顯示yaaw頁面,點擊右上的配置圖標,如下圖
在set頁面中存在該值:
保存好后,在離線頁面的每行記錄的取回本地后面會出現一個下拉菜單,選擇yaaw就會直接添加到yaaw任務中了。
到此,樹莓派的NAS服務器搭建完成,試了一下效果,還是很滿意的。
六、制作外殼
1、外殼
直接從家里找了一個orico的包裝盒,大小正好合適,而且外殼比較硬,外觀也比較不錯。
2、加裝1602顯示屏
加裝一個1602顯示屏,目的是顯示時間和CPU溫度,當然也可以顯示其它內容,我這里只顯示了這兩項。這里還需要加裝一個電位器(也就是可變電阻,如果沒有,可以加一個10K的電阻)
(1)1602硬件連接
1602共16個端口,只用其中12個,具體接法如下:
LCD1602液晶屏模塊提供了16個引腳,我們只需接其中的12個即可:
VSS,接地 |
VDD,接5V電源 |
VO,液晶對比度調節,接電位器中間的引腳,電位器兩邊的引腳分別接5V和接地。 |
RS,寄存器選擇,接GPIO14 |
RW,讀寫選擇,接地,表示寫模式 |
EN,使能信號,接GPIO15 |
D0,數據位0,4位工作模式下不用,不接 |
D1,數據位1,4位工作模式下不用,不接 |
D2,數據位2,4位工作模式下不用,不接 |
D3,數據位3,4位工作模式下不用,不接 |
D4,數據位4,接GPIO17 |
D5,數據位5,接GPIO18 |
D6,數據位6,接GPIO27 |
D7,數據位7,接GPIO22 |
A,液晶屏背光+,接5V |
K,液晶屏背光-,接地 |
注意:1、這里的VSS、VDD等在有些1602的板子上會標明,有些則只標了數字,如一端寫着1,一端寫着16,1對應的就是VSS端,16對應的就是K端,因此依次連接就可以了。
2、GPIO各端口及5V、接地等端口見下圖,因為我用的是B+的板了,因此這里的圖也是B+的端口圖。
3、連接通電后,1602會亮起,其中一行為黑色方格,一行什么也不顯示,如果全不顯示,可調節一下電位器
(2)代碼
對於1602板子的操作,已經有人做了一個示例,這樣用起來就比較簡單了。示例代碼下載地址:https://github.com/lifanxi/rpimenu.git
,解壓后有Adafruit_CharLCD.py文件,此文件在LCD上會顯示兩行字符:LCD 1602 Test, 123456789ABCDEF。這里只需要在此文件上進行一下修改就可以了。
#!/usr/bin/python
#轉載請注明:@小五義http://www.cnblogs.com/xiaowuyi QQ群:64770604
#
# based on code from lrvick and LiquidCrystal
# lrvic - https://github.com/lrvick/raspi-hd44780/blob/master/hd44780.py
# LiquidCrystal - https://github.com/arduino/Arduino/blob/master/libraries/LiquidCrystal/LiquidCrystal.cpp
#
#from time import sleep
import time,os
class Adafruit_CharLCD:
# commands
LCD_CLEARDISPLAY = 0x01
LCD_RETURNHOME = 0x02
LCD_ENTRYMODESET = 0x04
LCD_DISPLAYCONTROL = 0x08
LCD_CURSORSHIFT = 0x10
LCD_FUNCTIONSET = 0x20
LCD_SETCGRAMADDR = 0x40
LCD_SETDDRAMADDR = 0x80
# flags for display entry mode
LCD_ENTRYRIGHT = 0x00
LCD_ENTRYLEFT = 0x02
LCD_ENTRYSHIFTINCREMENT = 0x01
LCD_ENTRYSHIFTDECREMENT = 0x00
# flags for display on/off control
LCD_DISPLAYON = 0x04
LCD_DISPLAYOFF = 0x00
LCD_CURSORON = 0x02
LCD_CURSOROFF = 0x00
LCD_BLINKON = 0x01
LCD_BLINKOFF = 0x00
# flags for display/cursor shift
LCD_DISPLAYMOVE = 0x08
LCD_CURSORMOVE = 0x00
# flags for display/cursor shift
LCD_DISPLAYMOVE = 0x08
LCD_CURSORMOVE = 0x00
LCD_MOVERIGHT = 0x04
LCD_MOVELEFT = 0x00
# flags for function set
LCD_8BITMODE = 0x10
LCD_4BITMODE = 0x00
LCD_2LINE = 0x08
LCD_1LINE = 0x00
LCD_5x10DOTS = 0x04
LCD_5x8DOTS = 0x00
def __init__(self, pin_rs=14, pin_e=15, pins_db=[17, 18, 27, 22], GPIO = None):
# Emulate the old behavior of using RPi.GPIO if we haven't been given
# an explicit GPIO interface to use
if not GPIO:
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
self.GPIO = GPIO
self.pin_rs = pin_rs
self.pin_e = pin_e
self.pins_db = pins_db
self.GPIO.setmode(GPIO.BCM)
self.GPIO.setup(self.pin_e, GPIO.OUT)
self.GPIO.setup(self.pin_rs, GPIO.OUT)
for pin in self.pins_db:
self.GPIO.setup(pin, GPIO.OUT)
self.write4bits(0x33) # initialization
self.write4bits(0x32) # initialization
self.write4bits(0x28) # 2 line 5x7 matrix
self.write4bits(0x0C) # turn cursor off 0x0E to enable cursor
self.write4bits(0x06) # shift cursor right
self.displaycontrol = self.LCD_DISPLAYON | self.LCD_CURSOROFF | self.LCD_BLINKOFF
self.displayfunction = self.LCD_4BITMODE | self.LCD_1LINE | self.LCD_5x8DOTS
self.displayfunction |= self.LCD_2LINE
""" Initialize to default text direction (for romance languages) """
self.displaymode = self.LCD_ENTRYLEFT | self.LCD_ENTRYSHIFTDECREMENT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode) # set the entry mode
self.clear()
def begin(self, cols, lines):
if (lines > 1):
self.numlines = lines
self.displayfunction |= self.LCD_2LINE
self.currline = 0
def home(self):
self.write4bits(self.LCD_RETURNHOME) # set cursor position to zero
self.delayMicroseconds(3000) # this command takes a long time!
def clear(self):
self.write4bits(self.LCD_CLEARDISPLAY) # command to clear display
self.delayMicroseconds(3000) # 3000 microsecond sleep, clearing the display takes a long time
def setCursor(self, col, row):
self.row_offsets = [ 0x00, 0x40, 0x14, 0x54 ]
if ( row > self.numlines ):
row = self.numlines - 1 # we count rows starting w/0
self.write4bits(self.LCD_SETDDRAMADDR | (col + self.row_offsets[row]))
def noDisplay(self):
""" Turn the display off (quickly) """
self.displaycontrol &= ~self.LCD_DISPLAYON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
def display(self):
""" Turn the display on (quickly) """
self.displaycontrol |= self.LCD_DISPLAYON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
def noCursor(self):
""" Turns the underline cursor on/off """
self.displaycontrol &= ~self.LCD_CURSORON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
def cursor(self):
""" Cursor On """
self.displaycontrol |= self.LCD_CURSORON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
def noBlink(self):
""" Turn on and off the blinking cursor """
self.displaycontrol &= ~self.LCD_BLINKON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
def noBlink(self):
""" Turn on and off the blinking cursor """
self.displaycontrol &= ~self.LCD_BLINKON
self.write4bits(self.LCD_DISPLAYCONTROL | self.displaycontrol)
def DisplayLeft(self):
""" These commands scroll the display without changing the RAM """
self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVELEFT)
def scrollDisplayRight(self):
""" These commands scroll the display without changing the RAM """
self.write4bits(self.LCD_CURSORSHIFT | self.LCD_DISPLAYMOVE | self.LCD_MOVERIGHT);
def leftToRight(self):
""" This is for text that flows Left to Right """
self.displaymode |= self.LCD_ENTRYLEFT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode);
def rightToLeft(self):
""" This is for text that flows Right to Left """
self.displaymode &= ~self.LCD_ENTRYLEFT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
def autoscroll(self):
""" This will 'right justify' text from the cursor """
self.displaymode |= self.LCD_ENTRYSHIFTINCREMENT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
def noAutoscroll(self):
""" This will 'left justify' text from the cursor """
self.displaymode &= ~self.LCD_ENTRYSHIFTINCREMENT
self.write4bits(self.LCD_ENTRYMODESET | self.displaymode)
def write4bits(self, bits, char_mode=False):
""" Send command to LCD """
self.delayMicroseconds(1000) # 1000 microsecond sleep
bits=bin(bits)[2:].zfill(8)
self.GPIO.output(self.pin_rs, char_mode)
for pin in self.pins_db:
self.GPIO.output(pin, False)
for i in range(4):
if bits[i] == "1":
self.GPIO.output(self.pins_db[::-1][i], True)
self.pulseEnable()
for pin in self.pins_db:
self.GPIO.output(pin, False)
for i in range(4,8):
if bits[i] == "1":
self.GPIO.output(self.pins_db[::-1][i-4], True)
self.pulseEnable()
def delayMicroseconds(self, microseconds):
seconds = microseconds / float(1000000) # divide microseconds by 1 million for seconds
time.sleep(seconds)
def pulseEnable(self):
self.GPIO.output(self.pin_e, False)
self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns
self.GPIO.output(self.pin_e, True)
self.delayMicroseconds(1) # 1 microsecond pause - enable pulse must be > 450ns
self.GPIO.output(self.pin_e, False)
self.delayMicroseconds(1) # commands need > 37us to settle
def message(self, text):
""" Send string to LCD. Newline wraps to second line"""
for char in text:
if char == '\n':
self.write4bits(0xC0) # next line
else:
self.write4bits(ord(char),True)
if __name__ == '__main__':
while 1:
lcd = Adafruit_CharLCD()
lcd.clear()
cputemp=os.popen('vcgencmd measure_temp').readline()
sumcputemp=cputemp.replace("temp=","CPU:").replace("'C\n","")
lcdout=time.strftime('%Y-%m-%d %H:%M',time.localtime(time.time()))+"\n"+sumcputemp
lcd.message(lcdout)
time.sleep(30)
3、開面自啟動上面的程序
將以上文件命名為1602.py,保存在/home/pi下面,修改/etc/rc.loca,添加上sudo python /home/pi/1602/py。樹莓派開機時,插上電源,當1602能正常顯示CPU溫度時,表示機器已經啟動完成,各項功能可正常使用。
4、一些其它的想法
(1)本想再加裝一個風扇用來散熱,結果手上沒有3.3V的風扇了,所以就沒加。感興趣的朋友可以自己加一下,因為樹莓派輸出為3.3V,所以最好是直接買3.3V的,如果買5V的,就一定要帶個3.3V的繼電器,要不沒法對風扇控制。如果風扇一直常開那就無所謂了,5V就可以,直接接正負級。我原本的想法是CPU上了50度,風扇再運轉,這樣可以降溫,同時噪音也不會大。
(2)這個家庭服務器搭建起來以后,后面還有很多文章可做,比如可以依托他建立家庭監控系統,裝上兩個攝像頭什么的,也可以做一些外網訪問的設置,這樣就可以直接從外網進行操作了。
[參考文獻]
1、樹莓派變身Aria2下載服務器:http://blog.csdn.net/sonsie007/article/details/18942943
2、樹莓派搭建NAS服務器:http://blog.sina.com.cn/s/blog_9ea6edb90101ci06.html
3、DIY一套NAS+私有雲盤+下載機:http://www.kissthink.com/archive/8897.html
4、樹莓派變身Aria2下載服務器:http://www.eeboard.com/bbs/thread-27396-1-1.html
5、打造增強型Raspberry Pi-液晶屏篇http://www.freemindworld.com/blog/2013/130310_raspberry_pi_with_lcd.shtml