Arduino CLI 从入门到精通 以 ESP32开发为例

Arduino CLI 的发展历程与 1.0 版本的发布


众所周知,Arduino 一直是电子 DIY 爱好者心中的宠儿。它简单易学的编程语言和丰富的硬件生态,让无数Maker 从此踏上了创客之路。多年以来,Arduino 官方的 Arduino IDE 一直是用户进行编程开发的主要工具。

然而,这款基于 Java 的重量级 IDE 在功能与性能上都难尽人意。为了给用户提供更好的开发体验,Arduino 官方从 2018 年起启动了全新的开发工具项目 - Arduino CLI。

不同于 Arduino IDE,Arduino CLI 是一个运行在命令行下的轻量级工具。它将 Arduino IDE 的核心功能如板卡管理、库管理、程序编译、烧录等,从臃肿的图形界面中解放出来,以命令行的方式呈现给用户。这种"去 GUI 化"的设计,不仅让 Arduino CLI 的安装、使用变得更加简单,也为 Arduino 提供机器接口、与其他工具整合创造了可能。

Arduino CLI 的另一大亮点,是采用了全新的 gRPC 接口。gRPC 是由 Google 开发的高性能 RPC 框架,支持多种编程语言。得益于此,用户可以很方便地用 Golang、Python 等语言来调用 Arduino CLI,实现自动化测试、持续集成等功能。

尽管 Arduino CLI 在 2018 年就已经启动,但在最初的一段时间里,它的功能还比较简陋,也缺乏详细的文档。直到近期,随着几个里程碑式的版本发布,Arduino CLI 才逐渐走向成熟。

2024 年 6 月,备受期待的 Arduino CLI 1.0 版本终于正式发布。这个版本不仅全面提升了性能和稳定性,还新增了包括 Board Manager、Library Manager、对多合一固件的支持等重要功能,标志着 Arduino CLI 正式成为了一个完善的 Arduino 开发工具。

在 1.0 版本之后,Arduino 官方又陆续发布了几个新的小版本,修复了一些 Bug,新增了一些小功能。截止目前(2024 年 9 月),Arduino CLI 的最新版本已经来到了 1.0.4。

本文将基于这个最新的 1.0.4 版本,为大家全面讲解 Arduino CLI 的安装、使用方法,以及在实际项目中的最佳实践。通过学习和使用 Arduino CLI,我们可以开启一段全新的 Arduino 开发之旅,提升开发效率和体验。

Arduino CLI的安装方法


安装Arduino CLI有多种方式,你可以根据自己的操作系统和需求选择合适的方法。

    1. Homebrew安装(macOS/Linux)

如果你使用的是macOS或Linux,推荐使用Homebrew包管理器来安装Arduino CLI,非常简单方便:

brew update
brew install arduino-cli

    2. 安装脚本

Arduino官方提供了一个安装脚本,可以自动下载并安装Arduino CLI。在Linux、macOS或Windows的Git Bash中,运行以下命令:

curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh

这会将Arduino CLI安装到当前目录的bin文件夹中。你也可以通过设置BINDIR环境变量来指定其他安装路径。

    3. 下载预编译的二进制文件

Arduino官方为所有支持的操作系统提供了预编译的二进制文件,可以从Github发布页面下载最新版本或历史版本。

下载后解压,并将arduino-cli添加到PATH环境变量中,以便在任何地方都能使用arduino-cli命令。

除了稳定版本,你也可以下载最新开发版本。

    4. 从源码编译

如果你熟悉Go语言或想参与Arduino CLI的开发,也可以选择从源码编译。具体步骤可参考Arduino CLI的"如何贡献"页面。

总的来说,在macOS和Linux上推荐使用Homebrew安装,在Windows上建议下载预编译文件。如果想体验最新特性,也可以选择安装脚本或最新的开发版本。

选择一种适合自己的方式安装完Arduino CLI后,你就可以开始使用arduino-cli命令了。在接下来的章节中,我们会详细介绍arduino-cli的常用命令和实用功能,让你轻松掌握Arduino CLI的使用技巧。

arduino-cli board相关命令


arduino-cli board提供了一系列与开发板相关的子命令,可以帮助我们管理和使用已连接的开发板。

    1. arduino-cli board list

用于列出当前已连接到电脑的Arduino开发板。它会自动检测连接的开发板并显示它们的信息,如端口号、开发板名称、FQBN等。例如:

