Arduino 命令行指南:使用 Git 和 Vim 摆脱 GUI!
喜欢 Arduino 但讨厌 GUI?试试 arduino-cli。
在本文中,我将探讨 Arduino 团队发布的一款新工具,它可以让您摆脱现有的基于 Java 的 Arduino 图形用户界面。这允许开发人员使用他们偏好的工具和工作流程。也许更重要的是,它将使 Arduino 工具链本身更容易、更深入地进行创新。
美好的旧时光当我在 20 世纪 90 年代开始使用微处理器构建业余电子项目时,这个过程需要一个分立的处理器、RAM、ROM 和大量的胶合逻辑芯片,它们使用点对点或“绕线”技术连接在一起。(孩子们,查一下!)程序存储在玻璃窗口 EPROM 芯片上,需要用紫外线擦除。所有工具都很昂贵且难以使用,开发周期非常缓慢。图 1-3 显示了我 20 世纪 90 年代中期使用分立 CPU、RAM 和 ROM 的微处理器项目的一些示例。注意:没有闪存,没有 I/O,没有 DAC,没有 ADC,没有定时器——所有这些都意味着更多的芯片!

图 1. 20 世纪 90 年代中期的微处理器示例

图 2. 20 世纪 90 年代中期的微处理器示例

图 3. 20 世纪 90 年代中期的微处理器示例
这一切都在 2003 年随着 Arduino 的出现而改变。
“Arduino”这个词经常会引起广泛的意见,有时甚至是情绪。对于许多人来说,它代表着进入微控制器世界的极低门槛。2003 年之前的这个世界通常需要昂贵、晦涩和闭源的开发工具。Arduino 一直是一个伟大的均衡器,打破了封闭花园的大门。Arduino 现在代表着一个庞大的硬件生态系统,它使用(大部分)通用语言,并简化了从一个硬件平台到另一个硬件平台的过渡。今天,如果您是一家销售微控制器的公司,那么让您的开发板与 Arduino 协同工作符合您的最佳利益。它为您的产品快速进入大量用户手中提供了一条低摩擦的路径。
同样重要的是要注意,Arduino 的简单性并没有限制深入挖掘微控制器。没有什么能阻止您直接调整寄存器和使用高级功能。然而,这确实会降低您在板之间的可移植性。
对于嵌入式开发新手来说,Arduino 软件非常容易上手。这是它成功的一个主要原因——它开箱即用,随时可用。但对于更有经验的开发人员来说,包含的图形用户界面可能会令人沮丧。它可能成为使用现代开发工具和版本控制(如 Git)的障碍。我知道编译器和工具链都深深地埋藏在 GUI 的某个地方。我只是想使用我最喜欢的编辑器,编译我的代码,并使用我喜欢的工作流程将我的项目上传到开发板。对于许多开发人员来说,这是一个命令行或脚本化的过程。
进入 arduino-cli之前曾有几次尝试将 Arduino 分离到命令行,但大多数都未能获得广泛的支持。然而,现在 Arduino 团队已经 alpha 发布了 arduino-cli。这个新框架不仅提供了一套全面的命令行功能,而且该团队还表示它将用作下一代 Arduino 图形界面底层的核心。这是一个令人兴奋的消息,并表明了对这个新概念的承诺。
对我来说,我首选的开发工作流程是使用 Git 进行版本控制和 Vim 编辑器,所以这就是我在本文的其余部分演示的内容。
安装 arduino-cli在撰写本文时,arduino-cli 仍处于 alpha 发布阶段。它以 Go 源代码包和预构建二进制文件的形式分发。Go 语言生成非常可移植的二进制文件,因此您只需要下载正确的文件并将二进制文件放在 $PATH 中的某个位置即可。大多数阅读本文的用户可能需要适用于 Intel/AMD 系统的 Linux 64 位版本。这里的示例中,我的系统碰巧运行的是 Fedora 29,但任何最近的 Linux 版本都应该可以工作。查看项目的 GitHub 页面以获取更新的版本;在撰写本文时,0.3.2 是最新的 alpha 版本。最后,确保您的用户可以通过将他们添加到“dialout”组来访问串行和 USB 连接的 Arduino 开发板(注意:您需要重新登录才能获取新的组成员身份,并在最后一个命令中将“me”替换为您的用户名)
me@mybox:~ $ wget https://downloads.arduino.cc/arduino-cli/
↪arduino-cli-0.3.2-alpha.preview-linux64.tar.bz2
***downloading***
me@mybox:~ $ tar -xjf arduino-cli-0.3.2-alpha.preview-
↪linux64.tar.bz2
me@mybox:~ $ sudo mv arduino-cli-0.3.2-alpha.preview-linux64
↪/usr/local/bin/arduino-cli
me@mybox:~ $ sudo usermod -a -G dialout me
假设 /usr/local/bin 在您的 $PATH 中,您应该能够以 Linux 系统上的任何用户身份运行 arduino-cli。
或者,如果您想从源代码构建 Go 包,您可以使用 get
函数从 Arduino GitHub 存储库下载、构建和安装源代码包
me@mybox:~ $ sudo dnf -y install golang
me@mybox:~ $ cd ; export GOPATH=`pwd`/go
me@mybox:~ $ go get -u github.com/arduino/arduino-cli
me@mybox:~ $ sudo mv $GOPATH/bin/arduino-cli /usr/local/bin/
Arduino 命令行指南
首先,让我们做一些内务处理。您需要拉取当前的 Arduino “核心”索引,并搜索支持您的开发板的核心。在第一个示例中,让我们安装对由 ATMega AVR 处理器驱动的经典 UNO 板的支持
me@mybox:~ $ arduino-cli core update-index
Updating index: package_index.json downloaded
me@mybox:~ $ arduino-cli core search avr
Searching for platforms matching 'avr'
ID Version Name
arduino:avr 1.6.23 Arduino AVR Boards
arduino:megaavr 1.6.24 Arduino megaAVR Boards
atmel-avr-xminis:avr 0.6.0 Atmel AVR Xplained-minis
emoro:avr 3.2.2 EMORO 2560
littleBits:avr 1.0.0 littleBits Arduino AVR Modules
me@mybox:~ $ arduino-cli core install arduino:avr
*** lots of downloading omitted ***
me@mybox:~ $ arduino-cli core list
ID Installed Latest Name
arduino:avr@1.6.23 1.6.23 1.6.23 Arduino AVR Boards
就是这样。您已经拥有了为 Arduino UNO 板创建新的 Arduino 项目所需的一切。现在,让我们创建一个名为 myBlinky 的项目。您还将初始化并设置一个 Git 存储库来管理版本控制,然后进行您的第一次提交
me@mybox:~ $ arduino-cli sketch new myBlinky
Sketch created in: /home/me/Arduino/myBlinky
me@mybox:~ $ cd /home/me/Arduino/myBlinky
me@mybox:~/Arduino/myBlinky $ git config --global
↪user.email "me@mybox.com"
me@mybox:~/Arduino/myBlinky $ git config --global
↪user.name "My Name"
me@mybox:~/Arduino/myBlinky $ git init
Initialized empty Git repository in /home/me/Arduino/
↪myBlinky/.git/
me@mybox:~/Arduino/myBlinky $ ls -la
total 16
drwxr-xr-x 3 me me 4096 Nov 22 10:45 .
drwxr-xr-x 3 me me 4096 Nov 22 10:45 ..
drwxr-xr-x 7 me me 4096 Nov 22 10:45 .git
-rw-r--r-- 1 me me 35 Nov 22 10:45 myBlinky.ino
me@mybox:~/Arduino/myBlinky $ cat myBlinky.ino
void setup() {
}
void loop() {
}
me@mybox:~/Arduino/myBlinky $ git add -A
me@mybox:~/Arduino/myBlinky $ git commit -m "Initial Commit"
[master (root-commit) ee95972] Initial Commit
1 file changed, 6 insertions(+)
create mode 100644 myBlinky.ino
me@mybox:~/Arduino/myBlinky $ git log
commit ee9597269c5da49d573d6662fe8f8137083b7768
↪(HEAD -> master)
Author: My Name <me@mybox.com>
Date: Thu Nov 22 10:48:33 2018 -0500
Initial Commit
不错!该工具在图形工具期望找到它们的相同 Arduino 目录结构下创建项目,允许您在工具之间切换(如果您愿意)。它还创建了一个包含熟悉的 setup()
和 loop()
函数的模板 .ino 文件。
空的 Git 存储库已初始化,您可以看到它创建了 .git 子目录,所有版本数据都将保存在其中。是时候编码了!
现在,只需在您喜欢的编辑器中打开 myBlinky.ino ——为了最大限度地提升街头信誉,当然是 Vim。永远不要 EMACS(开玩笑!)。。。说真的,使用任何你喜欢的编辑器(我听说 Eclipse 也不错)——然后输入并保存一个经典的“Hello World”闪烁程序。像这样
// Simple Demo Blinker -MEH
#define PIN_LED 13
void setup() {
pinMode(PIN_LED,OUTPUT);
}
void loop() {
digitalWrite(PIN_LED,HIGH);
delay(500);
digitalWrite(PIN_LED,LOW);
delay(500);
}
现在,让我们编译并将其上传到 Arduino UNO。使用 board
命令集来搜索上传
me@mybox:~/Arduino/myBlinky $ arduino-cli board list
FQBN Port ID Board Name
arduino:avr:uno /dev/ttyACM0 2341:0001 Arduino/Genuino Uno
找到了开发板。现在编译
me@mybox:~/Arduino/myBlinky $ arduino-cli compile -b
↪arduino:avr:uno
Build options changed, rebuilding all
Sketch uses 930 bytes (2%) of program storage space. Maximum
↪is 32256 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving
↪2039 bytes for local variables. Maximum is 2048 bytes.
编译干净利落。接下来,使用 upload
命令、开发板名称和您之前发现的端口上传到开发板
me@mybox:~/Arduino/myBlinky $ arduino-cli upload
↪-b arduino:avr:uno -p /dev/ttyACM0
与命令行工具常见的情况一样,沉默是金。upload
命令完成,UNO 愉快地闪烁起来。您最好使用 git commit
锁定这种好运
me@mybox:~/Arduino/myBlinky $ git commit -a -m "It works!
↪First blink."
[master 35309a0] It works! First blink.
1 file changed, 7 insertions(+)
-m
选项接受提交消息;它应该是关于此提交中包含内容的注释。如果您省略消息,git
将在文本编辑器中打开一个模板消息(默认是 Vim,但您可以通过设置 $EDITOR
来更改它)。
现在来点更雄心勃勃的东西,让我们尝试使用非 Arduino 开发板,并逐步完成添加第三方核心的步骤。即使使用图形用户界面,这也很棘手,但使用 arduino-cli 却非常简单。让我们以非常流行的 ESP8266 为目标。
首先,您需要将第三方存储库添加到文件中,以便 arduino-cli 知道如何定位核心。这是通过名为 .cli-config.yml 的文件完成的。您可能会认为这应该放在您的主目录或项目目录中,并且您这样想是对的。但是,arduino-cli 早期版本的一个怪癖是,该文件位于 arduino-cli 程序所在的目录中。目前,这是 /usr/local/bin,但请密切关注网站,因为这很可能在未来的版本中发生变化!在下面,您将添加一个新的开发板配置定义。此文件使用 YAML 格式,因此请注意仅在缩进中使用空格。编辑(使用 sudo
),并将以下文本放在 /usr/local/bin/.cli-config.yml 中
board_manager:
additional_urls:
- http://arduino.esp8266.com/stable/
↪package_esp8266com_index.json
现在,像以前一样,更新索引并安装核心
me@mybox:~/Arduino/myBlinky $ arduino-cli core update-index
Updating index: package_index.json downloaded
Updating index: package_esp8266com_index.json downloaded
您可以看到它找到了并下载了 esp8266 核心的索引。很好。现在,让我们下载并安装核心本身
me@mybox:~/Arduino/myBlinky $ arduino-cli core search esp
Searching for platforms matching 'esp'
ID Version Name
esp8266:esp8266 2.4.2 esp8266
me@mybox:~/Arduino/myBlinky $ arduino-cli core install
↪esp8266:esp8266
Downloading esp8266:esptool@0.4.13...
esp8266:esptool@0.4.13 downloaded *** much omitted ***
现在,您可以为 esp8266 重建您的 myBlinky 项目并上传它。您首先需要编辑您的 myBlinky.ino 并将 #define PIN_LED
更改为具有 LED 的引脚。在我的开发板上,它是引脚 2。进行修改并保存它
#define PIN_LED 2
插入 esp8266 开发板后,您再次运行 board list
命令以尝试找到它
me@mybox:~/Arduino/myBlinky $ arduino-cli board list
FQBN Port ID Board Name
/dev/ttyUSB0 1a86:7523 unknown
它检测到了它,但无法确定它是什么。这对于像 esp8266 这样需要按下按钮或特殊编程模式的开发板来说非常常见。
接下来,在按下编程按钮的同时重置您的 esp8266 开发板后,进行编译和上传。像上次一样,使用在 list
操作期间发现的开发板名称和端口
me@mybox:~/Arduino/myBlinky $ arduino-cli board listall
↪|grep esp8266
Generic ESP8266 Module esp8266:esp8266:generic
(omitted long list)
me@mybox:~/Arduino/myBlinky $ arduino-cli upload -b
↪esp8266:esp8266:generic -p /dev/ttyUSB0
Uploading 252000 bytes from /home/me/Arduino/myBlinky/
↪myBlinky.esp8266.esp8266.generic.bin to flash at 0x00000000
..................................................... [ 32% ]
..................................................... [ 64% ]
..................................................... [ 97% ]
....... [ 100% ]
并且,它闪烁了!再次 git commit
并保存您的进度
me@mybox:~/Arduino/myBlinky $ git add -A
me@mybox:~/Arduino/myBlinky $ git commit -m
↪"Blinking on esp8266 board"
[master 2ccff1d] Blinking on esp8266 board
5 files changed, 61 insertions(+), 1 deletion(-)
create mode 100755 myBlinky.arduino.avr.uno.elf
create mode 100644 myBlinky.arduino.avr.uno.hex
create mode 100644 myBlinky.esp8266.esp8266.generic.bin
create mode 100755 myBlinky.esp8266.esp8266.generic.elf
正如您所看到的,它将编译后的代码的二进制版本保存在项目目录中。如果您希望将这些文件从您的提交中省略,您可以将 *.bin、*.hex 和 *.elf 添加到 .gitignore 文件中。如果您保存了它们,则可以使用 -i
选项和 .bin 文件来上传特定的二进制文件。
在您的成功基础上,您应该下载并安装一个库。让我们提升闪烁游戏的水平,并安装对一些 Adafruit NeoPixels(又名 WS2812B、PL9823 等)的支持。首先,使用 lib
命令搜索它,然后下载并安装
me@mybox:~/Arduino/myBlinky $ arduino-cli lib search neopixel
(omitting large list)
me@mybox:~/Arduino/myBlinky $ arduino-cli lib install
↪"Adafruit NeoPixel"
Adafruit NeoPixel@1.1.7 downloaded
Installed Adafruit NeoPixel@1.1.7
现在您需要修改程序;使用这些修改编辑 .ino 文件
// Fancy NeoPixel Blinky Blinker
#include <Adafruit_NeoPixel.h>
#define PIN_LED 14
Adafruit_NeoPixel strip = Adafruit_NeoPixel(1, PIN_LED,
↪NEO_GRB + NEO_KHZ800);
void setup() {
strip.begin();
}
void loop() {
strip.setPixelColor(0,strip.Color(255,0,0))'
delay(200);
strip.setPixelColor(0,strip.Color(0,255,0));
delay(200);
strip.setPixelColor(0,strip.Color(0,0,255));
delay(200);
}
接下来,执行相同的编译和上传步骤,当然,在将 NeoPixel 或兼容 LED 连接到引脚 14 之后
me@mybox:~/Arduino/myBlinky $ arduino-cli compile -b
↪esp8266:esp8266:generic
Build options changed, rebuilding all
Sketch uses 248592 bytes (49%) of program storage space.
↪Maximum is 499696 bytes.
Global variables use 28008 bytes (34%) of dynamic memory,
↪leaving 53912 bytes for local variables. Maximum
↪is 81920 bytes.
me@mybox:~/Arduino/myBlinky $ arduino-cli upload -b
↪esp8266:esp8266:generic -p /dev/ttyUSB0
Uploading 252960 bytes from /home/me/Arduino/myBlinky/
↪myBlinky.esp8266.esp8266.generic.bin to flash at 0x00000000
.................................................... [ 32% ]
.................................................... [ 64% ]
.................................................... [ 96% ]
........ [ 100% ]
并且,您应该有一个彩色闪烁——非常漂亮。现在是提交更改以记录您的进度的另一个好时机
me@mybox:~/Arduino/myBlinky $ git add -A
me@mybox:~/Arduino/myBlinky $ git commit -m
↪"Blinky with NeoPixels"
[master 122911f] Blinky with NeoPixels
3 files changed, 20 insertions(+), 13 deletions(-)
rewrite myBlinky.ino (81%)
使用 GitHub
到目前为止,git 存储库完全位于您的项目目录中。这没什么问题,但假设您想将您的工作发布到 GitHub。入门非常快速和容易。首先,登录到 github.com 并创建一个帐户(如果您还没有帐户)。然后,单击按钮以创建一个“新存储库”。

