【重写】树莓派驱动的b站点播台

之前做的那个挺。。简陋的点播台。。。终于被我废弃了2333

我又写了个新的

已经有的功能为:

弹幕点歌

弹幕点MV

弹幕反馈(发送弹幕)

旧版实现的视频推流功能

自定义介绍字幕

基础的歌词显示

切歌

显示排队歌曲

下载时的cpu温度

闲时随机播放预留歌曲

播放音乐时背景图片随机选择

可点播b站任意视频(会员限制除外)

具体的大家直接去gayhub看readme吧,我写的很详细的~

https://github.com/chenxuuu/24h-raspberry-live-on-bilibili

直播间:http://live.bilibili.com/16703

欢迎捧场哦~

树莓派驱动SSD1331 OLED屏幕

本文内容基本来源于https://luma-oled.readthedocs.io/en/latest/index.html(英文注意)

之前树莓用了一块ssd1306驱动的黑白oled屏,可惜坏掉了,所以我又买了块彩色的(要吃土了

昨天买,今天就到了,好在资料找起来非常顺利,简简单单就找到了可用的库

效果如下:

(↑来自Lumia950XL)

接下来就简单讲下树莓驱动这块彩屏吧,因为有现成的库,所以步骤十分简单

首先是引脚连接,我直接把官方推荐的接发复制过来就好了:

SIP接法:

OLED Pin Name Remarks RPi Pin RPi Function
1 VCC +3.3V Power P01-17 3V3
2 GND Ground P01-20 GND
3 D0 Clock P01-23 GPIO 11 (SCLK)
4 D1 MOSI P01-19 GPIO 10 (MOSI)
5 RST Reset P01-22 GPIO 25
6 DC Data/Command P01-18 GPIO 24
7 CS Chip Select P01-24 GPIO 8 (CE0)

I2C接法:

OLED Pin Name Remarks RPi Pin RPi Function
1 GND Ground P01-6 GND
2 VCC +3.3V Power P01-1 3V3
3 SCL Clock P01-5 GPIO 3 (SCL)
4 SDA Data P01-3 GPIO 2 (SDA)

具体接法解释请点我前往官网文档

我这里用的是SPI接法,另外附一张树莓2B引脚图(去年发过了233):

连好之后,记得开启SPI/I2C接口:

sudo raspi-config

设置完之后,重启:

sudo reboot

接下来安装我们要用到的luma库:

sudo apt-get install python-dev python-pip libfreetype6-dev libjpeg-dev
sudo -H pip install --upgrade pip
sudo apt-get purge python-pip
sudo -H pip install --upgrade luma.oled

一句一句执行完毕,安装成功后,我们接下来装上示例程序:

sudo usermod -a -G i2c,spi,gpio pi
sudo apt-get install python-dev python-pip libfreetype6-dev libjpeg-dev
sudo apt-get install libsdl-dev libportmidi-dev libsdl-ttf2.0-dev libsdl-mixer1.2-dev libsdl-image1.2-dev
sudo -H pip install --upgrade pip setuptools
sudo apt-get purge python-pip
git clone https://github.com/rm-hull/luma.examples.git
cd luma.examples
sudo -H pip install -e .

同样一句一句执行成功后,我们就可以测试了。

cd examples
sudo ./demo.py -d ssd1331 -i spi --width 96 --heig 64
#请根据自己的实际情况更改参数

另一张效果图:

教程完毕

希望本文能让需要本教程的朋友少走一些弯路

树莓派实现24小时直播点歌功能

在这篇文章发布之前,我在it水家已经投过一稿了:http://www.ithome.com/html/win10/311694.htm

另外上一篇不带点歌功能,只有推流功能的教程:https://www.chenxublog.com/2017/06/02/raspi-live-24h-bilibili.html

如果是零基础,建议先看一遍上面那两篇文章,如果是使用代码,请参考本文。这几天代码已经更新多次。

我写的代码只能保证可用,毕竟我是业余的233333欢迎大神拿我的思路进行优化

github:https://github.com/chenxuuu/24h-raspberry-live-on-bilibili

php端运行的代码(最后更新于2017.6.4晚):

<head>
<meta charset="utf-8">
</head>
<body>
<form action="" method="post">
<p>一个简陋的点歌台23333</p>
<p>搜索结果来自网易云</p>
<p>输入歌曲名搜索歌曲:<input type="text" name="song" /></p>
<p><input type="submit" name="sub" value="搜索" /></p>
</form>
<form action="" method="post">
<p>或者直接输入id点歌(推荐!)<br/>实例(红色部分为id):<br/>http://music.163.com/song/<font color="red">26489014</font>/?userid=261620056<br/>http://music.163.com/#/song?id=<font color="red">32477053</font></p>
<p>id:<input type="text" name="id" /></p>
<p><input type="submit" name="sub" value="查看" /></p>
</form>
by 晨旭/chenxublog.com | running on Raspberry Pi 2 Model B<br/>直播间地址:http://live.bilibili.com/16703<br/><br/><br/>
当前状态:<div id='t'></div>
<?php
require_once 'NeteaseMusicAPI_mini.php';

function get_url_id($id)
{
    $api = new NeteaseMusicAPI();
    $result = $api->url($id);
    $result = str_replace("[","",$result);
    $result = str_replace("]","",$result);
    $data=json_decode($result, true);
    return $data['data']['url'];
}
function urlcheck($url)
{
    $counttemp=0;
    for($counttemp=1;$counttemp<31;$counttemp++)
    {
        if (file_exists($counttemp.'.txt') && $url==file_get_contents($counttemp.'.txt'))   
        {   
            return false;
        }
    }
    return true;
}
function netease_http($url)
{
    $refer = "http://music.163.com/";
    $header[] = "Cookie: " . "appver=1.5.0.75771;";
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
    curl_setopt($ch, CURLOPT_REFERER, $refer);
    $cexecute = curl_exec($ch);
    curl_close($ch);
    if ($cexecute)
    {
        $result = json_decode($cexecute, true);
        return $result;
    }
    else
    {
        return false;
    }
}
function getStatus($url){
    if($headers = @get_headers($url)){
            $status  = $headers[0];
            $statusno= false;
            if(preg_match_all('%HTTP/1\.1 ([\d]{3})%i',$status,$matches)){
                    $statusno = $matches[1][0];
            }
            return $statusno;
    }
        return false;
}

if(!empty($_POST['song'])){

$song=$_POST['song'];
echo '搜索关键词:'.$song.'<br/>=========================================================<br/>';
$url = "http://s.music.163.com/search/get/?type=1&s=".$song;
$response = netease_http($url);
$counttemp=0;
for($counttemp=0;$counttemp<10;$counttemp++)
{
    if(getStatus($response['result']['songs'][$counttemp]['audio'])=='200')
    {
        echo $response['result']['songs'][$counttemp]['name'].'<img src="'.$response['result']['songs'][$counttemp]['album']['picUrl'].'" height="100"/><a href="?down='.$response['result']['songs'][$counttemp]['audio'].'">就选这首了</a><br/>试听:<audio src="'.$response['result']['songs'][$counttemp]['audio'].'" controls="controls"></audio><br/>=========================================================<br/>';
    }
    else
    {
        echo '第'.($counttemp+1).'首歌曲获取失败(歌曲失效/版权问题/网络抽风)<br/>=========================================================<br/>';
    }
}

}
elseif(!empty($_POST['id'])){
    echo '试听:<audio src="'.get_url_id($_POST['id']).'" controls="controls"></audio><br/><a href="?down='.get_url_id($_POST['id']).'">就选这首了</a>';
}
elseif(!empty($_GET['down']) && empty($_GET['write']) && strpos($_GET['down'],"music.126.net")!=false && getStatus($_GET['down'])=='200')
{
    echo '当前可供选择的空闲的序列(注意,直播是从第1首到第30首按顺序播放的。歌曲长度最大限制六分钟,超过将丢弃。):<br/>';
    $counttemp=0;
    for($counttemp=1;$counttemp<31;$counttemp++)
    {
        if($counttemp%5==0)
        {
            echo '<br/>';
        }
        if (!file_exists($counttemp.'.txt'))
        {
            echo '<a href="?write='.$counttemp.'&down='.$_GET['down'].'">换掉第'.$counttemp.'首歌</a>(<font color="green">可以换歌</font>)|';
        }
        else
        {
            echo '第'.$counttemp.'首歌(<font color="red">排队渲染中</font>)|';
        }
    }
}
elseif(!empty($_GET['write']) && !empty($_GET['down']) && urlcheck($_GET['down']) && getStatus($_GET['down'])=='200')
{
    if(!file_exists($_GET['write'].'.txt'))
    {
        //file_put_contents('songs/'.$_GET['write'].'.txt', $_GET['down']);
        $myfile = fopen($_GET['write'].'.txt', "w") or die("Unable to open file!");
        fwrite($myfile, $_GET['down']);
        fclose($myfile);
        echo '第'.$_GET['write'].'首歌曲的渲染请求提交成功!<a href="index.php">返回首页</a>';
    }
    else
    {
        echo '啊哦!这个序号已经有人选中了!正在渲染!';
    }
}
else
{
    echo '树莓当前负载状态(注意,直播是从第1首到第30首按顺序播放的):<br/>';
    $counttemp=0;
    for($counttemp=1;$counttemp<31;$counttemp++)
    {
        if($counttemp%5==0)
        {
            echo '<br/>';
        }
        if (!file_exists($counttemp.'.txt'))
        {
            echo '第'.$counttemp.'首歌(<font color="green">可以换掉</font>)|';
        }
        else
        {
            echo '第'.$counttemp.'首歌(<font color="red">排队渲染中</font>)|';
        }
    }
}

?>
<script type="text/javascript" src="now.js"></script>
</body>

同目录下需要新建一个NeteaseMusicAPI_mini.php,文件取自:

https://github.com/metowolf/NeteaseCloudMusicApi/blob/master/weapi/NeteaseMusicAPI_mini.php

php文件我全部放到了/usr/share/nginx/www/songs目录下。

渲染处理部分:

ff.py(路径/home/pi/songs/)

# -*- coding:utf-8 -*-
import os
import urllib
import eyed3
import time
for i in range(1, 30+1):
  if(os.path.exists(str(i)+'.mp3')):
    os.remove(str(i)+'.mp3')
    os.remove('/usr/share/nginx/www/songs/'+str(i)+'.txt')
  if(os.path.exists('/usr/share/nginx/www/songs/'+str(i)+'.txt')):
    f = open('/usr/share/nginx/www/songs/'+str(i)+'.txt')
    content = f.read()
    fileout = file('/usr/share/nginx/www/songs/now.js','w')
    fileout.write('t.innerHTML=("正在下载'+str(i)+'.mp3")')
    fileout.close()
    urllib.urlretrieve(content, str(i)+'.mp3')
    print('download success')
    xx=eyed3.load(str(i)+'.mp3')
    seconds=xx.info.time_secs
    if(seconds<600):
      fileout = file('/usr/share/nginx/www/songs/now.js','w')
      fileout.write('t.innerHTML=("正在生成'+str(i)+'.mp4的一图流视频 第一步/共两步")')
      fileout.close()
      os.system('ffmpeg -loop 1 -r 1 -t '+str(seconds)+' -f image2 -i '+str(i)+'.png -vcodec libx264 -pix_fmt yuv420p -crf 24 -y SinglePictureVideo.mp4')
      fileout = file('/usr/share/nginx/www/songs/now.js','w')
      fileout.write('t.innerHTML=("正在将'+str(i)+'.flv的视频与音频合为一体 第二步/共两步")')
      fileout.close()
      os.system('ffmpeg -i SinglePictureVideo.mp4 -i '+str(i)+'.mp3 -c:v copy -c:a aac -y '+str(i)+'.flv')
      os.remove(str(i)+'.mp3')
      os.remove('SinglePictureVideo.mp4')
      os.remove('/usr/share/nginx/www/songs/'+str(i)+'.txt')
      fileout = file('/usr/share/nginx/www/songs/now.js','w')
      fileout.write('t.innerHTML=("成功渲染'+str(i)+'.flv!60秒后会开始渲染下一个视频")')
      fileout.close()
    else:
      os.remove(str(i)+'.mp3')
      os.remove('/usr/share/nginx/www/songs/'+str(i)+'.txt')
    time.sleep(60)
time.sleep(10)

ff.sh(路径/home/pi/songs/)

#!/bin/bash
while true
do
 python ff.py
done

路径/home/pi/songs/下还有1-30.png文件用于作为视频内容

启动ffmpeg部分:

playlist.txt请自己写吧,规则见https://trac.ffmpeg.org/wiki/Concatenate

live.sh(与playlist.txt同级)

#!/bin/bash
while true
do
  ffmpeg -re -f concat -safe 0 -i playlist.txt -vcodec copy -acodec aac -b:a 192k -f flv "你的直播地址和码"
done

理论上到这里就结束了,但是网络老断,那我只能暴力检测和强制重启推流来解决了

断网自动重推部分:

net.py

#coding:utf8
'''python3 code
author's email: chenyan@feling.net
通过统计ifconfig命令的输出,计算当前网速
'''

import logging
logging.basicConfig(level=logging.INFO,
                format='%(message)s',
                #filename='speed',
                #filemod='w'
                )

import os, sys, time
import re

def get_total_tx_bytes(interface, isCN):
    grep = '发送字节' if isCN else '"TX bytes"'
    r = os.popen('ifconfig '+interface+' | grep '+grep).read()
    total_bytes = re.sub('(.+:)| \(.+','',r)
    return int(total_bytes)

def get_total_rx_bytes(interface, isCN):
    grep = '接收字节' if isCN else '"RX bytes"'
    r = os.popen('ifconfig '+interface+' | grep '+grep).read()
    total_bytes = re.sub(' \(.+','',r)
    total_bytes = re.sub('.+?:','',total_bytes)
    return int(total_bytes)


if __name__=='__main__':
    interface = sys.argv[1]
    get_total_bytes = get_total_tx_bytes if sys.argv[2]=='tx' else get_total_rx_bytes
    isCN = True if sys.argv[3]=='cn' else False
    freq = int(sys.argv[4])
    low_count = 0
    for i in range(1, 10 + 1):
        last = get_total_bytes(interface, isCN)
        time.sleep(freq)
        increase = get_total_bytes(interface, isCN) - last
        logging.info(str(increase/freq/1000))
        speed_now = increase/freq/1000
        if(speed_now < 5):
            low_count = low_count +1
    if(low_count > 5):
        os.system('killall ffmpeg')
        time.sleep(1)
        os.system('killall ffmpeg')
        time.sleep(1)
        os.system('killall ffmpeg')
        logging.info('666')
    else:
        logging.info('ok!')

net.sh

#!/bin/bash
while true
do
python net.py eth0 tx false 1
done

这样所有我用的脚本都贴在这里了,启动方式就是扔几个screen就行了

screen sh live.sh
#按ctrl+a,ctrl+d
screen sh net.sh
#按ctrl+a,ctrl+d
cd songs/
screen sh ff.sh
#按ctrl+a,ctrl+d

完毕~

技术不高,如有错误,请指出,谢谢o(* ̄▽ ̄*)ブ

利用树莓派实现b站24小时音乐直播

本教程参考了以下文章:

ffmpeg-rtmp搞事指南

树莓派安装ffmpeg

使用FFmpeg在B站直播的姿势

第一步:安装ffmpeg

先安装解码器

git clone git://git.videolan.org/x264
cd x264
./configure --host=arm-unknown-linux-gnueabi --enable-static --disable-opencl
make
sudo make install
cd ..
rm -rf x264

再安装ffmpeg

git clone git://source.ffmpeg.org/ffmpeg.git
cd ffmpeg
sudo ./configure --arch=armel --target-os=linux --enable-gpl --enable-libx264 --enable-nonfree
make
sudo make install
cd ..
rm -rf ffmpeg

有两个地方需要注意:

  1. git下载慢的话可以先导入到gitosc再clone

  2. 编译ffmpeg的过程在树莓上十分漫长。。。我的花了两个半小时,所以建议使用screen扔到后台,以免断网导致需要重来

第二步:准备直播所需要的视频文件

我们需要制作一个只有背景音乐的视频,一般会做一个一图流的视频(整个视频画面就是一张图)

这里我使用了小丸工具箱(点我下载

先要合并一堆mp3文件,具体方法:

  1. 全选这些mp3文件

  2. 右击添加到压缩文件

  3. 文件类型选择zip,压缩类型选择“储存”

  4. 将压缩好的xxx.zip拓展名改为.mp3即可(是不是很神奇hhhhh)

接下来照一张图片,打开小丸工具箱,选择“常用”选项卡

把图片拖到“一图流”的“图片”框里,把整合好的音乐拖到“音频”框里,点击“压制”

这样我们就得到了我们需要的文件

第三步:进行推流

把文件传到树莓上,使用下面的命令即可推流

ffmpeg -re -i "1.mp4" -vcodec copy -acodec aac -b:a 192k -f flv "你的rtmp地址/你的直播码"

由于此命令只能运行一次,播放完就停了,所以要实现无限循环播放的话就需要编写一个sh文件,内容如下

#!/bin/bash
while true
do
ffmpeg -re -i "1.mp4" -vcodec copy -acodec aac -b:a 192k -f flv "你的rtmp地址/你的直播码"
done

保存为live.sh,使用下面的命令运行即可(如果没有screen,先使用sudo apt-get screen 安装)

screen nohup sh live.sh &

搭建好的直播间:http://live.bilibili.com/16703

不保证我以后的直播内容不变哈

记校园网代理中转网站的搭建过程

学校的教务系统从16年开始便只能用校内网或者是宿舍的移动网打开登陆,去年的时候我用树莓搭建了一个中转(毕竟树莓闲置着的,另外科创连的是校内网)

当时采用的是nginx+Glype当作服务端,采用的是花生壳提供的内网穿透服务,不过说实话花生壳提供的免费服务确实不咋地,后来我用了natapp.cn提供的ngrok内网转发,五块钱一个月那个。现在采用的是ngrok.cc提供的免费ngrok服务,网站总体所需流量不大,所以用这个的话效果也还可以。

下面我简单讲一下搭建的流程吧,主要就是两点:搭建nginx+php和运行ngrok服务

我在这里用的是树莓派2B,系统镜像是2015-01-31-raspbian

首先把所有该初始化的东西搞完,我们就可以开始装nginx+php了

首先安装nginx:

sudo apt-get install nginx

启动nginx:

sudo /etc/init.d/nginx start

接下来修改配置文件:

sudo nano /etc/nginx/sites-available/default

在“listen 80”那个大括号里,把“index index.html index.htm”后面加上“index.php”:

listen 80;
root /usr/share/nginx/www;
index index.html index.htm index.php;

然后找到php那一段,改成下面这样:

location ~ .php$ {
 fastcgi_pass unix:/var/run/php5-fpm.sock;
 fastcgi_index index.php;
 include fastcgi_params;
}

改完配置文件之后,保存关闭

安装php和必要组件:

sudo apt-get install php5-fpm php5-sqlite

重启nginx:

sudo /etc/init.d/nginx reload

到这里的话,nginx服务器搭建过程基本上都是抄的“树莓派开发系列教程7——树莓派做web服务器(nginx、Apache)”这篇文章里的东西,但是到后面你会发现Glype无法运行,原因其实就是php里的curl组件没装上,所以我们还需要执行以下命令:

sudo apt-get install php5-curl

你要是不嫌麻烦可以把所有需要的组件都装上:

apt-get install php5-mysql php5-curl php5-gd php5-intl php-pear php5-imagick php5-imap php5-mcrypt php5-memcache php5-ming php5-ps php5-pspell php5-recode php5-snmp php5-sqlite php5-tidy php5-xmlrpc php5-xsl

至此,nginx+php服务器搭建完毕,接下来只要把Glype扔到/usr/share/nginx/www里就能正常运行了,当然我改了好多东西

接下来解决外网访问的问题,我就解释一下ngrok的用法

其实用法很简单(如果你不想自己搭建服务器的话)

用ngrok.cc提供的服务举例:

首先到后台开通一个隧道,隧道协议选择“http”、本地端口写你前面设置的端口(前面配置文件里写的是80)“127.0.0.1:80”其他的按照自己的需求来写就行

然后下载官网提供的软件,树莓的话要选linux arm版,

下载之后先给777权限:

sudo chmod 777 xxxx#文件名

然后按教程运行就行了:

./sunny clientid xxxxxxxxxxxxxx

这样的话其实整个代理已经搭建完了,但是有一个重要的问题没有解决:这个服务一但遇到了停电或者是网络不稳定的情况之后,必须手动重启才可以,这样的话就会变得相当棘手。想象一下,你寒假回家了,但是服务器挂了,你找谁给你开启服务啊

所以我加了两个自动检测的脚本

一个是一分钟运行一次的“autorun.sh”,可以保证ngrok服务一直处于开启状态:

#!/bin/sh
ps -fe|grep sunny |grep -v grep
if [ $? -ne 0 ]
then
echo "start process....."
screen -dm nohup sudo /home/pi/sunny clientid xxxxxxxxxxxxxxxx &
else
echo "runing....."
fi

另一个是十分钟运行一次的“check.sh”,用于保证网站可访问,当打不开时会自动重启软件:

#!/bin/sh
result=`curl http://wfkj.papapoi.com/check.php -s`
if [ $result == "ok" ];then
echo "ok"
else
sudo killall sunny
screen -dm nohup sudo /home/pi/sunny clientid xxxxxxxxxxxxxxxx &
fi

最后打开定时任务列表:

crontab -e

加上这俩货:

* * * * * /home/pi/autorun.sh &
*/10 * * * * sudo sh /home/pi/check.sh &

大功告成!

最后把做好的网址发在这里:http://wfkj.papapoi.com/

从此,随时随地都可以让大家感受到挂科的喜悦了(雾

树莓派驱动12464OLED播放Bad Apple

效果查看:

屏幕驱动安装见 http://www.chenxublog.com/2016/08/20/raspi-12864-spi-oled.html

本视频程序下载:https://pan.baidu.com/s/1miMfwM0 密码: f3kx

制作流程:视频经过FFmpeg转换为每帧图片→通过signpics处理为128×64分辨率的图片→转为png→通过pngtopnm命令转为ppm序列图片→程序调用显示

附赠一个可以提高姿势水平的视频程序:

点我预览效果

程序下载:http://chenxublog.ctfile.com/fs/pHJ158469949

树莓派驱动SPI接口的12864OLED屏

昨天玩了玩18b20,然后今天想起来还有两块从车上扣下来的12864小OLED屏,所以准备研究下

然后发现这个库依旧依旧有人写好了23333

(怪不得树莓那么多人玩)

以下教程不完全参考自(毕竟理论和实际会有出入233):http://www.dfrobot.com.cn/community/thread-13396-1-1.html

先看看效果图:

这个功能和某宝上的“CPU Info”差不多啊。。。(黑粗翔

下面开始教程:

0x00、硬件连接√:

照例,贴一张树莓的针脚分布图:

按照下面的来对应连接:

GND 任意一个0v
VCC 任意一个5v/3.3v
D0(SCLK) 23号物理接口
D1(MOSI) 19号物理接口
RST 11号物理接口
DC(数据与命令选择) 13号物理接口
CS(SPI 片选) 24号物理接口

最好整齐的连上,下图是错误的示范:

请大家不要连的像我的一样这么杂乱(笑

0x01、启动SPI服务

在树莓开机后输入命令:

sudo raspi-config

选“Advanced Options”这一项,找到“SPI”和“I2C”,开启就好。

然后重启树莓派:

sudo reboot

重启后运行指令:

cd /dev
ls -al

如果你看到了这两项,就说明刚才的设置成功了:

0x02、安装SPI屏幕的库:

先安装必要组件:

sudo apt-get update
sudo apt-get install build-essential python-dev python-pip
sudo pip install RPi.GPIO
sudo apt-get install python-imaging python-smbus
sudo apt-get install git

然后,将SPI屏驱动函数的库下载下来:

cd ~
git clone https://git.oschina.net/chenxuuu/Adafruit_Python_SSD1306.git
#这里我换成了国内源,为的是速度快一些,原地址:https://github.com/adafruit/Adafruit_Python_SSD1306.git

安装Python的SPI驱动模块:

cd Adafruit_Python_SSD1306
sudo python setup.py install

0x03、测试程序:

测试Python代码如下:

#!/usr/bin/python/
# coding: utf-8
import time
import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306
import Image
import ImageDraw
import ImageFont

# Raspberry Pi pin configuration:
RST = 17
# Note the following are only used with SPI:
DC = 27
SPI_PORT = 0
SPI_DEVICE = 0

# 128x64 display with hardware SPI:
disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))

# Initialize library.
disp.begin()

# Clear display.
disp.clear()
disp.display()

# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
width = disp.width
height = disp.height
image = Image.new('1', (width, height))

# Get drawing object to draw on image.
draw = ImageDraw.Draw(image)

# Draw a black filled box to clear the image.
draw.rectangle((0,0,width,height), outline=0, fill=0)

# Draw some shapes.
# First define some constants to allow easy resizing of shapes.
padding = 1
top = padding
x = padding
# Load default font.
font = ImageFont.load_default()

# Alternatively load a TTF font.
# Some other nice fonts to try: http://www.dafont.com/bitmap.php
#font = ImageFont.truetype('Minecraftia.ttf', 8)

# Write two lines of text.
draw.text((x, top), 'This is first line', font=font, fill=255)
draw.text((x, top+10), 'This is second line', font=font, fill=255)
draw.text((x, top+20), 'This is third line', font=font, fill=255)
draw.text((x, top+30), 'This is fourth line', font=font, fill=255)
draw.text((x, top+40), 'This is fifth line', font=font, fill=255)
draw.text((x, top+50), 'This is last line', font=font, fill=255)

# Display image.
disp.image(image)
disp.display()

至于我用的代码,我也给大家贴出来:

#!/usr/bin/python/
# coding: utf-8
import time
import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306
import Image
import ImageDraw
import ImageFont

import socket
import fcntl
import struct
def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,  # SIOCGIFADDR
        struct.pack('256s', ifname[:15])
    )[20:24])
	

while True:

	# 打开温度传感器文件
	tfile = open("/sys/bus/w1/devices/28-0115a83f87ff/w1_slave")
	# 读取文件所有内容
	text = tfile.read()
	# 关闭文件
	tfile.close()
	# 用换行符分割字符串成数组,并取第二行
	secondline = text.split("\n")[1]
	# 用空格分割字符串成数组,并取最后一个,即 t=23000
	temperaturedata = secondline.split(" ")[9]
	# 取 t = 后面的数值,并转换为浮点型
	temperature = float(temperaturedata[2:])
	# 转换单位为摄氏度
	temperature = temperature / 1000

	# Raspberry Pi pin configuration:
	RST = 17
	# Note the following are only used with SPI:
	DC = 27
	SPI_PORT = 0
	SPI_DEVICE = 0

	# 128x64 display with hardware SPI:
	disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))

	# Initialize library.
	disp.begin()

	# Clear display.
	disp.clear()
	disp.display()

	# Create blank image for drawing.
	# Make sure to create image with mode '1' for 1-bit color.
	width = disp.width
	height = disp.height
	image = Image.new('1', (width, height))

	# Get drawing object to draw on image.
	draw = ImageDraw.Draw(image)

	# Draw a black filled box to clear the image.
	draw.rectangle((0,0,width,height), outline=0, fill=0)

	# Draw some shapes.
	# First define some constants to allow easy resizing of shapes.
	padding = 1
	top = padding
	x = padding
	# Load default font.
	font = ImageFont.load_default()

	# Alternatively load a TTF font.
	# Some other nice fonts to try: http://www.dafont.com/bitmap.php
	#font = ImageFont.truetype('Minecraftia.ttf', 8)

	# Write two lines of text.
	draw.text((x, top), "Chenxu's Raspebrry Pi", font=font, fill=255)
	draw.text((x, top+10), time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time())), font=font, fill=255)
	draw.text((x, top+20), 'The temperature:' + str(temperature), font=font, fill=255)
	draw.text((x, top+30), "Pi's ip:", font=font, fill=255)
	draw.text((x, top+40), 'eth  ip:'+ get_ip_address('eth0'), font=font, fill=255)
	draw.text((x, top+50), 'wlan ip:'+ get_ip_address('lo'), font=font, fill=255)

	# Display image.
	disp.image(image)
	disp.display()
	time.sleep(5)