arduino-cli board list

    2. arduino-cli board listall

列出所有已安装的开发板,以及它们对应的FQBN(完全合格开发板名称)。你也可以指定一个关键字来搜索特定的开发板。例如:

arduino-cli board listall
arduino-cli board listall uno

    3. arduino-cli board search

在Board Manager中搜索指定名称的开发板。这个命令会查询已安装的开发板,以及可以从Board Manager中安装的开发板。例如:

arduino-cli board search
arduino-cli board search nano

    4. arduino-cli board attach

为当前sketch设置默认的开发板和端口。如果不指定端口、FQBN或编程器,则显示当前的默认值。例如:

arduino-cli board attach -p COM3
arduino-cli board attach -b arduino:avr:uno

    5. arduino-cli board details

显示指定开发板的详细信息,特别是开发板的可用选项,可添加到FQBN字符串中以自定义板配置。例如:

arduino-cli board details -b arduino:avr:nano

以上就是arduino-cli提供的几个常用board子命令。通过这些命令,你可以很方便地管理你的开发板,查看它们的信息,设置默认值等。

值得一提的是,所有这些子命令都支持一些通用的选项,如--json用于输出JSON格式的结果,--log-level 用于设置日志级别等。你可以运行arduino-cli board --help来查看所有可用的选项。

arduino-cli中与编译、缓存管理和命令补全相关的几个命令。


arduino-cli compile - 编译 Arduino 程序

这个命令用于编译Arduino草图(sketch)。你需要指定要编译的草图文件路径,以及使用 -b 选项指定目标开发板的 FQBN。例如:

arduino-cli compile -b arduino:avr:uno /home/user/Arduino/MySketch

这会编译 /home/user/Arduino/MySketch 目录下的 Arduino 草图,目标开发板为 arduino:avr:uno。

compile命令还有一些其他常用选项:

  • --libraries 指定额外的库文件搜索路径

  • --build-property 指定额外的编译属性

  • --output-dir 指定编译输出目录

  • -e 将编译后的二进制文件导出到草图目录

  • -u 在编译完成后自动上传程序到开发板

  • -v 打印详细的编译过程信息

arduino-cli cache 和 arduino-cli cache clean - 管理缓存

这两个命令用于管理Arduino CLI的缓存。

在安装开发板平台和库文件时,相关的压缩包会被下载到缓存目录进行解压。cache命令可以查看和管理缓存,目前它只有一个子命令 clean。

arduino-cli cache clean 用于清空缓存目录,删除所有已下载的压缩包文件。这在你遇到某些异常情况需要重置Arduino CLI环境时会很有用。

arduino-cli completion - 生成命令行补全脚本

这个命令可以为bash、zsh、fish等常见的shell环境生成arduino-cli的命令行补全脚本。有了命令行补全,你在输入arduino-cli命令时可以通过Tab键触发自动补全,提示可用的子命令和选项。

例如要为bash生成补全脚本:

arduino-cli completion bash > arduino-completion.sh
source arduino-completion.sh  

这会将补全脚本输出到 arduino-completion.sh 文件中,执行source使其生效。之后在输入arduino-cli命令时就可以利用Tab补全了。

以上就是这几个arduino-cli命令的基本用法,你可以通过 -h 选项查看每个命令完整的使用帮助。善用这些命令可以让你的Arduino开发工作变得更加高效。

config子命令


arduino-cli提供了一系列config子命令,用于管理Arduino CLI的配置。让我们一起来看看这些命令的具体用法。

    1. arduino-cli config init

这个命令会在数据目录或自定义目录下创建或更新配置文件,将当前的配置设置写入文件。例如:

arduino-cli config init  //在数据目录下创建/更新配置文件
arduino-cli config init --dest-dir /home/user/MyDir  //在指定目录下创建配置文件

    2. arduino-cli config dump

打印当前的完整配置信息。这对了解当前生效的所有配置项非常有用。

    3. arduino-cli config set

设置一个配置项的值。你需要指定配置项的完整路径和要设置的值。例如:

arduino-cli config set logging.level trace
arduino-cli config set sketch.always_export_binaries true

    4. arduino-cli config get

获取一个配置项的值。你需要指定配置项的完整路径。

    5. arduino-cli config add

为一个配置项追加一个或多个值。通常用于那些支持多个值的配置项,如

board_manager.additional_urls。例如:

arduino-cli config add board_manager.additional_urls
https://example.com/package_example_index.json

    6. arduino-cli config remove

