树莓派上的-Java-教程-一-

249 阅读1小时+

树莓派上的 Java 教程(一)

原文:Java on the Raspberry Pi

协议:CC BY-NC-SA 4.0

一、动机

这本书主要关注在机器人项目和物联网项目中使用树莓派和 Java。第二个重点是使用 Apache NetBeans 进行远程代码开发。我发现 Raspberry Pi、Java 和 NetBeans 的组合是开发机器人项目的非常强大和高效的方法。我相信这种组合也适用于物联网项目。在本章中,我将讨论机器人和物联网项目背景下的动机

  • 使用树莓派作为计算资源的主要提供者

  • 使用 Java 作为主要的编程语言

  • 使用 Apache NetBeans 远程开发运行在树莓派上的 Java 程序

在深入讨论动机之前,我想强调一些非常重要的事情。这本书的大部分内容都在探索为机器人和物联网项目中使用的设备寻找或创建支持。因此,即使您不进行远程开发、不使用 NetBeans、不使用 Java 或不使用 Raspberry Pi,许多与设备相关的材料也适用。

也就是说,说到动机!

为什么是树莓派?

要理解为什么树莓派非常适合机器人和物联网项目,我们必须探索这些项目的需求。我不会深究术语机器人的定义,因为它可以有一个或宽或窄的范围,这取决于上下文,并且它是不断发展的。举个例子,对我的孙子来说,因为一个微控制器驱动两个伺服系统而挥动翅膀的玩具鸟就是机器人。对我来说,除非一个系统感知它的环境并对环境做出反应自主,否则它不是一个机器人。对一些人来说,可能是现在,当然也可能是几年内,除非一个系统能够根据自己的经验感知环境并做出适应性反应(即,除非它包括人工智能和机器学习),否则它不可能是机器人。

出于本书的目的,机器人技术总是意味着

  • 传感器以各种方式对环境进行采样

  • 能够对环境做出反应的致动器

  • 智能解释传感器的输出并驱动执行机构以实现预期目标

物联网的定义也很松散,并且仍在不断发展。从根本上说,物联网是关于通过互联网进行通信的事物(例如,门锁、恒温器或冰箱)。事物感知它们的环境,并发送数据进行分析。数据被分析以通知事物,零个或多个事物做出反应,尽管不一定是事物做出感应。与机器人技术一样,人工智能和机器学习正在成为物联网的一个重要方面,但通常是在中,而不是在中。

就本书而言, IoT 意味着

  • 传感器以各种方式对环境进行采样,总是

  • 通信通过“互联网”进行通信,总是

  • 致动器允许对环境做出反应,有时

显然,这两个学科之间有重叠之处。事实上,一个机器人可能是一个东西。即使不是一件的事情,对于一些机器人来说,通信与物联网项目一样重要。例如,一个机器人可以与其他机器人合作,或者利用云服务,如图像处理甚至人工智能。

机器人和物联网还有其他共同需求。许多机器人系统和一些物联网系统是移动的,因此无线通信和小尺寸和低重量往往是考虑因素。这种系统必须由电池供电。一些物联网系统是固定的,但部署在偏远地区;这些也需要无线通信和电池供电。本书假设项目需要无线通信和电池供电。

那么,是什么让树莓派成为机器人和物联网的好选择呢?

  • 所有型号都支持多种类型的基本 I/O ,用于与传感器和执行器(设备)交互。相关的基本 I/O 类型有数字输入和输出(也称为 GPIO)、UART 协议(串行端口或只是串行),以及更复杂的串行协议,即内部集成电路总线(I2C 1 )和串行外设接口总线(SPI)。

  • 大多数型号提供现代无线通信技术,即 Wi-Fi、蓝牙和蓝牙低能耗(BLE)。

  • 所有型号都支持多种操作系统和多种编程语言。

  • 各种型号提供了内存和处理能力以及物理大小的选择,以支持从相对简单的控制器到桌面计算的广泛需求。

  • 所有型号的功耗都相当低。

  • 所有机型都有相当不错的性价比。

  • 用户社区是巨大的,并且是支持的。

公平地说,有些竞争产品拥有更快的处理器、更大的内存、更好的 I/O 能力或更低的价格。然而,据我所知,没有任何产品能接近树莓派社区的规模(截至 2021 年 5 月,已售出超过 4000 万个)。当你遇到一个问题时,你几乎总会发现有人在某个地方遇到了这个问题并解决了它。

因此,对于您的项目,您可能会找到一个似乎更适合的竞争产品。然而,与选择树莓派相比,你可能会做更多的工作,获得更少的支持。

机器人领域的“最佳”树莓派

如果您的项目侧重于机器人,突出的特征是低功耗、基本 I/O 能力、通信能力和尽可能多的计算能力,以便 Pi 可以提供项目的“大脑”。所有现代的树莓派系列都具有相同的基本 I/O 功能,但在其他方面有所不同。在我看来,在撰写本文时,树莓派 3 系列的三个型号之一是低电力消耗和高计算能力之间的最佳妥协。

你可以在树莓基金会的网站上找到这些模型的完整描述(见 www.raspberrypi.org/products/ )。表 1-1 显示了各型号显著特征的对比。该表没有列出等效的功能,如基本 I/O、音频、摄像头和显示器支持。

表 1-1

树莓派 3 模型的比较

|

特征

|

3B

|

3B+

|

3A+

| | --- | --- | --- | --- | | CPU 速度 | 1.2 千兆赫 | 1.4 千兆赫 | 1.4 千兆赫 | | 随机存取存储 | 1 GB | 1 GB | 512 兆字节 | | 无线网络 | 2.4ghz | 2.4 GHz 和 5 GHz | 2.4 GHz 和 5 GHz | | 蓝牙 | brotherhood of locomotive engineers 火车司机兄弟会 | 蓝牙 4.2 和 BLE | 蓝牙 4.2 和 BLE | | 以太网 | 100 碱基 | 基于 USB 2.0 的千兆以太网 | 钠 | | USB 2.0 端口 | four | four | one | | 大小 | 56 毫米 x 85 毫米 | 56 毫米 x 85 毫米 | 56 毫米 x 65 毫米 | | 成本(美元) | Thirty-five | Thirty-five | Twenty-five |

如您所见,B+和 A+型比 B 型具有更高的 CPU 速度和更好的无线通信功能。但是,如果您已经有了 B 型,它很可能是可以接受的。如果您必须购买 Pi,B+或 A+型号将是更好的选择。B+和 A+之间的选择取决于项目所需的 RAM 数量、物理大小和连接性,以及项目的成本敏感性。

出于本书的目的,这三个模型是等价的。我会用一个树莓派 3 型号 B+ (Pi3B+)。第二章告诉你如何设置。

Note

你可能会奇怪,为什么我不推荐树莓派 model 4 家族的一员。在撰写本文时,与 Pi3B+相比,任何 Pi4 都成本更高,需要更大的功率(因此需要更大的电池),并且需要散热器甚至风扇。Pi4 价格下降,但其他差异没有改变。如果您希望使用 Pi4,本书中关于 Pi3B+的大部分内容也适用于 Pi4。

物联网的“最佳”树莓派

如果您的项目侧重于物联网,突出的特征是低功耗、基本 I/O 能力、无线通信能力和适度的计算能力。在我看来,在本文写作之时,只有一款机型,树莓派 Zero W (Zero W)是候选机型。它的尺寸大约是 Pi3B+的 40% (30 毫米 x 65 毫米),重量只有 Pi3B+的 20%。

你确实有一个选择。您可以购买带(14 美元)或不带(10 美元)带引脚的 GPIO 接头的 Zero W。如果您打算只连接 I2C 或 SPI 器件,或者只使用几个 GPIO 引脚,最好使用零 W,只焊接您需要的引脚。如果你需要大量的 GPIO 管脚或者讨厌焊接,就用预焊的插头管脚来获得零 WH。第三章告诉你如何设置一个零 w。

为什么是 Java?

我承认我很难对 Java 保持客观(没有双关语的意思)。当 Java 在 1995 年推出时,我开始用它编程。我还在用 Java 编程。我最雄心勃勃的机器人项目大多是用 Java 编写的,有时混合了一点 C/C++(对于 Arduino)和 Python。也就是说,在下面的讨论中,我将尽量保持客观。

树莓派支持广泛的编程语言。事实上,树莓派的主要目标是让所有年龄段的人都能学习如何编程。我不会试图将 Java 与该范围进行比较,而是将讨论限制在我称为专业级编程语言的范围内,这些语言面向独立程序,支持多任务处理,支持机器人和物联网设备访问,支持网络访问,由专业级开发工具支持,等等。我认为这将编程语言的选择局限于 Java、Python 或 C/C++。

选择的标准是什么?有几个;我将使用的,主要是按重要性排序:

  • 程序员生产率

  • 表演

  • 行业接受度

程序员生产率

程序员的生产力是多方面的,很难精确定义,并且测量起来有些主观。我将讨论我认为最有说服力的方面。

面向对象编程

OOP 是不言自明的。虽然与高性能的目标有些矛盾,但我认为 OOP 的好处是值得权衡的。这些好处包括改进的模块化、可维护性、质量、可重用性和灵活性——基本上是对程序员生产率的巨大提升。

Java 从一开始就被设计来促进 OOP,事实上也强制要求 OOP。Python 支持 OOP,但在我看来,并不强调它。因此,虽然存在于 Python 中,但 OOP 在 Java 中得到更好的支持。

当然 c 根本不是面向对象的。C++先于 Java 出现(尽管它直到 1998 年才标准化),看起来像是后来才出现的,实际上是 C 语言的面向对象“包装器”。因此,我的观点是,虽然 OOP 出现在 C++中,但它在 Java 中得到更好的支持。

安全

安全性是指在程序中引入难以诊断甚至危险的错误的可能性。更安全的语言的好处意味着调试时间更少,软件甚至硬件系统崩溃的风险更小——实际上是更高的编程效率。

Python 有一些我(主观上)不喜欢的特性,因为我觉得它们可能会引入 bug。Python 的松散或动态类型化就是最好的例子;我更喜欢 Java 的静态类型。即使 Python 看似令人满意地使用空白作为其语法的一部分,也可能引入逻辑错误,因为这使得开发工具在运行之前更难发现错误;Java 公认的更加冗长的语法消除了这个问题。因此,我认为 Java 比 Python 更安全。

c,在我看来,基本上是一种非常接近系统硬件和操作系统的“高级机器语言”。你几乎可以做任何事情。这意味着你只是一个模糊的错误(例如,糟糕的指针算法,一个错误的memcpy,或者一个相应的malloc丢失了free)就有可能使程序甚至整个系统崩溃(我已经做到了!).C++在消除 C 的危险方面做得很少,如果有的话。Java 防止这种危险,所以 Java 比 C/C++安全得多。

一次编写,随处运行

Java 以“一次编写,随处运行”的承诺而闻名。在本书的上下文中,这意味着您可以在任何平台上编写、构建、编码并运行可执行文件——您的 Raspberry Pi、macOS 工作站、Windows 10 工作站或某些 Linux 机器。这一承诺得到了兑现——除非涉及到平台细节。显然,在将机器人和物联网设备连接到树莓派时,您必须使用特定于平台的基本 I/O。然而,我在机器人领域的经验是,可能 10–20%的项目与硬件一起工作,因此多达 90%的项目可以在高性能工作站上编写和测试,而不是在树莓派上。这可以极大地提高程序员的工作效率。然而,我认为对于物联网项目来说,增幅不会那么大。

Python 作为一种解释型语言,在这方面享有和 Java 一样的优势。因此,Java 和 Python 大致相当。

C/C++作为编译语言,在这方面比不上 Java。虽然在高性能工作站上开发和测试平台无关的代码是可能的,但是要使它在树莓派上运行,必须将代码复制到 Pi 上并在 Pi 上编译。可以在工作站上交叉编译 Pi,然后复制到 Pi。在这两种情况下,谨慎的做法是在 Pi 上再次测试。这对程序员的生产力是一个不愉快的打击。

图书馆

虽然在机器人和物联网的背景下可能没有前面的生产力方面重要,但 Java 广泛的标准库集合是 C/C++或 Python 无可匹敌的。凡是你能想到的,Java 很可能都有它的标准库;仅举几个例子,网络、数据库、安全、加密、并发和集合。c 强制你滚动自己的支持或者找第三方库。C++和 Python 没有 Java 得到广泛的支持。在这方面,Java 丰富的函数库无疑给了它在程序员生产率方面的优势。

限制

使用 Java 时,程序员的生产率有限制吗?答案是肯定的。为了解释这些局限性,我们需要检查这本书为机器人和物联网项目假设的理想化软件架构;如图 1-1 所示。 树莓派 OS 层代表操作系统及其内核。该层为树莓派的基本 I/O 功能(GPIO、串行、I2C、SPI)提供了一个低级 C API 2。当然,该层对具体的设备一无所知。

img/506025_1_En_1_Fig1_HTML.jpg

图 1-1

理想化的软件架构

应用层代表你为你的项目编写的 Java 应用程序。一个应用程序想要使用一个 API 来呈现一个设备的抽象;也就是说,应用程序只关心设备做什么,而不关心设备如何做。一些例子:

  • 对于通过 GPIO 连接的 LED,应用需要“打开”或“关闭”,而不是“将 GPIO 引脚 8 设为高电平”或“将 GPIO 引脚 8 设为低电平”。

  • 对于通过 I2C 连接的温度传感器,应用想要“读取温度”,而不是“从寄存器 0x0E 开始,从 I2C 总线 1 上地址 0x42 的器件读取 2 个字节,从这 2 个字节组装一个 14 位值,应用补偿因子以产生温度。”

基本 I/O 层代表一个基本 I/O 库,“神奇”代码 3 提供了一个 Java API,用于通过树莓派 OS 层的 C API 提供的树莓派基本 I/O 功能。从根本上说,该层将 Java 程序员从可怕且难以使用的 OS C API 中抽象出来。像树莓派 OS 层一样,基本 I/O 层对特定设备一无所知;它只是通过单个基本 I/O 库或多个基本 I/O 库为 GPIO、串行、I2C 和 SPI 提供了一个 Java API。

设备层代表一个设备库。设备库知道关于一个设备的一切,包括它做什么和如何做。设备库为应用程序提供了一个高级的 Java API,对设备的功能进行了抽象。设备库利用其特定于设备的知识,使用基本 I/O 层提供的基本 I/O API 来实现 how 。因此,从根本上来说,设备库允许应用程序员关注设备做什么,而不是如何做。

这时你可能会问,为什么在应用层和树莓派 OS 层之间有两层,设备和基本 I/O,而不是一层。一个原因:重用!从 Java 访问基本 I/O C API 并不简单,使用该 API 也不简单。对每个设备重复这项工作将会适得其反。将这些工作封装在基于 Java 的 I/O 库中允许在所有设备上重用,节省了大量的工作和时间,有效地提高了程序员的生产率。

那么,有哪些局限性呢?

  1. Java 没有标准的基本 I/O 库来提供对树莓派 OS 基本 I/O C 接口的访问。鉴于 Java 的“随处运行”口号,这并不奇怪,但它抑制了设备库的开发。

  2. 我还没有找到为他们的设备提供 Java 设备库的制造商或供应商。我觉得是需求低的问题。大多数设备都瞄准了广阔的市场,远不止树莓派。此外,Java 社区是整个 Pi 社区的一小部分。

幸运的是,这些限制并非不可克服。“树莓派的 Java”社区惊人的庞大、熟练、专注和活跃。我已经找到了,你也可以找到,一个支持你的项目需求的基本 I/O 库。事实上,你可以找到多种选择。

一旦您选择了一个基本 I/O 库或一组适用于您的设备的基本 I/O 库,有时就有可能从第三方找到一个您可以使用或改编的 Java 设备库,特别是对于流行的设备。如果您找不到 Java 库,您几乎总是可以找到一个非 Java 设备库,您可以在基本 I/O 库或库中将它移植到 Java,工作量几乎总是可以接受的。我会在第六章深入讨论这个话题。

结论是 Java 提供了最好的程序员生产率,其次是 Python,然后是 C/C++。

表演

业绩是不言自明的,讨论业绩很容易做到客观。对于任何任务,性能必须足以及时完成任务。然而,我的经验是,性能需求通常很难准确预测。因此,通常应该选择性能最好的语言,除非这种选择与其他标准相矛盾。

与 Python 相比,Java 是一个明确的选择。比较基准( https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/python3-java.html )表明 Java 几乎总是比 Python 3 快,事实上可以快几百倍,这取决于基准。

c 比 Java 有明显的性能优势。将 C 语言的基准测试( https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/c.html )与 Java 语言的基准测试( https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/java.html )进行比较,C 语言的运行速度是 Java 的六倍。这些基准测试表明 C++比 C 慢,但通常还是比 Java 快。

