树莓派制作智能镜全过程

第一部分——点子与镜子

作为一个男人,跟女友逛商城时,像是梅西百货那种的,难免会走神。我就是那号人,去年一月在纽约就发生过一回。长话短说。在我闲晃时我发现一面有灯光照明的镜子。我完全能自己做一面出来,而且比这更好。我想要属于我自己的智能镜!

magic_mirror1

一回到家,我开始构想我需要的东西:一面镜子,薄的那种,一个树莓派,一些木头和油漆,还需要大量空余时间。

关于镜子

普通的镜子是不行的。镜子是要那种单面透光那种,或更加精细功能的:后面屏幕黑屏时,它是一面镜子;而信息在屏幕上显示时就该像普通玻璃窗那样。

和警察局问询室内那面镜子原理一样,当只有一间房有光时,它就像一面镜子,其他时候它就是普通玻璃窗。

magic_mirror3

我所需要的是一面观察镜。现在,请相信我,当你问买玻璃的要一面观察镜时,会被反问一些奇怪的问题。他们那些人往往有更多新奇点子……嘿嘿,肮脏的思想永远是快乐的源泉。

终于我还是得到了一块不错的观察镜。开始找乐子吧!

第二部分——显示器

magic_mirror4

解决了镜子问题后,是时候为魔镜项目入手一台显示器了。

在为魔镜选择合适的显示器过程中,有一些纠结的决定。我是买一台新显示器还是捡一台呢?我需要什么尺寸?屏幕最薄会是多少?我如何移动控制按钮?屏幕是否够亮来盖过我的堂堂仪表?

因为我用显示器作为仪容之用,选择合适尺寸差不多就是选择合适的宽度(也就是镜子合适的高度)。在一些测量和尝试用胶带固定在墙上我想放置镜子的位置后,24英寸屏幕会是完美的选择。额外带来的好处是,绝大多数(便宜的)24英寸屏幕初始就带有1080P分辨率,正是我想在这个项目所使用的分辨率。

为了合适的屏幕类型和品牌,我几乎跑遍了方圆20公里内的电器铺。我敢肯定保安大叔在盯着我,而我正仔细检查所有屏幕背面和底部。

大多数品牌被立即否定了,因为它们的电源和视频连接线在背后。我需要转接线是在侧面的那种。

magic_mirror5

最后我选择了Iiyama显示器,它最接近我所希望的——价格便宜,边框窄小,简单触控按钮和正确转接器方向。

直到现在,我还是不清楚显示器外壳能否轻易被卸除,控制面板如何在显示器内部被连接上。销售人员不许我做出怪异的动作,打开显示器外壳,所以买到这台合适的显示器纯属运气。

magic_mirror6

我订购了一台24英寸Iiyama E2481HS-B1显示器。为确定显示器和镜子之间气密性良好,我拆下了外壳。在刚刚开箱就进行拆卸显示器够战战兢兢的,但……勉强成功。

这台Iiyama显示器的好处是,显示控制器(金属盒内的电子元件)为这面镜子的其他零件留下了足够的空间,而又保持了它原本的苗条外形。

magic_mirror7

实际的显示板仅有9毫米厚,而小小的边框也只是10毫米宽。加上显示控制器后,就是下列尺寸:556毫米x323毫米x46毫米(外加6毫米的镜子厚度)。这些尺寸构成了新的木头外壳尺寸。

第三部分——外壳

magic_mirror8

在量度新外壳所需尺寸后,就开始享受DIY的喜悦吧。我用松木做了个结实坚固的框架,用地板地脚线固定镜子和显示器的位置,那尺寸刚刚好(30毫米宽),还有圆角边框效果。

镜子很可能会发热,那就需要通风口了。此外,在外壳的背后还加了几个既美观又结实的挂点。

小剧透:产品最终重量6.5千克,由我做的两个挂载点所推测得来。

magic_mirror11

补充一下,我在外壳的底部开了条细缝作为电源线槽。

当然,它需要进行上色。在涂抹油灰(我在打磨抛光时后悔涂太多油灰了)、一些地漆及上土层后,新外壳完工。

magic_mirror14

有个木工小步骤我要去做的:我做了4个挂在块来安装显示器与镜子。现在准备好将它们上在镜框里面。

magic_mirror15

木工部分到此结束,进入魔镜的下一环节,安装硬件。

第四部分——安装硬件

magic_mirror16

魔镜开始成形。我订购了镜子,找到合适的显示器,完成打磨白色的外壳,是时候开始安装硬件了。

目前我手上有以下零件: 显示器 + 树莓派 + 一条HDMI线(连接树莓派和显示器) + 一条USB转micro USB转接线(用来为树莓派供电) + 一条显示器电源线

但接着我遭遇到小小挫折。在找合适的显示器时,我完全没想到看看显示器有没有一个USB口,用来驱动树莓派。我以为现在的显示器都默认装有USB口,不过我错了,它没有。

这不是不能解决的问题,但我真心希望只用一条线来驱动魔镜。所以我只能将电源分为两条线,一条给显示器,一条给240伏USB降压器。补充一点,我希望用一条普通C13电源线就能驱动智能镜。

magic_mirror17

也就是说,我要做的是中间带有USB充电器的接插电源线。在翻了我几个闲置线材抽屉后,我找到了个旧USB充电器。

magic_mirror18

拆开充电器比想象中的容易,只要一点点焊接工序,一些胶和绝缘胶布即可。我要设法做个外观高大上的电源线。

magic_mirror20

我做了试运行,确保电源线正常工作。我将所有零件连接好,插好电源线,打开显示器。树莓派启动正常,USB充电器没有发热过量。不错!

magic_mirror21

接着组装所有零件。这次没有倒霉事件:所有东西完美吻合。

magic_mirror24

另一个阶段完成了,包括所有实体部分(除了还没把两颗螺丝钉在墙上)。进入戏肉的部分:安装树莓派。

Magic Mirror: Part V – Installing the Raspberry Pi

第五部分——安装树莓派

magic-mirror25

那么,做完所有硬件之后,就轮到安装树莓派了。要达到智能镜的所有需求,树莓派就要有以下功能:

· Wifi连接 · 屏幕旋转90度,符合照镜方向 · 本地网络服务维持界面 · 在全屏幕下运行的浏览器,用于显示界面

基本安装

因为Raspbian操作系统的灵活性和背后有开源社群支持,我就选了它。下载了操作系统映像后,就把它写入SD卡。

拷贝一个映像档需要很长时间,那么有三种选择:

  1. 用树莓派技术文档中提到的rdisk方法拷贝。
  2. 拿杯咖啡,坐下,在等待中享受咖啡因的感觉。
  3. 上面两者都选。

我选了3。完成拷贝后,我启动树莓派、登入,进入命令行的sudo raspi-config开始配置向导。在这个配置中,有几件重要事项需要配置:

· 确保系统启动到桌面(取代命令行模式或调试模式)。 · 调整时区,使魔镜显示正确时间。 · 在高级选项部分,确保显存超过128MB。 如果你想做和这个一样的镜子,尽管尝试选择所有其他选项。只是记住,如果选砸了,就再泡杯咖啡重装系统吧。

Wifi连接

我不想在智能镜上加任何多余的连接线,就选择了以Wifi连接因特网。安装Wifi接收器真的依赖频宽和种类,因此写下完全过程是多余的。有最好的替代吗?看看这个神奇的网站……

老实说,这部分安装确实很花时间。一旦装好了,就能工作正常。

旋转屏幕

智能镜在设计上是纵向肖像模式,所以我需要将屏幕顺时针旋转90度,最终显示分辨率为1080 x 1920。我曾担心这会是最大的问题,最终却很容易解决了。

树莓派的BIOS设置储存在系统启动分区中。在这分区中,有一个config.txt文件,载有所有设置。要旋转显示器,在这文件内加上以下一行代码:
display_rotate=1

要让显示器连接更加可靠,我就不解释为何加上下面允许HDMI线热插拔的代码了:
hdmi_force_hotplug=1

配置文件存盘后重启树莓派,我不禁会心一笑:这感觉真好,腰不疼颈不酸了!

网络服务器

要维持界面(很简单的一个网页),我需要在树莓派上Apache服务器。这在树莓派上是其中一个很常见的应用,安装过程简直行云流水。

首先我运行下列指令,确定我用的是最新系统软件。
sudo apt-get update && apt-get upgrade -y

现在是时候真的安装Apache了:
sudo apt-get install apache2 apache2-doc apache2-utils

完成了!就是所有这些。但要保证在服务器上能用到一些PHP脚本(以后会更多的),我也加上了PHP支持:
sudo apt-get install libapache2-mod-php5 php5 php-pear php5-xcache

又完成了!重启之后,网页服务器就挂载上线运行了!我在/var/www文件夹内放置了index.php文件,将浏览器首页指向树莓派的IP地址,发现成功了。

信息模式(kioskmode)

现在就是要确定树莓派能够显示我在信息模式(kioskmode)下用Chromium浏览器显示的网页。Chromium浏览器是个能在树莓派操作系统上运行的开源浏览器。

一如既往,安装很简单:
sudo apt-get install chromium x11-xserver-utils unclutter

但这一次,它需要一些额外设置,在信息模式下禁用屏幕保护和自动重启。我在/etc/xdg/lxsession/LXDE/autostart作了编辑,在前面加上了#号。
@xscreensaver -no-splash

另外我还加了以下代码:
@xset s off @xset -dpms @xset s noblank @chromium –kiosk –incognito http://localhost

这样就能完全禁用所有屏保功能,及Chromium浏览器在开机后自动启动,开启全屏模式并导向本地主页。

存盘并再一次重启,检查工作效果。树莓派并不是世界上最快的电脑,它需要花点时间,但最终测试页还是在旋转了90度的画面上显示出来。要得!

进入项目的最后部分,界面开发。

第六部分——界面开发

回顾一下,我买了合适的镜子、显示器,做了个新外壳,安装好硬件及配置完成树莓派,那就进入最后一步——界面开发。

需求和功能

我开始项目时,我发现不能通过镜子直接进行任何交互,要不然在铮亮的镜面上会抹上油脂和什么脏东西。但还有更重要的原因,还有别的更好设备可用于用户交互。我希望智能镜只是个被动信息来源。

而更更重要的是,镜子就是镜子,不应被大量(无用的)信息所填满。只有边上能用来作摘要性显示,给本帅哥留些足够自恋的空间吧。

这样我需要以下信息类别目录来满足我对信息的需求:

· 问候语 贴心问候,每日美好的开始。

· 天气 看到我穿的衬衫吗?不错吧!嗯?今天穿T恤衫不会鸡冻吧?

· 时钟和日历 现在赶时间吗?还有足够时间顾影自怜吧?

· 消息反馈 我只是担心自己形象帅不帅吗?还有别的需要上心吗?

当然,未来版本当中有大量的改进可能,现在列出的这些应该够用了。

基本安装

前面提过,程序界面不是一个在树莓派桌面上神奇的应用,仅仅是一个全屏幕网页。我能用HTML、CSS和Javascript开发外,还有一个额外的好处,在我将它放入智能镜之前,能在我的苹果电脑上开发测试。

magic-mirror28

在自己写的代码基础上,我用了一些开源库文件来优化它的运行速度:

Jquery

像大多数网站那样,智能镜使用Jquery来简化DOM操作方式,对我这种懒人最为适用。

Moment.js

它对我在时间安排操作上帮助不少,尤其是在争分夺秒时更节省不少时间。