从一个支持多值的配置项中移除一个或多个值。同样需要提供完整的配置路径和要移除的值。

    7. arduino-cli config delete

删除一个配置项及其所有子项。例如:

arduino-cli config delete board_manager  //删除board_manager及其所有子配置项
arduino-cli config delete board_manager.additional_urls  //只删除additional_urls子项

以上就是arduino-cli提供的所有配置管理命令。通过灵活使用这些命令,你可以方便地查看和修改Arduino CLI的各项配置,以满足不同的使用需求。

一些常见的配置项包括:

  • logging.level: 日志输出级别

  • sketch.always_export_binaries: 是否总是导出编译后的二进制文件

  • board_manager.additional_urls: board manager的附加URL列表

  • daemon.port: arduino-cli后台进程的监听端口

arduino-cli config命令族给了我们很大的灵活性来管理CLI的行为,充分利用它们可以让你的arduino-cli使用体验更上一层楼。

core子命令


arduino-cli提供了一组core子命令,用于管理Arduino开发板核心(platform)。这里的"核心"指的是某个特定架构(如AVR、ARM等)的开发板所需的一整套工具链和运行时库。下面我们来逐个解释这些子命令:

    1. arduino-cli core download & arduino-cli core install

这两个命令用于下载和安装某个核心,区别在于download只下载核心包到本地,而install会下载并解压安装。它们的用法是:

arduino-cli core download <PACKAGER>:<ARCH>[@<VERSION>] 
arduino-cli core install <PACKAGER>:<ARCH>[@<VERSION>]

其中是核心供应商(如arduino、esp32等),是架构(如avr、samd等),是可选的版本号。例如:

arduino-cli core install arduino:avr  //安装Arduino AVR核心的最新版本
arduino-cli core download arduino:samd@1.8.9 //下载Arduino SAMD核心的1.8.9版

    2. arduino-cli core uninstall

用于卸载已安装的核心。用法与install类似:

arduino-cli core uninstall arduino:avr

    3. arduino-cli core list

列出所有已安装的核心。支持一些过滤选项如--updatable只显示可更新的核心。

    4. arduino-cli core search

在Board Manager中搜索可安装的核心。你可以提供一些关键词来过滤搜索结果:

arduino-cli core search MKR

    5. arduino-cli core update-index

更新本地的Board Manager索引到最新版本。在下载或搜索核心之前,通常需要先运行这个命令以获得最新的核心列表。

    6. arduino-cli core upgrade

将一个或所有已安装的核心升级到最新版本。例如:

arduino-cli core upgrade              //升级所有核心
arduino-cli core upgrade arduino:samd //升级Arduino SAMD核心

以上就是arduino-cli core命令的概览。这套命令为你管理开发板核心提供了完整的解决方案,从搜索、下载、安装到卸载、升级,一应俱全。

在使用这些命令时,有几点需要注意:

  • 对于第三方核心,你需要先将其Board Manager URL添加到arduino-cli的配置文件中,相关核心才能被找到

  • 下载和安装核心可能需要较长时间,取决于你的网络条件。耐心等待

  • 安装核心前最好先更新索引,以免安装到过时的版本

  • 卸载核心时,arduino-cli会自动检查其他已安装的核心是否依赖于该核心,以免误删

lib子命令


arduino-cli还提供了一组lib子命令,用于管理Arduino库。下面我们来逐个了解这些命令的用法。

    1. arduino-cli lib install & arduino-cli lib download

这两个命令用于安装库。区别在于install会下载并安装库到Arduino的库目录,而download只会下载库文件而不安装。它们的用法是:

arduino-cli lib install <库名>[@<版本号>]
arduino-cli lib download <库名>[@<版本号>] 

其中版本号是可选的,不提供则安装/下载最新版本。例如:

arduino-cli lib install "WiFi101"    //安装WiFi101库的最新版
arduino-cli lib install "WiFi101@0.16.1"  //安装WiFi101库的0.16.1版

除了从库管理器安装,你也可以通过--git-url或--zip-path选项从Git仓库或本地zip包安装库。

    2. arduino-cli lib uninstall

卸载指定的一个或多个已安装的库。用法:

arduino-cli lib uninstall <库名1> <库名2> ...

    3. arduino-cli lib list

列出所有已安装的库。你可以提供一个可选的库名参数,只列出该库的信息。默认不会列出内置库,添加--all选项可列出内置库。

    4. arduino-cli lib search