基本上,如果你想在性能上达到极致,那么 C 甚至 C++是最好的选择。Java 是比 Python 好得多的选择。

行业接受度

行业认可度指的是这种语言在专业程序员中的广泛使用程度。一个必然的结果是,这种语言的经历会让你对潜在雇主产生多大的吸引力。

在很长一段时间里,Java 是全世界职业程序员中排名第一的编程语言。随着大量新语言的出现和不断变化的需求,排名也发生了变化。在 2020 年 10 月和 2020 年 12 月的民意调查中,C 排名第一,Java 第二,Python 第三(C++第四)。2020 年 11 月的一项民意调查将 C 排在第一,Python 第二,Java 第三。在未来的几年里,Java 将是一种重要的、受到良好支持的语言。因此,我认为行业接受度竞赛是一场平局,至少在未来几年内是如此。

判决

Java 提供了比 Python 好得多的程序员生产率。Java 比 Python 快多了。Java 和 Python 一样受欢迎(在有经验的程序员中)。总的来说,Java 胜于 Python。

Java 提供了比 C/C++好得多的程序员生产力。Java 比 C/C++慢。Java 和 C 一样受欢迎(在有经验的程序员中),而且比 C++更受欢迎。总的来说,Java 胜于 C/C++。

结论:对于树莓派上的复杂机器人和物联网项目,Java 是最好的初级编程语言。

你可能想知道为什么我在结论中包括形容词“主要的”。Java 和树莓派操作系统都不能保证“实时”行为。在机器人学中,发现需要“实时”或需要并行处理的情况是很常见的。在这种情况下,您可以将任务委托给像 Arduino 这样的微控制器,它可以独立于树莓派执行任务,并更好地实现“实时”行为。使用 Arduino 意味着使用 C/C++作为第二编程语言。

你可能也想知道为什么我要用“复杂”这个形容词我不得不说实话。有些物联网项目复杂(例如,只需要一两个传感器,并且只需要很少的数据处理)。在这种情况下,您不会编写或运行大量代码。程序员的生产力、性能和受欢迎程度并不重要。在这种情况下,Python 可能是更好的选择,除非您的 Java 环境已经就绪。

为什么使用 NetBeans 进行远程开发?

你能在树莓派上开发 Java 程序吗?简短的回答是“是的”更好的答案是“是的,但是……”考虑以下因素:

  • 你的程序的复杂性

  • 运行程序的树莓派的计算能力和内存大小

假设你的程序是一个类,只有几十行。然后,即使有一个计算能力适中、只有 512 MB 内存的 Zero W,你也可以在 Pi 上做所有的事情,而手动完成。这意味着

  • 在使用简单的文本编辑器编辑类和使用javac命令编译类之间循环,找到简单的语法错误以及更严重的错误,直到您有了可以运行的东西。

  • 使用java命令运行该类。

不幸的是,任何一个有趣的项目只有一门课几乎肯定是不现实的。

假设复杂性增加了一点,现在你有多个类或者必须使用 Java 运行时环境(JRE)中没有的库(对于机器人和物联网,你需要库)。你仍然可以手动完成 Pi 上的所有操作。这意味着

  • 对于多个 中的每一个,在文本编辑器和javac 之间迭代。

  • 使用多个类,或者一个或多个库,或者两者都用jar命令构建可执行文件。

  • 使用java命令运行可执行文件。

这变得痛苦而无益。即使对于一些物联网项目,这也可能是不可接受的。

远在 Java 出现之前,为哪怕是中等复杂程度的项目开发代码的严酷现实促使各种编程语言的集成开发环境(ide)的出现。Modern,professional gradeIDE4实际上是在您键入时进行编译,以便您可以立即看到语法和其他错误,提供代码完成功能,自动完成构建过程,并允许您在 IDE 中运行和调试程序。这种 IDE 极大地提高了程序员的工作效率,现在绝大多数开发人员都在使用 IDE,无论是编程语言还是项目复杂性。

所以,答案是在树莓派上运行 IDE!可惜,没有!考虑一些更残酷的现实。所有现代的 ide 都需要图形用户界面(GUI)。GUI 需要一个窗口系统(通常称为桌面),它支持像 IDE 这样的基于 GUI 的应用程序。支持一个桌面需要大量的 CPU 能力和内存。你会在第二章中看到 Pi3B+为桌面提供了合理的支持;零 w 就不一样了。

更糟糕的是,专业级 ide 需要的计算资源(CPU 和内存)至少和台式机一样多。比如运行在 macOS 上的 NetBeans 12(见第五章)最高消耗 4 GB 内存; 5 我相信其他专业级别的 ide 也会差不多。我认为公平地说,即使是拥有 1 GB 物理内存的 Pi3B+也难以提供足够的用户体验。在零 W 上,算了吧。

但是,假设您可以合理地在树莓派上运行桌面和 IDE(并且您很可能在 8 GB 的 Pi 4 上运行)。您的项目在运行时会与他们争夺计算资源。因此,您永远无法进行真实的性能测试,甚至可能会因为运行 IDE 时多任务处理导致的延迟而遇到随机错误。这意味着要进行真实的测试,你至少需要关闭 IDE,很可能还要关闭桌面。如果你需要修复一个错误,一切都必须重新启动。痛苦!

解决方案:远程开发。这是什么意思?从广义上讲,远程开发意味着

  • 所有代码的编写、编译和可执行文件的构建都发生在一个 IDE 中,该 IDE 运行在一个工作站上,该工作站拥有足够的资源来提供一个高效和愉快的用户体验。

  • 可执行文件(必要时包括所有库依赖项)从工作站被推送到目标系统。

  • 可执行文件在目标系统上运行,没有任何外来程序在目标系统上争用资源。

在本书中,我使用了远程开发的更狭义的定义,其中

  • IDE 在工作站上运行。

  • IDE 自动将可执行文件推送到远程目标系统。

  • IDE 自动在目标系统上运行可执行文件,并连接到正在运行的程序,以控制和监控执行和调试。

因此,通过远程开发,开发人员获得了两个世界的最佳效果——在一个功能强大的工作站上运行的专业 IDE 和在真实环境中在树莓派上运行的项目可执行文件。

为什么选择 NetBeans?