图 4. 新存储库
填写您的项目的详细信息,并确保取消选中使用 README 初始化存储库的选项。这是因为您已经创建了一个存储库,并且您将“推送”您的本地存储库到 GitHub,所以您希望它是空的。

图 5. 创建存储库
创建后,您将看到一些关于如何将代码推送到 GitHub 的有帮助的选项。您需要“推送现有存储库”的命令。

图 6. 推送现有存储库
现在让我们开始吧!按照说明创建一个名为“origin”的 git “远程”条目,它将代表 GitHub。然后您将推送,它将提示您输入您的 GitHub 用户名和密码(替换您自己的 GitHub URL、用户名和密码)
me@mybox:~/Arduino/myBlinky $ git remote add origin
↪https://github.com/sysmatt/myBlinky.git
me@mybox:~/Arduino/myBlinky $ git push -u origin master
Username for 'https://github.com': sysmatt
Password for 'https://sysmatt@github.com': ******************
Counting objects: 18, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (18/18), 825.31 KiB | 5.00 MiB/s, done.
Total 18 (delta 4), reused 0 (delta 0)
remote: Resolving deltas: 100% (4/4), done.
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
现在,如果您浏览到 GitHub.com 上的存储库,您将看到您的所有文件和您的每一个提交。您可以及时回溯并查看每个版本。在实践中,您可以使用 SSH 密钥来消除每次都必须输入密码的情况。