教程完毕√

更新:

加了个显示内存占用的功能,代码如下

#!/usr/bin/python/
# coding: utf-8
from __future__ import print_function
from collections import OrderedDict

import time
import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306
import Image
import ImageDraw
import ImageFont

import socket
import fcntl
import struct
def get_ip_address(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    return socket.inet_ntoa(fcntl.ioctl(
        s.fileno(),
        0x8915,  # SIOCGIFADDR
        struct.pack('256s', ifname[:15])
    )[20:24])
	
def meminfo():
    meminfo = OrderedDict()
    with open('/proc/meminfo') as f:
        for line in f:
            meminfo[line.split(':')[0]] = line.split(':')[1].strip()
    return (format(meminfo['MemFree']) + '/' + format(meminfo['MemTotal']))

while True:
	
	# 打开温度传感器文件
	tfile = open("/sys/bus/w1/devices/28-0115a83f87ff/w1_slave")
	# 读取文件所有内容
	text = tfile.read()
	# 关闭文件
	tfile.close()
	# 用换行符分割字符串成数组,并取第二行
	secondline = text.split("\n")[1]
	# 用空格分割字符串成数组,并取最后一个,即 t=23000
	temperaturedata = secondline.split(" ")[9]
	# 取 t = 后面的数值,并转换为浮点型
	temperature = float(temperaturedata[2:])
	# 转换单位为摄氏度
	temperature = temperature / 1000

	# Raspberry Pi pin configuration:
	RST = 17
	# Note the following are only used with SPI:
	DC = 27
	SPI_PORT = 0
	SPI_DEVICE = 0

	# 128x64 display with hardware SPI:
	disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))

	# Initialize library.
	disp.begin()

	# Clear display.
	disp.clear()
	disp.display()

	# Create blank image for drawing.
	# Make sure to create image with mode '1' for 1-bit color.
	width = disp.width
	height = disp.height
	image = Image.new('1', (width, height))

	# Get drawing object to draw on image.
	draw = ImageDraw.Draw(image)

	# Draw a black filled box to clear the image.
	draw.rectangle((0,0,width,height), outline=0, fill=0)

	# Draw some shapes.
	# First define some constants to allow easy resizing of shapes.
	padding = 1
	top = padding
	x = padding
	# Load default font.
	font = ImageFont.load_default()

	# Alternatively load a TTF font.
	# Some other nice fonts to try: http://www.dafont.com/bitmap.php
	#font = ImageFont.truetype('Minecraftia.ttf', 8)

	# Write two lines of text.
	draw.text((x, top), "Chenxu's Raspebrry Pi", font=font, fill=255)
	draw.text((x, top+10), time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(time.time())), font=font, fill=255)
	draw.text((x, top+20), 'The temperature:' + str(temperature), font=font, fill=255)
	draw.text((x, top+30), meminfo(), font=font, fill=255)
	draw.text((x, top+40), 'eth  ip:'+ get_ip_address('eth0'), font=font, fill=255)
	draw.text((x, top+50), 'wlan ip:'+ get_ip_address('lo'), font=font, fill=255)

	# Display image.
	disp.image(image)
	disp.display()
	time.sleep(5)