在撰写本文时,根据做评估的组织或个人,排名前三的专业级跨平台 Java IDEs 分别是 Eclipse ( www.eclipse.org/eclipseide )、NetBeans ( https://netbeans.org )和 IntelliJ ( www.jetbrains.com/idea )。Eclipse 几乎普遍是第一,NetBeans 或 IntelliJ 是第二,另一个是第三。本着完全公开的精神,我在 2001 年 Eclipse 首次发布时就开始使用它进行 Java 开发;2014 年,我开始使用 NetBeans 以及 Eclipse2017 年,我独家转投 NetBeans,完全是基于它对树莓派上远程开发的支持。我必须承认我从未使用过 IntelliJ。

从根本上说,在这三个 ide 中,只有 NetBeans 支持我对远程开发“开箱即用”的狭义定义使用 NetBeans 进行远程开发与本地开发没有什么不同。您可以在多个 NetBeans 项目中创建多个类,并且需要多个外部 jar 文件(库)。只需单击一个按钮,NetBeans 就会编译所有的类,构建可执行文件,将可执行文件(以及任何所需的相关库)下载到 Raspberry Pi,并运行甚至调试可执行文件。也就是说,还是有局限性的。然而,我发现这些限制只对某些测试是个问题。

底线是远程开发极大地提高了程序员的生产力。此外,只有 NetBeans 支持“开箱即用”的非常有效的远程开发形式,从而进一步提高了程序员的工作效率。我将在第五章向你展示如何设置和使用 NetBeans。

Note

如果您比我更熟练,您可以在 Eclipse 和 IntelliJ 中创建类似 NetBeans 的行为。这样做需要对 IDE 和您选择的构建工具有相当深入的了解,还要对工作站操作系统的脚本构建有一定的了解。我没有追求这一点,因为 NetBeans 使它没有必要。也就是说,参见附录 A3 中关于如何实现的示例。

摘要

在本章中,我讨论了机器人和物联网项目几个方面的建议动机:

  • 使用树莓派进行总体控制,这是因为此类项目的需求与 Pi 的大规模支持网络非常匹配

  • 使用 Java 作为主要的编程语言,这是由于它的程序员生产率和性能

  • 进行远程开发,因为程序员的工作效率提高了;使用 NetBeans,因为它对远程开发的一流支持,进一步提高了程序员的工作效率

本书的其余部分假设您想使用 Raspberry Pi,使用 Java,并使用 NetBeans 进行远程开发。内容预览:

  • 第二章向您展示如何设置 Pi3B+。

  • 第三章告诉你如何设置一个零 w。

  • 第四章讨论了远程计算技术,其中大部分只与 Pi3B+相关。

  • 第五章向你展示如何设置 NetBeans。

  • 第六章探讨了 Java 基本 I/O 支持的选项。

  • 第七章讨论了本书对 Java 基本 I/O 支持的选择,并提供了关于树莓派基本 I/O 功能的有用细节。

  • 第 8 到 14 章着眼于对机器人和物联网中使用的特定设备的支持。

  • 附录 A1 和 A2 讨论将任务卸载到 Arduino。

  • 附录 A3 检查了 Maven 作为 NetBeans 中的构建工具的使用。

好好享受!

Footnotes 1

I2C 是最常见的缩写;有时使用 C 和 IIC。

  2

不管是好是坏,我使用的是“API”的现代定义,它实际上意味着任何编程接口,在应用程序级别或软件堆栈中的任何地方。

  3

“魔力”包括 Java 本地接口(JNI)框架。

  4

我不认为 ide 带有树莓派 OS 专业级。

  5

NetBeans 8.2 存在内存泄漏,可能会消耗多达 12 GB 的内存!

 

二、树莓派 3B+ 设置

我假设您正在阅读这一章,因为您对使用树莓派 3 Model B+(我将在本章的剩余部分使用 Pi3 )和 Java 构建机器人项目感兴趣。在本章中,您将学习如何

  • 为 Pi3 选择“最佳”操作系统

  • 安装树莓派操作系统

  • 为远程开发配置树莓派操作系统

  • 在树莓派操作系统上安装 Java

设置注意事项

当然,每个树莓派项目都需要“基础知识”:

  • 覆盆子馅饼

  • 用于文件系统存储的 microSD 卡

  • 一种能源

在设置和一些项目开发过程中,您可以从电源插座(通过合适的电源)或电池供电。在本章我将介绍的设置方法中,你需要连接一个 HDMI 兼容的显示器或电视、一个 USB 键盘和一个 USB 鼠标。在项目开发过程中,你不需要这些。

选择操作系统

你应该使用什么操作系统?树莓派运行许多操作系统。然而,默认操作系统,以前叫做 Raspbian,现在叫做 树莓派 OS ,吸引了绝大多数用户和绝大多数在线支持。我建议使用它,除非你有一个非常好的理由使用另一个。本书中的所有材料都假设了树莓派操作系统,并且没有在任何其他操作系统上测试过。

树莓派操作系统有三个版本:

  • 完整的包括核心操作系统、桌面图形用户界面,以及许多有用的工具和应用程序。默认情况下,它会引导到桌面。

  • 推荐的(一个有点不正式的术语)包括核心操作系统、桌面,以及少数有用的工具和应用程序。默认情况下,它会引导到桌面。

  • Lite 只包含核心操作系统。它会引导至命令行界面(CLI)。你必须安装任何你需要的非操作系统工具或应用程序。

本书的基础是远程开发,其中所有的重型工具都运行在一个健壮的工作站上,为您的项目留下 Pi CPU 周期和存储空间。因此,事实上, Lite 几乎肯定是大多数项目的正确选择。然而

  • 我发现使用推荐完全中的桌面,第一次启动后的初始配置要容易得多。我将向您展示如何关闭桌面,以便当您不再需要它时,它不会消耗内存或 CPU 周期。

  • 我发现利用推荐的中包含的工具有时很有用。

出于这些原因,对于 Pi3,我建议使用推荐的,并将向您展示如何安装和配置推荐的。注意,如果你喜欢那个版本,同样的说明也适用于 Full

Caution

以下操作系统说明适用于所有型号的 Raspberry Pi。我只在一辆 3B(约 2015 年设计)、一辆 3B+(约 2017 年设计)和一辆 1 型(约 2011 年设计)上进行了测试。然而,最新版本的 Java 不能安装在像 model 1 这样的老系统上。

在 microSD 卡上加载树莓派操作系统

我将首先描述获得树莓派操作系统的一些选项。然后,我将描述我认为的最佳方法。

获取树莓派操作系统

有几种方法可以获得树莓派操作系统:

  • 你可以买一个预装 NOOBS 的 microSD 卡(新的开箱即用软件;见 www.raspberrypi.org/documentation/installation/noobs.md )。这提供了几个操作系统,你可以安装你的选择。

  • 你可以买一张空的 microSD 卡,下载 NOOBS 并将其写入工作站上的 microSD 卡。同样,你可以安装你选择的操作系统。

  • 你可以购买一张空的 microSD 卡,然后使用 树莓派 Imager 工具将树莓派操作系统写入工作站上的卡中。我觉得这是最简单的方法,我会在下面描述。

图像树莓派操作系统

树莓派 Imager ( www.raspberrypi.org/downloads )是一个很棒的工具,可以下载树莓派操作系统映像并将其写入 microSD 卡。您可以从 www.raspberrypi.org/blog/raspberry-pi-imager-imaging-utility 获得关于该工具的更多信息。

您可以下载适用于 Windows、macOS 或 Ubuntu 的工具。我使用 macOS,但我怀疑下面的描述对于其他操作系统来说会非常相似。

在 macOS 上,你下载一个.dmg文件。它以类似于imager_1.4.dmg的名称出现在Downloads文件夹中。双击弹出安装对话框,如图 2-1 所示。

img/506025_1_En_2_Fig1_HTML.jpg

图 2-1

树莓派成像仪安装程序对话框

树莓派成像仪图标拖放到对话框中的Applications文件夹,安装程序。安装只需几秒钟。

要启动树莓派成像仪,您可以

  • 转到Finder窗口,并导航到Applications文件夹。找到树莓派成像仪图标。双击该图标。

  • 按 Command-space 调出聚光灯搜索。在“树莓派 Imager”中键入足够的字符,以便 Spotlight 找到工具,然后按下 Enter 键。

您将会看到一个对话框,询问您是否真的想要打开该应用程序(仅第一次)。如果是,点击打开。图 2-2 显示成像仪主对话框。

img/506025_1_En_2_Fig2_HTML.jpg

图 2-2

树莓派成像仪主对话框

点击选择 OS *。*图 2-3 显示了允许你选择你想要的操作系统的对话框。

img/506025_1_En_2_Fig3_HTML.jpg

图 2-3

树莓派成像仪操作系统选择对话框

出于本书的目的,选择第一选择, 树莓派 OS (32 位);这就是我上一节所说的推荐的(你可以在描述中看到那个术语)。这将调出主对话框,显示所选择的操作系统,如图 2-4 所示。此时,如果您还没有这样做,您必须使 microSD 卡可用于您的工作站。

Tip

除非你预计你的项目需要大量的文件存储,否则我推荐 16 GB 或 32 GB 容量的 microSD 卡。大于 32 GB 将强制您重新格式化 microSD 卡,然后才能使用它。幸运的是,树莓派成像仪可以重新格式化它。更多信息见 www.raspberrypi.org/documentation/installation/sdxc_formatting.md

img/506025_1_En_2_Fig4_HTML.jpg

图 2-4

树莓派成像仪主对话框;选择的操作系统

现在,您必须选择成像仪写入所选操作系统映像的 SD 卡。点击选择 SD 卡查看可用的卡。图 2-5 显示了一个类似于你将看到的 microSD 选择对话框。在这种情况下,只有一张卡可用。如果您安装了多张 microSD 卡,请单击您想要使用的那张。

img/506025_1_En_2_Fig5_HTML.jpg

图 2-5

树莓派成像仪 SD 卡选择对话框

现在,您将再次看到主对话框,显示选择的操作系统、选择的 SD 卡和一个活动的写入按钮。见图 2-6 。

img/506025_1_En_2_Fig6_HTML.jpg

图 2-6

树莓派成像仪主对话框;选择的操作系统和 SD 卡

点击写入开始下载写入。你会看到一个警告对话框,提示当前卡上的所有内容都将被删除。只需点击。接下来会提示您输入用户密码。输入密码,点击确定。你最终会再次看到带有进度条的主对话框,如图 2-7 所示。

img/506025_1_En_2_Fig7_HTML.jpg

图 2-7

树莓派成像仪写入对话框

树莓派操作系统下载和 microSD 卡写入操作需要几分钟时间。实际时间取决于操作系统的大小、互联网连接速度和 microSD 卡的速度。注意取消写入按钮,您可以在紧急情况下使用。写入完成后,该工具会再花几分钟进行验证。验证后,你应该会看到成功的指示,如图 2-8 所示。

img/506025_1_En_2_Fig8_HTML.jpg

图 2-8

树莓派成像仪成功对话框

点击继续返回主对话框(见图 2-5 )。从那里,你可以重新开始整个过程来写另一个 microSD 卡。或者您可以移除 microSD 卡,然后开始引导和配置 Pi3。

Tip

树莓派成像仪帮了你一个忙…也许吧。该工具将下载的操作系统映像缓存在您的工作站文件系统中。因此,如果您想将相同的操作系统写入另一个 SD 卡,您不必再次下载映像,因此对 microSD 进行映像的整个任务应该会运行得更快。太好了。除非你不想再写同样的 OS;如果没有,您已经丢失了大约 2 GB 的文件系统。不幸的是,工具开发人员没有记录操作系统在哪里被缓存。然而,在大量的调查之后,我发现在 macOS 中,你可以在~/Library/Caches/Raspberry Pi/Imager下找到缓存的图片。在 Windows 机器上,它应该在c:\users\your-username\AppData\Local中,在 Ubuntu 上,它应该在~/.cache中。找到它,如果你愿意,你可以删除它。

引导和配置树莓派操作系统

在给 Pi3 通电之前,您必须将 microSD 卡插入 microSD 插槽。接下来,将 HDMI 电缆插入 Pi,然后插入 HDMI 兼容显示器或电视。接下来,将 USB 键盘和鼠标插入 Pi3。

最后,对于电源,您可以选择插入提供 5V 和 2.5A 电源的墙上适配器,或者使用类似规格的电源组。虽然初始启动和配置可能需要一段时间,但电池应该没问题。我经常用一个 10,000 mAh 的电池几个小时。

Note

不使用显示器、键盘和鼠标也可以设置 Raspberry Pi。它更复杂。参见第三章了解操作方法。

初始配置

一旦你给 Pi3 通电,奇迹就开始发生了。初始启动可能需要几十秒到几分钟。最终你会看到桌面和欢迎水花,如图 2-9 所示。

img/506025_1_En_2_Fig9_HTML.png

图 2-9

树莓派操作系统桌面和欢迎飞溅

Welcome splash 表示出现了一个非常好的配置工具。它以一种我发现比使用其他配置工具更容易的方式帮助设置所有的要素。在欢迎画面中点击下一个开始配置。

您看到的第一个对话框允许您设置适当的地区、时区和键盘。图 2-10 显示,和以往一样,英国的情况是默认的。

img/506025_1_En_2_Fig10_HTML.jpg

图 2-10

用于设置区域设置、时区和键盘的对话框

由于我生活在美国,假装读写美式英语,所以我使用了图 2-11 所示的设置。一旦你为自己做了适当的设置,点击下一步

img/506025_1_En_2_Fig11_HTML.jpg

图 2-11

用于设置区域设置、时区和键盘的示例设置

接下来,你会看到一个对话框,如图 2-12 所示,它让你调整桌面以全屏显示。只需按照说明操作,然后点击下一步

img/506025_1_En_2_Fig12_HTML.jpg

图 2-12

设置屏幕对话框

现在您有机会更改默认用户 ID“pi”的密码,如图 2-13 中的对话框所示。

img/506025_1_En_2_Fig13_HTML.jpg

图 2-13

更改密码对话框

如果您不想更改“raspberry”的密码,请将这些字段留空,然后单击下一个的**。如果您想更改密码,我建议您首先取消选择隐藏字符,然后在两个文本字段中输入新密码,并点击下一步。如果您决定更改密码,您必须使用至少八个字符的密码,以便将来的设置步骤能够正常工作。 不要忘记密码!**

接下来,你有机会连接到 Wi-Fi 网络,如图 2-14 所示。如果您通过以太网连接到网络,可以跳过这一步。既然这本书假设无线通信,不如现在就做。

img/506025_1_En_2_Fig14_HTML.jpg

图 2-14

无线网络选择对话框

滚动对话框中显示的列表找到您的网络,选择它,然后单击下一个 *。***在下一个对话框中,如图 2-15 所示,您可以输入网络密码。

img/506025_1_En_2_Fig15_HTML.jpg

图 2-15

网络密码对话框

与前面的对话框一样,您可以跳过连接到 Wi-Fi 网络,但您应该连接。一旦你输入了正确的密码(取消选择隐藏字符使得输入正确的密码更容易),点击下一步

现在你将有机会确保树莓派操作系统是最新的,如图 2-16 所示。请注意,如果没有网络连接,操作系统甚至无法检查必要的更新,更不用说更新了。更新总是一个好主意,我强烈建议你这样做!点击下一个

img/506025_1_En_2_Fig16_HTML.jpg

图 2-16

更新软件对话框

现在,当操作系统读取更新列表、获取更新、下载更新、安装更新并最终完成时,您将看到一系列状态消息。图 2-17 所示为该系列。

img/506025_1_En_2_Fig17_HTML.jpg

图 2-17

树莓派操作系统更新消息

点击确定继续。你应该得到设置完成的确认,如图 2-18 所示。你可以选择现在重启操作系统或者做一些其他的事情。我个人觉得在做其他事情之前重启更安全。点击重启重启。

img/506025_1_En_2_Fig18_HTML.jpg

图 2-18

安装完成对话框

恭喜你!您已经完成了初始配置,并且运行了最新的树莓派操作系统!

配置远程计算

你现在有了一个可以作为台式电脑使用的树莓派系统,尽管你可能会发现它对任何重要的活动都令人失望。我将向您展示如何配置 Pi3 进行无头操作,即不连接显示器/电视、键盘或鼠标。然而,你将完全控制这个系统。这种配置非常适合机器人或物联网系统以及远程开发。

我假设此时您已经完成了上一节中描述的初始配置,已经重新启动,并且可以使用桌面来完成附加配置。通过菜单【树莓】偏好设置树莓派配置 调出桌面的树莓派配置工具。您应该会看到如图 2-19 所示的对话框。

img/506025_1_En_2_Fig19_HTML.jpg

图 2-19

树莓派配置对话框

配置工具在系统选项卡上打开。您需要更改一些默认值。如果你希望有多个树莓派连接到你的网络,我强烈建议你更改主机名

Boot 行控制引导时加载的用户界面的类型。如你所见,默认情况下,操作系统启动桌面。它很现代,也很容易使用。但是,正如您可以想象的那样,它占用了 CPU 周期和内存方面的资源。另一个选项是 CLI(命令行界面)。它更难使用,但需要的资源少得多。因为您希望将尽可能多的 Pi3 资源用于您的项目,所以您希望引导到 CLI。选择 CLI先不要点击确定

配置接口功能

现在是时候让 Pi3 通过其各种基本 I/O 接口与机器人和物联网设备进行交互了。默认情况下,并非所有接口都启用。在配置工具中,点击接口选项卡。你会看到类似图 2-20 的东西。该对话框显示所有接口和当前启用状态。

img/506025_1_En_2_Fig20_HTML.jpg

图 2-20

“接口”对话框的默认设置

感兴趣的接口有

  • 摄像头:与 Pi3 上的树莓派摄像头插槽相关。本书中的项目不利用相机,所以我将禁用它。如果您计划在项目中使用摄像机,请启用它。

  • SSH :通过安全外壳远程访问 Pi3。你需要这个;这将是与 Pi 交互的主要方式!你必须启用它。

  • VNC :与虚拟网络计算有关。您将使用它,但具有讽刺意味的是,您希望禁用它!这是因为 VNC 在运行时也会窃取资源。更多关于 VNC 的信息,请参见第四章。

  • SPI :与串行外设接口协议相关。本书中的一些设备需要它,所以启用它。

  • I2C :与集成电路间协议相关。本书中的一些设备需要它,所以启用它。

  • 串口:与树莓派 GPIO 头上可用的串口相关(RX & TX 引脚)。保持启用状态。

  • 串口控制台:与串口相关;如果启用,操作系统将串行端口用于控制台输出。如果您计划将串行端口用于设备,则必须禁用串行控制台。本书中没有一个项目会用到它,但出于说明的目的,我还是会禁用它;参见第七章。

其余设置都可以接受。根据前面的建议,本书的接口配置如图 2-21 所示。

img/506025_1_En_2_Fig21_HTML.jpg

图 2-21

启用或禁用相关界面的界面对话框

一旦您完成了项目所需的启用和禁用任务,单击 OK 确认配置。如果愿意,您可以关闭配置工具。

在树莓派操作系统上安装 Java

是时候在 Pi3 上安装 Java 了。要开始安装,请在桌面上启动一个终端。只需点击桌面左上方启动栏中的终端图标。

安装什么 Java?

在安装之前,最好确定要安装哪个版本的 Java。在撰写本文时,最新的 Java 是版本 14,但是版本 8 到 14 已经存在。你可以在 Pi3 上安装它们中的任何一个(或者实际上是全部),但是你可能会发现一些程序无法运行或者无法优化。最安全的 Java 版本是树莓派 OS 存储库中可用的版本。在撰写本文时,存储库中可用的最新版本是 Java version 11。

可以安装 JRE (Java 运行时环境),它允许您运行以前构建的程序,或者安装 JDK (Java 开发工具包),它允许您构建和运行程序。对于大多数项目,考虑到远程开发的预期,JRE 就足够了。然而,出于本书的目的,我将向您展示如何安装与 Pi3 兼容的 JDK。

检查以前的 Java 安装

在撰写本文时,关于 Java 是否包含在最新的树莓派操作系统中,似乎还有点混乱。我的经验说不包括在内;但是,检查是谨慎的。为此,在终端中,输入java -version命令来查找 Java 的当前默认版本。

有三种可能的反应:

  1. -bash: java: command not found

  2. openjdk version "11.x.x" 202x-xx-xx

  3. 不同的东西

如果得到第一个响应,就要装 Java 了。跳到下一小节。

如果您得到第二个响应,那么 Java 11 已经安装好了,您可以跳过下一小节。

如果你得到第三个回应,你还有更多工作要做。“有些不同”意味着操作系统将不同版本的 Java 设置为默认版本。除非默认值已更改,否则操作系统默认为安装的最新版本。因此,要么没有安装 Java 11,要么安装了 Java 11,并将其他一些 Java 版本设置为默认版本。

您可以使用以下命令来诊断情况并更改默认版本:

sudo update-alternatives --config java

响应列出了安装的 Java 版本。默认版本标有“*”。该命令还允许您将不同的版本指定为默认版本。如果你看到

/lib/jvm/java-11-openjdk-armhf/bin/java

在列表中,在字符串左侧键入数字,然后按 Enter 键。如果您在列表中没有看到该路径,您必须安装 Java 11,在这种情况下,您必须阅读下面的小节。

在你安装了 Java 11 之后,如果一个更高版本的 Java 是默认的,你必须使用update-alternatives命令来使 Java 11 成为默认的。

Note

你可以从 https://phoenixnap.com/kb/install-java-raspberry-pi 中获得关于默认 Java 版本以及如何操作它的更多细节。

安装 JDK 11

我发现安装 Java 最简单的方法是通过命令行。为此,在终端中输入以下命令(这是一个好主意,尽管系统应该是最新的):

sudo apt update

您最终应该会看到以下响应:

All packages are up to date.

现在,对于好的东西,输入以下命令:

sudo apt install default-jdk

几秒钟后,系统会询问您是否希望继续。输入“Y”。几分钟后,安装完成,没有任何大张旗鼓,只是返回命令行提示符。

现在,再次输入命令java -version。shell 现在应该会返回类似下面的内容:

openjdk version "11.0.8" 2020-07-14

如果你得到了这样的回应(或类似的东西),你可以继续下一小节。如果没有,您应该从上一小节重新开始。

完成 Java 安装

为了设置 NetBeans,在第五章中,你需要知道 Java 11 的安装路径。输入命令

sudo update-alternatives --config java

您应该会在响应中看到如下内容:

/usr/lib/jvm/java-11-openjdk-armhf/bin/java

你可以 记住这个路径 或者稍后运行这个命令。

完成 Pi3 设置

现在您需要找到新配置和连接的 Pi3 的 IP 地址。将鼠标指针悬停在桌面菜单栏右侧的 Wi-Fi 图标上。您应该会看到一个类似于图 2-22 所示的弹出窗口。

img/506025_1_En_2_Fig22_HTML.jpg

图 2-22

网络弹出窗口

第一行确认不存在以太网连接。第二行显示 Pi 所连接的 Wi-Fi 路由器的名称。第三行显示 IP 地址。 你需要记住 IP 地址

现在你应该关闭 Pi。新配置的某些方面在下次重新启动之前不会生效。例如,桌面仍将运行,直到您重新启动。要关机,使用菜单(树莓)注销。你会看到关机选项对话框。点击关机。你可能会看到一个认证对话框;如果是,输入“pi”的密码并点击 OK 。几秒钟后,绿色 LED 应该停止闪烁;此时,Pi 已经关闭。

一旦系统关闭,就可以安全地切断电源。你应该这样做。然后断开显示器/电视、键盘和鼠标的连接。从这一点上来说,除了远程计算什么都没有!

Tip

我发现最新版本的树莓派操作系统包括一个屏幕捕捉工具。它叫做斯克罗特。要捕捉整个屏幕,只需按下键盘上的 PrtScr 键。默认情况下,Scrot 存储。它在用户的主目录中生成的 png 文件。我用 Scrot 截取了本节使用的所有截图。你可以从 https://magpi.raspberrypi.org/articles/take-screenshots-raspberry-pi 了解更多。

摘要

在本章中,您已经

  • 了解如何为机器人选择合适的树莓派操作系统

  • 安装和配置操作系统,以生产基于 Pi 的功能性计算机

  • 进一步配置操作系统,以支持所需的接口和远程计算

  • 安装了正确版本的 Java

恭喜你!您的树莓派 3 模型 B+设置已完成!在第四章中,您将学习如何从您的工作站控制 Pi3。在第五章中,你将学习如何在 Pi3 上设置远程开发的 NetBeans。

二、树莓派 0W 设置

我假设如果你正在阅读这一章,你对使用树莓派 Zero W(我将在本章的其余部分使用 Zero)和 Java 构建物联网项目感兴趣。在本章中,您将学习如何

  • 为 Pi 选择“最佳”操作系统

  • 安装树莓派操作系统

  • 为远程开发配置树莓派操作系统

  • 在树莓派操作系统上安装 Java

设置注意事项

零涉及的步骤与树莓派 3 型号 B+相同;但是,有些执行方式不同。同样,Pi、microSD 卡和电源的“基础”也是一样的。然而,Zero 使得连接 HDMI 显示器或电视、USB 键盘和 USB 鼠标有些困难,除非你有合适的连接器。因此,在这一章中,我将向您展示如何进行“无头”设置,这在任何情况下理解起来都不是一件坏事。

选择操作系统

考虑事项与树莓派 3 模型 B+类似。树莓派 OS 是操作系统(OS)的最佳选择。有趣的决定是在第二章描述的精简版推荐版完整版之间做出的。可以做一个安装推荐的案例,但是我推荐 Lite 。因此,我将向您展示如何安装和配置 Lite

在 microSD 卡上加载树莓派操作系统

我在第二章描述了获得树莓派操作系统的选项。在这一章,我将跳转到使用树莓派成像仪。如果您的工作站上没有安装,请参见第二章。

写树莓派 OS

启动树莓派成像仪(详见第二章)。您将会看到一个对话框,询问您是否真的想要打开该应用程序(仅第一次)。如果是,点击打开。图 3-1 显示成像仪主对话框。

img/506025_1_En_3_Fig1_HTML.jpg

图 3-1

树莓派成像仪主对话框

点击选择 OS 。图 3-2 显示了允许你选择你想要的操作系统的对话框。

img/506025_1_En_3_Fig2_HTML.jpg

图 3-2

树莓派成像仪操作系统选择对话框

就本书而言,选择第二个选择 树莓派 OS(其他)。这将弹出如图 3-3 所示的窗口。

img/506025_1_En_3_Fig3_HTML.jpg

图 3-3

操作系统选择

你会看到树莓派操作系统 LiteFull 的选择。出于本书的目的,请单击 树莓派 OS Lite (32 位)。你会再次看到显示所选操作系统的主对话框,如图 3-4 所示。此时,如果您还没有这样做,您必须使 microSD 卡可用于您的工作站。

img/506025_1_En_3_Fig4_HTML.jpg

图 3-4

树莓派成像仪主对话框;选择的操作系统

现在,您必须选择成像仪写入所选操作系统映像的 SD 卡。点击选择 SD 卡查看选项。图 3-5 显示了一个类似于你将看到的 microSD 选择对话框。在这种情况下,只有一张卡可用。如果您安装了多张 microSD 卡,请单击您想要使用的那张。

img/506025_1_En_3_Fig5_HTML.jpg

图 3-5

树莓派成像仪 SD 卡选择对话框

现在,您将再次看到主对话框,显示选择的操作系统、选择的 SD 卡和一个活动的写入按钮。见图 3-6 。

img/506025_1_En_3_Fig6_HTML.jpg

图 3-6

树莓派成像仪主对话框;选择的操作系统和 SD 卡

点击写入按钮后,树莓派成像仪下载操作系统,将其写入 microSD 卡,并验证写入。在看到指示成功的对话框之前,不要取出 microSD 卡。更多细节请参见第二章。

Tip

参见第二章中的提示关于树莓派成像仪对操作系统映像的缓存。

完成可启动的 microSD 卡

由于我们正在进行“无头”设置,Zero 没有显示器,也没有键盘,你不能简单地将刚写好的 microSD 卡插入 Zero 并启动。您必须首先采取一些额外的重要措施:

  • 支持通过安全外壳 (SSH)访问设备。

  • 配置 Wi-Fi 网络。

Caution

Zero W 支持 5 GHz Wi-Fi 网络。

确保 microSD 卡仍可由您的工作站访问。要启用 SSH,只需在 microSD 卡的根文件夹中创建一个名为ssh的空文件。请注意,文件名没有文件扩展名或类型,这一点很重要。

Tip

要在 macOS 上创建没有扩展名的空文件,请打开终端,导航到您想要文件的文件夹,然后输入命令touch <fileName>。要在 Windows 上这样做,打开记事本,创建一个新文件,然后点击另存为,导航到你想要文件的文件夹,输入“<文件名>”;引号消除了扩展名。

要配置 Zero 使其可以连接到您的 Wi-Fi 网络,请在 microSD 卡的根文件夹中创建一个名为wpa_supplicant.conf的文件。然后用您选择的文本编辑器编辑该文件,使其内容如清单 3-1 所示。

country=<2 letter ISO 3166-1 country code>
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1

network={
  scan_ssid=1
  ssid="<WIFI LAN name>"
  psk="<WIFI LAN password>"
}

Listing 3-1wpa_supplicant.conf

< 2 个字母的 ISO 3166-1 国家代码> 标识您的国家(参见 www.iso.org/obp/ui/#search )。对美国来说,应该是"US";对于英国,应该是"UK";等等。 < WIFI 局域网名称> 是您的 Wi-Fi 网络的名称, < WIFI 局域网密码> 是该网络的密码。注意清单 3-1 中的第二行和第三行实际上应该是一行。

现在您已经准备好引导和配置 Zero。

引导和配置树莓派操作系统

在给 Zero 加电之前,必须将 microSD 卡插入 microSD 插槽。电源方面,可以使用供电 5V 和 1.2A 以上的壁式适配器;您也可以使用相同规格的电池/电源组。确保将电源插入标有“PWR IN”的微型 USB 连接器

接通电源后,初次启动大约需要 90 秒。如果一切顺利,绿色 LED 最终停止闪烁并保持点亮。这表示 Zero 已经完成启动。

Caution

我注意到,当连接到一个空闲的零点时,至少有一些电源组决定关闭。我相信这是因为零在空闲时的功耗低于 150 mA。在开发过程中,您可能希望使用壁式电源为设备供电。

找到 IP 地址

你必须做的下一件事是找到零的 IP 地址。最简单的方法是通过一个终端模拟器。在 macOS 上,终端模拟器叫终端;在 Windows 10 上,等效物也称为终端。我将用通用词终端来指代这两者。打开工作站上的终端,输入命令ping raspberrypi.local。响应包含 IP 地址。如果 Zero 是您的 Wi-Fi 网络上唯一一个主机名为raspberrypi的设备,这种方法就有效。

如果 Zero 不是您的 Wi-Fi 网络上唯一具有主机名raspberrypi的设备,您可以使用无线路由器的配置工具来查找 Zero 的 IP 地址。基本上,您必须将浏览器定向到 192.168.1.1 或 192.168.1.254 或类似的地址(请参阅您的无线路由器文档)。四处寻找,直到找到连接到网络的设备列表。然后,您应该能够识别您的零点并确定 IP 地址。

接零

连接到 Zero 的最简单和最常用的方法是从工作站的终端发出的安全外壳命令(ssh)。打开终端并输入命令

ssh <IP address> -l pi

其中<IP address>表示您之前确定的零的 IP 地址。输入命令后,终端可能会警告您“主机的真实性”;如果是这样,只需输入yes继续。将提示您输入密码;用户pi的默认密码是raspberry。一旦你输入了密码,你应该会看到零响应,如图 3-7 所示。

img/506025_1_En_3_Fig7_HTML.jpg

图 3-7

初始树莓派操作系统 ssh 响应

更新和升级树莓派操作系统

我建议连接到 Zero 后做的第一件事是更新和升级操作系统。为此,您可以在终端中输入以下两个命令:

sudo apt-get update -y
sudo apt-get upgrade -y

完成update命令需要相当短的时间。它打印了几行反馈。完成后,您将在下一个命令提示符前看到下面一行:

Reading package lists... Done

upgrade命令可能需要很长时间。Zero 不是一个快速的设备,而且总的时间会受到网络速度和 microSD 速度的影响。该命令打印数百行反馈。您看到的可能有所不同,但是当我升级时,下一个命令提示符前的最后一行如下所示:

Processing triggers for libc-bin (2.28-10+rpi1)

您必须重新启动以确保一切生效。输入命令sudo reboot重启。当然,您必须在终端中再次输入ssh命令,以便在终端完成重启后重新连接到 Zero。

附加配置

现在,谨慎的做法是进行额外的配置。要启动树莓派配置工具,请输入命令sudo raspi-config。您将看到如图 3-8 所示的配置工具主对话框(细节可能有所不同)。您可以使用键盘上的 tab 键和箭头键在工具对话框中导航以突出显示选项。当您突出显示了所需的操作后,只需按回车键。

img/506025_1_En_3_Fig8_HTML.jpg

图 3-8

树莓派操作系统配置工具主对话框

注意图 3-7 中为用户pi修改密码的建议。假设您在一个完全本地的网络上工作,我认为这是可选的。如果您希望这样做,那么在配置工具启动时,它已经被高亮显示了。要更改用户pi的密码,只需点击 Enter。您将看到一个对话框,确认您将要更改用户pi的密码。按回车键。您将离开工具对话框并返回到 shell 来输入,然后重新输入密码。完成后,您将返回到工具,确认密码更改成功;按回车键。您将再次看到图 3-8 中的主对话框。

另一个可选配置是更改主机名。我建议这样做。要更改主机名,在主对话框中导航到网络选项(使用向下箭头),然后点击 Enter。你会看到网络选项对话框,如图 3-9 所示。

img/506025_1_En_3_Fig9_HTML.jpg

图 3-9

树莓派操作系统配置工具网络选项对话框

您将看到主机名已经突出显示,因此只需点击 Enter。您将看到一个对话框,描述主机名中什么是合法的,什么是不合法的;只需按回车键。现在您将看到一个对话框,允许您键入新的主机名。这样做;然后按 tab 键或向下箭头键,使 < OK > 高亮显示,然后按 Enter 键。你会再次看到如图 3-8 所示的主对话框。

接下来,您将配置本地化选项(在美国也称为本地化选项)。导航到该选项,然后按 Enter 键。您将看到图 3-10 中的对话框。

img/506025_1_En_3_Fig10_HTML.jpg

图 3-10

树莓派操作系统配置工具本地化选项对话框

您应该更改区域设置;该选项已经被选中,所以只需按 Enter 键。您将看到如图 3-11 所示的区域设置选择对话框。

img/506025_1_En_3_Fig11_HTML.jpg

图 3-11

树莓派操作系统配置工具区域设置对话框

选择框包含一个区域列表。您可以使用上下箭头键滚动列表。您可以通过按空格键来选择或取消选择区域设置。你会发现。默认选择 UTF-8 UTF-8 。由于我在美国,我取消了它,然后选择了 en_US。UTF-8 UTF-8 (如图 3-11 )。一旦选择了所有需要的语言环境,按 tab 键使 < OK > 高亮显示,然后按 Enter 键。现在您将看到另一个区域设置对话框,让您选择系统的默认区域设置。参见图 3-12 。

img/506025_1_En_3_Fig12_HTML.jpg

图 3-12

树莓派操作系统配置工具区域设置默认对话框

虽然不会有太大的不同,但最好的选择是 en_US。UTF-8 。使用向下箭头键选中该选项,然后输入。零点会处理一段时间,当它完成时,你会再次看到主对话框(图 3-8 )。

现在,您将更改时区,以便 Zero 知道您所在位置的正确时间。再次选择定位选项,将会看到如图 3-10 所示的对话框。现在突出显示并选择更改时区。您将看到如图 3-13 所示的对话框。

img/506025_1_En_3_Fig13_HTML.jpg

图 3-13

树莓派操作系统配置工具时区对话框

你需要为自己选择合适的地理区域。我选择了美国选项。按回车键继续。接下来,您将看到与该地理区域相关的时区列表,在我的例子中,是与美国相关的时区。见图 3-14 。

img/506025_1_En_3_Fig14_HTML.jpg

图 3-14

树莓派操作系统配置工具时区对话框

如您所见,我选择了中部时区。当你为自己选择了合适的选项后,按回车键。你将返回到主对话框(见图 3-8 )。

配置接口功能

现在是时候让 Zero 通过各种接口与外部设备进行交互了。在组态工具主对话框中,选择接口选项。你会看到类似图 3-15 的东西。该对话框显示所有界面。

img/506025_1_En_3_Fig15_HTML.jpg

图 3-15

树莓派操作系统配置工具界面对话框

感兴趣的接口与第二章中讨论的相同。界面的初始配置如图 2-20 所示,除了一个例外;您已经启用了 SSH。本书中的一些物联网设备需要 SPI 或 I2C,因此同时启用两者。串行端口没有被使用,所以你不需要做任何事情;如果您计划使用串行端口,您必须禁用串行控制台。

要启用 SPI,突出显示 SPI 并按 Enter 键。系统会询问您是否要启用它。确保 Yes 高亮显示,并按下回车键。您将收到一条消息,表明 SPI 已启用;只需按回车键。你将返回到如图 3-8 所示的主对话框。

要启用 I2C,在主对话框中选择接口选项,高亮显示 I2C ,并点击回车。系统会询问您是否要启用它。确保高亮显示,并点击确认。您将收到一条消息,表明 I2C 已启用;只需按回车键。你将返回到如图 3-8 所示的主对话框。

现在是重新启动的好时机,这样您的新配置就会生效。在主对话框中,用 tab 键高亮显示 <完成> ,然后回车。将询问您是否希望重新启动。由于 <是> 已经高亮显示,您可以点击回车。

在树莓派操作系统上安装 Java

是时候从零开始安装 Java 了。要开始安装,在工作站终端再次使用ssh命令访问零点。要登录,如果您更改了默认的“raspberry”,您当然需要使用新密码

安装什么 Java?

为了确保本书中机器人技术(参见第二章)和物联网项目的一致性,你要安装 Java 版本 11。可悲的是,树莓派 OS repository 实现的 Java 11 在 Zero 上不起作用!Java 11 的存储库实现需要比 Zero 中使用的更现代的处理器架构。Java 8 的存储库实现应该可以工作,但是为了兼容在第二章配置的树莓派 3 Model B+,你需要 Java 11。

幸运的是,Azul ( www.azul.com/ )提供了一个 JRE (Java Runtime Environment,Java 运行时环境),允许你运行之前构建的程序,还提供了一个 JDK (Java Development Kit,Java 开发工具包),允许你在几个处理器架构上为几个版本的 Java 构建和运行程序。更幸运的是,它们可以免费用于非商业用途。

你可以去 Azul 下载页面( www.azul.com/downloads/zulu-community/?architecture=x86-64-bit&package=jdk )确定树莓派 Zero 有哪些 JRE 和 JDK 版本。在撰写本文时,该页面包含一个过滤功能,可以缩小选择范围;见图 3-16 。

img/506025_1_En_3_Fig16_HTML.png

图 3-16

阿苏尔 JDK/JRE 下载过滤器

我用图 3-16 所示的滤镜组合达到了最好的效果。请特别注意架构滤波器。如图所示,我为树莓派设置了适当的值;请注意,“HF”标志表示硬件浮点能力。在撰写本文时,过滤器生成的结果表只包含 JDK 8、JDK 11 和 JDK 13 的包。显然,你会想要 JDK 11 号。

检查以前的 Java 安装

在撰写本文时,我的经验表明 Java 不包含在最新的树莓派操作系统中。原因可能是默认的 Java 版本不能在所有的树莓派模型上运行。无论如何,检查是谨慎的。有关详细信息,请参考第二章“检查先前的 Java 安装”小节。

安装 JDK 11

即使系统应该是最新的,检查操作系统是否需要更新也是一个好主意。为此,请在终端中输入以下命令:

sudo apt update

您最终应该会看到以下响应:

All packages are up to date.

现在,您必须为 JDK 创建一个文件夹,然后导航到该文件夹。输入以下命令:

sudo mkdir /opt/jdk
cd /opt/jdk

现在,在您的工作站浏览器中,转到 Azul 下载页面,并在表格中找到与 JDK 11 相对应的行。见图 3-17 。

img/506025_1_En_3_Fig17_HTML.png

图 3-17

阿苏尔 JDK/JRE JDK 11 下载行

将鼠标光标悬停在该行右侧的下载图标(右边有一个带文本“ .tar.gz ”的小云)上。右键单击(在 macOS 上,即按住 Ctrl 键单击或用两个手指单击)图标,弹出一个操作弹出窗口。点击复制链接

现在在终端中,输入命令sudo wget,然后粘贴你复制的链接。例如,我使用的命令(在终端中,该命令应该是一行)是

sudo wget https://cdn.azul.com/zulu-embedded/
bin/zulu11.41.75-ca-jdk11.0.8-linux_aarch32hf.
tar.gz

下载 JDK 需要几分钟时间。有一个进度条让你知道命令正在工作。

下载完成后,您需要找到下载文件的名称。使用ls命令来完成。复制文件的名称。然后输入命令sudo tar -zxvf,将文件名粘贴到终端中。例如,我使用的命令(同样,都在一行中)是

sudo tar -zxvf zulu11.41.75-ca-jdk11.0.8-
linux_aarch32hf.tar.gz

该命令将需要几分钟的时间来提取所有文件。没有进度条,有时它似乎停滞不前。耐心点。

当命令完成时(您将看到一个新的命令提示符),做一些清理是一个好主意。tar.gz文件很大,应该删除。为此,您可以使用以下命令:

sudo rm *.tar.gz

现在您需要为javajavac命令创建符号链接(javac是可选的,因为它不太可能被使用)。首先,找到tar命令创建的目录的名称。使用ls命令来完成。复制目录的名称。使用以下命令(同样是单行命令)创建符号链接:

sudo update-alternatives --install
     /usr/bin/java java <name of the directory you
     copied>/bin/java 1

sudo update-alternatives --install
/usr/bin/javac javac <name of the directory
you copied>/bin/javac 1

同样,您应该能够将目录名粘贴到终端中。例如,我使用的命令是

sudo update-alternatives --install
/usr/bin/java java /opt/jdk/zulu11.41.75-
ca-jdk11.0.8-linux_aarch32hf/bin/java 1

sudo update-alternatives --install
/usr/bin/javac javac /opt/jdk/zulu11.41.75
     -ca-jdk11.0.8-linux_aarch32hf/bin/javac 1

现在输入命令

java -version

shell 现在应该会返回类似下面的内容:

openjdk version "11.0.8" 2020-07-14 LTS

为了设置 NetBeans,在第五章中,你需要知道 Java 11 的安装路径。输入命令

sudo update-alternatives --config java

您应该会在响应中看到如下内容:

/usr/bin/java

您可以记住该路径,也可以稍后运行该命令。

摘要

在本章中,您已经

  • 了解如何为物联网选择合适的树莓派操作系统

  • 安装和配置操作系统以生产基于树莓派 Zero W 的无头计算机

  • 进一步配置操作系统以支持所需的接口

  • 安装了正确版本的 Java

恭喜你!您的树莓派 Zero W 设置已完成!第四章主要与树莓派 3 型号 B+相关,因此请随意继续第五章。在第五章中,你将学习如何设置远程开发的 NetBeans。

四、设置工作站

在前两章中,您配置了一个树莓派来支持用 Java 编写的机器人和物联网项目,并支持远程计算。在本章中,我将向您展示如何为远程计算设置工作站,以及如何将工作站连接到 Pi。您将设置两种形式的远程计算:

  • 用于树莓派 3 模型 B+和树莓派 Zero W 的命令行控制的安全外壳(SSH)

  • 用于树莓派 3 模型 B+的桌面控制的虚拟网络计算(VNC)

使用 SSH 的远程计算

连接到树莓派的最简单和最常用的方法是从终端仿真器发出的安全 shell ( ssh)命令。如果你看第三章,这一节有些多余,可以跳过;如果没有,继续读。在 macOS 上,终端模拟器叫终端;在 Windows 10 上,等效物也称为终端。我就用通用词终端来指代两者。

要从工作站连接到 Raspberry Pi,请打开终端。以两种形式之一输入ssh命令:

ssh <IP address> -l <username>
ssh <hostname> -l <username>

“IP 地址”是您希望控制的 Pi 的地址;这种形式总是有效的,因为 IP 地址在网络域中必须是唯一的。类似地,“主机名”是您希望控制的 Pi 的主机名;只有当您的 Pi 在网络域中有唯一的主机名时,此表单才有效。该命令实际上是让您使用“用户名”登录系统系统会提示输入“用户名”的密码;您可以在树莓派操作系统配置期间设置密码。图 4-1 显示了使用带有 IP 地址的ssh访问第二章中配置的树莓派 3 Model B+ (Pi3)的结果。

img/506025_1_En_4_Fig1_HTML.jpg

图 4-1

突出显示 ssh 命令的终端 shell

成功!您可以在图 4-1 的最后一行看到来自 Pi3 的提示。现在,您可以输入操作系统中所有可用的命令。坐在您的工作站上,您实际上可以完全控制 Pi3。

Note

在旧版本的 Windows 和 Windows 10 上,您可以使用 PUTTY 来代替终端。PUTTY 是一个用于 Windows 的免费开源 ssh 客户端。

VNC 远程计算

虚拟网络计算(VNC)为远程计算提供了客户端/服务器架构,允许您与树莓派操作系统桌面进行交互。VNC 服务器运行在树莓派上,VNC 客户端运行在您的工作站上。VNC 服务器已经安装在 Pi3 上,因为它是推荐的操作系统安装的一部分。因为您将 VNC 配置为禁用,所以当 Pi3 启动时,VNC 服务器不会启动。没有烦恼;您可以在需要时启动和停止它。

启动 VNC 服务器

在您之前打开的终端中,输入命令vncserver。您将得到一个冗长的响应,表明服务器正在运行,如图 4-2 所示。请特别注意回复的最后一行。它显示了您需要用于 VNC 客户端的完整地址。在这种情况下,它是 192.168.1.70:1。

img/506025_1_En_4_Fig2_HTML.jpg

图 4-2

确认 VNC 服务器正在运行

获取并启动 VNC 浏览器

Pi3 上的 VNC 服务器来自 RealVNC 公司。您将需要为您的工作站获得一个兼容的客户端,该兼容的客户端也来自 RealVNC 可以从 www.realvnc.com/en/connect/download/viewer 下载。在 macOS 上,安装很简单。下载的是一个.dmg文件。只要双击它,你就会得到如图 4-3 所示的安装程序。将 VNC 浏览器图标拖放到应用程序文件夹图标开始安装;可能会提示您输入密码。

img/506025_1_En_4_Fig3_HTML.jpg

图 4-3

VNC 浏览器安装

现在你可以在 macOS 上启动 vnc 浏览器,方法是点击它在应用程序文件夹中的图标,或者使用字符“VNC”进行 Spotlight 搜索工具第一次启动时,会问你(至少在 macOS 上)是否真的要打开;你知道你做了,所以点击打开按钮。图 4-4 显示了第一次运行时的查看器。

img/506025_1_En_4_Fig4_HTML.jpg

图 4-4

VNC 客户初始开放

在文本字段中键入 Pi3 的 IP 地址,后跟分号和数字(如 192.168.1.70:1),然后按 Enter 键。系统会提示您输入用户 ID 和密码,如图 4-5 所示。输入正确的凭证(对于您在第二章中创建的配置,用户 ID 为“pi”,密码为“raspberry”,除非您更改了它)。您可能需要选中“记住密码”框。点击确定

img/506025_1_En_4_Fig5_HTML.jpg

图 4-5

VNC 客户端用户 ID/密码提示

验证后,服务器会提示您“访问本地电脑的辅助功能,将播放和音量等媒体键发送到远程电脑”我说拒绝访问,但你的需求可能不同。现在,您应该会看到一些与您在初始 Pi3 配置中看到的桌面非常相似的东西,如图 4-6 所示。

img/506025_1_En_4_Fig6_HTML.png

图 4-6

通过 VNC 浏览器的树莓派操作系统桌面

现在,您可以在 VNC 浏览器中通过显示器、键盘和鼠标直接使用 Pi3 进行任何操作。探索。尝试一些事情。玩得开心。

调整 VNC 服务器

您可以做一些事情来定制 VNC 服务器的外观,以适合您的偏好。我将讨论其中的两个:光标的外观和桌面的大小。

改变光标

当你在 VNC 服务器版本的桌面上玩的时候,你可能已经注意到光标是一个“X”而不是一个箭头。如果你喜欢,那好;忽略本小节的其余部分。我更喜欢箭头作为光标,我将向您展示如何使光标成为箭头。

首先,您必须终止查看器和服务器之间的连接。将光标移动到客户端窗口的中上方。一个菜单将会下拉。将光标移动到 X 处并点击。您将会看到一个弹出窗口,询问您是否真的要关闭。确认。

现在回到连接到 Pi 的终端。输入以下命令终止 VNC 服务器:

vncserver -kill :1

“:1”指的是您之前启动的特定服务器(数字可能不同)。您不会得到任何确认,但服务器不再运行。

要将服务器光标更改为箭头,首先需要将 VNC 服务器配置文件从其系统位置复制到用户 pi 的主文件夹,然后修改副本中的光标形状。在终端中,使用命令cd ~/.vnc导航到.vnc文件夹。现在,使用下面的命令(以“.”结尾)将配置文件复制到该文件夹中很重要,因为它指示当前文件夹是复制的目标;xstartup和“.”之间的空格也很重要):

cp /etc/vnc/xstartup .

现在你要编辑xstartup的副本。您可以使用任何可用的编辑器,但是我更喜欢使用nano,因为它很简单。要编辑文件,输入命令nano xstartup。您现在应该在编辑器中看到xstartup文件。它看起来有点像图 4-7 。

img/506025_1_En_4_Fig7_HTML.jpg

图 4-7

用编辑器nano打开xstartup的结果

现在你需要找到这样一行

xsetroot -solid grey

在 nano 中,您可以通过按 Ctrl-w 并在提示符下键入“xsetroot”(不带引号)来完成此操作。按回车键开始搜索。现在输入附加文本,使该行如下所示:

xsetroot -solid grey -cursor_name left_ptr

通过按 Ctrl-o 保存编辑过的文件;在提示符下,只需按回车键;您应该会看到一个文件被写入的确认。按 Ctrl-x 退出 nano。

现在,使用vncserver命令,再次启动服务器。返回 VNC 浏览器窗口。它的外观应该是不同的,如图 4-8 所示,因为查看者记得你之前建立的连接。

img/506025_1_En_4_Fig8_HTML.jpg

图 4-8

显示先前配置的连接的 VNC 浏览器

要重新建立连接,您只需双击地址为 192.168.1.70:1 的 Pi3 图标。请注意,查看者会记住多个连接。当桌面出现时,您应该会看到一个光标箭头。

更改桌面大小

假设你不喜欢你工作站上 VNC 桌面的尺寸。幸运的是,您可以在启动 VNC 服务器时更改大小。如果你想改变大小,你必须先杀死服务器,如前所述。然后,您可以使用类似下面的命令启动 VNC 服务器:

vncserver -randr=640x480

该命令在您的工作站上产生 640 像素宽、480 像素高的 Pi 桌面窗口。你可以使用不同的尺寸,比如 1024x768,但是我没有做过足够的实验来知道极限。

Tip

我的经验表明,vncserver 会记住输入的大小。所以,如果你对某个特定的尺寸很满意,你就不用再输入了。

摘要

你现在

  • 学习如何从终端模拟器使用 ssh

  • 安装了 VNC 浏览器

  • 学习了如何在树莓派上启动和停止 VNC 服务器

  • 已了解如何将 VNC 浏览器连接到 VNC 服务器

  • 了解如何定制 VNC 服务器以满足您的需求

基本上,您现在有两种使用树莓派进行远程计算的方式(假设安装了桌面)。太棒了!继续第五章来设置远程开发的 NetBeans。

五、将 NetBeans 用于远程 Java 开发

在本章中,我将向您展示使用 NetBeans 进行远程 Java 开发的基础知识。我将教您如何安装 NetBeans 并为远程开发进行配置。该配置适用于第二章中设置的树莓派 3 型号 B+和第三章中设置的树莓派 Zero W。我将讨论如何

  • 确定哪个 NetBeans 是“最好的”

  • 确定哪个 Java 版本是“最好的”

  • 安装 Java

  • 安装 NetBeans

  • 在 NetBeans 中配置远程开发

  • 远程运行和调试

选择 NetBeans 和 Java 版本

就本书而言,最好的 NetBeans 是最新的“长期支持”(LTS)版本。在撰写本文时,那是 NetBeans 12.0。

NetBeans 不仅支持 Java 开发,它本身也是一个 Java 应用程序。NetBeans 12.0 可以在 Java 版本 11 到 14 上运行。要运行 NetBeans 12.0,您需要在工作站上安装其中一个版本。

前几章向您展示了如何在树莓派上安装 Java 11。为了优化远程开发,您的树莓派和工作站上必须安装相同版本的 Java。这意味着你需要在你的工作站上安装 Java 11。

安装 Java 11

您必须首先从甲骨文下载页面( www.oracle.com/java/technologies/javase-jdk11-downloads.html )下载适用于您工作站操作系统的 JDK 11。重要的是要明白,在当前的许可下,下载对于个人或开发使用是免费的。也就是说,您可能需要在下载前创建一个帐户。

Note

您下载的 JDK 11 的次要和安全版本号可能与本章中显示的和本书中使用的不同(11.0.8)。只要您的树莓派版本和工作站具有相同的编号,一切都应该正常工作。

对于 macOS 和 Windows 10,你可以下载一个安装程序,它会帮你完成大部分工作。我将展示 macOS 使用安装程序的过程;对于 Windows 来说,应该是非常类似的。

要执行安装程序下载,请在下载页面的表格中查找“macOS 安装程序”行。单击该行右侧的链接。在这一点上,你可能会被要求创建一个帐户或注册,如果是这样,就这样做。执行下载需要一些时间。macOS .dmg文件下载完成后,在 macOS 上,转到Downloads文件夹,双击该文件。您将看到如图 5-1 所示的窗口。

img/506025_1_En_5_Fig1_HTML.jpg

图 5-1

JDK 安装程序软件包

双击.pkg图标开始安装。首先你看到介绍面板如图 5-2 所示。

img/506025_1_En_5_Fig2_HTML.jpg

图 5-2

JDK 安装对话框

点击继续。你会看到安装类型对话框,但是除了退出安装,回到安装面板,或者继续之外,你什么也做不了。点击安装。系统将提示您输入管理 ID 和密码来启用安装。输入这些凭证并点击安装软件。一旦安装完成,您将在图 5-3 中看到确认。

img/506025_1_En_5_Fig3_HTML.jpg

图 5-3

JDK 安装确认

点击关闭结束安装程序。它会方便地询问您是否希望删除安装程序。这样做会释放文件系统上的空间。现在,您可以继续安装 NetBeans 了。

安装 NetBeans 12.0

首先,您必须从 Apache NetBeans 下载页面( https://netbeans.apache.org/download/nb120/nb120.html )下载 NetBeans 12.0。您可以找到适用于 macOS、Windows 和 Linux 的安装程序。单击适当的链接开始下载您需要的软件。下载完成后,在 macOS 上,双击下载文件夹中的.dmg文件。接下来你会看到如图 5-4 所示的安装包。双击.pkg图标开始安装。

img/506025_1_En_5_Fig4_HTML.jpg

图 5-4

NetBeans 安装程序包

现在安装程序问你是否真的要安装程序;见图 5-5 。点击继续

img/506025_1_En_5_Fig5_HTML.jpg

图 5-5

安装程序请求权限

您现在将看到 NetBeans 的简介面板。这与 JDK 非常相似(见图 5-2 )。点击继续。接下来是一个牌照面板。点击继续。接下来,您将被要求同意您几乎肯定没有阅读的许可。点击同意。接下来你会看到安装类型面板,如图 5-6 所示。

img/506025_1_En_5_Fig6_HTML.jpg

图 5-6

NetBeans 安装程序安装类型面板

NetBeans 12.0 允许您使用多种编程语言进行开发。默认情况下,除了基本 IDE 之外,安装还包括 Java SE、Java EE、HTML5/JavaScript 和 PHP。你显然需要 Java SE。点击定制可以选择安装什么。不包括其他的可以节省很多存储空间,但是我选择全部安装;谁知道下一个项目会需要什么?我推荐使用默认的安装位置,但是你可以通过点击改变安装位置来改变它。想了这么多之后,点击安装。系统将提示您输入管理员 ID 和密码。输入凭证,点击安装软件。一旦安装完成,您会看到图 5-7 中的确认。点击关闭结束安装。请注意,该安装程序不会删除.pkg.img文件。如果您希望释放文件系统上的空间,您必须手动执行此操作。

img/506025_1_En_5_Fig7_HTML.jpg

图 5-7

NetBeans 12.0 安装成功确认

测试 NetBeans 安装

现在,您可以在 macOS 上打开 NetBeans 12.0,方法是打开 Spotlight search,在字符串“Apache NetBeans 12.0”中键入字符,直到它出现,然后按 Enter 键。NetBeans 对自身进行初始化,然后显示图 5-8 中的窗口。

img/506025_1_En_5_Fig8_HTML.png

图 5-8

NetBeans 12 初始窗口外观

现在您可以创建一个测试。总的来说,我不会尝试给出关于 NetBeans 开发或 Java 的教程,但是我会讲述一些基本概念。

在 NetBeans 工具栏中,单击新建项目图标,这是一个看起来像文件夹的图标(工具栏中左起第二个)。你会看到如图 5-9 所示的新建项目对话框。

img/506025_1_En_5_Fig9_HTML.jpg

图 5-9

NetBeans 新建项目对话框

从图 5-9 中注意到,在 NetBeans 12 中,默认的项目管理/构建工具是 Maven 。Maven 不支持我对远程开发“开箱即用”的定义蚂蚁工具支持。由于本书的一个重点是简单而有效的远程开发,所以本书使用了 Ant,在这一章中,我将向您展示如何使用 Ant 进行开发。

Tip

Maven 在自动化其他开发任务方面做得更好。通过一些工作,Maven 可以近似“蚂蚁风格”的远程开发。详见附录 A3。在阅读附录 A3 之前,我建议您至少浏览本章的其余部分以及第 6 、 7 ,甚至 8 章,以建立足够的上下文。

要上手 Ant,在新建项目对话框(图 5-9 ,点击 Java with Ant ,然后点击 Java 应用,再点击下一个。您将看到名称和位置对话框,如图 5-10 所示,该对话框允许您输入项目的名称(本例中为“FirstTest”)和应用程序(或主类),管理文件的位置(我建议不要更改默认位置,除非您确实需要这样做),决定是否创建一个主类(在本例中为 yes),并输入包名(对于本测试,默认是可以的)。当您满意地输入完信息后,点击完成

img/506025_1_En_5_Fig10_HTML.jpg

图 5-10

NetBeans“新建项目”对话框:输入项目名(和主类名)、位置和包名

NetBeans 创建项目并打开主类的类编辑器,在我的例子中是FirstTest。你会看到类似图 5-11 的东西。

img/506025_1_En_5_Fig11_HTML.png

图 5-11

NetBeans 类编辑器

现在,您可以输入一个简单的 print 语句来创建经典的“Hello World”应用程序。清单 5-1 显示了我使用的代码(我省略了 NetBeans 注入到类文件中的样板文件)。

public class FirstTest {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

Listing 5-1The “Hello World!” application code

点击 Run 图标(工具栏中间的绿色向右箭头)运行代码。假设一切正常,您应该在编辑器下方的 NetBeans 输出窗格中看到以下内容:

run:
Hello World!
BUILD SUCCESSFUL (total time: 1 second)

成功!您已经安装并测试了 NetBeans。

将树莓派配置为远程平台

现在,您将配置 NetBeans,以将树莓派识别为远程开发平台。在 NetBeans 菜单栏中,选择工具Java 平台。您将看到如图 5-12 所示的 Java 平台管理器弹出窗口。

img/506025_1_En_5_Fig12_HTML.jpg

图 5-12

NetBeans Java 平台管理器

请注意,当前唯一的平台是工作站上的 JDK 11 本地版。点击添加平台,这样你就可以添加一个树莓派了。图 5-13 显示了添加平台对话框。默认情况下,您将添加另一个本地 JDK。在这种情况下,你想添加一个 Pi,那么选择远程 Java 标准版选项,然后点击下一步

img/506025_1_En_5_Fig13_HTML.jpg

图 5-13

NetBeans 添加 Java 平台对话框

现在,您将看到图 5-14 所示的设置远程平台对话框。您必须输入一个平台名称。应该是比较独特的东西。我有时会在三个远程系统上同时开发项目组件,在这种情况下,惟一的名称是必须的。您必须输入远程 Pi 的主机 IP 地址或主机名;您应该使用第二章或第三章中确定的地址或名称,除非您正在处理另一个 Raspberry Pi。您必须输入一个用户 ID;出于本书的目的,请使用“圆周率”最简单的认证类型是密码,因此确保选择使用密码认证并输入您在第二章或第三章中创建的密码。

img/506025_1_En_5_Fig14_HTML.jpg

图 5-14

完整的设置远程平台对话框

对话框中一个非常关键的字段是远程 JRE 路径。你应该使用在第 2 或第三章中发现的路径。如果您不记得了,找到该路径的最佳方法是到一个与 Pi 有ssh会话的终端,输入以下命令:

sudo update-alternatives --config java

响应应该类似于以下内容:

/usr/lib/jvm/java-11-openjdk-armhf/bin/java

远程 JRE 路径字段中输入字符串,减去“/bin/java”。你可以改变远程的工作目录,但是我发现默认就可以了。当你完成这个对话框时,它看起来应该类似于图 5-14 。点击完成创建远程平台。NetBeans 可能需要几秒钟才能完成。完成后,您将再次看到 Java 平台管理器,其中显示了新创建的远程平台信息。参见图 5-15 。

img/506025_1_En_5_Fig15_HTML.png

图 5-15

具有远程平台的 NetBeans Java 平台管理器

注意 Java 平台管理器中的测试平台按钮。如果您愿意,您可以尝试一下,但是在创建新的远程平台之后,这是不必要的。但是,对于您已经有一段时间没有使用的远程平台或者您已经对其进行了可能会影响配置的更改的远程平台,它可能会很有用。现在你可以点击关闭来关闭 Java 平台管理器

测试远程开发

现在您将运行之前在树莓派上创建的FirstTest程序。在 NetBeans 项目窗格中,右键单击 FirstTest 项目,弹出项目属性对话框。在类别下,点击运行查看项目的运行时属性,如图 5-16 所示。点击配置字段右侧的新建。在出现的创建新配置弹出窗口中,输入配置名称并点击确定。该名称可以是任何名称。点击运行时平台字段右侧的下拉图标。从弹出的列表中,选择您之前创建的远程平台(本例中为 PiForBook )。点击确定保存属性。

img/506025_1_En_5_Fig16_HTML.jpg

图 5-16

NetBeans 项目属性(运行)

现在再次运行该项目。这次在 NetBeans 输出窗格中,您将看到类似于图 5-17 的内容。注意与 Pi 的通信,创建一个文件夹来存储 Pi 上的结果 jar 文件,下载 jar 文件,运行 jar 文件,并检索要显示的输出。成功了。恭喜你,你正在远程开发!

img/506025_1_En_5_Fig17_HTML.png

图 5-17

远程平台的 NetBeans 输出窗格

远程调试

NetBeans 也支持远程调试。可以如下测试。在FirstTest编辑器中,在println语句前添加以下行:

int i = 5;

现在点击println语句的行号。整条线以红色高亮显示。点击主菜单栏中的调试图标;它是紧挨着运行图标右边的图标。遗憾的是,调试尝试可能会失败!至少它会失败,除非 NetBeans 开发人员已经修复了可疑的错误。如果有效,很好;您可以跳过下一小节。如果失败了,不要害怕;继续读。

修复远程调试

我最初认为这是一个常见问题,有一个容易发现的解决方案。我错了。然而,我四处搜寻,拼凑出了一个解决方案。来解决这个问题(至少在撰写本文时这是有效的)

  1. 点击项目标签右侧的文件标签。

  2. 展开 FirstTest 项目。

  3. 展开build.xml

  4. 向下滚动,直到找到debug-remote元素。

  5. 双击debug-remote;它的编辑器会在编辑器面板中打开。

  6. 搜索字符串“debug-args-line”;你会发现两个事件;重要的一个是在名为“-debug-remote-passwd”的元素中。

  7. 在该元素的子元素<remote:runwithpasswd/>中,删除字符串${debug-args-line}

  8. 保存文件并关闭run-remote编辑器。

现在再次点击调试。应该能行。不幸的是,有一个警告。我还没有发现如何在系统范围内解决这个问题。因此,在您希望远程调试的每个新 NetBeans 项目中,您都必须应用本小节中描述的修复程序。

成功调试

当 debug 运行时,您应该看到println语句变成绿色,表明调试器在执行它之前已经停止在那一行。见图 5-18 。

img/506025_1_En_5_Fig18_HTML.png

图 5-18

NetBeans 调试

现在您可以调试运行在树莓派上的代码了!

调试时检查变量

调试时,在输出面板中,您现在可以看到子面板、正常输出和调试器控制台。调试时,一般需要看变量。为此,单击 NetBeans 窗口左下角的变量(见图 5-18);出现变量弹出窗口;它覆盖了输出窗格。你现在可以看看变量;特别是,您可以看到变量i的值为 5。

您可能不希望变量弹出窗口覆盖输出窗格。要使变量成为输出窗格中的另一个选项卡,请单击图 5-18 所示 NetBeans 窗口左下角的“双窗口”图标。现在输出面板如图 5-19 所示(我对断点做了和对变量一样的事情)。

img/506025_1_En_5_Fig19_HTML.png

图 5-19

NetBeans 输出窗格,带有“输出”、“断点”和“变量”选项卡

调试器菜单

调试值得多讨论一下。首先,图 5-18 只显示了调试菜单的一部分,这是由于我截屏时 NetBeans 窗口的大小。图 5-20 显示了最有用的调试器控件的图标。

img/506025_1_En_5_Fig20_HTML.jpg

图 5-20

NetBeans 调试器控件

从左到右,控件是

  • 完成:终止调试会话

  • 暂停:暂停调试会话

  • 继续:运行到下一个断点

  • 跳过:运行一条语句

  • 单步执行表达式:运行单个表达式

  • 进入:进入一种方法

  • 步出:方法返回后运行到语句

在之前启动的调试会话中,如果您没有做任何其他事情,println语句应该仍然是绿色的。点击跳过,该语句将再次变为红色(表示是断点),其后包含“}”的行将变为绿色,表示下一步将退出该方法。您可以查看输出选项卡,查看println语句是否有效。点击继续结束,因为不再有断点存在。

在没有 NetBeans 的情况下在树莓派上运行

现在,您可以使用运行在桌面上的 NetBeans 来开发 Java 程序,然后在树莓派上运行和调试该程序,这真是太棒了。但是,在某些时候,您可能希望在 Pi 上运行程序,而不涉及 NetBeans。我遇到的原因不多:

  • 当您的项目处于“生产”阶段,甚至是进行一些测试时,您不需要或不想让 NetBeans“碍事”。

  • 不幸的是,虽然这并不奇怪,但是运行在 Pi 上的远程程序不能接收键盘输入。

  • 我发现高度格式化的控制台输出(例如由System.out.format产生的)不能正确呈现。

在这一节中,我将描述一些在没有 NetBeans 参与的情况下在 Pi 上运行程序的方法。后面的部分将描述其他的方法。

当您使用 NetBeans 在树莓派上运行或调试程序时,NetBeans 会将程序下载到 Pi。以前,当您将 Pi 配置为远程平台时,您必须标识 NetBeans 以 jar 文件的形式保存下载程序的文件夹(或 NetBeans 术语中的目录)(参见图 5-14 )。用户 pi 的默认文件夹是/home/pi/NetBeansProjects。在该基本文件夹中,NetBeans 会创建一个与项目同名的特定子文件夹。NetBeans 将 jar 放在名为dist的子文件夹中。对于前面的示例项目,完整路径是/home/pi/NetBeansProjects/FirstTest/dist

要在 Pi 上运行程序,首先从工作站终端 ssh 到 Pi。然后输入以下命令(在一行中):

java -jar /home/pi/NetBeansProjects/
FirstTest/dist/FirstTest.jar

您将在终端中看到执行的结果。见图 5-21

img/506025_1_En_5_Fig21_HTML.png

图 5-21

不使用 NetBeans 执行程序(第一种方式)

您也可以使用稍微不同的方法来完成同样的事情。首先,在终端中,将工作目录(通过cd命令)更改为 jar 文件的位置。然后输入命令

java -jar FirstTest.jar

你会得到完全相同的行为。见图 5-22

img/506025_1_En_5_Fig22_HTML.png

图 5-22

在没有 NetBeans 的情况下执行程序(第二种方式)

这些技术之所以有效,是因为 jar 文件中的信息标识了要执行 jar 中的哪个主类。该信息来自 NetBeans 项目的运行的属性名为的主类。您可以在项目属性对话框中查看并设置感兴趣项目的值;NetBeans 在创建包含主类FirstTestFirstTest 项目时会自动设置该值(参见图 5-16 )。

在复杂项目中利用 NetBeans

在开发复杂的系统项目时,我遵循一个经典的开发实践,将大系统划分成更小的子系统。NetBeans 为这种实践提供了很大的支持,我总是在开发过程中创建多个 NetBeans 项目。例如,我可能有一个 NetBeans 项目提供“设备库”,第二个项目提供“数据处理库”,第三个项目包含使用“设备库”和“数据处理库”的应用程序

Note

库促进代码重用。虽然一个库通常包含多个类,它们都以某种方式相关联,但是一个库只包含一个单个类也是完全可以接受的。事实上,在下面的例子中,库只包含一个类。本书中开发的设备库有时包含单个类,有时包含多个类,这取决于设备的特性。

创建和测试库

为了探究其中的含义,您将为一个简单的库创建一个新的 NetBeans 项目并测试该库:

img/506025_1_En_5_Fig23_HTML.jpg

图 5-23

新库类的 NetBeans 窗口

  1. 正如您之前对 FirstTest 项目所做的那样,在 NetBeans 中,单击菜单栏中的新项目图标。

  2. 新项目对话框中点击 Java with Ant

  3. 新建项目对话框中点击 Java 类库

  4. 新建项目对话框中点击下一个

  5. 新建 Java 类库对话框中,输入类库的名称;在这个例子中,我将使用“LibraryTest”。

  6. 新建 Java 类库对话框中点击完成。您应该会看到新项目出现在 NetBeans 项目窗格中。

  7. 右键 LibraryTest ,悬停在 New 上,点击 Java 包。你会看到新 Java 包对话框。

  8. 输入所需的包名;在本例中为“org.addlib”。

  9. 新 Java 包对话框中点击完成。您应该会在 LibraryTest 项目下看到这个新包。

  10. 右击 org.addlib ,悬停在 New 上,点击 Java 类。您应该会看到新 Java 类对话框。

  11. 新 Java 类对话框中输入所需的类名,在本例中为“AddThem”,点击完成。您将看到AddThem类的编辑器。NetBeans 窗口应该类似于图 5-23 所示。

新类需要一个带参数的构造器和一个带参数的方法。该方法会将其参数添加到构造器的参数中,并返回结果。输入清单 5-2 中的代码完成AddThem

public class AddThem {
    int base;
    public AddThem(int base) {
        this.base = base;
    }

    public int addIt(int it) {
        return base + it;
    }
}

Listing 5-2The AddThem class

将代码添加到AddThem后,请注意“项目”面板中的变化。由于该项目被指定为一个库,NetBeans 不希望在源包中找到主类。预计您会想要测试库类,因此 NetBeans 友好地为测试类添加了一个测试包文件夹,并为只与测试相关的类添加了测试库。见图 5-24 。

img/506025_1_En_5_Fig24_HTML.jpg

图 5-24

“项目”面板中的测试包和库

这些工件旨在支持 JUnit 测试程序(超出了本书的范围),但是您可以创建自己的简单测试用例。但是,需要理解的是,当 NetBeans 为库 构建 jar 文件时,它不包括任何测试类或测试库 !这是一件非常好的事情,因为您不希望测试用例塞满一个库 jar 文件。然而,这也意味着测试用例永远不会被下载到 Raspberry Pi,因此,举例来说,您不能使用 Pi 上的测试包中的测试用例来测试设备库。

现在您将创建一个简单的主类来测试库中的单个类。展开测试包;你会看到 <默认包> 。出于本书的目的,这是放置测试库的主类的好地方。右击 <默认包> ,悬停在新建上,点击主类。在出现的新 Java 主类对话框中,在类名字段中输入“TestAdd”,然后点击完成。你会看到课程的编辑。完成该类,使其看起来如清单 5-3 所示。

public class TestAdd {
    public static void main(String[] args) {
        AddThem at = new AddThem(6);
        System.out.println("The result: " + at.AddIt(5));
    }
}

Listing 5-3The TestAdd class

您将在以“AddThem at”开头的行上看到一个错误指示。这是因为 NetBeans 不知道AddThem的包名。点击行上的红色球,然后点击高亮显示的选项为 org.addlib.AddThem 添加导入。NetBeans 会为您添加导入,并且错误会消失。啊,美丽的 IDE!

现在点击运行图标。您将看到一个弹出的错误,指出该项目没有主类集。如果你检查项目运行属性,你会发现你不能设置TestAdd主类;你甚至在对话框里都找不到!这与前面的 jar 文件讨论有关;因为测试包从未出现在 jar 文件中,所以它们不可能是可运行的类。

但是可以跑TestAdd!在项目窗格中,右键单击 TestAdd 。在弹出的窗口中,点击运行文件。在输出窗格中,您会看到

The result: 11

有效!你不仅可以运行测试程序,还可以调试它。在提到的弹出窗口中,点击调试文件而不是运行文件

该库已经编写并经过测试。是时候使用它了。然而,在使用它之前,要认识到TestAdd是在您的工作站上运行的,而不是在树莓派上。这是极其重要的。您可以在您的工作站上对独立于硬件的代码进行大量测试。Java 的“编写一次,在任何地方运行”的特性对于这种情况确实很有价值。

Caution

我们在后面章节中开发的设备库而不是硬件独立的,并且必须运行在树莓派上。因此,您必须使用不同的测试方法。详见第八章。

使用库

我现在将向您展示如何使用之前创建的库。为了说明一些额外的要点,您将在已经配置为在树莓派上运行的 FirstTest 项目中创建一个新程序(主类)。

  1. 右键单击首测下的源包

  2. 将鼠标悬停在上,然后点击 Java 包

  3. 新建 Java 包对话框中,在包名字段中输入包名;对于图书,输入“org.lib.user”,然后点击完成

  4. 右击 org.lib.user ,悬停在弹出的 New 上,点击 Java 主类

  5. 在出现的 New Java Main Class 对话框中,在 Class Name 字段中输入类名;对于书籍,输入“LibTest”,然后点击完成。与其他类一样,NetBeans 会创建一个框架,并在编辑器窗格中打开该类。

  6. 完成该类,使其看起来像清单 5-4 。

public class LibTest {

    public static void main(String[] args) {
        AddThem at = new AddThem(6);
        System.out.println("The result: " + at.AddIt(5));
    }
}

Listing 5-4The LibTest class

与前面提到的TestAdd一样,您将在以“AddThem at”开始的那一行得到一个错误指示。点击线上的红色球。你会发现选项为 org.addlib.AddThem 添加导入没有出现!这是因为 NetBeans 不知道在哪里可以找到包含正确的AddThem的库(可能不止一个)。

您必须告诉 NetBeans 哪个库包含适当的AddThem类。为此,右键单击项目 FirstTest ,然后单击 Properties 。在出现的项目属性对话框中,在类别下,点击。您将看到如图 5-25 所示的库属性。

img/506025_1_En_5_Fig25_HTML.jpg

图 5-25

库的 NetBeans 项目属性

现在点击类路径右边的 + 。在弹出的小窗口中,点击添加项目。你现在会看到如图 5-26 所示的添加项目对话框。点击库测试,然后点击添加项目 JAR 文件。您将返回到项目属性对话框。点击确定

img/506025_1_En_5_Fig26_HTML.jpg

图 5-26

NetBeans 添加项目对话框

返回到TestAdd编辑器。点击红色的球。现在在弹出窗口中,您将看到所需的选项为 org.addlib.AddThem 添加导入。单击该选项,NetBeans 将为您添加从库中导入的内容,错误随即消失!

现在点击运行图标。您会看到主类FirstTest运行在树莓派上。这显然不是你想要的。运行LibTest有两种方式。如果您打算运行一两次,只需在项目窗格中右键单击 LibTest ,然后单击运行文件。注意,该弹出窗口还包含一个调试文件选项,因此您可以用同样的方式进行调试。第二种方式更有趣,我将在下一节介绍它。

选择要从 NetBeans 运行的程序

想一遍遍跑LibTest怎么办?然后你想使用运行图标。我将向您展示如何配置 NetBeans 来实现这一点。

首先右击 FirstTest ,选择项目属性。在类别下,点击运行。参见图 5-16 。查看主类旁边字段中的条目。您会看到 NetBeans 被配置为运行FirstTest。要选择运行另一个主类,单击主类右侧的浏览。您将看到一个弹出窗口,其中列出了项目中的主要类,并选择了firsttest.FirstTest。见图 5-27 。

img/506025_1_En_5_Fig27_HTML.jpg

图 5-27

NetBeans 浏览主类对话框

在对话框中点击org.lib.user.LibTest,然后点击选择主类。在项目属性对话框中,点击确定。现在当你点击运行图标,LibTest运行!

在没有 NetBeans 的情况下在树莓派上运行选择的程序

前一节向您展示了如何使用java -jar命令来运行在先前下载的项目 jar 文件中标识的主类。如果您想在一个 jar 文件中运行多个主程序,您必须使用不同形式的java命令。

在上一节中,您创建了一个包含两个主要类的项目,FirstTestLibTest。你配置 NetBeans 运行LibTest;因此,在远程终端中,当您输入以下命令时

java -jar FirstTest.jar

你发现LibTest跑了。如果你想运行FirstTest,你使用下面的命令:

java -cp FirstTest.jar firsttest.FirstTest

图 5-28 显示了运行各种命令的结果。

img/506025_1_En_5_Fig28_HTML.png

图 5-28

具有各种java命令结果的远程终端

通常,您应该使用前面描述的第二种形式:

java -cp <jar>.jar <package>.<main class>

在哪里

  • <jar>是指 NetBeans 创建并下载的 jar 文件(注意,这个名称与 NetBeans 项目名称相同)。

  • <package>指您想要运行的主类的包名。

  • <main class>指你要运行的主类的名字。

用 NetBeans 下载就行了

在上面几节中,您了解了 NetBeans 可以将项目下载到 Raspberry Pi,然后运行或调试 jar 文件中指定为主类的程序。随后,您可以在没有 NetBeans 的 Pi 上运行同一个项目中的许多程序(主类)之一。

您还了解了如果您想要运行的主类不是 jar 文件中指定要运行的主类,您可以解决这个问题。但是,如果您变得懒惰(像我一样),只想使用 NetBeans 下载一个更新的项目,然后在 Pi 上运行您想要的程序,该怎么办呢?

很简单。在这个项目中,您创建了一个“哑”主类,它除了指示下载成功之外什么也不做(有点多余)。当您单击 Run 图标时,您将它指定为主类来运行。对于示例项目首测

  1. 右键单击首测下的源包

  2. 将鼠标悬停在上,点击 Java 主类;你会看到新的 Java 主类对话框。

  3. 类名字段中,键入一个主类名,例如“Dummy”;在字段中,输入一个包名,例如“dummy”,点击完成;此时,如果你想添加代码在Dummy运行时打印一些东西,可以这样做,但不是必须的。

  4. 调出 FirstTest 项目属性对话框。

  5. 类别下,点击运行

  6. 主类行右侧,点击浏览;您将看到浏览主类对话框(参见图 5-27 中的示例)。

  7. 你应该在主类列表中看到dummy.Dummy;点击它并点击选择主类,你将返回到项目属性(运行)对话框。

  8. 现在点击确定

现在点击运行图标。在输出窗格中,你看不到FirstTestLibTest的输出,因为两者都没有运行;Dummy跑了,也确实没什么。您将在输出窗格中看到的内容如下:

run-remote:
BUILD SUCCESSFUL (total time: 3 seconds)

当然,如果你把一个println语句注入Dummy,你会看到它打印出来的东西。当然,你仍然可以使用一个ssh终端从命令行运行树莓派上的FirstTestLibTest

摘要

在本章中,您已经

  • 工作站上安装的 Java

  • 在工作站上安装了 NetBeans

  • 在 NetBeans 中将您的树莓派配置为远程平台

  • 学习如何使用 NetBeans 从工作站和树莓派以多种方式构建、运行和调试复杂的 Java 程序

现在,您已经有了使用 Java 和树莓派开发机器人和物联网项目的工具。在第六章中,您将了解为机器人和物联网中使用的设备开发设备库的注意事项。

六、Java 中的设备支持

如果没有 没有奋斗,就没有进步。

—弗雷德里克·道格拉斯,1857 年

在第一章,我提到了在树莓派上使用 Java 时为你的设备寻找或创建设备库的挑战。这一挑战存在于两个层面:

  1. 为各种形式的基本 I/O 寻找基本 I/O 库,即数字 I/O(也称为 GPIO)、串行、I2C 和 SPI,在这些基础上可以构建设备库

  2. 为您的设备寻找或创建设备库,这需要一种或多种形式的基本 I/O

在这一章中,我将讨论

  • 查找基本 I/O 库

  • 为您的项目和本书选择基本 I/O 库

  • 将基本 I/O 库引入 NetBeans

  • 查找设备库

  • 将非 Java 设备库移植到 Java

查找 Java 的基本 I/O 库

对于任何给定的项目,这组器件可能需要 GPIO、串行、I2C 和 SPI 的某种组合。遗憾的是,没有一个集中的来源提供关于树莓派上 Java 基本 I/O 的信息。或者,也许更准确地说,我找不到它,如果它存在的话。所以,要找到信息,你必须使用搜索引擎。很难立即产生有用的结果。例如,如果您想找到对串行 I/O 的支持,您可以使用搜索术语“串行”、“Java”和“Raspberry Pi”你毫无疑问会找到几个候选人,比如, Pi4JRxTx (又名 RXTXjserialcomusb4javajRXTX ,以及 jSSC 。有时候,在“第一顺序”搜索之后,你必须在找到所有候选人之前跟踪一系列链接。例如:

  • 沿着 Pi4J 走下去,你会发现它是一个封装了 wiringPi 库(用 C 编写)的包装器。

  • 沿着 jRXTX 走下去,你会发现它是围绕 RxTx 的一个“更容易使用”的包装器。

但是你还没有完成。我发现,有时,出于不清楚的原因,您必须搜索其他基本 I/O 类型才能获得完整的图片。因此,举例来说,即使你对 I2C 不感兴趣,你可能也应该搜索一下,然后沿着一条新的链接线索,看看你是否能找到其他东西。这样做,你会找到很多关于 Pi4J 的参考资料。你还会找到对设备 I/O (又名 DIO)和 diozero 的引用。Pi4J、DIO 和 diozero 都支持一切 : GPIO、串行、I2C 和 SPI。你可能还需要在 C 中寻找 I2C 支持,并找到支持一切的 pigpio。深入研究 pigpio,你会发现有一个 pigpio 的 Java“包装器”叫做 pigpioj 。我想你能明白我的观点;一般来说,你必须做一个相当广泛,详尽的搜索,以获得一个完整的图片。

选择最佳的基本 I/O 库

当您为一种类型的基本 I/O 找到多个选项时,有几个选择“最佳”的标准我建议不一定要按优先顺序

  • 功能覆盖范围

  • 表演

  • 支持

  • 易用性

功能覆盖范围

功能覆盖提出了一个问题“它做了我需要做的所有事情了吗?如果没有,需要什么样的妥协?”一些例子:

  • 树莓派有两种形式的串行 I/O:通过 USB 端口的 USB 串行和通过 GPIO 头上的 RX/TX 引脚的 TTY 串行。usb4java 只支持 usb 端口,而前面提到的其他一些支持两种形式。

  • 一些 GPIO 库为数字 I/O 提供上拉和下拉电阻支持;有些没有。

通常,您可以从文档中确定功能覆盖范围。然而,我发现测试有时是必要的。例如,在 2017 年,测试显示 Pi4J I2C 支持只能从寄存器地址 0 开始进行块读取,在某些情况下强制使用底层 wiringPi。

表演

性能其实是双管齐下的。第一个问题是“这个选项可靠吗?”例如,2017 年测试 jRXTX 表明它可以工作,但表现不稳定;我从未确定原因。显然不是最佳选择。

第二个问题是“选项见效快吗?”你肯定不想浪费时间或资源。如果一个选项执行任务的速度比其他选项快得多,那么它可能是最佳选择。比如 2017 年测试 Pi4J serial 和 jserialcom,结果显示 jserialcom 比 Pi4J 快很多(或者说我无法正确配置 Pi4J)。

您应该从这个讨论中了解到,您不仅要准备好测试一个库是否能够可靠地工作,还要准备好测试它在您的项目中是否具有足够的性能。

支持

支持是一个有点模糊的总称。有几件事需要考虑。您找到的任何库都是由个人、团队或组织创建和支持的。通常,创建和支持实体越大越好。

支持的现状和性质至关重要。您可能应该对使用几年没有更新或没有可见支持渠道的库保持警惕。例如,截至 2020 年 10 月

  • jSSC 似乎自 2013 年以来没有更新过。

  • 我发现自 2017 年以来没有更新,也没有提到 RxTx。

  • wiringPi 的作者不赞成使用它,这实际上是反对 Pi4J 的当前版本(1.2)。

  • usb4java 直到 2018 年才被积极支持。

  • jRXTX 似乎有积极的支持和更新。

  • jSerialComm 似乎得到了积极的支持和更新。

  • DIO 似乎很少使用。

  • diozero 得到了积极的支持和更新。

  • pigpio 拥有积极的支持和更新,pigpioj 包装器也是如此。

  • Pi4J 2.0 正在构建中。

所以,公平的警告,当你读这本书的时候,我为这本书所发现和推荐的可能会改变。你应该自己做研究。

另一个考虑因素是用户社区的规模。越大越好,虽然这可能很难确定(搜索引擎可以帮助)。一个大的用户社区提供了更多的机会来寻找使用实例,并获得关于不寻常的用例或异常行为的帮助。然而,庞大的用户群体并不能保证“最好”。在所有基本 I/O 库中,Pi4J 似乎拥有最大的用户群体,但是请记住,当前版本应该被认为是过时的(不仅底层 wiringPi 库过时了,Pi4J 1.2 的某些部分在 Java 版本 9 或更高版本上也不能工作)。

易用性

易用性是主观和模糊的,可以包括许多方面。例如,理想情况下,要使用这个库,您可以获得一个单独的 jar 文件,这样就完成了。一些图书馆做到了这一点。另一方面,有些可能要求您在树莓派上构建 C 代码,在 Pi 上安装其他代码,弄乱 Java 权限文件,或者其他消耗您在项目上花费的时间的活动。

另一个方面在前面已经提到。有些库支持多种类型的 I/O。如果您需要的所有类型都由一个库满足,那么这个选项可能是“最佳的”,除非有其他标准禁止。只有一个图书馆,生活更简单;例如,您有单一的文档来源和单一的支持问题联系人。

其他方面包括文档的存在和质量、代码示例的存在以及 API 的复杂性。所有这些都会影响您使用库的速度。

这本书的基本 I/O 选择

不管是好是坏,这本书主要是一组独立的以设备为中心的项目,而不是一个单一的项目。在某种程度上,这种方法是由于机器人项目和物联网项目之间的差异,前者通常需要几个设备,后者通常只需要一两个设备。在某种程度上,这是因为想要展示树莓派的所有形式的基本 I/O。因此,出于本书的目的,我将寻找一个支持树莓派上可用的所有基本 I/O 功能的库,即 GPIO、串行、I2C 和 SPI。

在撰写本文时(2020 年末),没有太多繁琐的细节,根据功能覆盖、相对性能、支持和易用性,对支持所有类型基本 I/O 的可用“一体化”库进行了筛选,结果只产生了两个可行的候选库:

正是在这一点上,最终的决定变得非常有趣。图 1-1 显示了适用于本书的理想化软件架构,相关文本描述了该架构四层的本质。我们将使用该架构来比较候选人。我断言,当比较 pigpioj 和 diozero 时,没有必要考虑应用层,因为你将总是必须在应用层编写程序。

看看皮格皮奥伊

图 6-1 显示了使用 pigpioj 时,图 1-1 的软件架构,减去了应用层。对于 pigpioj,基本 I/O 层由两个子层组成。 pigpio 子层代表 pigpio C 库,C 中公开一个基本 I/O API;pigpio 使用更原始的树莓派 OS C API 作为基本 I/o。pigpioj子层是 pigpio 的 pig pioj“包装器”。pigpioj 子层公开了用于创建设备库的 Java 基本 I/O API;它使用 pigpio C API。

img/506025_1_En_6_Fig1_HTML.jpg

图 6-1

pigpioj 软件架构

设备层表示您找到或编写的设备库。它们向应用程序公开特定于设备的 API。他们使用pigpioj base I/O API。

pigpio 和 pigpioj 的结合提供了一个有趣的特性——远程 I/O 。这意味着您可以在不同的计算平台上运行您的应用程序,但是在目标树莓派上执行 I/O。这当然是用 NetBeans 进行远程开发的一种替代方法。详情参见 pigpioj 文档。

看一看迪奥西诺

图 6-2 显示了使用 diozero 时,图 1-1 的软件架构,减去了应用层。将图 6-2 与图 6-1 进行比较,您会发现相似之处,但也有显著差异。虽然在图 6-2 中并不明显,但与 pigpioj 的相对简单性相比,diozero 是一个提供了一系列有趣特性的扩展框架。

Note

本书中所有关于 diozero 的陈述在 1.3.0 版本中都是正确的;然而,在 2021 年夏天,diozero 正在积极开发中,新的和改进的功能频繁发布。因此,以后的版本可能会有所不同。此外,以下章节中的所有代码都是针对 1.3.0 进行测试的;以后的版本可能需要或受益于代码更新。

在图 6-2 中,首先注意到单板计算机 OS 层。该层表示几个单板计算机(SBC)中的一个,包括 Raspberry Pi。没错;diozero 在树莓派上工作,也在类似的 SBC 上工作,如 Odroid C2 和 BeagleBone Black。您可以在 diozero 文档中找到更多关于受支持的 SBC 的信息。

img/506025_1_En_6_Fig2_HTML.jpg

图 6-2

使用 diozero 的软件架构

使用 diozero,基本 I/O 层由 diozero 提供者组成。dio zero 提供商尽可能地调整底层 SBC 基本 I/O 功能,以提供由基本 I/O 层公开的基本 I/O API。提供者公开了用于创建设备库的 Java 基本 I/O API。它使用更原始的 SBC OS C API 进行基本 I/O

提供者的概念可能代表了 diozero 最有趣的特性。提供者实现了众所周知的服务提供者模式(参见 www.javapedia.net/Design-Patterns/1593 )。这意味着可以使用不同的提供商,而不改变更高层*。因此,您可以编写一个设备库,它可以跨多个提供者和多个 SBC 工作(在 SBC 的基本 I/O 能力范围内)。diozero 支持通用和工作于任何 SBC 的提供者和 SBC 专用的提供者。在 diozero 版本 1.3.0 中,树莓派有四个提供者:*

** 内置:在 Pi 基本 I/O 功能的范围内提供最佳的功能和性能选择。内置提供程序是通用的。

  • pigpio :使用 pigpio C 库。pigpio 提供程序是 Pi 特定的。

  • diozero remote :提供一种远程计算形式,应用程序运行在主机平台上,I/O 操作运行在 Pi 上。diozero-remote 提供程序是通用的。diozero-remote 提供程序是远程开发的一个替代方案。

  • pigpio remote :提供一种远程计算形式,应用程序运行在主机平台上,I/O 操作运行在 Pi 上。pigpio-remote 提供程序是 Pi 特定的。pigpio-remote 提供程序也是远程开发的一种选择。

您可以在 diozero 文档中找到关于各种 SBC 的提供者的更多信息。

在图 6-2 中,设备层用其暴露的设备 API 表示设备库;他们使用基本 I/O 层(也称为提供者)API。diozero 的另一个很大的特点是它包括了一个广泛的设备库,你不必去写!当然,如果 diozero 不支持您的设备,您可以使用基本 I/O 编程接口来创建一个设备库。两全其美!您可以在 diozero 文档中找到受支持设备的列表。

Note

本小节仅描述 diozero 与树莓派和类似 SBC 相关的方面。diozero 还支持其他计算平台,例如 Arduino 和粒子光子。更多细节见 diozero 文档。

评估选择

现在我将使用前面提到的四个标准来评估 pigpioj 和 diozero,以便在它们之间进行选择。

功能覆盖范围

pigpioj 为您提供了一个健壮的基础 I/O 层,用于在树莓派上创建设备库。就这样。

diozero 给你

  • 用于创建设备库的强大的基础 I/O

  • 多个提供者为基础 I/O 层提供不同的特性

  • 一组现有的设备库,用于 LED、按钮、环境传感器、电机控制器甚至 IMU 等设备

  • 支持额外的计算平台,例如,Odroid C2 和 BeagleBone Black

显然,diozero 具有更优越的功能覆盖面。

表演

如前所述,pigpioj 是 pigpio 上的一个薄薄的包装。因此,在 Java 中,pigpio 的性能已经是最好的了。

diozero 提供的提供商之一是 pigpio。diozero 内置提供程序提供的 GPIO 性能大约是 pigpio 提供程序的七倍,两个提供程序的 I2C、SPI 和串行性能大致相当。因此,声称 diozero 提供卓越的性能当然是合理的。

支持

如果您仔细阅读 pigpioj 和 diozero 的文档,您会注意到这些库是由同一个人创建的。因此,支持很可能是一个平局。另一方面,diozero 是一项更加全面的工作,因此,及时提供支持可能更加困难。

易用性

至于易用性,pigpioj 还是蛮不错的。在尝试使用 pigpioj 之前,您必须在您的树莓派上安装 pigpioj 然而,这样做很简单。您必须在您的工作站上获取 pigpioj jar 文件。要构建和运行应用程序,必须将 jar 文件添加到 NetBeans 项目中。

然而,使用 pigpioj 要小心。底层 pigpio 库必须以 root 权限运行。因此,您必须通过sudo命令以超级用户身份运行您的 Java 应用程序。因此,您的应用程序可能会无意中造成混乱。虽然可能性不大,但还是有可能的。

diozero 的易用性也非常好。根据您使用的提供者,您必须获得三个或四个 jar 文件。要构建和运行应用程序,必须将 jar 文件添加到 NetBeans 项目中。正如您将在下面看到的,NetBeans 使这变得很容易。

pigpioj 和 diozero 都支持其基本 IO 层中的所有基本 I/O,即 GPIO、串行 I/O、I2C 和 SPI。diozero 的文档更好一些,自然也更广泛。虽然两个基本的 I/O 编程接口都不难使用,但我发现 diozero API 更容易使用,而且同样有效。diozero 还提供了一些 pigpioj 中没有的有用的便利方法和函数。

总的来说,这两个标准大致相同,尽管我觉得 diozero 有一点点优势。

最终选择——dio zero

就支持和易用性而言,pigpioj 和 diozero 之间没有明显的区别。但是 diozero 在 GPIO 上可以大大胜过 pigpioj。diozero 的功能覆盖面及其众多引人注目的特性远远超过 pigpioj。因此,本书中开发的设备库使用 diozero。当然,你可以做出不同的选择。

请记住,除非您坚持开放基本 I/O 选项,否则您只需要支持项目设备所需的一个或多个库。虽然 diozero 因其广泛的框架和令人钦佩的性能而成为本书的最佳选择,但这一选择的一个关键因素是支持所有的基本 I/O。如果您只需要一种特定形式的基本 I/O,例如串行,diozero 很可能至少是一个不错的候选,但您可能需要针对其他候选进行自己的评估。

Caution

我想强调的是,diozero 并不针对机器人或物联网。它是一个通用框架,支持任何类型设备的基本 I/O 功能。

在 NetBeans 中配置 diozero

现在 diozero 被确定为这本书的基本 I/O 库;我将向您展示如何使 diozero 对 NetBeans 可用,以便对于您的项目,您可以使用 diozero 中现有的设备库,或者使用 diozero 开发设备库。

我在第五章中提到,我发现在 NetBeans 中只有 Ant 项目管理/构建工具支持“开箱即用”的高效远程计算因此,我将向您展示如何设置基于 Ant 的项目。 1

首先,您需要下载所需的 diozero jar 文件。最简单的方法是获取 diozero“发行版 ZIP”文件,其中包含 diozero 依赖项的所有dio zero JAR 文件和所有* JAR 文件,以及依赖项的依赖项,等等。*

在下载之前,你得考虑好你要用什么版本的 diozero。除非你有很好的理由不这样做,否则你应该使用最新的版本(最高的版本号)。我找到了三种简单的方法来下载 diozero 发布版本的发行版 ZIP 文件。首先,调出 diozero 文档( https://www.diozero.com )。如果你想要最新的 diozero 版本,在左边的导航面板中选择创建你自己的应用。单击名为 diozero-distribution ZIP 文件的链接(就在 XML 清单下面)立即下载最新的发行版 ZIP 文件。如果你认为你可能想要一个更早的 diozero 版本,在你调出文档后,向下滚动直到你看到部分 Maven 依赖/下载链接。本节描述了查找和下载 diozero 所有发布版本的发行版 ZIP 的两种方法。

使用前面提到的方法之一下载您选择的版本的发行版 ZIP。您将下载一个名为diozero-distribution-i.j.k-bin.zip的文件,其中i.j.k代表版本号,例如 1.3.0。您可能需要解压缩文件;在 macOS 上,它被自动解压缩,所有包含的 JAR 文件都放在文件夹Downloads / diozero-distribution-i.j.k中。如果您使用的是 Windows,下载和解压缩(如果需要)应该会产生一个装满 JAR 文件的子文件夹(同名)。

发行版 ZIP 包含的 JAR 文件比您实际需要的要多得多。在本书中,您将只使用内置的提供程序。 2 这意味着下载的几十个 JAR 文件中,你只需要三个:

  • diozero-core-i.j.k.jar(包含内置提供程序;要看后面两个)

  • tinylog-api-m.n.o.jar 和 tinylog-impl-m.n.o.jar(这两个版本号是一样的;该编号可能不同于 diozero 核心的版本号)

现在您创建一个 Ant 库用于 diozero 项目。在 NetBeans 中,点击菜单栏中的工具。点击弹出窗口中的;你会看到如图 6-3 所示的蚂蚁库管理器对话框。

img/506025_1_En_6_Fig3_HTML.jpg

图 6-3

NetBeans Ant 库管理器对话框

点击新建库按钮;你看到新库对话框(图 6-4 )允许你给新库命名;你可以看到我使用的是“DIOZERO”,但是你可以使用任何独特的东西。输入姓名后,点击确定

img/506025_1_En_6_Fig4_HTML.jpg

图 6-4

新建库对话框

您将再次看到 Ant Library Manager 对话框,在这里您可以将适当的 JAR 文件添加到您正在创建的库中。点击添加 JAR/文件夹按钮;你会看到如图 6-5 所示的浏览 JAR/文件夹对话框(你可能需要水平展开它才能看到完整的文件/文件夹名称)。

img/506025_1_En_6_Fig5_HTML.jpg

图 6-5

浏览 JAR/文件夹对话框

导航到包含您刚刚下载的 JAR 文件的文件夹。选择前面提到的三个 JAR 文件,点击 Add JAR/Folder 。您将再次看到 Ant Library Manager 对话框,其中有您刚刚添加的用于创建库 DIOZERO 的 JAR 文件;见图 6-6 。

img/506025_1_En_6_Fig6_HTML.jpg

图 6-6

与 DIOZERO 库的 Ant 库管理器对话框

点击 OK 创建 DIOZERO 库。 Ant Library Manager 对话框关闭,库可以使用了。

现在我们来看看如何将 DIOZERO 库添加到项目中。这与添加一个项目库的过程非常相似,如第五章所述,所以我将只讨论不同之处。首先,打开项目属性,点击,你会看到如图 5-25 所示的对话框。现在点击类路径右边的 + 。在弹出的小窗口中,点击添加库。你现在会看到如图 6-7 所示的添加库对话框。

img/506025_1_En_6_Fig7_HTML.jpg

图 6-7

添加库对话框

点击 DIOZERO ,然后点击添加库。你将返回到如图 6-8 所示的项目属性对话框。

img/506025_1_En_6_Fig8_HTML.jpg

图 6-8

将 DIOZERO 库添加到项目的结果

您还需要为项目设置构建打包复制依赖库属性。点击确定。现在,您可以编写一个使用 diozero 中包含的一些设备库的应用程序,或者您可以使用 diozero base I/O API 编写自己的设备库,或者两者兼而有之!下一节将帮助您决定做什么和如何做。

查找(和移植)设备库

你已经为你的项目获得了一个闪亮的新设备。你如何找到对它的支持?记住搜索引擎是你的朋友。一个好的方法是

  • 查看您设备的 diozero 设备库列表(参见 https://www.diozero.comwww.javadoc.io/doc/com.diozero/diozero-core/latest/com/diozero/devices/package-summary.html )。

  • 在互联网上搜索使用 diozero base I/O 层的 Java 设备库。

  • 搜索使用其他基本 I/O 支持的树莓派提供程序的 Java 设备库,例如 Pi4J 或 pigpioj。

  • 更广泛地搜索 Java 设备库。这个搜索应该会得到其他计算平台以及树莓派的支持。

  • 从销售商、制造商或任何其他地方为您的设备搜索非 Java 库。

  • 从头开始为你的设备实现一个库。

你会发现自己处于几种情况中的一种(或多种)。以下各小节或多或少地按照可取性的顺序讨论了这些情况。

在分析情况之前,我必须提几点。第一点是重要的现实。即使在最好的情况下,也可能会有需求差异要求您完成工作。有时一个设备库表现出太少的设备能力;例如,IMU 库可能不支持此类设备中常见的 FIFO。有时候一个设备库做的太多;在我的一个项目中,我只使用了 9 轴 IMU 的 z 轴陀螺仪。有时候,可悲的是,你发现“懒惰编程”;在一个例子中,开发者在出错的情况下编码控制台输出,而不是更健壮的方法。不管在什么情况下,你必须总是准备好自己解决这样的需求差异,除非你的项目在他们存在的情况下运行良好。

第二点是一个重要的机会。在第一章中,我断言你应该认为自己很幸运能够在为某些设备找到一个库。如果您确实找到了一个库,甚至多个库,您可以选择移植,也可以选择从头开始。后者可能是更好的选择,这取决于设备的复杂性、编写现有设备库的语言、实际需要使用的现有库的大小以及其他因素。然而,有一件事你应该一直考虑,如果你有必要的资源,实际上是运行一个现有的库。您可以简单地检查设备是否真的按照您期望的方式工作。您可以在创建资源库时,将现有资源库的行为或结果与您的资源库进行比较。如果你有能力,通过一个 IDE,你可以调试让你更深入地了解现有的库。

记住这两点,我们现在来看看可能的情况。

Java 设备库和 diozero 基本 I/O

这种情况有两种情况:

  • 你可以在 diozero 中找到一个设备库。

  • 您会发现一个使用 diozero base I/O 的非 diozero 设备库。

在这些非常理想的情况下,你不需要做任何工作!除了解决前面提到的需求差异之外,没有其他工作。

如果你没有找到这两种情况,你应该检查 diozero 是否为类似你的设备提供了一个设备库。各类设备通常有一些共同的特征。根据 diozero 支持的设备和您的设备之间的差异,您可能能够修改该库(例如,更改 I2C 地址、寄存器地址、控制常量)。至少,你可以用它作为指导。

Tip

有一种方法可以确保你在这种偶然的情况下结束。在为您的项目选择设备之前,检查 diozero 支持的设备,并尽可能使用它们。没有工作!

Java 设备库和非 diozero 基本 I/O

在这种情况下,您会发现一个 Java 设备库使用了一个非 diozero 基本 I/O 库。设备库可能以树莓派或不同的 SBC 为目标。最有可能的基本 I/O 库是 Pi4J,因为它很受欢迎并且覆盖了所有的基本 I/O。其他可能的库包括 pigpioj 和 jSerialComm。

对于所有的可能性,将设备库移植到 diozero base I/O API 应该是相当简单的。所有的设计和大部分代码应该不加修改地移植。显然,您必须理解非 diozero 和 diozero 基本 I/O API 的语义和语法,以便在它们之间进行转换。移植有两种基本选择:

  • 您可以将对非 diozero 基本 I/O API 的调用替换为逻辑和对 diozero 基本 I/O API 的调用的适当组合。

  • 您可以创建适配器方法,在其接口中模拟非 diozero 基本 I/O API,并封装逻辑和对 diozero 基本 I/O API 的调用的适当组合。您甚至可以将这样的方法分组到一个类中。如果您需要使用相同的非 diozero 基本 I/O API 的多个设备库,这是可取的。

然而,我必须对这种情况提出警告。我发现的 Java 设备库倾向于嵌入到一个更大的框架中。有时很容易忽略更大的框架,而使用库的大部分;有时候不是。如果有其他选择,要小心所涉及的努力。

C/C++设备库

您很有可能找到使用基于 C/C++的 I/O 库的 C/C++设备库。我的经验表明,最常见的设备库形式是 Arduino C++库,因为 Arduino 非常流行。这些通常会在设备供应商网站、制造商网站或两者上引用。您有时可以找到使用 pigpio 或 wiringPi 的设备库。这些几乎总是来自与供应商或制造商没有联系的个人或小团队。

一般来说,C/C++的大部分设计和实现应该是可用的;几乎可以用复制/粘贴来移植(尤其是 C++)。另一方面,移植现在包括

  • 了解非 diozero base I/O API 以及 diozero base I/O API

  • 处理 C/C++和 Java 之间的语法差异(例如,类定义、地址和指针、malloc / free)

  • 处理差异是变量类型;例如,在 Java 中没有无符号类型,但是在 C/C++中有

这些项目都不是很费力,但是总的来说,这种情况显然比大多数纯 Java 情况需要更多的工作。所涉及的工作量取决于设备的复杂性、C/C++库开发人员的能力(例如代码中的注释)、您对 C/C++的了解以及其他因素。

Python 设备库

您可能会找到一个 Python(或某种变体)设备库,它使用某种基于 Python 的 I/O 库,这主要是因为 Python 是树莓派的默认编程语言。Python 有几个基本的 I/O 库;最受欢迎的似乎是 RPi。GPIO 和 gpiozero。C pigpio 库也有 Python 包装器;和 pigpioj 一样,Python pigpio 库(是的,它和 C 库的名字完全一样)完全公开了 pigpio 接口。

使用 Python,设计应该是可用的,但是显然您必须将 Python 语法和语义移植到 Java。您将面临移植 C/C++库的所有问题,痛苦可能被夸大了(想想松散类型与强类型)。除非您精通 Python,否则移植 Python 设备库将比移植 C/C++库需要更多的工作,因此比移植 Java 需要更多的工作。也就是说,移植 Python 库可能比从头开始花费更少的工作。

没有设备库

如果在所有的搜索之后你没有找到合适的库,你显然必须做所有的工作。在某些方面,这是一种解放。你有一个干净的石板,你可以设计和实施精确的能力,你需要从你的设备。您不需要担心理解非 diozero 基础 I/O API。你不用担心语言之间的翻译。

或许与其他情况的最大区别在于,你必须对你的器件非常了解(例如,至少阅读两遍数据手册),但这不一定是件坏事。您应该搜索该器件的应用笔记,以及任何可能有助于您理解该器件简明数据手册的内容。请记住,您可以通过查看类似设备的设备库来获得指导。

摘要

在这一章中,我讨论了树莓派对 Java 的设备支持,包括

  • 寻找基本 I/O 功能支持的搜索技术

  • 为您的项目选择最佳候选人的标准

  • 本书的基 I/O 选择为*,即 diozero*

** 使用 diozero 开发的 NetBeans 配置

*   查找设备库的搜索技术

*   将这些库移植到 Java(如果需要的话)以及使用您选择的基本 I/O 库(如果需要的话)所涉及的工作

*   找不到图书馆时的努力* 

*现在你掌握了一些技巧和指导方针,可以让你应对任何情况。在第七章中,我们将更详细地了解 diozero 基础 I/O API。之后,我们会找到或创建一些设备库!

Footnotes 1

正如我在第五章提到的,通过一些工作,Maven 可以近似“蚂蚁风格”的远程开发。详见附录 A3。如果你决定使用 Maven,你可以跳过本章的其余部分。

  2

附录 A3 是一个例外。它使用远程提供者。

 

**