树莓派上安装配置Archlinux

安装Archlinux

安装Archlinux这部分在Linux系统中测试通过。sdX是SD卡盘符。

SD卡分区

  1. 使用fdisk工具 # fdisk /dev/sdX
  2. fdisk提示命令下删除旧分区并新建:
    •  按o 删除全部分区
    • p列出分区,此时应该没有任何分区。
    • n新建分区, 然后p选择为主分区, 输入1作为SD卡的第1个主分区; 按回车选择默认开始扇区,再输入+100M设置结束扇区.
    • t,然后按c设置刚才的主分区类型为W95 FAT32(LBA).
    • n新建分区,然后p选择为主分区,输入2作为SD卡的第2个主分区;按两次回车默认把SD卡剩下的空间都给第2主分区.
    • w写入保存分区, 退出fdisk.

格式化和挂载分区

把第1主分区格式化为FAT分区,并挂载到boot:

mkfs.vfat /dev/sdX1
mkdir boot
mount /dev/sdX1 boot

把第2分区格式化为ext4分区,并挂载到root:

mkfs.ext4 /dev/sdX2
mkdir root
mount /dev/sdX2 root

下载树莓派Archlinux ARM版本, 安装到SD卡

wget http://archlinuxarm.org/os/ArchLinuxARM-rpi-latest.tar.gz
tar -zxpf ArchLinuxARM-rpi-latest.tar.gz -C root
sync
mv root/boot/* boot

安装完成,卸载分区

unmount boot root

系统安装完成

Archlinux镜像已经安装成功,连上网线,插上电源,可以直接SSH到树莓派了。
默认用户名和密码为:alarm
管理员用户名和密码为:root
管理员帐号无法远程登录

配置Archlinux

添加国内源

编辑 /etc/pacman.d/mirrorlist

在文件头部添加:

  • 清华软件源:Server = http://mirrors.tuna.tsinghua.edu.cn/archlinuxarm/$arch/$repo
  • 中科大软件源:Server = http://mirrors.ustc.edu.cn/archlinuxarm/$arch/$repo

更新软件源:

pacman -Syyu

安装SUDO

安装sudo:

 pacman -S sudo

输入 visudo 去掉 #%wheel ALL=(ALL) ALL 此行注释,使wheel用户组可以临时使用sudo 提高权限.

visudo

参考资料

  1. http://archlinuxarm.org/platforms/armv6/raspberry-pi

转载自

http://www.jianshu.com/p/be4a44a54b65

20分钟理解并写出简易的网速监控API

这是一篇学习笔记。用于快速理解,并在Raspbian(或者其他Linux系统)上,利用Python的Flask框架快速写出一份简易的网速监控API。

0 序言

我目前成为了树莓派的重度使用者。平时Python的练习可以在上面做,同时它也是我的NAS(简易版)、离线下载机、无线路由器……

对于我来说,对某台机器网速的监控有很大的需求,因此之前尝试利用基于PHP的探针提供的API来监控实时网速

PHP探针在建站环境上的主机会非常方便。但是对于没有PHP环境的主机,专门为了一个探针而配置PHP,则过于臃肿。

今天写了这篇文章,同时也作为我自己的笔记,用Python的Flask框架快速写出一份简易的网速监控API。

进行操作后,不只是网速监控API,可以根据自身需求推广到其他API的快速搭建。

我们最终的目标是,HTTP访问目标ip:端口,得到json形式的返回结果:

{
"interface": "eth0",
"rx": "58829838538",
"time": "1506500429.11",
"tx": "59272128479"
}

包含网口名,rx和tx字节数,此时的时间戳(api提供端无状态,只提供时间戳。网速信息在api获取端运算)。

注:JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

1 了解 /proc

Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构、改变内核设置的机制。proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为访问系统内核数据的操作提供接口。

pi@raspberrypi:/proc $ ls
1     1158  1323  1452  1673  2057  2474  45   576  66    77    8032  904        bus          interrupts   modules        timer_list
10    1180  1336  146   1674  2058  25    46   579  67    7791  8035  912        cgroups      iomem        mounts         timer_stats
1009  1184  1350  1460  1691  21    26    47   58   670   7797  8097  915        cmdline      ioports      net            tty
104   1187  1356  148   1695  2122  27    48   580  68    78    8134  916        consoles     irq          pagetypeinfo   uptime
1076  124   1357  1482  17    2126  273   49   582  69    7804  8136  917        cpu          kallsyms     partitions     vc-cma
1077  1259  1358  15    1736  22    28    5    59   6948  7811  82    918        cpuinfo      keys         sched_debug    version
1078  1260  1361  1536  1742  222   29    50   60   7     7813  83    919        crypto       key-users    self           vmallocinfo
1079  1269  1363  1585  1777  223   3     51   61   70    79    85    922        devices      kmsg         slabinfo       vmstat
108   1272  1364  1625  1780  224   31    52   619  71    7901  879   932        device-tree  kpagecgroup  softirqs       zoneinfo
1081  1290  1365  1626  18    228   32    53   62   72    7936  88    933        diskstats    kpagecount   stat
1085  1291  1378  1646  1813  2288  322   54   63   73    7940  89    937        driver       kpageflags   swaps
1097  13    1379  1648  1871  23    33    55   64   738   8     892   946        execdomains  loadavg      sys
11    1309  14    1651  19    238   34    56   65   75    80    898   960        fb           locks        sysrq-trigger
1108  1312  1402  1652  2     239   35    57   658  7669  8025  9     asound     filesystems  meminfo      sysvipc
1154  1321  1442  1668  2056  24    44    575  659  7691  8030  90    buddyinfo  fs           misc         thread-self

详情可参考 Linux下/proc目录简介 [1]

对于状态监控,我们一般关心的信息如下:
/proc/cpuinfo cpu的信息
/proc/loadavg 根据过去一段时间内CPU和IO的状态得出的负载状态
/proc/meminfo RAM使用的相关信息
/proc/uptime 系统已经运行了多久
/proc/net 网卡设备信息
/proc/net/dev 显示网络适配器及统计信息
/proc/diskstats 取得磁盘信息

这样,我们就可以各取所需。在本例中,我使用了/proc/net/dev 显示网络适配器及统计信息。

Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
  tun0: 3852102709 17680346    0    0    0     0          0         0 1974345633 21150157    0 182375    0     0       0          0
 wlan0: 7886340   51924    0    4    0     0          0       248 15654713   23263    0    0    0     0       0          0
    lo: 1109576    6222    0    0    0     0          0         0  1109576    6222    0    0    0     0       0          0
  eth0: 1357382867 17758879    0 32317    0     0          0         0 354351259 21157222    0    0    0     0       0          0
  eth1: 145114110 1581538    0    0    0     0          0         0 2151465834 4647523    0    0    0     0       0          0

/proc/net/dev就是我们流量监控的数据来源。

我关心eth0的网卡流量。因此我只要抓出eth0(第六行)行的RX字节数和TX字节数即可,再在api中返回此时的时间戳。

对于 /proc/net/dev 文件中我关心的信息,我使用的部分Python代码如下。

f = open('/proc/net/dev','r')
 for x in range(5):
       f.readline()
 line = f.readline()
 strline = line.split(' ')
 strline2 = []
 for a in strline:
         if a != ' ':
                 if a !='':
                         strline2.append(a)

至此,我们得到的strline2就是eth0行中包含的数据列表。根据/proc/net/dev 格式,rx数据量是strline2[1],tx数据量是strline2[9]。当然,你也可以用正则表达式来实现。

毕竟是自己使用的简易API,如果不是特别在意的话,实现方法不优雅也无妨。

至此我们就能把自己需要的信息提取出来了。

2 熟悉 flask 框架

Flask是一个使用Python编写的轻量级Web应用框架。基于Werkzeug WSGI工具箱和Jinja2 模板引擎。 Flask使用BSD授权。 Flask也被称为“microframework”,因为它使用简单的核心,用extension增加其他功能。Flask没有默认使用的数据库、窗体验证工具。然而,Flask保留了扩增的弹性,可以用Flask-extension加入这些功能:ORM、窗体验证工具、文件上传、各种开放式身份验证技术。

Flask有提供文档 http://docs.jinkan.org/docs/flask/

用简单的话说,Flask可以让你快速搭建起来一个web服务端,而省去一些技术细节。

不要误解,Flask的能力足以支撑大型的商业项目。但由于其轻量易上手,使得我们也可以在自己的项目中轻松使用。我们来看一下其helloworld代码。

from flask import Flask
app = Flask(__name__)
 
@app.route("/")
def hello():
    return "Hello World!"

如你所见,短短几行代码实现了基本的web静态服务。

我们将上面获取网速的代码加入,就可以实现我们的API功能。

具体操作如下:

安装flask

sudo pip3 install flask

在我们的目录下新建一个app.py并编辑

#!flask/bin/python
from flask import Flask
 
app = Flask(__name__)
 
@app.route('/')
def index():
    return "Hello, World!"
 
if __name__ == '__main__':
    app.run(host='0.0.0.0',port='5050',debug=True)

注意,相比helloworld,最后一行代表的含义是:在0.0.0.0(本地/不检查ip)上开放,端口5050,开启调试,然后执行。

此时访问 http://localhost:5050 或者 http://目标机器ip:5050 即可返回HelloWorld。(访问失败,注意防火墙设置)

具体特性如调试、路由等等使用方法,本文不多提及,请参照官方文档。

3 写出服务端

我们最终的目标是,HTTP访问目标ip:端口,得到json形式的返回结果:

{
"interface": "eth0",
"rx": "58829838538",
"time": "1506500429.11",
"tx": "59272128479"
}

接下来将上面两部分结合,写出服务端即可。我的代码如下:

#!flask/bin/python
from flask import Flask, jsonify
import time
 
app = Flask(__name__)
 
net =   {
                'interface':'eth0',
                'rx':'0',
                'tx':'0',
                'time': '0'
        }
 
 
@app.route('/')
def index():
    try:
                f = open('/proc/net/dev','r')
                f.readline()
                f.readline()
                f.readline()
                f.readline()
                line = f.readline()
                strline = line.split(' ')
                strline2 = []
                for a in strline:
                        if a != ' ':
                                if a !='':
                                        strline2.append(a)
                net['rx']=strline2[1]
                net['tx']=strline2[9]
                net['time']=str(time.time())
 
        finally:
                if f:
                        f.close()
                strline=[]
                strline2=[]
        return jsonify(net)
 
 
if __name__ == '__main__':
    app.run(host='0.0.0.0',port=5050,debug=True)

说明:
1 jsonify是flask提供的快速打包工具。使用jsonify(net),即可将net打包为json,然后直接返回即可。
2 成功实现后,请取消debug。

我提供一个示例:

http://sfo01.misaka.cc:5050/

访问得到

{
"interface": "eth0",
"rx": "58829838538",
"time": "1506500429.11",
"tx": "59272128479"
}

关于此api的利用,可以参阅我之前的文章。定期刷新获取json,解析后,两次请求数据量差与time时间戳之差之商即为网速。

4 持久运行与使用

可以使用一切使进程持续运行的方法。

可以使用tmux

开启新对话时使用 tmux

在新的会话中使用

sudo python app.py

终端即可直接关闭

5 小结

至此。我们使用flask完成了一个最简单的API的搭建。下一步可以考虑更广的用途。

最后,笔者为生活在一个不需要重复造轮子的时代而感到幸运。

6 相关阅读

[1] Linux下/proc目录简介 http://blog.csdn.net/zdwzzu2006/article/details/7747977
[2] 百度百科-JSON https://baike.baidu.com/item/JSON
[2] Flask框架中文文档 http://docs.jinkan.org/docs/flask/

原文来自 https://steinslab.xyz/archives/1275

 

用树莓派DIY共享鱼缸,支持微信远程喂鱼

近期把精心打理数年的水族缸给“开源共享了”,实现了远程观赏和喂鱼互动的功能,先看效果吧。
直播页面:http://maker.quwj.com/program/nature-aquarium
远程喂鱼没有自己设计操作界面,而是接入了微信公众平台,通过微信发送指令实现投食。看这段现场演示视频:https://v.qq.com/x/page/f0554ga4h2k.html

投食说明在直播页面和项目主页都有详细介绍。这个项目的意义还在于你可以把自家的屏幕变成虚拟水族馆,没事看看鱼,和鱼互动一下,等同于养了一缸鱼。更让人激动的是,你根本只管投食只管享用悠然自得,维护鱼缸等琐碎繁杂的问题全都不用管,是不是便宜占尽了呢?

 

下面分享一下搭建这套共享水族馆的 Make 过程,其中有关于树莓派上实现视频直播的几种方案近期会在树莓派实验室进行介绍,有兴趣的朋友可以参考把自家的宠物也共享出来(需要支持可以联系本项目作者)。

组件清单

普通生态鱼缸 × 1
树莓派主板 × 1
罗技 C270 摄像头 × 1
自动投食器 × 1
LED 鱼缸灯 × 1
继电器 × 2
路由器 × 1
公网IP地址 × 1
微信公众账号 × 1

系统架构

这里介绍下最关键的投食流程。用户通过微信给趣无尽微信公号发送投食指令,微信公众平台调用之前设定好的后台服务,将指令保存在控制服务器上。然后由树莓派去从控制服务器上取这个指令并执行。
这么设计主要是考虑到实际环境下的稳定性,当然最简单的方式是把树莓派直接暴露在外网,用户直接连上树莓派进行操作也完全可行。
树莓派拿到投食的指令之后,控制投食机完成投食。
没错,这个投食机怎么方便实现是小问题。我直接买了一个现成的投食机,Hack 一下开关部件,加一个继电器接入树莓派就搞定了。

Hack 投食机

Hack 前的投食机如图所示。

拆开后发现结构简单,测试了一下,最上面的开关位置短接即可启动投食机。

所以就把开关接出来,用继电器控制吧。用烙铁在旁边捅了个洞,以便把线引出来。

 

接好继电器。

整个树莓派控制设备如下。

投食机装到鱼缸上,大功告成。

至于直播,采用 motion、simple rtmp plublish 或 gstreamer 方案。几种方案近期会在树莓派实验室进行介绍。

其中最关键的非技术性因素是,你的 ISP 需要给你分配了公网 IP 地址,这样你才可以将树莓派的某个服务(比如视频采集)通过路由器的端口映射暴露在外网。

项目主页:http://maker.quwj.com/project/4

项目补充说明:
1.视频实时采集自一台树莓派3B,由于树莓派性能、稳定性、家庭带宽等多重因素限制,在线人数较多时直播服务可能会出现卡顿或不可用。
2.请使用安装了 Flash 插件的浏览器打开,目前暂不支持 iPhone、iPad 浏览器观看,推荐使用 Chrome。
3.一般情况下,10~22点之外的时间段水族馆灭灯,这时基本上神马都看不到属于正常状况。
4.项目当前处于测试中,对性能优化尚在探索中,画质没有开到最佳。
5.项目随时会因设备维护而临时中断直播、关闭投食,属于正常状况。维护结束后会重新开放。
6.如发现水族馆存在异常状况,请联系作者处理,微信 spoony002。
7.作者组建了一个微信群,欢迎对热带鱼、草缸等有兴趣的朋友加入交流养鱼的经验和乐趣。添加作者微信号 spoony002 说明入群。

本文来自

用树莓派DIY共享鱼缸,支持微信远程喂鱼

无屏幕和键盘配置树莓派WiFi和SSH

不算是什么新功能了,在树莓派3B发布后不久,树莓派官方 Raspbian 系统久加入了允许在开机前对 WiFi 网络进行配置的机制。

一、WiFi 网络配置

用户可以在未启动树莓派的状态下单独修改 /boot/wpa_supplicant.conf 文件配置 WiFi 的 SSID 和密码,这样树莓派启动后会自行读取 wpa_supplicant.conf 配置文件连接 WiFi 设备。

操作方法简单:将刷好 Raspbian 系统的 SD 卡用电脑读取。在 boot 分区,也就是树莓派的 /boot 目录下新建 wpa_supplicant.conf 文件,按照下面的参考格式填入内容并保存 wpa_supplicant.conf 文件。

country=CN
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
 
network={
ssid="WiFi-A"
psk="12345678"
key_mgmt=WPA-PSK
priority=1
}
 
network={
ssid="WiFi-B"
psk="12345678"
key_mgmt=WPA-PSK
priority=2
scan_ssid=1
}

说明以及不同安全性的 WiFi 配置示例:
#ssid:网络的ssid
#psk:密码
#priority:连接优先级,数字越大优先级越高(不可以是负数)
#scan_ssid:连接隐藏WiFi时需要指定该值为1

如果你的 WiFi 没有密码

network={
ssid="你的无线网络名称(ssid)"
key_mgmt=NONE
}

如果你的 WiFi 使用WEP加密

network={
ssid="你的无线网络名称(ssid)"
key_mgmt=NONE
wep_key0="你的wifi密码"
}

如果你的 WiFi 使用WPA/WPA2加密

network={
ssid="你的无线网络名称(ssid)"
key_mgmt=WPA-PSK
psk="你的wifi密码"
}
<span id="mce_marker" data-mce-type="bookmark" data-mce-fragment="1">​</span>

如果你不清楚 WiFi 的加密模式,可以在安卓手机上用 root explorer 打开 /data/misc/wifi/wpa/wpa_supplicant.conf,查看 WiFi 的信息。

二、开启 SSH 服务

和 WiFi 配置相似,同样在 boot 分区新建一个文件,空白的即可,文件命名为 ssh。注意要小写且不要有任何扩展名。
树莓派在启动之后会在检测到这个文件之后自动启用 ssh 服务。随后即可通过登录路由器找到树莓派的 IP 地址,通过 ssh 连接到树莓派了。

如果需要远程桌面方式操作树莓派,可以通过 ssh 安装 xrdp,再用 Windows 的远程桌面客户端连接到树莓派

这个小技巧对于没有有线网卡、没有标准 USB 接口来直连键鼠,但集成了 WiFi 的树莓派 Zero W 尤其实用。

本文来自

无屏幕和键盘配置树莓派WiFi和SSH

树莓派驱动OLED屏幕以及花屏问题的处理

最近在学习树莓派,驱动OLED屏时出现了一个问题,就是花屏,折腾了两天后发现原来这个OLED的驱动芯片不是SSD1306而是SH1106,所以用Adafruit_Python_SSD1306这个库是花屏的。
OLED的驱动芯片有好几种,但是有的库只支持SSD1306芯片,所以当你的OLED屏出现花屏时就应该是芯片和库没对应上,购买OLED屏时最好购买i2c的SSD1306芯片的,库多且接线比较简单。

Python有两个可以用的OLED库:

Adafruit_Python_SSD1306库与Luma.oled库的安装说明(看不懂英文没关系,看下面我会说)。

本文的Luma.oled库参考了I2C接口的OLED在树莓派3上的应用 ,但这是旧版本的,新版本库不是这样安装,请看下文。

i2c接线

OLED引脚 树莓派物理BOARD引脚
VCC 1号
GND 6号
SCL 5号
SDA 3号

接好线后就是像一个L型的。

开启i2c功能

sudo apt-get install -y python-smbus
sudo apt-get install -y i2c-tools
sudo raspi-config

打开树莓派配置选择5 Interfacing Options。

选择P5 I2C回车激活I2C。

按回车启动就得了。

查看i2c地址

sudo i2cdetect -y 1

然后你能看到下面的地址,3c就是oled屏的i2c地址了,说明已经成功开启i2c啦

– 安装Adafruit_Python_SSD1306库

终端输入下面命令。

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
git clone https://github.com/adafruit/Adafruit_Python_SSD1306.git
cd Adafruit_Python_SSD1306
sudo python setup.py install

安装好Adafruit_Python_SSD1306库后,cd examples进入例程目录,ls查看文件,以shapes.py例程说明。

import time
      
import Adafruit_GPIO.SPI as SPI
import Adafruit_SSD1306
      
import Image
import ImageDraw
import ImageFont
 
# Raspberry Pi pin configuration:
RST = 24
# Note the following are only used with SPI:
DC = 23
SPI_PORT = 0
SPI_DEVICE = 0
      
# Beaglebone Black pin configuration:
# RST = 'P9_12'
# Note the following are only used with SPI:
# DC = 'P9_15'
# SPI_PORT = 1
# SPI_DEVICE = 0
 
# 128x32 display with hardware I2C:
disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST)
      
# 128x64 display with hardware I2C:
# disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)
      
# Alternatively you can specify an explicit I2C bus number, for example
# with the 128x32 display you would use:
# disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, i2c_bus=2)
      
# 128x32 display with hardware SPI:
# disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, dc=DC, spi=SPI.SpiDev(SPI_PORT, SPI_DEVICE, max_speed_hz=8000000))
      
# 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))
      
# Alternatively you can specify a software SPI implementation by providing
# digital GPIO pin numbers for all the required display pins.  For example
# on a Raspberry Pi with the 128x32 display you might use:
# disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST, dc=DC, sclk=18, din=25, cs=22)
 
# 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 = 2
shape_width = 20
top = padding
bottom = height-padding
# Move left to right keeping track of the current x position for drawing shapes.
x = padding
# Draw an ellipse.
draw.ellipse((x, top , x+shape_width, bottom), outline=255, fill=0)
x += shape_width+padding
# Draw a rectangle.
draw.rectangle((x, top, x+shape_width, bottom), outline=255, fill=0)
x += shape_width+padding
# Draw a triangle.
draw.polygon([(x, bottom), (x+shape_width/2, top), (x+shape_width, bottom)], outline=255, fill=0)
x += shape_width+padding
# Draw an X.
draw.line((x, bottom, x+shape_width, top), fill=255)
draw.line((x, top, x+shape_width, bottom), fill=255)
x += shape_width+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),    'Hello',  font=font, fill=255)
draw.text((x, top+20), 'World!', font=font, fill=255)
 
# Display image.
disp.image(image)
disp.display()

按照你的oled屏修改代码,程序默认是12832的,你的oled屏是这个就不用改直接运行就OK。
如果是12864的I2C就像下面那样修改,把12832加#注释,12864#注释去掉保存。

# 128x32 display with hardware I2C:
#disp = Adafruit_SSD1306.SSD1306_128_32(rst=RST)
      
# 128x64 display with hardware I2C:
disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)

终端输入sudo python shapes.py或用Python打开文件运行就能看到OLED屏有显示了。

– 安装Luma.oled库

终端输入下面命令。

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<span id="mce_marker" data-mce-type="bookmark" data-mce-fragment="1">​</span>

注:如果你需要安装Python3的Luma.oled库的则按下面对应的Python3版本修改上面的命令进行安装。
pip ⇒ pip3
python ⇒ python3
python-dev ⇒ python3-dev
python-pip ⇒ python3-pip

如果安装Luma.oled库时出现红字错误,请继续执行命令重试,那是因为网络问题下载一个叫Pillow的库不成功。

安装好Luma.oled库后新建文件命名为oled.py,复制粘贴下面代码。参考这里使用说明

from luma.core.interface.serial import i2c, spi
from luma.core.render import canvas
from luma.oled.device import ssd1306, ssd1325, ssd1331, sh1106
 
# rev.1 users set port=0
# substitute spi(device=0, port=0) below if using that interface
serial = i2c(port=1, address=0x3C)
 
# substitute ssd1331(...) or sh1106(...) below if using that device
device = sh1106(serial)#这里改ssd1306, ssd1325, ssd1331, sh1106
 
with canvas(device) as draw:
    draw.rectangle(device.bounding_box, outline="white", fill="black")
    draw.text((30, 40), "Hello World", fill="white")

如果你的oled驱动芯片是其它型号找到device = sh1106(serial),把sh1106改成库支持的其它型号。
树莓派上用Python2打开oled.py运行就能看到下图的Hello World。

能驱动成功后我们去下载Luma.oled的examples代码
然后是examples里面的例子怎么用呢?如果是非ssd1306芯片直接运行还是花屏的,因为那个examples的代码需要修改。
下面以pi_logo.py为例参考上面那个Hello World的例子修改成自己OLED芯片型号的(文件放在在examples内)。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2014-17 Richard Hull and contributors
# See LICENSE.rst for details.
# PYTHON_ARGCOMPLETE_OK
 
"""
Display the Raspberry Pi logo (loads image as .png).
"""
 
import os.path
from PIL import Image
 
from luma.core.interface.serial import i2c, spi
from luma.oled.device import ssd1306, ssd1325, ssd1331, sh1106
 
def main():
    img_path = os.path.abspath(os.path.join(os.path.dirname(__file__),
        'images', 'pi_logo.png'))
    logo = Image.open(img_path).convert("RGBA")
    fff = Image.new(logo.mode, logo.size, (255,) * 4)
 
    background = Image.new("RGBA", device.size, "white")
    posn = ((device.width - logo.width) // 2, 0)
 
    while True:
        for angle in range(0, 360, 2):
            rot = logo.rotate(angle, resample=Image.BILINEAR)
            img = Image.composite(rot, fff, rot)
            background.paste(img, posn)
            device.display(background.convert(device.mode))
 
if __name__ == "__main__":
    try:
        serial = i2c(port=1, address=0x3C)
        device = sh1106(serial)
        main()
    except KeyboardInterrupt:
        pass

Python运行上面的程序oled屏会出现一个能旋转的树莓派LOGO。

本文来自

http://shumeipai.nxez.com/2017/09/13/solve-the-raspberry-pi-drive-oled-problem.html

裸板开发操作系统Baking-Pi教程 一

OK01这个教程会从零开始尝试把树莓派的RCA和USB口附近的那个’ACT’LED点亮,并搭建好环境为接下来的教程做好铺垫。

准备

在实际动手之前,需要你先看完前一篇教程,并下载安装了必要的GUN工具链以及代码的模版文件OS Template

文件结构

在模版文件夹里面你会看到这样的文件目录:

build/
    (empty)
source/
    main.s
kernel.ld
LICENSE
Makefile

找个编辑器打开main.s文件,我们就可以开始写汇编代码了,树莓派使用的汇编是ARMv6,我们要写的汇编也就是ARMv6。

把下面这些代码复制粘贴进去:

.section .init
.globl _start
_start:

这些代码对树莓派没有直接的作用,它们是写给汇编器看的,汇编器是一个把我们将要写的汇编代码转换成树莓派能直接运行的机器码的程序。在汇编代码中,每一行都是一条新的命令,这里的第一行告诉汇编器和链接器把我们的代码放到哪里去,.init这里的代码会和模版文件组合,最终被放到输出代码的最前面。这一点很重要,因为我们要保证哪部分代码首先运行,如果我们不这么做的话,代码会按照字母表的顺序运行。
.section命令只是告诉了汇编器从这一点到下一个.seciton是代码的链接后的位置,而后面的两行告诉了工具链程序的入口。

第一行代码

把下面的代码拷贝粘贴进去

ldr r0,=0x20200000

在汇编代码中,计算机会简单的从上往下运行代码,每一行都是一个指令,除非遇到某些指令发生跳转。 这第一行代码告诉处理器,把0x20200000这个数字存储到r0这个寄存器里面,0x20200000显然是个十六进制的数字,那么什么是寄存器?

寄存器是处理器内部的一些用来存数据的小部件,可以理解成一个个的抽屉,有些寄存器会有一些特定的功能,在树莓派上有13个通用寄存器,每一个可以存储一个32比特的数字(从0到4,294,967,295 ),从r0一直到r12,对于这13个寄存器,做任何操作和运算都没关系,在这一行代码中,换成其他寄存器也没关系。

这行代码把0x20200000存到r0,是为了接下来的控制GPIO,而GPIO控制器的位置恰好就是0x20200000,这一点可以通过参考中的数据手册来查到。

指令

ldr reg,=val  
把val存到对应的寄存器中

设置GPIO的输出模式

mov r1,#1
lsl r1,#18
str r1,[r0,#4]

要让这个ACT LED亮起来,首先和Arduino类似的要先设置这个引脚端口为输出模式,然后再让它输出高电平。
上面的代码就能让ACTLED这个GPIO16设置为输出模式,首先我们把1存到r1,然后通过lsl指令,得到二进制的1000000000000000000,其实也可以直接把这个数存到r1,但是为了后面的操作和代码,这样写更有意义。

在GPIO控制器中,有24个字节用来设置GPIO,前4个对应前10个GPIO,第二个4个对应第二个10个,总共有54个GPIO,所以我们需要6×4总共24个字节。
在4个一组里面,每三个比特对应一个GPIO,我们操作的是16号GPIO,所以我们需要操作第二个4字节中第六个3比特,也就是上面代码中18的由来。
其中的str指令,会把r1中的值,写到地址为r0的值加上4偏移的位置

指令

mov reg, #val  
把val存到对应的reg寄存器  
mov指令比ldr快,因为mov不牵涉到内存,而ldr是从内存把数存到寄存器,但是mov只能对某些数字做操作  

lsl reg, #val  
reg寄存器的值逻辑左移val位

str reg, [dest, #val]  
把reg寄存器重的值写到地址为dest寄存器的值+val

输出高电平

mov r1,#1
lsl r1,#16
str r1,[r0,#40]

 

现在GPIO已经准备好被点亮了,这意味着我们要让GPIO16输出低电平,没错是低电平,板子本身设计就是这样。
上面的指令都已经见过了,为了让GPIO16输出低电平,我们得让一个第十六位是1的数写到偏移GPIO控制器40的地址位置,这样就能输出低电平了。

死循环

需要的代码都写完了,应该结束了,但是假如就那样的话,只要有供电,处理器就会持续工作,如果不给他其他的任务,树莓派就会崩溃。

loop$:
b loop$

 

这里的第一行不是一个命令,是一个标签,或者说名字,这意味着我们可以通过loop$这个名字来找到这一行代码,代码编译完成之后标签都没有意义了会变成地址,对于写代码的我们则是又很重大的意义,b指令的作用是下一条执行的指令跳转到后面的标签所指代的代码块,在这里就会导致树莓派一直循环直到断电。

另外GNU工具链要求代码的最后有一个空行。

编译和运行

编译非常简单,用终端进入到代码的根目录,也就是Makefile的同级目录中,运行make,没什么问题的话,就会生成一个kernel.img的文件。

安装这个系统代码之前,首先需要一个已经装好了常规的Raspbian系统的树莓派SD卡,在SD卡的目录中很容易就能找到一个kernel.img的文件,把它替换成刚刚生成的新文件,然后插上电源,就能看到这个ACTLED亮起来了。

参考

数据手册

Batocera系统上配置neogeo模拟器

neogeo模拟器和常规的其他模拟器有所区别,首先他的rom是一个zip压缩文件,里面有很多小的文件,不像NES这种是一个nes结尾的小文件。

此外呢,他运行的时候除了本身这个zip文件还需要一个neogeo的文件(被称为BIOS或者驱动文件),具体来讲就是,你想玩一个neogeo游戏时,除了这个游戏本身,在这个目录下面还需要有一个neogeo.zip的驱动文件,否则是无法成功运行的,一开始我甚至以为下载到的拳皇rom都是有问题的、不完整的,其实需要的就是一个neogeo的驱动文件。

对于Batocera的FBA模拟器来说,需要把rom和neogeo的驱动文件一起粘贴到fba_libretro文件夹,然后重新扫描一遍游戏文件,就能开始玩了。

DietPi——树莓派上的轻量级系统

随着树莓派的逐步发展,官方的Raspbian系统在一步步完善和开发,软件和资源越来越多,往往也意味着慢慢地臃肿。
而DietPi就是在这样的背景下被开发出来,在DietPi系统中,默认只有一些必要的软件,其他的任何不需要的软件在初始化的DietPi上面都是不存在的;在干净和简洁的同时,在DietPi上安装需要的软件也比其他软件方便和简单。

安装配置DietPi

初次配置时需要网络连接

下载镜像

在官网的下载页面下载对应的板子的镜像。

解压并烧写

  • 在Windows上可以使用Win32DiskImager
  • 在Linux上可以用dd命令
dd if=/path/to/DietPi_vXX.img of=/dev/sdb

配置WiFi(可选)

将烧写好的SD卡插入电脑,和Raspbian类似,DietPi上有一个文件dietpi.txt也是用来做开机时的配置。

在这个文件里面设置好

Wifi_Enabled=1
Wifi_SSID=MySSID
Wifi_KEY=MyWifiKey

给板子上电

把SD卡插入板子,然后上电,之后DietPi会自动重启两次来完成初次的配置。

登录

默认的用户名是root,密码是dietpi
假如上面的WiFi配置成功了,那么这里也能直接ssh了,DietPi默认装了Dropbear SSH Server。

DietPi默认是没有桌面环境的,所以这个时候还是只能终端操作。

选择软件安装

接下来就可以选择你需要的软件来进行个性化的安装了,可以安装的软件包括以下这么多选择:

桌面

  • LXDE – 高度优化的轻量级桌面
  • MATE – Gnome 2桌面
  • XFCE – 轻量级桌面
  • GnuStep – 另类的桌面系统
  • Chromium – 浏览器

远程桌面

  • Tightvnc Server – 远程桌面软件
  • VNC4 Server – 远程桌面软件
  • NoMachine – 功能更丰富的远程桌面软件
  • XRDP – 针对Windows客户端的远程桌面软件
  • RealVNC Server – 远程桌面软件

媒体系统

  • Kodi – Media Centre / Player
  • YMPD – Lightweight web Interface audio player for MPD
  • O!MPD – Feature-rich web Interface audio player for MPD
  • CAVA – Optional: Console-based audio visualizer for MPD
  • Mopidy – Web Interface Music /Radio Player
  • SubSonic – Feature rich media streaming server with web interface.
  • SqueezeBox – Also known as Logitech Media Server.
  • SqueezeLite – Audio player for SqueezeBox.
  • Shairport Sync – AirPlay audio player with multiroom sync
  • BruteFIR – EQ and Digital Room Correction via ALSA.
  • ReadyMedia – (MiniDLNA) Media streaming server (DLNA, UPnP)
  • Ampache – Web interface media streaming server.
  • Emby – Web interface media streaming server.
  • Plex Media Server – Web interface media streaming server.
  • PlexPy – Monitoring and tracking tool for Plex Media Server.
  • Murmur – Mumble VoIP Server
  • Roon Bridge – Turns your device into a Roon capable audio player
  • Roon Server – Turns your device into a Roon capable audio player and Roon core
  • NAA Daemon – Signalyst Network Audio Adaptor (NAA).
  • IceCast – Shoutcast Streaming Server, including DarkIce.
  • jRiver – Media Center
  • Koel – Web interface streaming server.

BT/下载

  • Transmission – Lightweight BitTorrent server with web interface
  • Deluge – Alternative BitTorrent server with web interface
  • qBitTorrent – Lightweight and fast (c++) BitTorrent server with web interface
  • rTorrent – BitTorrent server with ruTorrent web interface
  • Aria2 – Download manager with web interface
  • SABnzbd – NZB download manager with web interface.
  • SickRage – Automatically download TV shows
  • Sonarr – Automatically download TV shows
  • Radarr – Automatically download Movies
  • CouchPotato – Automatically download movies.
  • Jackett – API Support for your favorite torrent trackers.
  • NZBget – NZB download manager with web interface.
  • HTPC Manager – combines all your favorite software into one slick interface.

模拟器和游戏客户端

  • OpenTyrian – Gaming
  • Cuberite – Fast Minecraft server with web interface
  • MineOS – Multiple Minecraft servers with web interface
  • AmiBerry – Amiga emulation system, further developed optimized builds of uae4arm-rpi
  • DXX-Rebirth – Descent 1 & 2 OpenGL port
  • Steam – Steam client

相机

  • DietPi-Cam – RPi Camera / Web Interface Surveillance
  • MotionEye – Camera / Web Interface Surveillance

云/备份

  • OwnCloud – Your own personal cloud based backup/data storage system
  • NextCloud – Your own personal cloud based backup/data storage system
  • Pydio – Feature-rich backup and sync server with web interface.
  • UrBackup Server – Full backups for systems on your network
  • Gogs – GitHub style server, with web interface.
  • Syncthing – Backup and sync server with web interface.
  • Tonido – Lightweight backup and sync server with web interface, and, cloud access.

社交/搜索

  • Forums – phpbb3
  • WordPress – Website Blog and Publishing platform.
  • Image Gallery – Host and browse your images from a web interface.
  • BaiKal – Lightweight CalDAV + CardDAV server.
  • OpenBazaar – Decentralized peer to peer market server using BitCoin.
  • YaCy – Decentralized open source search engine.

WiFi/热点

  • WiFi HotSpot – Turn your device into a wireless hotspot/access point.
  • Tor HotSpot – Optional: Routes all WiFi HotSpot traffic through the Tor network.

智能家居

  • EmonPi – Lightweight Energy usage stats with EmonPi PCB.
  • Grasshopper – Web App to control Bticino MyHome

硬件项目

  • RPi.GPIO – GPIO Interface library for RPi (python).
  • WiringPi – GPIO Interface library (c).
  • WebIOPi – Web interface to control RPi GPIO.
  • I2c – Enables support for I2c based hardware.
  • Node-Red – Visual tool for wiring together hardware devices, APIs and online services.
  • Mosquitto – Message broker that implements MQTT protocol versions 3.1 and 3.1.1.
  • Blynk Server – iOs and Android apps to control Arduino, ESP8266, Raspberry Pi and similar microcontroller boards over the Internet.

远程访问

  • Remot3.it – (Weaved) Access your device over the internet.
  • VirtualHere – Share physically attached USB devices from your SBC, over the network.

系统管理和监控

  • DietPi-Cloudshell – Lightweight system stats for your LCD display or monitor.
  • Raspcontrol – Web interface system stats
  • Linux Dash – Web interface system stats
  • PhpSysInfo – Web interface system stats
  • RPi Monitor – Web interface system stats
  • NetData – Web interface system stats
  • Webmin – Remote system management with web interface
  • Open Media Vault – Web interface network attached storage (NAS) solution

系统安全

  • Fail2Ban – Protects your system from brute-force attacks

Web服务器栈

  • LAMP Webserver – Apache2 / MySql / PHP
  • LASP Webserver – Apache2 / SQLite / PHP
  • LAAP Webserver – Apache2 / MariaDB / PHP
  • LEMP Webserver – Nginx / MySql / PHP
  • LESP Webserver – Nginx / SQLite / PHP
  • LEAP Webserver – Nginx / MariaDB / PHP
  • LLMP Webserver – Lighttpd / MySql / PHP
  • LLSP Webserver – Lighttpd / SQLite / PHP
  • LLAP Webserver – Lighttpd / MariaDB/ PHP
  • phpMyAdmin – Web interface SQL admin tool
  • Certbot – Free, automated SSL cert creation and setup, allowing https.
  • Tomcat8 – Apache Tomcat server

DNS 服务器

  • Pi-hole – A DNS/Web server that will block ads for any device on your network.

文件服务器

  • ProFTP – Simple, efficient, lightweight FTP file server.
  • Samba – Feature rich file server.
  • vsFTPD – Feature rich FTP file server.
  • NFS – Network file system server

VPN 服务器

  • OpenVPN – Easy to use, minimal hassle VPN server
  • PiVPN – OpenVPN installer & management tool

网络负载均衡

  • HaProxy – High performance TCP/HTTP load balancer.

网站域名

  • NoIp – Website URL Address

打印

  • CloudPrint – CUPS print server, with support for Google cloud printing
  • OctoPrint – Web interface for controlling 3D printers

文件服务器选择

  • ProFTP – Simple, efficient, lightweight file server.
  • Samba – Feature rich file server.

SSH选择

  • Dropbear – Lightweight SSH Server
  • OpenSSH – Feature rich SSH server with SFTP/SCP support.

日志系统选择

  • DietPi-Ramlog – Lightweight RAM logging.
  • Full – Full logging system with Rsyslog and Logrotate.

网络服务器选择

  • Apache2 – Feature-rich webserver
  • Nginx – Lightweight webserver
  • Lighttpd – Extremely lightweight webserver

预装软件:

  • dietpi-launcher (Select and Run any of the DietPi programs, all from one place.)
  • dietpi-config (Feature rich configuration tool for your device)
  • dietpi-software (Install optimized and ready to run software)
  • dietpi-uninstall (Allows you to uninstall DietPi software)
  • dietpi-update (Update your version of DietPi)
  • dietpi-backup -(Backup or restore your DietPi system)
  • dietpi-sync – (Allows you to sync/duplicate one directory to another).
  • dietpi-services – (Takes control of software services, enabling DietPi a method of quick service control).
  • dietpi-process_tool – (Tweak system wide nice/priority levels, for most software and processes).
  • dietpi-cleaner (Remove unwanted “junk” from your DietPi system and free up filesystem space)
  • dietpi-bugreport (Sends a bug report to DietPi)
  • dietpi-cron (Allows you to modify all start times for Cron Jobs)
  • dietpi-logclear (Keep ontop of your log files, features clearing and backup modes).
  • dietpi-morsecode (Converts a text file to morse code, then outputs to your screen)
  • dietpi-letsencrypt (Frontend for Lets Encrypt and DietPi integration)
  • htop (The only resource monitor you’ll ever need)
  • DietPi-Ramlog #1 (Mounts /var/log to RAM. Saves your SD card writes, and, uses less than 0.1mb~ of RAM).
  • Dropbear (Lightweight SSH server)

预装脚本

  • treesize (Shows current directory/file sizes, recursive)

 

Raspi-config的命令行用法

稍微多用过树莓派的朋友相信都用过raspi-config这个工具,通过它可以相对可视化的容易地改变树莓派的配置。
但是里面的有些操作假如我们想要用命令行直接运行而不想进入raspi-config那个界面,那要怎么做呢?

在这个代码里面可以看到一些细节。

很多命令都是成对出现的,比如和hostname相关的

  • raspi-config nonint get_hostnameraspi-config nonint get_hostname就是获得当前设置的hostname
  • raspi-config nonint do_hostname %s对应的就是设置hostname

设置启用I2C可以通过raspi-config nonint get_i2c 00表示开启,1表示关闭(不同的命令可能是不同的对应)。

当前一些命令有这么多

/* Command strings */
#define GET_CAN_EXPAND  "raspi-config nonint get_can_expand"
#define EXPAND_FS       "raspi-config nonint do_expand_rootfs"
#define GET_HOSTNAME    "raspi-config nonint get_hostname"
#define SET_HOSTNAME    "raspi-config nonint do_hostname %s"
#define GET_BOOT_CLI    "raspi-config nonint get_boot_cli"
#define GET_AUTOLOGIN   "raspi-config nonint get_autologin"
#define SET_BOOT_CLI    "raspi-config nonint do_boot_behaviour B1"
#define SET_BOOT_CLIA   "raspi-config nonint do_boot_behaviour B2"
#define SET_BOOT_GUI    "raspi-config nonint do_boot_behaviour B3"
#define SET_BOOT_GUIA   "raspi-config nonint do_boot_behaviour B4"
#define GET_BOOT_WAIT   "raspi-config nonint get_boot_wait"
#define SET_BOOT_WAIT   "raspi-config nonint do_boot_wait %d"
#define GET_SPLASH      "raspi-config nonint get_boot_splash"
#define SET_SPLASH      "raspi-config nonint do_boot_splash %d"
#define GET_OVERSCAN    "raspi-config nonint get_overscan"
#define SET_OVERSCAN    "raspi-config nonint do_overscan %d"
#define GET_CAMERA      "raspi-config nonint get_camera"
#define SET_CAMERA      "raspi-config nonint do_camera %d"
#define GET_SSH         "raspi-config nonint get_ssh"
#define SET_SSH         "raspi-config nonint do_ssh %d"
#define GET_VNC         "raspi-config nonint get_vnc"
#define SET_VNC         "raspi-config nonint do_vnc %d"
#define GET_SPI         "raspi-config nonint get_spi"
#define SET_SPI         "raspi-config nonint do_spi %d"
#define GET_I2C         "raspi-config nonint get_i2c"
#define SET_I2C         "raspi-config nonint do_i2c %d"
#define GET_SERIAL      "raspi-config nonint get_serial"
#define GET_SERIALHW    "raspi-config nonint get_serial_hw"
#define SET_SERIAL      "raspi-config nonint do_serial %d"
#define GET_1WIRE       "raspi-config nonint get_onewire"
#define SET_1WIRE       "raspi-config nonint do_onewire %d"
#define GET_RGPIO       "raspi-config nonint get_rgpio"
#define SET_RGPIO       "raspi-config nonint do_rgpio %d"
#define GET_PI_TYPE     "raspi-config nonint get_pi_type"
#define GET_OVERCLOCK   "raspi-config nonint get_config_var arm_freq /boot/config.txt"
#define SET_OVERCLOCK   "raspi-config nonint do_overclock %s"
#define GET_GPU_MEM     "raspi-config nonint get_config_var gpu_mem /boot/config.txt"
#define GET_GPU_MEM_256 "raspi-config nonint get_config_var gpu_mem_256 /boot/config.txt"
#define GET_GPU_MEM_512 "raspi-config nonint get_config_var gpu_mem_512 /boot/config.txt"
#define GET_GPU_MEM_1K  "raspi-config nonint get_config_var gpu_mem_1024 /boot/config.txt"
#define SET_GPU_MEM     "raspi-config nonint do_memory_split %d"
#define GET_HDMI_GROUP  "raspi-config nonint get_config_var hdmi_group /boot/config.txt"
#define GET_HDMI_MODE   "raspi-config nonint get_config_var hdmi_mode /boot/config.txt"
#define SET_HDMI_GP_MOD "raspi-config nonint do_resolution %d %d"
#define GET_WIFI_CTRY   "raspi-config nonint get_wifi_country"
#define SET_WIFI_CTRY   "raspi-config nonint do_wifi_country %s"
#define CHANGE_PASSWD   "(echo \"%s\" ; echo \"%s\" ; echo \"%s\") | passwd"

 