在库管理器中搜索指定名称的库。该命令支持非常强大的搜索运算符,可以按作者、类别、依赖项等多个维度搜索库。

    5. arduino-cli lib deps

列出指定库的依赖项及其安装状态。对解决库依赖问题很有帮助。

    6. arduino-cli lib update-index

更新本地的库索引到最新状态。与core update-index类似,在安装或搜索库之前通常需要先更新索引。

    7. arduino-cli lib upgrade

将已安装的一个或多个库升级到最新版本。不提供参数则升级所有已安装的库。

    8. arduino-cli lib examples

列出指定库提供的示例程序。你可以通过--fqbn选项指定开发板,只列出该开发板适用的示例。

这些就是arduino-cli提供的所有库管理命令。利用它们你可以方便地搜索、安装、升级Arduino库,并检查库的依赖关系和示例程序。

arduino 第三方 lib可以说是Arduino生态中非常重要的一部分,有了这套库管理命令,我们就可以利用丰富的第三方库来增强Arduino程序的功能,提升开发效率。而且这些操作都可以通过命令行完成,非常适合集成到自动化流程中。

arduino-cli的一些高级功能和辅助调试命令


接下来我们讲解arduino-cli的一些高级功能命令。

arduino-cli daemon - 将Arduino CLI作为gRPC服务运行

这个命令允许你将Arduino CLI作为一个gRPC服务在后台运行。这样其他程序就可以通过gRPC接口来调用Arduino CLI的功能,实现自动化或集成。

例如,运行以下命令即可启动gRPC服务:

arduino-cli daemon

启动后,你可以通过gRPC客户端与其通信。Arduino CLI提供的gRPC服务接口可以在文档的gRPC reference章节找到详细说明。

arduino-cli debug - 调试Arduino程序

这个命令可以帮助你调试Arduino程序。它会编译程序并在gdb调试器中打开,允许你进行单步调试、设置断点等。例如:

arduino-cli debug -b arduino:samd:mkr1000 -P atmel_ice -p /dev/ttyACM0 MySketch

这会在gdb中调试MySketch程序。注意使用前需要在命令行选项中指定开发板型号、使用的JTAG适配器和串口等信息。

arduino-cli monitor - 打开与开发板的串口通信

这个命令可以打开你的电脑与开发板之间的串口通信,查看开发板的串口输出,也可以向开发板发送数据。例如:

arduino-cli monitor -p /dev/ttyACM0

这会打开与/dev/ttyACM0端口相连的开发板的串口监视器。你可以在终端看到程序的串口输出。

arduino-cli update 和 arduino-cli upgrade - 更新

这两个命令用于将已安装的开发板核心和库升级到最新版本。其中update会更新核心和库的索引,upgrade会根据索引将实际的核心和库升级到最新。通常在升级前需要先运行update。例如:

arduino-cli update      //更新索引
arduino-cli upgrade     //执行升级

arduino-cli version - 查看版本

这个命令非常简单,就是输出你安装的Arduino CLI的版本号。

以上就是arduino-cli的一些高级功能命令。利用它们,你可以将Arduino CLI集成到其他系统,实现调试和自动化测试,并随时保持你的开发环境处于最新状态。

实战


好的,让我们一步步使用Arduino-CLI来创建和开发一个ESP32 BLE串口透传的示例项目。

    1. 创建项目

首先,使用以下命令创建一个新的Arduino sketch:

arduino-cli sketch new ESP32BLEUart
cd ESP32BLEUart

这会创建一个名为ESP32BLEUart的新项目文件夹,并进入该文件夹。

    2. 编写代码

