由于体积小且功耗低,Raspberry Pi 既受到电子爱好者的欢迎,也受到教育工作者的欢迎。 因此,它与“创客”场景相关联,有时 Arduino(和 Arduino 风格的嵌入式微控制器)和 Pi 之间的界限变得模糊。
事实上,Raspberry Pi 和 Arduino 是非常不同的设备,即使它们经常出现在同一个工作台上。 对于某些项目,Arduino 更有意义,但对于其他项目,Pi 实际上可能是更好的选择(例如,如果您要触发复杂的媒体事件)。 但是,如果您期望 Pi 完全替代 Arduino,您会感到有些意外。 我在不同的手工项目中使用了 Arduino 和 Pi,有时是因为很明显一个比另一个更适合,有时仅仅是因为我手头有一个而没有另一个。 如果您习惯了 Arduino(或者如果您只是阅读了很多关于它的内容并且不清楚它与 Pi 有何不同),那么以下是我发现的让 Pi 更像嵌入式微控制器而不是迷你 PC 的额外步骤。
GPIO
人们首先了解 Arduino 的一件事是,除非您有东西可以连接到它,否则它不是很有用; 您需要输入传感器和输出设备,否则您就是在编程一个没有任何东西可以控制的微控制器。 Pi 则完全相反; 它的很多功能都可以完全基于软件,因此连接外部电子设备的趋势不太常见。 但并非必须如此。
Raspberry Pi 有许多 GPIO 引脚(确切数量取决于型号),可以检测输入或发送输出信号。 与 Arduino 不同,所有这些引脚都是数字 IO,这意味着它们知道两种状态:开和关。 大多数 Arduino 板也有模拟引脚,可以检测状态的程度,其实际应用是可以连接温度传感器、光传感器或电位器以进行任意输入。
只要您可以进行二进制输入和输出,Pi 的 GPIO 引脚就非常有用。 但与 Arduino 不同,通过软件访问这些引脚并非理所当然。 要与 GPIO 引脚通信,您必须安装 GPIO 库。 有两个开发库可供选择
RPi.GPIO Python
RPi.GPIO 是一个 Python 库,使您能够从 GPIO 引脚读取和输出到 GPIO 引脚。 就 Arduino 用户可能期望的那样,它是一个相当高级的接口,因此没有 SPI 或串行功能。 但对于简单的项目,它工作得很好。 您可以打开和关闭 LED、激活电机等等。
WiringPi C
WiringPi 是用 C 编写的 GPIO 访问库。 它的语法和总体设计会让任何使用过 Arduino 系统的人感到熟悉,并且作为一个底层库,它甚至包含允许您使用外部板(如 Arduino 或类似设备)作为模拟输入的模块。
原始 WiringPi 项目的贡献者已经编写了 Python、Ruby、Perl、Java 等的封装器。
实时性能
与 Arduino 不同,使用 GPIO 库不提供实时性能。 Python 库具有 Python 的开销,Python 需要定期在后台执行内存管理任务,甚至 WiringPi 也受到 Linux 内核调度决策的影响。 在实践中,除非您正在构建一个至关重要地依赖实时性能的设备,否则这可能实际上不会对您产生影响。 在准备一个基于 Pi 的多媒体项目时,我确实做了一些测试,试图使用安全限制来提高性能,但它们都失败了(我从未重新编译内核,所以这没有帮助)。 最终,我发现该项目——一个受到不可预测的输入的影响并且确实需要一些瞬时响应的音乐界面——从未错过任何一个节拍,但您的结果可能会因您的项目而异。
启动时启动
由于 Arduino 是一个嵌入式系统,因此您刷入其芯片的程序始终在运行。 您打开 Arduino 电源,您的程序就会运行,不断循环,直到断电为止。 Pi 不会这样做。 当您打开 Pi 电源时,它会加载操作系统,然后耐心地等待您登录或执行某些操作。
如果您需要嵌入式行为,您基本上需要告诉 Pi 在启动时自动启动应用程序。 更好的是,您可以删除不需要的进程,以便启动时间更快。 您不必以这种方式进行操作(您可以将 Pi 的桌面设置为自动登录,然后设置启动应用程序),但是如果您将 Pi 视为伪嵌入式设备并且不需要桌面,为什么要使用资源来运行一个桌面呢? 并且为什么要引入它作为一个变量,知道在演示你很酷的新机器人(或者你正在构建的任何东西)方面,任何可能出错的事情都会出错?
要使 Pi 的行为类似于嵌入式操作系统,首先要删除不需要的服务。 这些服务是什么取决于您的项目。 如果您的项目不需要网络,则禁用网络服务。 如果您的项目不需要图形界面,请从您的系统中删除 X11 软件包。 查看启动时运行的服务,并尽可能多地禁用它们。
您还需要 Pi 自动登录。 如何实现这一点取决于您运行的 Pi 发行版。
没有 Systemd
Pi 的大多数现代发行版都使用 Systemd 作为 init 进程(启动进程),但有些发行版没有。 要在不使用 Systemd 的系统上激活自动登录,请编辑(使用 sudo 权限)/etc/inittab 文件并更改此行
1:2345:respawn:/sbin/getty 38400 tty1
改为此行
1:2345:respawn:/sbin/getty --autologin your-username-here 38400 tty1
将 your-username-here 替换为您想要自动登录的用户的用户名。 您的 Pi 可能附带 pi 作为默认用户,但您可能创建了一个新用户; 如果您不确定,请使用 whoami 查找您的用户名。
进行更改后,重新启动以确保它有效。 Pi 应该启动到 shell 提示符(而不是登录提示符)。
要在成功启动后立即运行您的应用程序,请将您的应用程序作为命令添加到文件 /etc/rc.local 中,位于最后一行(应该是 exit 0)的上方。 例如,这是我的示例项目的最后两行
$ sudo tail -n /etc/rc.local
/usr/local/bin/robotnix/robotnix.py
exit 0
确保 rc.local 是可执行的,并且您想要启动的应用程序是可执行的
$ sudo chmod a+x /etc/rc.local
$ sudo chmod a+x /usr/local/bin/robotnix/robotnix.py
再次重新启动以测试您的应用程序是否在成功自动登录后启动。
CentOS、Pidora 和其他系统上的 Systemd
在使用 Systemd 的发行版(例如 CentOS)上,该过程类似,但发生在不同的配置文件集中。
对于自动登录过程,编辑文件 >/usr/lib/systemd/system/getty@.service 并注释掉此行
ExecStart=-/sbin/agetty --noclear %I 38400
并将其替换为以下变体
## old line ## ExecStart=-/sbin/agetty --noclear %I 38400
## new command
ExecStart=/sbin/agetty --autologin your-username-here --noclear %I 38400
此 Systemd 文件会生成该进程,这与使用 inittab 的传统 UNIX 方法不同。
重新启动您的 Pi 以测试自动登录。
假设自动登录按预期工作(Pi 应该启动到 shell 提示符,而不是登录提示符),下一步是为您的应用程序创建自动启动规则。 整个互联网都建议将命令放在 rc.local 中应该有效(因为理论上,Systemd 会向后兼容地执行 rc.local),但我对此的成功率参差不齐。 我对自定义 Systemd 规则取得了一帆风顺的成功。
要编写 Systemd 规则,请使用 sudo 权限创建一个名为 /etc/systemd/system/robotnix.service 的文件(您可以随意命名;我使用 robotnix 是因为这是我为此文章生成的示例项目的名称)。
文件内容
[Unit]
Description=Robot Script Startup
[Service]
Type=idle
ExecStart=/usr/local/bin/robotnix/robotnix.py
[Install]
WantedBy=multi-user.target
现在启用该服务以便在启动时运行
$ sudo systemctl enable robotnix.service
再次重新启动 Pi 以确保您的应用程序正在自动启动。
Pi 还是 Arduino?
它们都很小,它们都很强大,并且它们都用于电子爱好项目,但 Raspberry Pi 不是 Arduino。 但是,Pi 可以在紧要关头很好地扮演这个角色。 也就是说,如果您还没有尝试过 Arduino 并且对它感到好奇,请不要害怕尝试。 它们都是您的工具包中很棒的工具。 使用本文中的技巧,您可以将 Pi 用作未来 Arduino 项目的试验台,或者您可以在一个设备中同时拥有两者的优点。
无论您最终在下一个硬件项目中使用什么,都保持开放和乐趣。
4 条评论