图 7. 提交历史
时间旅行(又名用 Git 打破物理定律)你说时间旅行?确实如此。假设你想及时回到过去,回顾一下你的 myBlinky 版本,当时它还在 Arduino UNO 上工作。这似乎是很久以前的事了。这很容易!您只需要识别提交 ID 并“检出”该版本。
使用 log
命令列出您的所有提交
me@mybox:~/Arduino/myBlinky $ git log
commit 122911f99dddce2dabbb251c3b640c8c7f9f98d9 (HEAD ->
↪master, origin/master)
Author: My Name <me@mybox.com>
Date: Thu Nov 22 21:22:59 2018 -0500
Blinky with NeoPixels
commit 2ccff1d7326b1523649510f24644c96df6dc6e12
Author: My Name <me@mybox.com>
Date: Thu Nov 22 11:42:02 2018 -0500
Blinking on esp8266 board
commit 35309a0c9e90668052abc9644f77f906ab57949c
Author: My Name <me@mybox.com>
Date: Thu Nov 22 11:09:44 2018 -0500
It works! First blink.
commit ee9597269c5da49d573d6662fe8f8137083b7768
Author: My Name <me@mybox.com>
Date: Thu Nov 22 10:48:33 2018 -0500
Initial Commit
看起来以 35309a0c 开头的提交是您想要的那个。注意:您可以将提交哈希字符串缩短到最少四个字符,只要它唯一地标识一个提交即可。让我们探索一下该版本
me@mybox:~/Arduino/myBlinky $ git checkout 35309a0c
HEAD is now at 35309a0... It works! First blink.
me@mybox:~/Arduino/myBlinky $ ls -l
-rw-r--r-- 1 me me 191 Nov 22 22:01 myBlinky.ino
me@mybox:~/Arduino/myBlinky $ cat myBlinky.ino
// Simple Demo Blinker -MEH
#define PIN_LED 13
void setup() {
pinMode(PIN_LED,OUTPUT);
}
void loop() {
digitalWrite(PIN_LED,HIGH);
delay(500);
digitalWrite(PIN_LED,LOW);
delay(500);
}
现在假设您已经完成浏览,那么让我们及时回到今天,让一切恢复到您打破物理定律之前的状态。在简单的 git 存储库中,这意味着跳转回“master”分支中的当前提交
me@mybox:~/Arduino/myBlinky $ git checkout master
Previous HEAD position was 35309a0... It works! First blink.
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
me@mybox:~/Arduino/myBlinky $ ls -l
total 1332
-rwxr-xr-x 1 me me 13956 Nov 22 22:04
↪myBlinky.arduino.avr.uno.elf
-rw-r--r-- 1 me me 2640 Nov 22 22:04
↪myBlinky.arduino.avr.uno.hex
-rw-r--r-- 1 me me 252960 Nov 22 22:04
↪myBlinky.esp8266.esp8266.generic.bin
-rwxr-xr-x 1 me me 1082905 Nov 22 22:04
↪myBlinky.esp8266.esp8266.generic.elf
-rw-r--r-- 1 me me 436 Nov 22 22:04 myBlinky.ino
不错!您又回到了 NeoPixel 闪烁。您看,git 将所有版本的已提交代码存储在 .git 子目录中。这实际上是存储库的真实位置。您编辑的文件只是“工作区”。当您在提交之间跳转时,git 会完成修改工作区中所有文件的神奇操作。如果您想跳回去并开始修改旧版本的代码,您可以创建一个新的“分支”来包含该工作,并继续使用 AVR 和 esp8266 代码的分支。它非常强大。
我在这里只触及了皮毛。Git、GitHub 和 arduino-cli 都是非常全面的工具。我希望本文能让您了解当您为 Arduino 项目利用良好的编程工作流程时,可能会实现什么。
资源