Thonny——树莓派上Python的最新IDE

Thonny是最新的Raspbian系统中直接自带的Python IDE,支持Python3.6,更新到最新的Raspbian之后无需安装其他,就能打开使用。

在Menu>Programming中就能找到这个IDE

 

打开之后可以看到主要是两个区域,包括一个代码编辑区和一个shell的窗口,前者用来编写代码,后者可以用来更加直接地交互。

与IDLE相比,Thonny还有一大堆更加强大的适合学习编程地特性,比如他的debug模式,在debug模式中可以逐行运行代码,同时可以看到所有对象或变量的状态,在其他的一些IDE里面,它们会需要用户来设置断点,但是Thonny不需要,它有更加方便的方法。

如何使用Thonny

在代码编辑区正常地编写代码,代码高亮是有的,当然补全还是不存在的,写完一部分代码之后单击上方的三角形来运行代码,运行结果就会在下方地shell窗口中显示出来。

 

用Thonny来Debug

选择View>Variables,就会有一个新的变量小窗口显示出来,并且可以看到当前的n的值(0),单击上方的Debug图标,就会开始调试模式,第一行会高亮,接着再点击Step Into就会高亮变量,接着点击,变量会变成他的高亮的值(10);另外单机Step Out就能跳出while这个循环。

在Thonny中理解递归

对于这样一段代码

n = 3

def count(n):
  if n > 0:
    print(n)
    count(n-1)
  else:
    print("Blast off!")

count(n)

通过Thonny的Debug模式,就能非常直观地来看懂这段递归的代码。

在Thonny中观察程序运行时的堆和对象

选择VIew > Heap和View > Objects,那么当你调试下面的面向对象的代码的时候,就能很方便地在调试过程中看每个对象的属性和方法。

class Animal():
  def __init__(self, c, n):
    self.creature = c
    self.name = n
    
  def get_creature(self ):
    return self.creature

  def get_name(self):
    return self.name
    
animals = []

animals.append(Animal("Dog", "Fido"))
animals.append(Animal("Cat", "Claws"))
animals.append(Animal("Mouse","Nibbles"))

for animal in animals:
  name = animal.get_name()
  creature = animal.get_creature()
  print(name + " is a " + creature)

 

总体而言,这是一个轻量级的、同时又有不错的调试模式的IDE,非常适合在树莓派上学习Python时使用。