bff.png 

树莓派实现NAS家庭服务器

一、家庭服务器实现的主要功能

1、流媒体播放服务:利用DLNA实现电视、手机、电脑播放其上面的媒体文件。

2、文件共享:利用samba实现手机、电脑等终端与服务器的文件共享。

3、自动下载:利用aria2c实现自动下载。

先上几张效果图:

用orico的包装盒做了个机箱。

262138045271003.jpg

 

内部效果,线还是有些凌乱

放在桌上,感觉还不错,呵呵

二、准备工作

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

1

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,结果为:

2

这里表示已挂载成功。

3、解决硬盘的自动挂载

      每次树莓派重启或者硬盘插拔都需要对硬盘进行重新挂载,比较麻烦,因此需要自动挂载。这里要修改/etc/fstab文件。有人喜欢用vi进行编辑,我比较喜欢直接vnc连接上后,用编辑器进行编辑。

image

 

可以看到,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,如下

4

5、测试samba安装效果

在windows计算机上,打开我的电脑,在左下角网络点右键,选映射网络驱动器

image

点击完成会提示输入用户名和密码,这里输入设置的共享用户名和密码。

image

 

最后在计算机下会出现共享的文件夹,点开文件夹,新建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

返回如下结果为正常。

image

5、在电脑上进行播放

先在树莓派以上对应的video等文件夹内存上一些文件(可利用samba直接从电脑上考入),然后返回到计算机进行操作。

点击我的电脑下面的网络,出现媒体设备

image

双击进入媒体播放器,在左边的列表栏下方其它媒体库中出现raspberrypi:root,点击后,可选择音乐,视频等。

image

 

 

这时双击就可以欣赏了。

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,如下

3

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,点击右下角的image ,下载后将解压后的文件夹内内容拷贝到/var/www文件夹下。这时输入树莓派IP,如果出现以下页面,则表示已经正常工作了。

image

这里可以点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里添加一个书签:

image

具体为:

===========================================================

名称为: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,然后点击迅雷页面右上角的配置按钮(小齿轮)。

image

image

image

在上面的窗口中填写aria2.json-RPC Path,这个值来自于yaaw那个页面,具体方法是,输入树莓派IP显示yaaw页面,点击右上的配置图标,如下图

image

在set页面中存在该值:

image

保存好后,在离线页面的每行记录的取回本地后面会出现一个下拉菜单,选择yaaw就会直接添加到yaaw任务中了。

image

image

 

到此,树莓派的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。这里只需要在此文件上进行一下修改就可以了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
#!/usr/bin/python
#<span style="font-family: 宋体; font-size: 12px;">转载请注明:@小五义<a href="http://www.cnblogs.com/xiaowuyi">http://www.cnblogs.com/xiaowuyi</a>   QQ群:64770604</span>
#
# based on code from lrvick and LiquidCrystal
#
 
#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)