FeedToJson

将RSS订阅用JSON数据转成javascript的方便工具。

iCal Parser

将iCal数据转化为JSON。可惜这个库文件并不完美,需要一些额外的优化。

以上这些库文件,加上我自己的HTML和Javascript足够使我的镜子成精了。

设计

我的智能镜需要个酷炫设计。我本人是个严重果粉,那么在设计上要遵从苹果系的设计指标

边框、倾角、阴影效果有时是用户界面厚重感的因素,甚至能盖过显示内容的光芒。所以,专注在内容设计,把用户交互界面摆在辅助位置上。

利用足够的实体空间,它是个重要内涵,在感官上更让人注意和易于理解。

怎么做到这一点?用Helvetica Neue字体,用天气图标对应显示天气信息。

magic-mirror29

镜子在背后没有光源时就只是一面镜子,用黑色背景是个重要设定。而为了有最好的对比度,显示内容字体应为白色,在加一些灰色阴影边缘,那灰度为50吧……

我大可以加上一些其他色彩,但目前为止我只想做到简洁的黑白界面。我可不想镜子比我的尊容还要出彩。

API设计

为了接收我想在镜子上显示的数据,我用了一些开源API和反馈代码。还有谁不太清楚什么是API,维基百科里面有详尽的解释:

“电脑操作系统(Operating system)’或‘程序库’提供给应用程序调用使用的代码。”

我心中的API就像你家的DVD播放器背后那样充满接口——如果你将其他设备连接到它的话,它就变得更加有用,这些接口本质上就是API。API让设备变得功能强大、有趣,尤其对我这种电脑狂人来说。

Openweathermap.org

Openweathermap有很好的API接口,能够免费得到天气预报信息。它允许你查询区域内的信息,定义你想要的信息类别。在这里我用了两个连接,一个是当前天气,另一个是预报天气。

iCal Calendar

iCloud允许你以iCal格式分享日历。因为javascript无法做到这一点(因为多站点脚本安全问题),我需要通过PHP代理服务器来开启数据。这其实很容易,只有三行代码而已:

12<!--?php <br ?-->    $url "https://p01-calendarws.icloud.com/ca/subscribe/1/mysupersecreticloudhash";    echo file_get_contents($url);

只需查询calendar.php就能将在同一个服务器内日历表在界面上显示出来。

前面说过的iCal语法分析编辑帮我把信息解析成有用信息。可是,iCloud在他们的反馈中用了一些非标准标签,我要添加额外的代码行来将代码解析为javascript文件。

magic-mirror30

NOS新闻订阅

新闻订阅只是用到了荷兰公共广播公司的RSS订阅功能。可是,他们不支持JSON格式数据,因此我用了FeedToJson插件来把RSS数据转为JSON格式的。

其他内容,例如当前日期与实践,还有问候语都只是一些简单的javascript语句。

自动更新

你看了这篇博客这么久,应该能接受更进阶的信息了吧。那么瞪大眼看下去吧……

在开发当中,我遇到了一个很不爽的境地,就是没有键盘和鼠标连在智能镜上的问题。如果我更新界面,就没有一个简单方法在智能镜上更新页面的方法。最简单直接的方法是重启整个树莓派,但让我在调试每个更新上花时间太多了。

我用GIT分布控制系统更新文件,而每个更新版本都有本身的哈希校验提交码,我用PHP就能读取出来。这启发了我再代码行内加上一个片段,将本地页面和刚刚开发的页面进行哈希比对。如果两者不符,程序将重新载入网页,显示最新版本。

我用以下PHP代码获取当前网页上的哈希校验码:

1trim(`git rev-parse HEAD`)));

对比过程在javascript主文件内完成,但只有在HTML文件有当前版本的哈希校验值前提下才能实现:

1var gitHash = '';

现在,对比过程就很直观,每3秒进行一次:

1234567891011121314(function checkVersion()    {        $.getJSON('githash.php', {}, function(json, textStatus) {            if (json) {                if (json.gitHash != gitHash) {                    window.location.reload();                    window.location.href=window.location.href;                }            }        });        setTimeout(function() {            checkVersion();        }, 3000);    })();

所有这些神奇的操作,让更新智能镜界面变得简单。只需用SSH登入树莓派,进入合适的文件夹,然后处理一个git推送请求。

给我交出代码来!

得了得了……好奇了吧?所有代码在GitHub上都有。有件事情要说一声:代码很少标注,以面条式代码填充,通篇都是TODO语句。哈,不怕晃晕菜的,尽管扎进去吧。

未来展望

智能镜还能做更多的功能,这是一个陆续发展过程。如有新功能上的建议,请不吝提供。让我知道你想在界面上的创意。不过请记住,少为美。:)

发布于 分类 Linux

树莓派安装Ubuntu 18 64位系统

开启强制HDMI输出:(很多现在的显示器在树莓派上并不能识别)
在TF卡分区,打开config.txt文件(开机后位置: /boot/config.txt),修改如下:

hdmi_safe=1
config_hdmi_boost=4
hdmi_ignore_edid=0xa5000080
hdmi_group=2
hdmi_mode=82
一些参数介绍:

项 含义
hdmi_safe=1 安全启动HDMI
config_hdmi_boost=4 开启热插拔
hdmi_group=1 CEA电视显示器
hdmi_group=2 DMT电脑显示器
hdmi_ignore_edid=0xa5000080 忽略自动探测的分辨率
输出分辨率:
hdmi_mode=4 640×480 60Hz
hdmi_mode=9 800×600 60Hz
hdmi_mode=16 1024×768 60Hz
hdmi_mode=82 1080p 60Hz
安装桌面方法
步骤一,安装Display Server。
sudo apt-get install –no-install-recommends xserver-xorg

sudo apt-get install –no-install-recommends xinit
步骤二,安装GUI桌面环境。
1,mate桌面环境

apt-get install ubuntu-mate-desktop

2,gnome桌面环境

apt-get install gnome

3,lxde桌面环境

apt-get install lxde

4,lxqt桌面环境

apt-get install lxqt

5,xubuntu桌面

apt-get install xubuntu-desktop

6,lubuntu桌面

apt-get install lubuntu-desktop

7,xfce桌面环境

apt-get install xfce4

8,cinnamon桌面环境

apt-get install cinnamon

9,bugie桌面环境

apt-get install ubuntu-budgie-desktop

这时,重启之后就完成了

发布于 分类 Linux

树莓派开机启动GUI程序

1、如果是lite版,先安装界面,https://www.raspberrypi.org/forums/viewtopic.php?f=66&t=133691

参考上面界面,多种界面添加方法及比较。

2、将我们的程序拷贝到树莓派,依赖库之类的也添加好。

3、要想启动自己的图形界面,就需要启动X server,这个东西是在你登录树莓派输入用户名和密码之前启动的,所以我们可以在启动树莓派之前和启动X server之后启动自己的程序,/etc/profile 这个文件就是这两个程序的中间,我们直接更改这个配置文件就行了

sudo nano /etc/profile
在文件开头输入你程序的路径prg,再执行你的程序guiprogram,如下:

cd /home/pi/prg
./guiprogram

另一种方法是增加环境变量,程序guiprogram在/home/pi/Downloads/dist/下,直接执行即可

# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
if [ "`id -u`" -eq 0 ]; then
  PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
else
  PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/home/pi/.local/bin:/home/pi/Downloads/dist"
fi
export PATH
guiprogram
发布于 分类 Linux

树莓派最小桌面系统

第1部分 – 建立基础

在这一部分,我们将专注于准备Raspbian Lite。