树莓派读取18b20温度

实验室扔着一个同组给的18B20。。。

然后在实验室还闲的无聊,就像显示个温度玩玩。

结果嘛。。。教程都是比较坑的。。。而且老方法还有些问题。。。

下面是显示结果:

话说今天感觉好凉快的说。。。。

0x00、连接硬件:

硬件基本连接就看下面那张图了。。(从别的地方搬来的233)

我连的样子:

(好难看啊23333)

0x01、启动必要服务:

网上给的教程就像下面的一样

运行两个命令:

sudo apt-get update
sudo apt-get upgrade

启动服务

sudo modprobe w1-gpio
sudo modprobe w1-therm

测试是否生效

cd /sys/bus/w1/devices/
ls

然后。。。这什么都没显示啊(摔!

后来发现这篇文章:http://blog.csdn.net/vvbbbbb/article/details/52053293

要多加两个步骤:

sudo nano /boot/config.txt

然后在末尾加上一句:

dtoverlay=w1-gpio

按ctrl+o保存,然后ctrl+x退出

重启设备:

sudo reboot

然后开机之后就可以按照之前的语句执行了:

sudo modprobe w1-gpio
sudo modprobe w1-therm
cd /sys/bus/w1/devices/
ls

此时会显示你的设备编号(如果前面步骤你都做对了的话。。。):

记住这个编号(28-0115a83f87ff),后面还要用到。

然后测试一下温度是否读出来了:

cd 28-0115a83f87ff   #按你的编号来
cat w1_slave

显示:

第二行的 t=35562 就是当前的温度值,要换算成摄氏度,除以 1000。

0x02、在py里读取温度:

我们回到home:

cd ~

新建t.py:

sudo nano t.py

放入以下代码:

# -*- coding:utf-8 -*-
# 打开温度传感器文件
tfile = open("/sys/bus/w1/devices/28-0115a83f87ff/w1_slave")
# 读取文件所有内容
text = tfile.read()
# 关闭文件
tfile.close()
# 用换行符分割字符串成数组,并取第二行
secondline = text.split("\n")[1]
# 用空格分割字符串成数组,并取最后一个,即 t=23000
temperaturedata = secondline.split(" ")[9]
# 取 t = 后面的数值,并转换为浮点型
temperature = float(temperaturedata[2:])
# 转换单位为摄氏度
temperature = temperature / 1000
# 打印值
print temperature

按ctrl+o保存,然后ctrl+x退出

然后用命令:

python t.py

看,温度是不是出来了啊~

(怎么又比刚才升温了擦)

教(bi)程(ji)完毕~

简单几步把树莓派做成离线下载器~

咱这里有个树莓派。。。放着也是放着,不如利用起来做个离线下载器玩玩~

准备:带整套装备的树莓派2B、32GU盘

0x00烧系统/配置树莓派:

烧系统什么的就不多说了:http://www.chenxublog.com/2015/09/21/树莓派如何安装系统?.html

然后连上网线(这里不推荐无线,非要用也不拦你23333:http://www.chenxublog.com/2015/09/26/piwithwlan.html

远程连接:用户名pi,密码raspberry

然后进行配置:

sudo raspi-config

选中“1 Expand Filesystem”一路按回车,将根分区扩展到整张 SD 卡

后面的大家看着办吧→_→ 设置好多

注意记得改密码,并且将语言改了,选择 en_US.UTF-8 和 zh_CN.UTF-8。在 Default locale for the -system environment:中,选择 zh_CN.UTF-8

然后装中文字体(没屏幕的不用管)

sudo apt-get update
sudo apt-get install ttf-wqy-zenhei ttf-wqy-microhei

0x01挂载U盘:

挂载 FAT32 格式的U盘:

#创建挂载点
sudo mkdir /mnt/myusbdrive
#编辑fstab让移动硬盘开机自动挂载
sudo nano /etc/fstab
#在最后一行添加如下内容
/dev/sda1 /mnt/myusbdrive auto defaults,noexec,umask=0000 0 0
#保存重启,即可生效

挂载 NTFS 格式的硬盘 (读写方式挂载):

#安装所需软件包
sudo apt-get install fuse-utils ntfs-3g
#加载内核模块
modprobe fuse
#编辑fstab让移动硬盘开机自动挂载
sudo nano /etc/fstab
#在最后一行添加如下内容
/dev/sda1 /mnt/myusbdrive ntfs-3g defaults,noexec,umask=0000 0 0
#保存重启,即可生效

挂载 exFAT 格式的硬盘:

sudo apt-get install exfat-fuse
/dev/sda1 /mnt/usbdisk vfat rw,defaults 0 0
#开机自动挂载

说明:

sda1 是取决于你的实际情况,a 表示第一个硬盘,1 表示第一个分区。

umask=0000 0 0

前面四个 0 就是对所有人, 可读可写可执行,

后面两个 0, 第一个代表 dump,0 是不备份

第二个代表 fsck 检查的顺序, 0 表示不检查

卸载:

sudo umount /mnt/myusbdrive

查看挂载情况可使用以下命令:

cd /mnt/myusbdrive
ls

0x02安装samba:

安装 samba:

sudo apt-get install samba samba-common-bin

安装完成后,配置 / etc/samba/smb.conf 文件:

sudo nano /etc/samba/smb.conf

在[global]里加上:

display charset = UTF-8
unix charset = UTF-8
dos charset = UTF-8

在其最后添加以下命令:

[raspi]                                   #共享文件的名称,将在网络上以此名称显示
        path = /mnt/myusbdrive                     #共享文件的路径
        valid users = pi             #允许访问的用户
        browseable = yes                  #允许浏览                                 
        public = yes                      #共享开放                                      
        writable = yes                    #可写

保存后,重启 samba 服务,输入:

/etc/init.d/samba restart

最后设置密码:

smbpasswd –a pi

然后加入开机自启:

sudo nano /etc/rc.loca

在exit 0前加上这句话:

/etc/init.d/samba start

0x03电脑连接远程共享:

右击网络(桌面上没有的可以去我的电脑左边那一列找到)

输入设置的ip、文件夹:

输入设置的用户名密码:

完成~

0x04安装aria2:

安装:

sudo apt-get install aria2

建立 aria2 设置文件:

cd /etc
sudo mkdir aria2
cd aria2
#创建空白的 aria2s session 文件
sudo touch /etc/aria2/aria2.session
#创建配置文件
sudo nano /etc/aria2/aria2.conf

编辑配置文件(下载目录按情况自己改):

dir=/mnt/myusbdrive
disable-ipv6=true
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

启动:

sudo aria2c --conf-path=/etc/aria2/aria2.conf -D

然后把启动命令加到开机自启。

0x05安装yaaw:

安装apache:

sudo apt-get install apache2

给权限:

sudo chmod 777 /var/www/html
cd /var/www/html

然后安装yaaw:

sudo git clone https://git.oschina.net/chenxuuu/webui-aria2.git /var/www/html
#你也可以连GitHub,但是速度嘛~ https://github.com/ghostry/webui-aria2.git

然后就可以访问http://树莓派ip/来进行离线下载了

我们下载一个文件试试~

下载成功~