使用你喜欢的文本编辑器打开ESP32BLEUart.ino文件,复制粘贴以下代码:

 #include <BLEDevice.h> 
 #include <BLEServer.h>
 #include <BLEUtils.h> 
 #include <BLE2902.h>

 #define SERVICE_UUID     "C0000001-C000-6666-8888-314159260732" // UART service UUID 
 #define CHARACTERISTIC_UUID_RX "C0000002-C000-6666-8888-314159260732" 
 #define CHARACTERISTIC_UUID_TX "C0000003-C000-6666-8888-314159260732"


 BLEServer *pServer = NULL; 
 BLECharacteristic *pTxCharacteristic;
 bool deviceConnected = false;


 class ServerCallbacks: public BLEServerCallbacks {
     void onConnect(BLEServer* pServer) {
         deviceConnected = true;
         Serial.println("Device connected");
     }

     void onDisconnect(BLEServer* pServer) {
         deviceConnected = false;
         Serial.println("Device disconnected");
     }
 };

 class RxCallbacks: public BLECharacteristicCallbacks {
     void onWrite(BLECharacteristic *pCharacteristic) {
         String rxValue = pCharacteristic->getValue().c_str();
         if (rxValue.length() > 0) {
             Serial.write(rxValue.c_str(), rxValue.length());
         }
     }
 };

 void setupBLE() {
     BLEDevice::init("COONEO_BLE_UART");
     pServer = BLEDevice::createServer();
     pServer->setCallbacks(new ServerCallbacks());

     BLEService *pService = pServer->createService(SERVICE_UUID);

     pTxCharacteristic = pService->createCharacteristic(                         
                             CHARACTERISTIC_UUID_TX,
                             BLECharacteristic::PROPERTY_NOTIFY
                         );
     pTxCharacteristic->addDescriptor(new BLE2902());

     BLECharacteristic *pRxCharacteristic = pService->createCharacteristic(                
                                             CHARACTERISTIC_UUID_RX,                                             
                                             BLECharacteristic::PROPERTY_WRITE
                                         );
     pRxCharacteristic->setCallbacks(new RxCallbacks());

     pService->start();

     BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
     pAdvertising->addServiceUUID(SERVICE_UUID);
     pAdvertising->setScanResponse(true);
     pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue     
     pAdvertising->setMinPreferred(0x12);
     BLEDevice::startAdvertising();

     Serial.println("BLE device initialized and advertising");
 }

 void setup() {
     Serial.begin(115200);
     while (!Serial) {
         ; // 等待串口连接
     }
     Serial.println("Serial started");

     setupBLE();
     Serial.println("BLE UART Transparent Transmission Ready");
 }

 void loop() {
     if (deviceConnected && Serial.available()) {
         size_t len = Serial.available();
         uint8_t buffer[128];
         len = Serial.readBytes(buffer, min(len, sizeof(buffer)));         
         pTxCharacteristic->setValue(buffer, len);
         pTxCharacteristic->notify();
     }

     // 如果设备未连接,每5秒重新开始广播
     static unsigned long lastAdvertisingTime = 0;
     if (!deviceConnected && millis() - lastAdvertisingTime > 5000) {         
         BLEDevice::startAdvertising();
         Serial.println("Restarting advertising");
         lastAdvertisingTime = millis();
     }

     delay(10);
 }

这段代码实现了一个BLE UART服务,可以通过BLE与手机端App进行双向通信。它会将手机发送给BLE的数据转发给ESP32的串口,同时将ESP32收到的串口输入转发至BLE。

    3. 编译项目

现在我们可以使用arduino-cli编译这个项目:

arduino-cli compile --fqbn esp32:esp32:esp32 ./

注意将 esp32:esp32:esp32 替换为你的ESP32开发板对应的FQBN。编译过程可能需要一些时间。

    4. 上传项目

编译完成后,将ESP32通过USB连接到电脑,然后使用以下命令上传程序:

arduino-cli upload -p /dev/ttyUSB0 --fqbn esp32:esp32:esp32c6 ./

将 COM3 替换为ESP32在你电脑上的实际端口号。同样注意FQBN要与编译时一致。

    5. 串口监视器

上传完成后,可以使用以下命令打开串口监视器:

arduino-cli monitor -p /dev/ttyUSB0 -c baudrate=115200

这样就可以看到ESP32输出的调试信息了。

    6. 测试BLE通信

现在可以使用手机上的BLE调试App(如nRF Connect)连接到ESP32,通过读写特征值进行通信测试。ESP32可以接收串口输入并通过BLE广播出数据,你发送的任何内容ESP32也会通过串口打印出来。

至此,我们就使用Arduino-CLI完成了一个ESP32 BLE串口透传示例的开发过程。你可以在此基础上进一步开发,实现更多有趣的BLE应用。

如果还有任何疑问,欢迎继续交流!

欢迎加入我们的交流群,该群面向热爱机器人研发的朋友们,方便大家一起学习、分享、交流智能机器人创造,结识更多志同道合的小伙伴。更有不定期的社区专属福利哦!关注公众号或在对话送发送“入群”,即可获取入群方式。

内容:TR

排版:SS

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值