1、下载最新的Raspbian Lite图像。(https://www.raspberrypi.org/downloads/raspbian/
2、使用Win32DiskImager把Raspbian Lite刷SD中.
3、将SD / microSD卡插入Pi。
4、将Pi连接到Internet。以太网是最快的方式。否则我们必须使用Wi-Fi,则必须在Pi完成引导后。由于我们的WI-FI是隐藏的,所以需要修改:/etc/wpa_supplicant/wpa_supplicant.conf

#sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

在文件中加入以下:

4.1也可以使用树莓派来配置WI-FI

    4.1.1运行:

          #sudo raspi-config 

          1. 选择 Network Options

          2. WI-FI(选择后输入SSID密码就可以了)

5、连接电视/显示器和键盘(此时鼠标是可选的)打开Pi,Pi应该成功启动并出现登录提示。
6、登录Raspbian。用户名是pi,密码是raspberry

第2部分 – 更新系统到最新

    1、安装更新,如果提示确认请输入Y.

      #sudo apt-get update   

      #sudo apt-get upgrade

      #sudo apt-get dist-upgrade

   2、运行完成后需要做一个清理。

      #sudo apt-get clean

第3部分 – 设定本地化

  1、首先们需安装中文的字体,不然会乱码    

sudo apt-get install ttf-wqy-zenhei ttf-wqy-microhei 安装文泉驿字体,若有中文字体则省略 
  2 、使用配置本地地址: sudo raspi-config 
  3、选择第四项 locallisation Options 
  4、I1 change locale 
  5、zh_cn.UTF8 和UTF-8 zh_GBK 空格键选择后 tab键确认 
  6、再次选择zh_cn.UTF-8 
  7、重启 sudo reboot

第4部分 – 开始安装桌面。

    下一部分重点介绍如何在Raspbian Lite上安装GUI。为了拥有GUI,我们需要以下4件事

     1.显示服务器
     2.桌面环境
     3.窗口管理器
     4.登录管理器

1、打开你的Pi并登录。我们将安装Xorg。要执行此操作,请键入:

   sudo apt-get install –no-install-recommends xserver-xorg

 然后按Enter键。将要安装许多依赖软件包,但必须安装这些软件包才能使GUI正常工作。安装中如果需要确认请输入Y。

如果只安装xserver-xorg,则无法从命令行启动Xorg Display Server。我们还需要安装xinit:

   sudo apt-get install –no-install-recommends xinit

2、Raspberry Pi Desktop(RPD)GUI 选择你想要安装的桌面。

    这里我选择的是LXDE GUI 它运行占用资源少。

    sudo apt-get install lxde-core lxappearance

    安装中如果需要确认请输入Y。

3、登录管理器安装:

     sudo apt-get install lightdm  

安装完成后我们就可以使用桌面系统了。

     startx

运行完成以上命令就可以看到你自己安装的桌面了。

4、Pi用户自动登录:

   sudo raspi-config

  1. 选择Boot Options
  2. Desktop / CLT
  3. Desktop Autologin Desktop GUI 桌面环境
  4. finish
  5. reboot

以上我们就完成了最小桌面系统。

#参考官方主页:

https://www.raspberrypi.org/forums/viewtopic.php?t=133691

下面我们来安装一些必要的软件。

1.安装Wi-FI 管理软件。     

sudo apt-get install network-manager-gnome

运行就可以看到图标了。

nm-applet

2.安装一个文本编辑器。

sudo apt-get install mousepad

3.安装Chromium.

sudo apt-get install chromium-browser

好了你现在可以上网了。

发布于 分类 Linux

树莓派使用Lazarus

树莓派上的LazarusLazarus on Raspbian Wheezy

Raspberry Pi Logo.png

本文只适合 Raspberry Pi.

Raspberry Pi(数莓派)是一个信用卡大小的单板计算机。它由英国的Raspberry Pi基金为了激励在学校的计算机基础科学教学发起的。Raspberry Pis也可以用来作为媒体服务器以及其他用途机器人、控制工程等多种用途。 Raspberry Pi基金会推荐Raspbian Wheezy作为标准的操作系统。大家可以选择在RPI运行RISC OS、各种Linux发行版以及Android等操作系统。 Lazarus可以在原生的Raspbian操作系统下运行。

Contents

 [hide

安装与编译器Lazarus

在 Raspbian上简单安装

Raspberry Pi 1

在 Raspbian OS上,安装Lazarus与 Free Pascal很容易。打开命令行窗口输入下面的指令:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install fpc
sudo apt-get install lazarus

这里安装的是为Raspberry Pi预编译的稳定版FPC与Lazarus 。当然,需要有网络连接。安装过程大概需要30分钟,这个过程是自动完成等的。安装完成以后,你就可以从LXDE的开始菜单的“Programming”启动Lazarus了。

  • 安装步骤 1
  • 安装步骤 2
  • 安装步骤 3
  • 安装步骤 4

如果你需要一个新的版本,或者抱怨Lazarus 的问题, 点击.

Raspberry Pi 2

自2015六月起,普通的“out of the box”安装方法也适用于安装树莓派2的B型。但是安装时获得的版本是相当旧的。想要获得新版FPC和Lazarus请看链接 相关文章.

  • Lazarus “out of the box” on Raspberry Pi 2

从Windows 对Raspberry Pi的交叉编译

1. 使用 fpcup

使用fpcup是实现交叉编译的一种方法,输入下面的指令: fpcup#Linux_ARM_cross_compiler

2. 使用脚本

可以使用手动批处理文件,按照以下步骤。

2.1 先决条件

FPC 2.7.1或更高的安装源代码
下载并安装Windows版本的Linaro binutils for linux gnueabihf到%FPCPATH%/bin/win32-armhf-linux [1]

2.2 创建脚本(需要匹配实际路径)

set PATH=C:\pp\bin\i386-win32;%PATH%;
set FPCMAKEPATH=C:/pp
set FPCPATH=C:/pp
set OUTPATH=C:/pp271
%FPCMAKEPATH%/bin/i386-win32/make distclean OS_TARGET=linux CPU_TARGET=arm  CROSSBINDIR=%FPCPATH%/bin/win32-armhf-linux CROSSOPT="-CpARMV6 -CfVFPV2 -OoFASTMATH" FPC=%FPCPATH%/bin/i386-win32/ppc386.exe
%FPCMAKEPATH%/bin/i386-win32/make all OS_TARGET=linux CPU_TARGET=arm CROSSBINDIR=%FPCPATH%/bin/win32-armhf-linux CROSSOPT="-CpARMV6 -CfVFPV2 -OoFASTMATH" FPC=%FPCPATH%/bin/i386-win32/ppc386.exe
if errorlevel 1 goto quit
%FPCMAKEPATH%/bin/i386-win32/make crossinstall CROSSBINDIR=%FPCPATH%/bin/win32-armhf-linux CROSSOPT="-CpARMV6 -CfVFPV2 -OoFASTMATH" OS_TARGET=linux CPU_TARGET=arm FPC=%FPCPATH%/bin/i386-win32/ppc386.exe INSTALL_BASEDIR=%OUTPATH%
:quit
pause

使用生成的ppcrossarm.exe和 ARM RTL,你可以创建跨平台的Lazarus工程,生成Raspberry Pi和其他armhf设备的应用程序。 注意,这里不包括所有Window 库。

编译源代码

如果你想要从Subversion编译Lazarus源代码。请看 Michell Computing: Lazarus on the Raspberry Pi

  • How to start Lazarus in Raspbian Wheezy
  • Lazarus on Raspberry Pi
  • Numbering of GPIO pins

用Gentoo(及其他版本)在Raspberry上编译源码

  • Gentoo是一个基于Linux的自由操作系统

如果你想安装最新版的FPC及附件,或者是集成FPC编译器:请阅读下面的指南 这是关于Gentoo的例子,本指南适用其他版本:Install fpc on Raspberry with Gentoo

访问外部硬件

Raspberry Pi 外部连接引脚

Raspberry Pi的发展的目标之一是方便轻松地访问外部设备,如传感器和控制器。Lazarus有五种方法来访问I/O设备:

  1. 原生代码直接访问,使用BaseUnix单元
  2. 通过 封装外壳调用
  3. 通过 wiringPi 库.
  4. 使用单元 rpi_hal.
  5. 使用单元 PiGpio.
  6. 通过 PascalIO 库访问.

1. 原生代码直接访问

对Raspberry Pi的GPIO端口访问的简单测试程序程序访问GPIO的测试电路演示实现电路

这种访问外部硬件的方法,不需要额外的库。唯一的要求是baseunix库,这是Free Pascal的RTL部分。

通过GPIO端口控制开关

下面将演示一个简单程序。控制GPIO的17号引脚的电压,可以用来控制LED、晶体管或继电器。 程序包含GPIO17ToggleBox的实例ToggleBox和日志返回LogMemo类的实例TMemo

例如,一个LED的阳极连接到引脚11上(BCM2835 SoC对应的GPIO为17)和LED的阴极通过一个68欧姆的电阻连接引脚6(GND)。随后,LED会随着应用程序的toggle box切换点亮和熄灭。

该代码需要root权限运行,即从root帐号(不推荐)运行或通过“su ‘

控制单元:

unit Unit1;
{Demo application for GPIO on Raspberry Pi}
{Inspired by the Python input/output demo application by Gareth Halfacree}
{written for the Raspberry Pi User Guide, ISBN 978-1-118-46446-5}
{$mode objfpc}{$H+}
interface
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  Unix, BaseUnix;
type
  { TForm1 }
  TForm1 = class(TForm)
    LogMemo: TMemo;
    GPIO17ToggleBox: TToggleBox;
    procedure FormActivate(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure GPIO17ToggleBoxChange(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
const
  PIN_17: PChar = '17';
  PIN_ON: PChar = '1';
  PIN_OFF: PChar = '0';
  OUT_DIRECTION: PChar = 'out';
var
  Form1: TForm1;
  gReturnCode: longint; {stores the result of the IO operation}
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormActivate(Sender: TObject);
var
  fileDesc: integer;
begin
  { Prepare SoC pin 17 (pin 11 on GPIO port) for access: }
  try
    fileDesc := fpopen('/sys/class/gpio/export', O_WrOnly);
    gReturnCode := fpwrite(fileDesc, PIN_17[0], 2);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  finally
    gReturnCode := fpclose(fileDesc);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  end;
  { Set SoC pin 17 as output: }
  try
    fileDesc := fpopen('/sys/class/gpio/gpio17/direction', O_WrOnly);
    gReturnCode := fpwrite(fileDesc, OUT_DIRECTION[0], 3);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  finally
    gReturnCode := fpclose(fileDesc);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  end;
end;
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
var
  fileDesc: integer;
begin
  { Free SoC pin 17: }
  try
    fileDesc := fpopen('/sys/class/gpio/unexport', O_WrOnly);
    gReturnCode := fpwrite(fileDesc, PIN_17[0], 2);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  finally
    gReturnCode := fpclose(fileDesc);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  end;
end;
procedure TForm1.GPIO17ToggleBoxChange(Sender: TObject);
var
  fileDesc: integer;
begin
  if GPIO17ToggleBox.Checked then
  begin
    { Swith SoC pin 17 on: }
    try
      fileDesc := fpopen('/sys/class/gpio/gpio17/value', O_WrOnly);
      gReturnCode := fpwrite(fileDesc, PIN_ON[0], 1);
      LogMemo.Lines.Add(IntToStr(gReturnCode));
    finally
      gReturnCode := fpclose(fileDesc);
      LogMemo.Lines.Add(IntToStr(gReturnCode));
    end;
  end
  else
  begin
    { Switch SoC pin 17 off: }
    try
      fileDesc := fpopen('/sys/class/gpio/gpio17/value', O_WrOnly);
      gReturnCode := fpwrite(fileDesc, PIN_OFF[0], 1);
      LogMemo.Lines.Add(IntToStr(gReturnCode));
    finally
      gReturnCode := fpclose(fileDesc);
      LogMemo.Lines.Add(IntToStr(gReturnCode));
    end;
  end;
end;
end.

Main program:

program io_test;
{$mode objfpc}{$H+}
uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Interfaces, // this includes the LCL widgetset
  Forms, Unit1
  { you can add units after this };
{$R *.res}
begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

读取引脚的状态

读取一个GPIO引脚状态的演示程序程序访问GPIO的测试电路实际电路

当然也可以从GPIO端口读取一个开关的状态。

下面的简单例子非常类似于前一个例子。使用GPIO的18号引脚,控制二进制设备如开关输入,晶体管或继电器。这个程序包含一个名称为CheckBoxGPIO18CheckBox 与LogMemo的实例TMemo日志返回代码。

在实例中,第12引脚的一端连接一个按钮,按钮的一端(对应的GPIO引脚18的BCM2835 SoC)通过一个10欧姆的上拉电阻和引脚1连接(+3.3 V,看接线图)。按钮的另一端连接6号引脚(GND)。按钮的开关状态对应和程序中复选框的打开或关闭状态对应。

注意,当按钮释放时18脚的电位为高(由通过上拉电阻连接到引脚1),当按钮压下时电压为低(因为在这种情况下,引脚18是通过开关连接到GND)。因此,按钮按下时GPIO引脚信号为0,当释放时信号为1。

这个程序同样需要root权限

控制单元:

unit Unit1;
{Demo application for GPIO on Raspberry Pi}
{Inspired by the Python input/output demo application by Gareth Halfacree}
{written for the Raspberry Pi User Guide, ISBN 978-1-118-46446-5}
{This application reads the status of a push-button}
{$mode objfpc}{$H+}
interface
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ButtonPanel, Unix, BaseUnix;
type
  { TForm1 }
  TForm1 = class(TForm)
    ApplicationProperties1: TApplicationProperties;
    GPIO18CheckBox: TCheckBox;
    LogMemo: TMemo;
    procedure ApplicationProperties1Idle(Sender: TObject; var Done: Boolean);
    procedure FormActivate(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
  private
    { private declarations }
  public
    { public declarations }
  end;
const
  PIN_18: PChar = '18';
  IN_DIRECTION: PChar = 'in';
var
  Form1: TForm1;
  gReturnCode: longint; {stores the result of the IO operation}
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormActivate(Sender: TObject);
var
  fileDesc: integer;
begin
  { Prepare SoC pin 18 (pin 12 on GPIO port) for access: }
  try
    fileDesc := fpopen('/sys/class/gpio/export', O_WrOnly);
    gReturnCode := fpwrite(fileDesc, PIN_18[0], 2);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  finally
    gReturnCode := fpclose(fileDesc);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  end;
  { Set SoC pin 18 as input: }
  try
    fileDesc := fpopen('/sys/class/gpio/gpio18/direction', O_WrOnly);
    gReturnCode := fpwrite(fileDesc, IN_DIRECTION[0], 2);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  finally
    gReturnCode := fpclose(fileDesc);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  end;
end;
procedure TForm1.ApplicationProperties1Idle(Sender: TObject; var Done: Boolean);
var
  fileDesc: integer;
  buttonStatus: string[1] = '1';
begin
  try
    { Open SoC pin 18 (pin 12 on GPIO port) in read-only mode: }
    fileDesc := fpopen('/sys/class/gpio/gpio18/value', O_RdOnly);
    if fileDesc > 0 then
    begin
      { Read status of this pin (0: button pressed, 1: button released): }
      gReturnCode := fpread(fileDesc, buttonStatus[1], 1);
      LogMemo.Lines.Add(IntToStr(gReturnCode) + ': ' + buttonStatus);
      LogMemo.SelStart := Length(LogMemo.Lines.Text) - 1;
      if buttonStatus = '0' then
        GPIO18CheckBox.Checked := true
      else
        GPIO18CheckBox.Checked := false;
    end;
  finally
    { Close SoC pin 18 (pin 12 on GPIO port) }
    gReturnCode := fpclose(fileDesc);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
    LogMemo.SelStart := Length(LogMemo.Lines.Text) - 1;
  end;
end;
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
var
  fileDesc: integer;
begin
  { Free SoC pin 18: }
  try
    fileDesc := fpopen('/sys/class/gpio/unexport', O_WrOnly);
    gReturnCode := fpwrite(fileDesc, PIN_18[0], 2);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  finally
    gReturnCode := fpclose(fileDesc);
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  end;
end;
end.

上面的例子主程序是相同的,。

2. 通过封装的外壳访问硬件

访问硬件的另一种方法是通过封装终端命令。这是通过使用fpsystem功能。这种方法可以访问baseunix单元不支持的功能。下面的代码实现了一个具有相同功能的程序,该程序是从上面的第一个清单所产生的。

控制单元:

unit Unit1;
{Demo application for GPIO on Raspberry Pi}
{Inspired by the Python input/output demo application by Gareth Halfacree}
{written for the Raspberry Pi User Guide, ISBN 978-1-118-46446-5}
{$mode objfpc}{$H+}
interface
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls, Unix;
type
  { TForm1 }
  TForm1 = class(TForm)
    LogMemo: TMemo;
    GPIO17ToggleBox: TToggleBox;
    procedure FormActivate(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure GPIO17ToggleBoxChange(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
var
  Form1: TForm1;
  gReturnCode: longint; {stores the result of the IO operation}
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormActivate(Sender: TObject);
begin
  { Prepare SoC pin 17 (pin 11 on GPIO port) for access: }
  gReturnCode := fpsystem('echo "17" > /sys/class/gpio/export');
  LogMemo.Lines.Add(IntToStr(gReturnCode));
  { Set SoC pin 17 as output: }
  gReturnCode := fpsystem('echo "out" > /sys/class/gpio/gpio17/direction');
  LogMemo.Lines.Add(IntToStr(gReturnCode));
end;
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  { Free SoC pin 17: }
  gReturnCode := fpsystem('echo "17" > /sys/class/gpio/unexport');
  LogMemo.Lines.Add(IntToStr(gReturnCode));
end;
procedure TForm1.GPIO17ToggleBoxChange(Sender: TObject);
begin
  if GPIO17ToggleBox.Checked then
  begin
    { Swith SoC pin 17 on: }
    gReturnCode := fpsystem('echo "1" > /sys/class/gpio/gpio17/value');
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  end
  else
  begin
    { Switch SoC pin 17 off: }
    gReturnCode := fpsystem('echo "0" > /sys/class/gpio/gpio17/value');
    LogMemo.Lines.Add(IntToStr(gReturnCode));
  end;
end;
end.

主程序与上面的例子相同。这个程序必须用根权限执行。

3. wiringPi方法与函数

Alex Schaller封装的Gordon Henderson的Arduino兼容wiringpi库,提供了一种类似Arduino电路板的编码方案。

Function wiringPiSetup:longint: 使用wiringpi引脚编号方案初始化wiringpi系统

Procedure wiringPiGpioMode(mode:longint): 用Broadcom的GPIO引脚编号方案wiringpi初始化系统。

Procedure pullUpDnControl(pin:longint; pud:longint): 控制内部GPIO引脚上拉/下拉电阻。

Procedure pinMode(pin:longint; mode:longint): 设置一个PIN的模式:输入、输出或pwm_output。

Procedure digitalWrite(pin:longint; value:longint): 设置一个输出位。

Procedure pwmWrite(pin:longint; value:longint): 设置一个输出PWM(脉宽调制)值,0到1024之间。

Function digitalRead(pin:longint):longint: 读取一个给定引脚的值,返回1或0。

Procedure delay(howLong:dword): 等待多少毫秒。

Procedure delayMicroseconds(howLong:dword): 等待多少微秒。

Function millis:dword: 返回程序调用wiringpisetup函数花费的毫秒数。

4. rpi_hal-hardware抽象库 (GPIO, I2C and SPI 函数与方法)

这个单元大约1700行代码,由Stefan Fischer提供,提供程序和函数访问RPI硬件I2C,SPI和GPIO:

下面是函数和方法的摘录:

procedure gpio_set_pin (pin:longword;highlevel:boolean); { 设置 RPi GPIO 引脚速率为高或低; 速率 @ 700MHz -> 0.65MHz }

function gpio_get_PIN (pin:longword):boolean; { 获取 RPi GPIO 引脚等级,当Pin为’1’时返回True,为’0’时返回false; 速率 @ 700MHz -> 1.17MHz } 

procedure gpio_set_input (pin:longword); { 设置 RPi GPIO 引脚为直接输入}

procedure gpio_set_output(pin:longword); { 设置 RPi GPIO 引脚为直接输出 }

procedure gpio_set_alt (pin,altfunc:longword); { 设置 RPi GPIO 引脚为备用功能 0..5 }

procedure gpio_set_gppud (mask:longword); { 设置RPI GPIO拉上/下登记(gppud)}

function rpi_snr :string; { 信噪比: 0000000012345678 }

function rpi_hw  :string; { 处理器类型: BCM2708 }

function rpi_proc:string; { ARMv6-compatible processor rev 7 (v6l) }

function i2c_bus_write(baseadr,reg:word; var data:databuf_t; lgt:byte; testnr:integer) : integer;

function i2c_bus_read (baseadr,reg:word; var data:databuf_t; lgt:byte; testnr:integer) : integer;

function i2c_string_read(baseadr,reg:word; var data:databuf_t; lgt:byte; testnr:integer) : string;

function i2c_string_write(baseadr,reg:word; s:string; testnr:integer) : integer;

procedure SPI_Write(devnum:byte; reg,data:word);

function SPI_Read(devnum:byte; reg:word) : byte;

procedure SPI_BurstRead2Buffer (devnum,start_reg:byte; xferlen:longword);

procedure SPI_BurstWriteBuffer (devnum,start_reg:byte; xferlen:longword); { 从缓冲区SPI的地址写入一段字节的内容 }

… 

测试程序 (testrpi.pas):

//Simple Test program, which is using rpi_hal;
  program testrpi;
  uses rpi_hal;
  begin
    writeln('Show CPU-Info, RPI-HW-Info and Registers:');
    rpi_show_all_info;
    writeln('Let Status LED Blink. Using GPIO functions:');
    GPIO_PIN_TOGGLE_TEST;
    writeln('Test SPI Read function. (piggy back board with installed RFM22B Module is required!)');
    Test_SPI;
  end.

5. 底层pascal单元 PiGpio(代替wiringpi C语言库的GPIO控制)

这个单元 (pigpio.pas[2]) 270 行代码是由Gabor Szollosi提供的 , 运行速度飞快(例如GPIO引脚输出开关频率达到8MHz) :

unit PiGpio;
{
 BCM2835 GPIO Registry Driver, also can use to manipulate cpu other registry areas
 This code is tested only Broadcom bcm2835 cpu, different arm cpus may need different
 gpio driver implementation
 2013 Gabor Szollosi
}
{$mode objfpc}{$H+}
interface
uses
  Classes, SysUtils;
const
  REG_GPIO = $20000;//bcm2835 gpio register 0x2000 0000. new fpMap uses page offset, one page is 4096bytes
  // hex 0x1000 so simply calculate 0x2000 0000 / 0x1000  = 0x2000 0
  PAGE_SIZE = 4096;
  BLOCK_SIZE = 4096;
    // The BCM2835 has 54 GPIO pins.
//	BCM2835 data sheet, Page 90 onwards.
//	There are 6 control registers, each control the functions of a block
//	of 10 pins.
  CLOCK_BASE = (REG_GPIO + $101);
  GPIO_BASE =  (REG_GPIO + $200);
  GPIO_PWM =   (REG_GPIO + $20C);
     INPUT = 0;
     OUTPUT = 1;
     PWM_OUTPUT = 2;
     LOW = False;
     HIGH = True;
     PUD_OFF = 0;
     PUD_DOWN = 1;
     PUD_UP = 2;
   // PWM
  PWM_CONTROL = 0;
  PWM_STATUS  = 4;
  PWM0_RANGE  = 16;
  PWM0_DATA   = 20;
  PWM1_RANGE  = 32;
  PWM1_DATA   = 36;
  PWMCLK_CNTL =	160;
  PWMCLK_DIV  =	164;
  PWM1_MS_MODE    = $8000;  // Run in MS mode
  PWM1_USEFIFO    = $2000; // Data from FIFO
  PWM1_REVPOLAR   = $1000;  // Reverse polarity
  PWM1_OFFSTATE   = $0800;  // Ouput Off state
  PWM1_REPEATFF   = $0400;  // Repeat last value if FIFO empty
  PWM1_SERIAL     = $0200;  // Run in serial mode
  PWM1_ENABLE     = $0100;  // Channel Enable
  PWM0_MS_MODE    = $0080;  // Run in MS mode
  PWM0_USEFIFO    = $0020;  // Data from FIFO
  PWM0_REVPOLAR   = $0010;  // Reverse polarity
  PWM0_OFFSTATE   = $0008;  // Ouput Off state
  PWM0_REPEATFF   = $0004;  // Repeat last value if FIFO empty
  PWM0_SERIAL     = $0002;  // Run in serial mode
  PWM0_ENABLE     = $0001;  // Channel Enable
type
  { TIoPort }
  TIoPort = class // IO bank object
  private         //
    //function get_pinDirection(aPin: TGpIoPin): TGpioPinConf;
  public
   FGpio: ^LongWord;
   FClk: ^LongWord;
   FPwm: ^LongWord;
   procedure SetPinMode(gpin, mode: byte);
   function GetBit(gpin : byte):boolean;inline; // gets pin bit}
   procedure ClearBit(gpin : byte);inline;// write pin to 0
   procedure SetBit(gpin : byte);inline;// write pin to 1
   procedure SetPullMode(gpin, mode: byte);
   procedure PwmWrite(gpin : byte; value : LongWord);inline;// write pin to pwm value
  end;
  { TIoDriver }
  TIoDriver = class
  private
  public
    destructor Destroy;override;
    function MapIo:boolean;// creates io memory mapping
    procedure UnmapIoRegisrty(FMap: TIoPort);// close io memory mapping
    function CreatePort(PortGpio, PortClk, PortPwm: LongWord):TIoPort; // create new IO port
  end;
var
    fd: integer;// /dev/mem file handle
procedure delayNanoseconds (howLong : LongWord);
implementation
uses
  baseUnix, Unix;
procedure delayNanoseconds (howLong : LongWord);
var
  sleeper, dummy : timespec;
begin
  sleeper.tv_sec  := 0 ;
  sleeper.tv_nsec := howLong ;
  fpnanosleep (@sleeper,@dummy) ;
end;
{ TIoDriver }
//*******************************************************************************
destructor TIoDriver.Destroy;
begin
  inherited Destroy;
end;
//*******************************************************************************
function TIoDriver.MapIo: boolean;
begin
 Result := True;
 fd := fpopen('/dev/mem', O_RdWr or O_Sync); // Open the master /dev/memory device
  if fd < 0 then
  begin
    Result := False; // unsuccessful memory mapping
  end;
 //
end;
//*******************************************************************************
procedure TIoDriver.UnmapIoRegisrty(FMap:TIoPort);
begin
  if FMap.FGpio <> nil then
 begin
   fpMUnmap(FMap.FGpio,PAGE_SIZE);
   FMap.FGpio := Nil;
 end;
 if FMap.FClk <> nil then
 begin
   fpMUnmap(FMap.FClk,PAGE_SIZE);
   FMap.FClk := Nil;
 end;
 if FMap.FPwm <> nil then
 begin
   fpMUnmap(FMap.FPwm ,PAGE_SIZE);
   FMap.FPwm := Nil;
 end;
end;
//*******************************************************************************
function TIoDriver.CreatePort(PortGpio, PortClk, PortPwm: LongWord): TIoPort;
begin
  Result := TIoPort.Create;// new io port, pascal calls new fpMap, where offst is page sized 4096 bytes!!!
  Result.FGpio := FpMmap(Nil, PAGE_SIZE, PROT_READ or PROT_WRITE, MAP_SHARED, fd, PortGpio); // port config gpio memory
  Result.FClk:= FpMmap(Nil, PAGE_SIZE, PROT_READ or PROT_WRITE, MAP_SHARED, fd, PortClk);; // port clk
  Result.FPwm:= FpMmap(Nil, PAGE_SIZE, PROT_READ or PROT_WRITE, MAP_SHARED, fd, PortPwm);; // port pwm
end;
//*******************************************************************************
procedure TIoPort.SetPinMode(gpin, mode: byte);
var
  fSel, shift, alt : byte;
  gpiof, clkf, pwmf : ^LongWord;
begin
  fSel := (gpin div 10)*4 ;  //Select Gpfsel 0 to 5 register
  shift := (gpin mod 10)*3 ;  //0-9 pin shift
  gpiof := Pointer(LongWord(Self.FGpio)+fSel);
  if (mode = INPUT) then
    gpiof^ := gpiof^ and ($FFFFFFFF - (7 shl shift))  //7 shl shift komplemens - Sets bits to zero = input
  else if (mode = OUTPUT) then
  begin
    gpiof^ := gpiof^ and ($FFFFFFFF - (7 shl shift)) or (1 shl shift);
  end
  else if (mode = PWM_OUTPUT) then
  begin
    Case gpin of
      12,13,40,41,45 : alt:= 4 ;
      18,19          : alt:= 2 ;
      else alt:= 0 ;
    end;
    If alt > 0 then
    begin
      gpiof^ := gpiof^ and ($FFFFFFFF - (7 shl shift)) or (alt shl shift);
      clkf := Pointer(LongWord(Self.FClk)+PWMCLK_CNTL);
      clkf^ := $5A000011 or (1 shl 5) ;                  //stop clock
      delayNanoseconds(200);
      clkf := Pointer(LongWord(Self.FClk)+PWMCLK_DIV);
      clkf^ := $5A000000 or (32 shl 12) ;	// set pwm clock div to 32 (19.2/3 = 600KHz)
      clkf := Pointer(LongWord(Self.FClk)+PWMCLK_CNTL);
      clkf^ := $5A000011 ;                               //start clock
      Self.ClearBit(gpin);
      pwmf := Pointer(LongWord(Self.FPwm)+PWM_CONTROL);
      pwmf^ := 0 ;		 	        // Disable PWM
      delayNanoseconds(200);
      pwmf := Pointer(LongWord(Self.FPwm)+PWM0_RANGE);
      pwmf^ := $400 ;                             //max: 1023
      delayNanoseconds(200);
      pwmf := Pointer(LongWord(Self.FPwm)+PWM1_RANGE);
      pwmf^ := $400 ;                             //max: 1023
      delayNanoseconds(200);
      // Enable PWMs
      pwmf := Pointer(LongWord(Self.FPwm)+PWM0_DATA);
      pwmf^ := 0 ;                                //start value
      pwmf := Pointer(LongWord(Self.FPwm)+PWM1_DATA);
      pwmf^ := 0 ;                                //start value
      pwmf := Pointer(LongWord(Self.FPwm)+PWM_CONTROL);
      pwmf^ := PWM0_ENABLE or PWM1_ENABLE ;
    end;
  end;
end;
//*******************************************************************************
procedure TIoPort.SetBit(gpin : byte);
var
   gpiof : ^LongWord;
begin
  gpiof := Pointer(LongWord(Self.FGpio) + 28 + (gpin shr 5) shl 2);
  gpiof^ := 1 shl gpin;
end;
//*******************************************************************************
procedure TIoPort.ClearBit(gpin : byte);
var
   gpiof : ^LongWord;
begin
  gpiof := Pointer(LongWord(Self.FGpio) + 40 + (gpin shr 5) shl 2);
  gpiof^ := 1 shl gpin;
end;
//*******************************************************************************
function TIoPort.GetBit(gpin : byte):boolean;
var
   gpiof : ^LongWord;
begin
  gpiof := Pointer(LongWord(Self.FGpio) + 52 + (gpin shr 5) shl 2);
  if (gpiof^ and (1 shl gpin)) = 0 then Result := False else Result := True;
end;
//*******************************************************************************
procedure TIoPort.SetPullMode(gpin, mode: byte);
var
   pudf, pudclkf : ^LongWord;
begin
  pudf := Pointer(LongWord(Self.FGpio) + 148 );
  pudf^ := mode;   //mode = 0, 1, 2 :Off, Down, Up
  delayNanoseconds(200);
  pudclkf := Pointer(LongWord(Self.FGpio) + 152 + (gpin shr 5) shl 2);
  pudclkf^ := 1 shl gpin ;
  delayNanoseconds(200);
  pudf^ := 0 ;
  pudclkf^ := 0 ;
end;
//*******************************************************************************
procedure TIoPort.PwmWrite(gpin : byte; value : Longword);
var
   pwmf : ^LongWord;
   port : byte;
begin
  Case gpin of
      12,18,40 : port:= PWM0_DATA ;
      13,19,41,45 : port:= PWM1_DATA ;
      else exit;
  end;
  pwmf := Pointer(LongWord(Self.FPwm) + port);
  pwmf^ := value and $FFFFFBFF; // $400 complemens
end;
//*******************************************************************************
end.

Controlling Lazarus unit:(Project files[3])

unit Unit1;
{Demo application for GPIO on Raspberry Pi}
{Inspired by the Python input/output demo application by Gareth Halfacree}
{written for the Raspberry Pi User Guide, ISBN 978-1-118-46446-5}
{$mode objfpc}{$H+}
interface
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, Unix, PiGpio;
type
  { TForm1 }
  TForm1 = class(TForm)
    GPIO25In: TButton;
    SpeedButton: TButton;
    LogMemo: TMemo;
    GPIO23switch: TToggleBox;
    Timer1: TTimer;
    GPIO18Pwm: TToggleBox;
    Direction: TToggleBox;
    procedure DirectionChange(Sender: TObject);
    procedure GPIO18PwmChange(Sender: TObject);
    procedure GPIO25InClick(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure GPIO23switchChange(Sender: TObject);
    procedure SpeedButtonClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
const
     INPUT = 0;
     OUTPUT = 1;
     PWM_OUTPUT = 2;
     LOW = False;
     HIGH = True;
     PUD_OFF = 0;
     PUD_DOWN = 1;
     PUD_UP = 2;
 // Convert Raspberry Pi P1 pins (Px) to GPIO port
     P3 = 0;
     P5 = 1;
     P7 = 4;
     P8 = 14;
     P10 = 15;
     P11 = 17;
     P12 = 18;
     P13 = 21;
     P15 = 22;
     P16 = 23;
     P18 = 24;
     P19 = 10;
     P21 = 9;
     P22 = 25;
     P23 = 11;
     P24 = 8;
     P26 = 7;
var
  Form1: TForm1;
  GPIO_Driver: TIoDriver;
  GpF: TIoPort;
  PWM :Boolean;
  i, d : integer;
  Pin,Pout,Ppwm : byte;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormActivate(Sender: TObject);
begin
  if not GPIO_Driver.MapIo then
  begin
     LogMemo.Lines.Add('Error mapping gpio registry');
  end
  else
  begin
    GpF := GpIo_Driver.CreatePort(GPIO_BASE, CLOCK_BASE, GPIO_PWM);
  end ;
  Timer1.Enabled:= True;
  Timer1.Interval:= 25;     //25 ms controll interval
  Pin := P22;
  Pout := P16;
  Ppwm := P12;
  i:=1;
  GpF.SetPinMode(Pout,OUTPUT);
  GpF.SetPinMode(Pin,INPUT);
  GpF.SetPullMode(Pin,PUD_Up);    // Input PullUp High level
end;
procedure TForm1.GPIO25InClick(Sender: TObject);
begin
  If GpF.GetBit(Pin) then LogMemo.Lines.Add('In: '+IntToStr(1))
                     else LogMemo.Lines.Add('In: '+IntToStr(0));
end;
procedure TForm1.GPIO18PwmChange(Sender: TObject);
begin
  if GPIO18Pwm.Checked then
  begin
    GpF.SetPinMode(Ppwm,PWM_OUTPUT);
    PWM := True;                          //PWM on
  end
  else
  begin
    GpF.SetPinMode(Ppwm,INPUT);
    PWM := False;                          //PWM off
  end;
end;
procedure TForm1.DirectionChange(Sender: TObject);
begin
  if Direction.Checked then d:=10 else d:=-10;
end;
procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
    GpF.SetPinMode(Ppwm,INPUT);
    GpF.ClearBit(Pout);
    GpIo_Driver.UnmapIoRegisrty(GpF);
end;
procedure TForm1.GPIO23switchChange(Sender: TObject);
Begin
  Timer1.Enabled := False;
  if GPIO23switch.Checked then
  begin
    GpF.SetBit(Pout); //Turn LED on
  end
  else
  begin
    GpF.ClearBit(Pout); //Turn LED off
  end;
  Timer1.Enabled := True;
end;
procedure TForm1.SpeedButtonClick(Sender: TObject);
var
  i,p,k,v: longint;
  ido:TDateTime;
begin
  ido:= Time;
  k:= TimeStampToMSecs(DateTimeToTimeStamp(ido));
  LogMemo.Lines.Add('Start: '+TimeToStr(ido));
  p:=10000000 ;
  For i:=1 to p  do Begin
    GpF.SetBit(P16);
    GpF.ClearBit(P16);
  end;
  ido:= Time;
  v:= TimeStampToMSecs(DateTimeToTimeStamp(ido));
  LogMemo.Lines.Add('Stop: '+TimeToStr(ido)+' Frequency: '+
                                IntToStr(p div (v-k))+' kHz');
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
  If PWM then Begin
    If (d > 0) and (i+d < 1024) then begin
          i:=i+d;
          GpF.PwmWrite(Ppwm,i);
    end ;
    If (d < 0) and (i+d > -1) then begin
          i:=i+d;
          GpF.PwmWrite(Ppwm,i);
    end;
  end;
end;
end.
发布于 分类 Linux

基于树莓派搭建个人服务器

No.1

前言
由于本人在这段时候,看到了一个叫做树莓派的东东,初步了解之后觉得很有意思,于是想把整个过程记录下来。

No.2

树莓派是什么?

Raspberry Pi(中文名为树莓派,简写为 RPi,(或者 RasPi / RPI) 是为学习计算机编程教育而设计),只有信用卡大小的微型电脑,其系统基于 Linux。随着 Windows 10 IoT 的发布,我们也将可以用上运行 Windows 的树莓派。

自问世以来,受众多计算机发烧友和创客的追捧,曾经一“派”难求。别看其外表“娇小”,内“心”却很强大,视频、音频等功能通通皆有,可谓是麻雀虽小,五脏俱全。

1. 用我的话理解

用我的话理解就是树莓派就是一台主机,你可以外接显示器,键盘鼠标,u盘等等外设,因为它体积很小,而且又有很多串口和外接的口,可以直接调用很多底层硬件。

2. 市面上的型号

市面上大多是 3 代 B+ 型,淘宝一搜树莓派一大堆都是,价钱纯主板(不要任何外设)在 230+ 左右,有点小贵,超过我的预算,所以我继续寻找廉价的,终于让我发现了一款 100+ 的树莓派。

3. 树莓派 zero w

树莓派 zero w 是一款 mini 的树莓派,体质只有 3b+ 的 1/3。实际到手后,你会发现它真的超级小,超级可爱。以下是我的实物图,你可以看看大小到底有多 mini。

你可以看到,最上面是一根普通的黑色签字笔,接下来是一个即插即用型的外接 wifi 网卡,然后是一个 USB 读卡器,最底下的就是我们今天的主角 zero w。它真的超级小,有木有。真的是完美的诠释了那句“麻雀虽小,五脏俱全”的话。

zero w 这款树莓派的主要参数如下:•  BCM2835 处理器,1GHz 主频,512MB RAM•  BCM43438 WiFi / BT 芯片•  micro-USB 电源接口•  micro-USB OTG 接口•  miniHDMI 端口•  复合视频和重置扩展接口•  脆弱的 CSI 摄像头接口•  micro-SD 卡座,存放操作系统•  40-pin GPIO 扩展接口•  尺寸:65mm*30mm你别看它的 cpu 只有 1 核,内存只有 512MB,就觉得它可能什么都做不了,但是实际上它的性能还是很好的,用于跑一个网站真的是小 case。

4. 更多树莓派

关于更多树莓派型号或者使用教程你可以去树莓派实验室这个网站,上面有丰富的资源。

No.3

树莓派zero w安装系统

1. 准备

你可能提前需要准备的东西如下:

•  16GB or 32GB 的 SanDisk 内存卡(注意是以前那种放在手机上,很小的哦)

•  一根最普通不过的 usb 安卓数据线(not type-c)

•  u 盘格式化工具(推荐使用 SDFormatter)

•  系统烧写工具(Win32DiskImager)

•  树莓派系统(可以去官网下载)

我使用的是 Raspbian Stretch Lite 这个系统镜像,这个系统是官方制作的,lite 是无桌面版的,只有黑漆漆的控制台,优点是体积小,省性能和内存。

名字带有 desktop 的是有桌面 ui 的,对不熟悉 liunx 系统的朋友可能更友好,但是体积很大,占用的性能也会更高。

2. 第一步下载系统镜像

下载好你需要的系统镜像后,如下图

一开始只有一个 zip 的压缩包,大小大概 360MB 左右,你需要把它解压,得到上图的文件夹。

然后进入文件夹可以看到一个 img 的镜像,大小为 1.7GB 左右。

ps:这个官方的 Raspbian 镜像,如果是其他第三方的镜像,可能下载后的压缩包解压后不是 img 镜像,这种情况请另行百度解决。

3. 使用 Win32DiskImager 往内存卡中写入镜像

把内存卡插入读卡器后,插入电脑。

打开 Win32DiskImager 软件后,选择 img 镜像,设备选择你的 U 盘,然后点击写入就可以了,写入完成后会弹出成功的提示框。

ps: 我上图没有选择设备,因为的没插入读卡器,仅仅是示范而已

4. 修改 boot 分区的文件

先别急着拔出读卡器,此时,我们电脑可以看到 u 盘中只有一个名为 boot 的分区,大小可能只有 40MB 左右,不要着急,因为 window 不识别内存卡中 liunx 系统的其他分区。 

4.1 新建 ssh 文件

因为我们的 zero w 有一个 mini hdmi 的接口,但是我不需要屏幕,所以需要使用 ssh 连接到 zero w 中的系统,所以需要在第一次开机就能开启 ssh 功能。

我们进入 boot 分区内,然后新建一个名为 ssh 的文件,注意不要后缀名!!!!也不要往里面写任何东西!!

4.2 新建 wpa_supplicant.conf 文件

因为 ssh 连接是需要 ip 地址的,所以我们需要将 zero w 在第一次开机自动连接 wifi,使其和我们的电脑处于一个局域网,这样我们才可以通过 ssh 连接到 zero w 的系统。

同样的在 boot 分区内,新建一个名为 wpa_supplicant.conf 的文件,然后往里面写入如下内容后保存:

country=CN
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
ssid="你的wifi名字"
psk="你的wifi密码"
}

5. 组装我们的最小主机并连接

取出读卡器中的内存卡,然后插入到 zero w 中,使用一根 usb 安卓数据线连接电源(5V1A)即可。

等待几分钟,期间我们的 zero w 的指示灯会一直闪烁,很正常,等待指示灯常亮的时候,我们去路由器上,查看一下树莓派的 ip 地址。

可以看到我们 zero w 的 ip 为 192.168.0.104,然后使用 ssh 连接工具(推荐使用 putty)连接树莓派,初始账户为 pi,密码是 raspberry。

连接成功,如上图所示。这样我们的系统就正确无误的安装好了。

ps: 如果是手机开启热点当做一个路由器的话,咱们手机下载一个名叫 android terminal 的 app,然后输入 ip neigh 指令,就可以查到连接到手机的设备的 ip 信息了。

6. 优化咱们树莓派的系统

6.1 修改源

因为国外的源,咱们在国内的连接过去网速很慢,所以我们需要修改为国内的源,我修改的是中科大的源。

6.1.1 修改 sources.list 文件

sudo nano /etc/apt/sources.list
--注释其他内容,添加以下:
deb http://mirrors.ustc.edu.cn/raspbian/raspbian/raspbian stretch main contrib non-free rpi

6.1.2 修改 raspi.list 文件

sudo nano /etc/apt/sources.list.d/raspi.list
--注释其他内容,添加以下:
deb http://mirrors.ustc.edu.cn/archive.raspberrypi.org/debian stretch main ui
6.1.3 执行更新
sudo apt-get update
sudo apt-get upgrade

6.2 修改时区

sudo dpkg-reconfigure tzdata

找到亚洲 Asia,然后选择 shanghai 就可以了。

6.3 开机自启 ssh

第一种:

sudo raspi-config

进入选择找到 interfacing option 选择,然后找到 ssh,按回车使能 enable 就可以了。

第二种:

在终端命令行中启动 SSH 服务后,如果系统重启或关机后启动,SSH 服务默认是关闭的,依然需要手动启动,为了方便可以设置 SSH 服务开机自动启动,打开 /etc/rc.local 文件,在语句 exit 0 之前加入:/etc/init.d/ssh start

建议都试试,反之我的是可以了。

7. 安装 nginx

#安装
sudo apt-get install nginx
#启动
sudo /etc/init.d/nginx start
#重启
sudo /etc/init.d/nginx restart
#停止
sudo /etc/init.d/nginx stop

打开浏览器访问 192.168.0.104(你的树莓派 ip 地址),可以看到 nginx 的页面,说明安装好了。

可以正常的看到页面了,但是这样只能在内网(局域网中)看到,我想让所有人都可以访问怎么办?

8. 内网穿透

内网穿透,意思就是将内网(本地)的 web 应用通过 nat 穿透到公网上,从而让别人可以访问到。

内网穿透目前主要由 ngrok 和 frp 两种,都非常好用,国内 ngrok 免费的有 ittun、sunny 和 natapp,这三个都是免费的,前面两个可以自定义域名,后面的需要 vip 版本才可以自定义域名。

我这三种都试过,我发现 sunny 的 arm 版本的 ngrok 客户端在我的树莓派运行不了,ittun 的和 natpp 的 ngrok 都可以,由于需要自定义域名,我使用的是 ittun 的 ngrok_arm 版本的。

使用方法这三者官网都有详细说明,大家自行查看。

现在,树莓派网站已经搭建完成,可以访问http://mixdiy.com

因为需要 ngrok 在后台运行,所以我用的是 screen 会话使其可以在后台运行。但是开启自启,还没有实现,万一断电或者断网了,我必须手动去运行一下 ngrok,这是目前没有解决的痛点。

9. 更多

树莓派不仅仅只是可以用于运行一个网站,还有很多很多的功能等待你的开发,可以多去看看树莓派实验室里面,很多大神都写了很多实用的教程。

我的 zero w 状态信息如下:

在上面开启了一个 nginx 和 ngrok 服务,内存剩余还有 250MB,还是很舒服的,cpu 温度也不算高,运行两天了,基本在 37-39 之间。

发布于 分类 Linux

树莓派被曝明年开春上市

根据英国《每日电讯报》的报道,树莓派可能很快就会以超过 3.7 亿英镑(4.93 亿美元)的价格上市。

目前,树莓派已聘请 Stifel 和 Liberum 这两家投资银行的顾问为该公司在 2022 年春季上市提供建议。该消息是在树莓派从 Lansdowne Partners 和 Ezrah Charitable 获得 4500 万英镑(6000 万美元)投资后几个月发布的。据消息人士透漏,树莓派的估值溢价约为 5 亿美元。 

树莓派首席执行官 Eben Upton 在接受《每日电讯报》采访时表示,树莓派一直在研究如何为企业的未来提供资金。“显然,我们在9月份筹集的4500万美元消除了一些关于我们如何为未来融资的紧迫感。另一方面,我们对未来五年要做的事情有很好的计划。” 
据悉,这不是树莓派第一次考虑上市。今年3月,《每日电讯报》曾报道了树莓派上市的可能性。

树莓派发展历史树莓派创始人Eben Upton 在牛津大学教书时,发现学生们计算机的编程能力很差,因为当时计算机很贵且并不普及,为了解决这个问题,他便辞职进入博通工作,制作一个编程开发平台。
2012年3月,Eben Upton正式发售世界上最小的台式机,又称卡片式电脑,外形只有信用卡大小,却具有电脑的所有基本功能,这就是Raspberry Pi电脑板,中文译名”树莓派”。
这块树莓派基于ARM微型电脑主板制作,拥有PC所有基本功能,可以全部在一张信用卡大小的主板上。在Linux系统的加持下,树莓派只需要几行代码,就可以制作出有趣的项目。刚开始的树莓派配置不高,但一经推出后,受到了各界的喜爱,树莓派很快就卖完了,响应也特别好,后来为了维护 ,树莓派也在不断的升级,直到现在已经到了4B版本。

树莓派历代版本简介第一代的树莓派包括多个版本:A, A+, B, B+ ,国内常见的是 B 版本,A 版实际上没有发售A 版是 B 版的简化版。树莓派首先发行的是 B 版本。

树莓派 B

树莓派B型内置512MB内存,带两个USB端口,带100M有线网接口。配置:

BroadcomBCM2835

ARM1176JZF-S核心(ARM11)700MHz

内存:512MByte

双核多媒体协处理器(采用VideoCore IV技术)

1个SD/MMC/SDIO接口、1个0/100以太网接口、2个USB host 接口、1个3.5mm音频插孔,1个HDMI视频接口、1个RCA视频接口,1个26pin扩展口(支持SPI.I2C、UART)2013年2月国内厂商深圳韵动电子取得了该产品在国内的生产及销售权限,为了便于区分市场,树莓派基金会规定韵动电子在中国大陆销售的树莓派一律采用红色的PCB。

树莓派 A

Model A基本上可以认为是树莓派Model B的廉价版本,没有网络接口,内存容量也进一步缩小。树莓派A型(未发售)内置256MB内存,带一个USB端口,不带有线网接口。

树莓派B+

“树莓派B+”版本,依然采用 BCM2835 处理器以及和上一代树莓派相同的系统软件。内存也依然是512MB,但是在以下几处关键部件做了改进:

更多的 GPIO 针脚,40针!(老版本是26针)更多的USB接口,比老版本多2个,4个!并且对热插拔和过流保护做了改良。用Micro SD插口替换了老的SD插口。

更低的功耗,降低了功耗0.5~1W。音频优化,音频电路采用了专用的低噪音电源。

更简洁的外形,B+版本将USB接口和电路板边沿对齐了、移除AV接口,并在主板上做了4个固定孔,方便固定。从配置上来说,model B+使用了和model B相同的BCM2835芯片和512MB内存,但和前代产品相比较,B+版本的功耗更低,接口也更丰富。model B+将通用输入输出引脚增加到了40个,USB接口也从B版本的2个增加到了4个,除此之外,model B+的功耗降到了0.5W到1W,旧款的SD卡插槽被换成了更美观的推入式microSD卡槽,音频部分则采用了低噪供电。从外形上来看,USB接口被移到了主板的一边,复合视频移到了3.5mm音频口的位置,此外还增加了四个独立的安装孔。

树莓派A+

这款新型号支持同Model B一样的 MicroSD 卡读卡器和40-pin的GPI连接端口,其他的功能包括博通 BCM2385 ARM11处理器、256MB的内存和HDMI输出端口。Model A+完整的规格如下:配256MB内存的700MHz博通BCM2835处理器40针的扩展GPIO1个USB 2.0端口4通道立体声输出和复合视频端口全尺寸HDMI端口连接树莓派摄像头的CSI端口连接树莓派触控显示屏幕的DSI端口用于加载系统和储存数据的MicroSD端口Micro USB电源更小的主板尺寸和完全兼容HAT能够支持1080P高清视频输出

树莓派2B


树莓派2代的Model B采用Broadcom BCM2836 900MHz的四核SoC,1GB内存,是新一代开拓者,兼容1代B+。但相比之下,树莓派2的性能提升6倍,内存翻了一番。Raspberry Pi 2不仅能跑全系列ARM GNU/Linux发行版,而且支持Snappy Ubuntu Core及Windows 10  IoT Core(物联网版本)配置:搭载900MHz 的四核处理器(900MHz quad-core ARM Cortex-A7 CPU ),预计性能6倍于之前的B+版本。1GB LPDDR2 SDRAM,2倍于之前的B+版本。与1代完全兼容。

树莓派zero

配置:博通 BCM2835 芯片 1GHz ARM11 core (比树莓派1代快 40%)512MB LPDDR2 SDRAM一个 micro-SD 卡槽一个 mini-HDMI 接口,支持 1080p 60hz 视频输出Micro-USB 接口用于供电和数据传输1个 40Pin 的 GPIO 接口,同树莓派A+、B+、2B版本一样(引脚空置,需要自己焊接,这样在不需要使用到GPIO的时候会显得更加小巧更容易封装)空置的视频接口(用于连接电视输出视频,需要自己焊接)有史以来最小的树莓派尺寸,65mm x 30mm x 5mm

树莓派3B

配置:64-bit 1.2 GHz ARM Cortex A53 处理器,内置 WIFI ,兼容 2.4GHz 802.11 b/g/n;视频和 3D 性能进步明显;支持蓝牙 4.1 规范。4 个 USB 2.0 端口, 10/100 以太网, HDMI 端口, 3.5mm 音频口和视频输出,CSI 和 DSI 摄像机和显示连接器。microSD 插槽以及 GPIO 插槽。

树莓派Zero W


配置:BCM2835,1GHz,ARM11 CPU512MB RAMMini-HDMI 接口Micro-USB On-The-Go 接口Micro-USB 电源接口40-pin GPIO HAT 预留焊接口CSI 摄像头软排线接口802.11n 无线网络支持蓝牙 4.0 支持

树莓派3B+

树莓派3B+是采用 BCM2837B0 型号 CPU 构建,是之前 3B 上用的博通处理器的更新版本,这个处理器包含完整的性能优化和散热器。这允许更好的时钟频率,并能更准确地监控芯片温度。

双频无线网卡和蓝牙采用 Cypress CYW43455 “combo” 芯片,与上一代产品相比,3B+ 在2.4GHz 频带的数据传输表现更好,并且在 5GHz 频带的表现将更好。配置:1.4GHz 64位4核 ARM Cortex-A53 CPU双频 802.11ac 无线网卡和蓝牙 4.2更快的以太网(千兆以太网 over USB 2.0)1G LPDDR2PoE 支持(Power-over-Ethernet,with PoE HAT)改进 PXE 网络与 USB 大容量存储启动

树莓派4B

树莓派4代基于 BCM2711 构建,完全重新实现了 28nm 的 BCM283X。使用更强大的 Cortex-A72 内核取代 Cortex-A53,从而使性能较树莓派3B+提高了2到4倍(具体取决于测试基准)。
配置:

1.5GHz 4核心64位 ARM Cortex-A72 CPU (~3×倍性能)

1GB/2GB/4GB LPDDR4 SDRAM 内存

全吞吐量千兆以太网

双频 802.11ac 无线网络

蓝牙 5.0

两个 USB 3.0 和两个 USB 2.0 接口

双显示器支持,分辨率高达 4K

VideoCore VI 显卡,支持 OpenGL ES 3.x

HEVC 视频 4Kp60 硬解码

完全兼容早期的树莓派产品

树莓派各版本参数

发布于 分类 Linux

Elsonic推8.8吋长条状显示器:专为刷社交媒体准备

Elsonic 近日宣布推出 EK-MD088 长条状 8.8 英寸显示器,屏幕分辨率为 420*1920,是专门为刷社交媒体以及类似滚动体验而准备的。虽然这造型有点像是源自笑话的产物,但是该显示器将于明年 2 月份正式发售,售价为 130 美元。

对于那些无法在一个屏幕上容纳所有需要的东西,但又不想掏钱买另一个完整的显示器的用户来说,这些可能是一个巧妙的选择。但在垂直模式下几乎与 4K 显示器一样高。截图特别显示它可以显示Discord和Twitter的信息。

根据日本商店页面的机器翻译,它可以通过USB-C直接接收笔记本电脑或台式机的电源,并通过迷你HDMI接收其视频信号。商店页面说移动电池也可以使用。

使用您的树莓派

介绍

在这里,您将学习如何使用树莓派操作系统Raspbian和它的一些软件,以及如何根据您的需要调整一些关键设置。

如果您还没有运行树莓派,请查看我们的 设置您的树莓派 指南。

pi桌面

树莓派桌面

您的树莓派运行Raspbian,这是Linux操作系统(OS)的一种发行版本。 (Windows和macOS是其他类型的操作系统)。

Raspbian启动后,您将看到桌面出现。

pi桌面

左上角的树莓派图标是您访问菜单的入口。

  • 单击它可以找到许多应用程序,包括 编程 和 办公 应用程序。
  • 要打开文本编辑器,请单击附件并选择文本编辑器 。
截图
截图
  • 通过单击窗口右上角的 x, 关闭文本编辑器。
  • 浏览菜单中的一些其他应用程序,例如Python游戏 。

键盘和鼠标设置

要设置鼠标和键盘,请从菜单中选择 首选项 ,然后选择 鼠标和键盘

键盘和鼠标设置菜单

鼠标

您可以在此处更改鼠标移动速度和双击时间,如果您是左撇子,则可以交换左右键。

鼠标设置

键盘

您可以在此处调整键重复延迟和间隔值。

键盘设置

要更改键盘布局,请单击 键盘布局 ,然后从国家/地区列表中选择布局。

键盘布局

连接到互联网

如果您想将树莓派连接到互联网,可以将以太网电缆插入其中(如果你有Pi Zero,你也需要一个USB转以太网适配器)。

如果您的型号是Pi 4, 3 或Pi Zero W,您还可以连接到无线网络。

连接到无线网络

  • 单击屏幕右上角的无线网络图标,然后从下拉菜单中选择您的网络。
没有wifi
wifi
  • 输入无线网络的密码,然后单击 确定
输入密码
  • 一旦您的树莓派连接到互联网,您将看到无线LAN符号而不是红色叉叉。
wifi
  • 通过单击Web浏览器图标并在Web上搜索 树莓派来测试您的连接。
浏览器

设置声音

您的树莓派可以将声音通过 HDMI 传接到屏幕的内置扬声器(如果您的屏幕有扬声器)或者传送到 模拟 耳机插孔。

  • 右键单击右上角的扬声器图标,选择您的Pi是否应使用 HDMI 或 Analog 连接进行声音处理。
pi声音连接
  • 单击扬声器图标可通过向上或向下移动滑块来调节音量。
pi音量

安装软件

有很多很多软件和应用程序您可以在树莓派上下载和安装。

注: 你的树莓派要 已经连接到互联网 ,然后才能安装软件。

  • 在菜单中,单击 首选项 ,然后单击 推荐软件
推荐的软件菜​​单

您可以浏览所有推荐的软件,也可以按类别对其进行过滤。

推荐的软件
  • 要安装某个软件,请单击以选中其右侧的复选框。
选择要安装的软件
  • 然后单击 确定 以安装所选软件。
安装软件

除了树莓派推荐的软件之外,还有一个庞大的可用程序和应用程序库。

  • 单击 首选项 ,然后单击菜单中的 添加/删除软件
添加删除软件菜单

您可以搜索软件,也可以从左侧菜单中选择一个类别进行浏览。

添加删除软件

让我们尝试安装名为 Pinta的绘图应用程序。

  • 在搜索框中输入“pinta”,然后按 回车键
  • 在出现的列表中选择 Simple drawing/paint program
pinta安装
  • 单击 确定 开始安装过程。
  • 出现提示时,输入您的密码;如果您没有更改密码,它将是’raspberry’。
验证软件安装

Pinta现在将被下载并安装。

安装包
  • 完成此过程后,从菜单中选择 图像 然后选择 Pinta 打开Pinta。
pinta菜单

更新你的Pi

最好定期使用最新功能和修复程序更新Pi上的软件。

  • 您可以使用 添加/删除软件 应用程序更新Pi:通过从菜单的 首选项 选择它来打开。
添加删除软件菜单

在检查并安装任何更新之前,您应该刷新Pi上的软件包列表。

  • 单击左上角的 选项 ,然后选择 刷新软件包列表
刷新软件包列表

然后,您的Pi将更新所有包列表。

下载新的软件包列表
  • 完成后,单击 选项 然后选择 检查更新
检查更新

软件包更新程序 将打开并自动检查更新是否可用。 它将显示它在列表中找到的任何内容。

软件包更新程序
  • 单击 安装更新 以安装所有可用更新。
  • 出现提示时,输入您的密码;如果您没有更改密码,它将是’raspberry’。
验证软件安装
  • 然后将下载并安装更新。 您可以通过检查左下角的进度条来查看安装。
下载软件包

访问您的文件

树莓派上的所有文件(包括您自己创建的文件)都存储在SD卡上。 您可以使用 文件管理器 应用程序访问您的文件。

  • 单击 附件,然后单击菜单中的 文件管理器,或选择菜单栏上的 文件管理器 图标。
文件管理器菜单

当文件管理器打开时,您将看到 pi 目录 – 这是您可以存储文件和创建新子文件夹的位置。

文件管理器
  • 双击 Documents 图标打开目录并查看其中的文件。
文档

要打开文件,请双击其名称,或右键单击该文件以打开文件菜单以获取更多选项。

文件菜单

您可以在树莓派上使用USB硬盘和U盘。 这是备份文件并将其复制到其他计算机的便捷方式。

  • 将U盘插入树莓派。 将弹出一个窗口,询问您要执行的操作。
插入U盘
  • 单击 确定 到 在文件管理器打开。

文件管理器将打开并显示U盘上的文件。

U盘文件管理器

使用终端

终端 是一个非常有用的应用程序:它允许您使用键入的命令来访问文件目录并控制树莓派,而不是单击菜单选项。 它通常出现在许多教程和项目指南中,包括我们网站上的指南。

  • 要打开终端窗口,请单击屏幕顶部的 终端 图标,或者在菜单中选择 附件 ,然后选择 终端
截图

您可以在终端窗口中键入命令,然后按键盘上的 回车键 运行命令。

  • 在终端窗口中,键入:
ls
  • 然后按键盘上的回车键

ls命令列出当前文件目录中的所有文件和子目录。 默认情况下,终端在打开时访问的文件目录是名为 pi的文件目录。

pi终端ls
  • 现在输入此命令 change directory切换到桌面。
cd Desktop

每次命令后都必须按 回车键 。

  • 使用ls 命令列出Desktop目录中的文件。
ls
pi终端ls桌面

终端可以做比列出文件更多的事情 – 这是与树莓派进行交互的一种非常强大的方式!

  • 仅作为一个小例子,尝试命令 pinout
pinout

这将显示GPIO引脚的标记图,以及有关Pi的其他一些信息。

pinout
  • 单击 x 或使用命令 exit关闭终端窗口。

配置你的Pi

您可以通过菜单上 首选项 的 Raspberry Pi Configuration 应用程序控制大部分树莓派的设置,例如密码。

pi配置菜单

系统

在此选项卡中,您可以更改Pi的基本系统设置。

pi配置系统
  • 密码 – 设置 pi 用户的密码(最好更改出厂默认设置的密码’raspberry’)
  • Boot – 选择在Raspberry Pi启动时显示 Desktop 或 CLI (命令行界面)
  • 自动登录 – 启用此选项将使树莓派在启动时自动登录
  • 引导时连接网络 – 选择此选项将使树莓派等待网络连接可用,然后再启动
  • 启动画面 – 选择是否在Raspberry Pi启动时显示启动画面

接口

您可以使用许多不同类型的连接将设备和组件链接到树莓派。 “接口”选项卡用于打开或关闭这些不同的连接,以便Pi识别出您通过特定类型的连接将某些东西链接到它。

pi配置接口
  • 摄像头 – 启用 树莓派摄像头模块
  • SSH – 允许使用SSH从另一台计算机远程访问您的树莓派
  • VNC – 允许使用VNC从另一台计算机远程访问树莓派桌面
  • SPI – 启用SPI GPIO引脚
  • I2C – 启用I2C GPIO引脚
  • Serial – 使能串行(Rx,Tx)GPIO引脚
  • 1-Wire – 启用1-Wire GPIO引脚
  • 远程GPIO – 允许从另一台计算机访问Raspberry Pi的GPIO引脚

性能

如果您需要为要处理的特定项目执行此操作,可以在此选项卡中更改Pi的性能设置。

警告:更改Pi的性能设置可能会导致其表现不正常或无法正常工作。

pi配置性能
  • 超频 – 更改CPU速度和电压以提高性能
  • GPU内存 – 更改给予GPU的内存分配

本土化

pi配置本地化

此选项卡允许您将Raspberry Pi设置更改为特定于国家或地区。

  • 区域设置 – 设置树莓派使用的语言,国家/地区和字符集
  • 时区 – 设置时区
  • 键盘 – 更改键盘布局
  • WiFi国家 – 设置WiFi国家代码
发布于 分类 Linux

开始使用树莓派

简介

在这个项目中,你将连接起一台树莓派电脑,并了解它可以做什么。

注: 本指南是对树莓派计算机的介绍,以及设置树莓派的详细指南使用您的树莓派 

你将能做什么

树莓派是一台可以做很多事情的小巧的计算机。 将其与和显示器、键盘和鼠标连接。

截屏

你将学到什么

本项目涵盖了树莓派数字制作课程如下几方面内容:

教师附加信息

如果您需要打印本项目文件,请使用适合打印版本

请使用页脚的链接访问此项目的GitHub版本库,文件夹’zh-CN/resources’里包含了所有资源(包括最终版示例) 。

你需要什么

硬件

  • 一个带有SD卡或Micro SD(TransFlash) 卡的树莓派
  • 带有连接线的显示器(可能还需要HDMI适配器)
  • USB键盘和鼠标
  • 一个电源
  • 耳机或扬声器(可选)
  • 以太网线(可选)

软件

  • Raspbian操作系统,通过NOOBS安装

认识树莓派

你将第一次见到树莓派! 你应该有一台树莓派电脑。 它应该没有连接任何东西。

  • 看一下你的树莓派。 你能找到图上标注的所有东西吗?
截图
  • USB端口 – 这些端口用于连接鼠标和键盘。 您还可以连接其他组件,例如U盘。
  • SD卡插槽 – 您可以将SD卡插入此处。 这是操作系统和文件存储的地方。
  • 以太网口 – 用于通过网线将树莓派连接到网络。 树莓派也能用wifi上网。
  • 音频插孔 – 您可以在此连接耳机或扬声器。
  • HDMI端口 – 用于连接显示器(或投影仪)将树莓派桌面显示出来。 如果您的显示器带有扬声器,您也可以使用它们播放声音。
  • Micro USB电源接口 – 这是连接电源的地方。 你应该永远在连接完所有其他组件后,最后再连接电源。
  • GPIO接口 – 这些接口允许您将电子组件(如LED和按钮)连接到树莓派。

连接你的树莓派

让我们连接你的树莓派并让它运行起来。

  • 检查树莓派底部的插槽,看看SD卡是否插入。 如果没有SD卡,则插入一个安装了Raspbian的SD卡(通过NOOBS)。截屏

注意: 许多micro Sd卡都是插在一个大号的卡套里的 – 您可以使用底部的凸起部分将卡取出。

sd 卡槽

用NOOBS安装Raspbian

  • 找到鼠标的USB插头,并将它连接到树莓派上的USB接口(随便哪个都可以)。截图
  • 以同样的方法连接好键盘。截屏
  • 确保您的显示器连接了电源并打开显示器开关。
  • 看看树莓派上的HDMI接口 – 请注意它顶部又大又平。
  • 使用HDMI线将显示器连接到树莓派的HDMI接口 – 如有必要,请使用适配器。树莓派4连接显示器到树莓派4的第一个HDMI接口 ,它标注了HDMI0.HDMI您可以以相同的方式连接的第二个屏幕。(可选)HDMI树莓派1,2,3代将屏幕连接到单HDMI端口。树莓派3 HDMI

注意: 现在屏幕上不会显示任何内容,因为树莓派尚未开机。

  • 如果要通过以太网将树莓派连接到因特网,请使用以太网网线将树莓派上的以太网接口连接到墙上或路由器上的以太网接口。 如果您要使用WiFi或者您不想连接到互联网,则无需执行此操作。
以太网
  • 如果您的屏幕有扬声器,您的树莓派可以通过显示器播放声音。 或者您可以将耳机或扬声器连接到音频端口。
耳机
  • 将电源插入插座并将其连接到树莓派的Micro USB电源接口上。
截屏

你应该看到树莓派上的红灯亮起并且显示器上显示出树莓图像。

然后,您的树莓派将引导到桌面。

截屏

完成设置

当您第一次启动树莓派时,将弹出 欢迎使用树莓派 应用程序并引导您完成初始设置。

树莓派设置向导
  • 单击 下一步 开始设置。
  • 设置您的 国家, 语言和 时区,然后再次单击 下一步 。
pi 设置国家向导
  • 为你的树莓派输入新密码,然后单击 下一步
pi设置密码向导
  • 选择要连接的WIFI网络名称,输入密码,然后点击 下一步完成连接。
pi 设置WIFI向导

注意: 如果您的树莓派型号没有无线连接,您将看不到这个屏幕。

  • 单击 下一步 让设置向导检查Raspbian的更新并安装它们(这可能需要一段时间)。
树莓派设置向导 更新
  • 单击 完成 或 重新启动 以完成设置。

注意: 如果需要完成更新,您只需要重新启动。

树莓派设置向导 完成

漫游树莓派

现在是时候去漫游树莓派了。

  • 你看到左上角的树莓图标了吗? 这就是你访问菜单的地方:点击它,可以找到很多应用程序。
  • 单击 Accessories 然后选择 Text Editor
截图
  • 在弹出的窗口输入我刚刚装好了一台树莓派电脑。
screenshot
  • 单击 File,然后选择 Save,然后选择 桌面 并将文件保存为 rp.txt
截图
  • 您应该看到名为 rp.txt 的图标出现在桌面上。
截图

您的文件已经保存到树莓派的SD卡上了。

  • 单击窗口右上角的 X 关闭文本编辑器。
  • 返回到树莓菜单,选择 Shutdown,然后选择 Reboot
  • 当树莓派重新启动后,您的文本文件应该仍然在桌面上。
  • 树莓派运行一种称为Linux的系统的一种发行版本(Windows和MacOS是其他操作系统)。 它允许您通过键入命令而不是单击菜单选项来完成各种任务。 点击屏幕顶部的 Terminal标志:
截图
  • 在出现的窗口中,输入:ls

然后按下键盘的 回车键。

您就可以在home中看到文件和文件夹的列表目录。

  • 现在,键入这个命令把目录更改(change directory )到Desktop:cd Desktop

您必须在每个命令后按 回车 键。

然后输入:

ls

你能看到你之前创建的文件吗?

  • 点击 X关闭终端窗口。
  • 现在将 rp.txt 拖动到桌面上的垃圾桶,以便树莓派可以被下一个人使用。截图

浏览网页

您可能想要将您的树莓派连接到互联网。 如果在安装过程中未插入以太网电缆或连接到WiFi网络,则可以现在连接。

  • 点击屏幕右上角带红色叉叉的图标,然后从下拉菜单中选择您要连接的网络。 您可能需要向老师询问您应该选择哪个网络。
Wifi未连接
  • 输入的无线网络密码,或请求大人为您输入密码,然后点击 确定
输入密码
  • 当您的树莓派连接到互联网时,您将看到无线局域网符号,而不是红色叉叉。
截屏
  • 点击网页浏览器图标并搜索 树莓派
截图

挑战:探索树莓派

浏览菜单 – 你能否找到:

  • 某一版本的Scratch?
  • 玩一个Python游戏?
  • 您可以编程的Minecraft版本?
发布于 分类 Linux