Logo
活死人の行知路

Arduino IDE 安装


📅 | 📝 1468 字
#Arduino #IDE #embedded

这是 Arduino IDE 安装与使用笔记的卡片盒笔记集合。每张卡片独立成篇,卡片之间通过 #锚点 互联。 遵循卢曼卡片盒笔记法:一张卡片 = 一个想法,用你自己的话写,像教别人一样。


学习大纲:从"下载软件"到"点亮第一颗灯"

一句话:本笔记按一条主线循序渐进——装好工具 → 认识界面 → 建好项目 → 理解程序结构 → 跑通第一个程序。

逻辑链条总览

① 下载 Arduino IDE
   │  装好工具才有得玩
   ▼
② 认识 IDE 界面
   │  工具栏 / 编辑区 / 状态栏各是啥
   ▼
③ 新建 sketch + 选开发板
   │  第一步创建项目并指定板子
   ▼
④ C 语言 → Arduino 代码转换
   │  main() 拆成 setup() + loop()
   ▼
⑤ 跑第一个程序:LED 闪烁
   │  编译 ✅ → 上传
   ├────────────────────────────┐
   ▼                            ▼
 上传报错①:端口找不到        上传报错②:速率过高崩溃
   │  Could not open port       │  chip stopped responding
   │  重新选端口                 │  921600 → 115200
   └──────────────┬─────────────┘
                  ▼
           🎉 板上 LED 亮起来

每一站:抛出的问题 → 你要掌握的答案

站你要问自己的问题答案在哪张卡片
① 怎么开始?从哪下载?选哪个版本?下载 Arduino IDE
② 装完怎么用?界面哪块是工具栏?代码写在哪?认识 IDE 界面
③ 第一个项目?怎么新建 sketch?怎么选 ESP32-S3?新建 sketch 与选开发板
④ 代码怎么写?C 和 Arduino 的入口函数差在哪?C 语言 → Arduino 代码转换
⑤ 怎么验证环境通?第一个程序怎么编译、上传?ESP32-S3 第一个程序
⑥ 上传报错怎么办?Could not open port 是什么?怎么解决?端口找不到/被占用
⑦ 端口对了还报错?chip stopped responding 是什么?上传速率过高崩溃

怎么用这个大纲

  • 自学:先看大纲掌握全貌 → 再逐张卡片深入 → 学完回到大纲确认"每条链我都懂了"
  • 讲给别人:照着流程讲——每站先抛出问题,再展开卡片里的答案;遇到上传报错正好是现成的故障案例

卡片索引

卡片类型说明
下载 Arduino IDE操作卡官网下载与版本选择
认识 IDE 界面概念卡默认打开界面长什么样
新建 sketch 与选开发板操作卡第一步创建项目并指定板子
C 语言 → Arduino 代码转换概念卡从 main() 到 setup()/loop()
ESP32-S3 第一个程序操作卡LED 闪烁:验证编译 + 上传
端口找不到/被占用故障卡Could not open port 排查
上传速率过高崩溃故障卡chip stopped responding 排查

操作卡:下载 Arduino IDE

一句话:去官网下载最新版,装完就能写代码。

下载地址

Arduino IDE 官方下载页

本文使用版本:Arduino IDE 2.3.9。

Arduino 官网下载页

👉关联卡


概念卡:认识 IDE 界面

一句话:Arduino IDE 2.x 的默认界面就是一个「编辑器 + 状态栏」,左上角是操作按钮。

默认打开界面

Arduino IDE 默认界面

界面核心区域

区域作用
左侧边栏库管理器、开发板管理器等
顶部工具栏验证 ✓、上传 →、选择开发板
编辑区写代码的地方
底部状态栏编译/上传进度、错误信息

👉关联卡


操作卡:新建 sketch 与选开发板

一句话:File -> New Sketch 新建项目,再从开发板管理器选对板子,不然编译会报错。

Step 1:新建 sketch

  • 菜单栏:File → New Sketch

Step 2:选择开发板

  1. 点击顶部工具栏的选择开发板下拉框 择开发板
  2. 搜索你的板子型号(本文用 ESP32-S3),如搜索 esp32s3 dev,选择第一个即可

搜索开发板

⚠️ 第一次选 ESP32 板子时,可能需要先在「开发板管理器」里安装 ESP32 支持包,否则搜不到。

👉关联卡


概念卡:C 语言 → Arduino 代码转换

一句话:C 语言从 main() 开始,Arduino 把入口拆成 setup()(跑一次)和 loop()(反复跑)。

两种程序结构对比

C 语言版(PC 上跑):

#include <stdio.h>

// 程序入口函数(所有C语言程序都从main()函数开始执行)
int main() {
   // 格式化输出函数,向控制台打印指定内容,\n表示换行符
   printf("Hello World!\n");
   printf("欢迎开始学习C语言!\n");

   // main函数返回0,表示程序正常结束
   return 0;
}

Arduino 版(板子上跑):

// Arduino程序不需要独立的main函数
// setup()函数在板子启动时执行一次
void setup() {
   // 初始化串口通信,设置波特率为9600
   Serial.begin(9600);

   // 打印信息到串口监视器
   Serial.println("Hello World!");
   Serial.println("欢迎开始学习 Arduino 语言!");
}

// loop()函数在setup()执行完后会不断循环执行
void loop() {
   // 这里什么都不做,因为只需要输出一次信息
   // 如果希望重复输出,可以在这里添加代码
}

核心差异

对比项C 语言Arduino
入口函数main()隐式入口
初始化一次main 开头写setup()
反复执行需要手动循环loop() 自动循环
输出方式printf()Serial.println()
运行环境PC 控制台嵌入式板子

验证编译

写完后点击 验证 ✓(Verify) 按钮,通过后会显示编译成功。

Verify 验证结果

👉关联卡

操作卡:ESP32-S3 第一个程序

一句话:把官方示例(LED 闪烁)烧进板子,第一次成功点亮板载 LED = 环境通了。

示例代码(官方自带)

打开 Arduino IDE 自带的实例:File → Examples → 01.Basics → Blink,或直接新建 sketch 粘贴下面代码:

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, HIGH);  // change state of the LED by setting the pin to the HIGH voltage level
  delay(1000);                      // wait for a second
  digitalWrite(LED_BUILTIN, LOW);   // change state of the LED by setting the pin to the LOW voltage level
  delay(1000);                      // wait for a second
}

代码拆解

代码作用
pinMode(LED_BUILTIN, OUTPUT)把板载 LED 引脚设为输出模式
digitalWrite(LED_BUILTIN, HIGH)点亮 LED(HIGH = 高电平)
delay(1000)停 1 秒
digitalWrite(LED_BUILTIN, LOW)熄灭 LED(LOW = 低电平)
循环执行亮 1 秒 → 灭 1 秒 → 循环

验证编译

写完后点击**验证 ✓(Verify)**按钮,通过后会显示编译成功。

Verify 验证结果

编译通过后,点击**上传 →(Upload)**按钮,把程序烧到板子上。

如果上传时报错,见下面的两张故障卡:#端口找不到/被占用、#上传速率过高崩溃。

👉关联卡


故障卡:端口找不到/被占用

一句话:Could not open port = Arduino 没找到你的板子,多半是端口选错了,重新选一下就好。

报错现象

点上传后,看到这样的输出:

Sketch uses 300960 bytes (22%) of program storage space. Maximum is 1310720 bytes.
Global variables use 21992 bytes (6%) of dynamic memory, leaving 305688 bytes for local variables. Maximum is 327680 bytes.
esptool v5.3.0
Serial port /dev/cu.usbmodem1101:

A fatal error occurred: Could not open /dev/cu.usbmodem1101, the port is busy or doesn't exist.
([Errno 2] could not open port /dev/cu.usbmodem1101: [Errno 2] No such file or directory: '/dev/cu.usbmodem1101')

Hint: Check if the port is correct and ESP connected

Failed uploading: uploading error: exit status 2

错误含义

关键信息在这一行:

A fatal error occurred: Could not open /dev/cu.usbmodem1101, the port is busy or doesn't exist.
  • Serial port /dev/cu.usbmodem1101: — Arduino 当前选中的端口
  • Could not open ... doesn't exist — 这个端口根本打不开/不存在

最常见原因:端口号变了

ESP32-S3 每次重新插拔后,Mac 分配的端口号可能会变(比如从 usbmodem1101 变成了 usbmodem1201)。

你上次选的端口号是 usbmodem1101,但这次板子插上后变成了另一个端口,Arduino 还指着旧端口,自然打不开。

解决步骤

  1. 去 Arduino IDE 顶部菜单栏点击 Tools(工具)→ Port(端口)
  2. 看看有没有新的 /dev/cu.usbmodemXXXX
  3. 重新选中它,然后再上传

重新选择端口

👉关联卡


故障卡:上传速率过高崩溃

一句话:The chip stopped responding = 烧录时芯片被"噎住"了,把上传速率从 921600 降到 115200 就好。

报错现象

端口选对后,上传还是失败,输出一串 Traceback:

Sketch uses 300960 bytes (22%) of program storage space. Maximum is 1310720 bytes.
Global variables use 21992 bytes (6%) of dynamic memory, leaving 305688 bytes for local variables. Maximum is 327680 bytes.
esptool v5.3.0
Serial port /dev/cu.usbserial-110:
Connecting.....
Connected to ESP32-S3 on /dev/cu.usbserial-110:
Chip type:          ESP32-S3 (QFN56) (revision v0.2)
Features:           Wi-Fi, BT 5 (LE), Dual Core + LP Core, 240MHz, Embedded PSRAM 8MB (AP_3v3)
Crystal frequency:  40MHz
MAC:                28:84:85:4b:4d:d0

Uploading stub flasher...
Running stub flasher...
Traceback (most recent call last):
  File "esptool/__init__.py", line 1362, in _main
  File "esptool/__init__.py", line 1256, in main
  File "esptool/cli_util.py", line 346, in __call__
  File "rich_click/rich_command.py", line 402, in __call__
  File "click/core.py", line 1524, in __call__
  File "rich_click/rich_command.py", line 216, in main
  File "click/core.py", line 1912, in invoke
  File "click/core.py", line 1308, in invoke
  File "click/core.py", line 877, in invoke
  File "click/decorators.py", line 34, in new_func
  File "esptool/__init__.py", line 822, in write_flash_cli
  File "esptool/cmds.py", line 1776, in attach_flash
  File "esptool/cmds.py", line 1637, in _verify_flash_connection
  File "esptool/loader.py", line 1964, in read_spiflash_sfdp
  File "esptool/loader.py", line 1917, in run_spiflash_command
  File "esptool/loader.py", line 977, in read_reg
  File "esptool/loader.py", line 637, in check_command
  File "esptool/loader.py", line 567, in command
  File "esptool/loader.py", line 503, in read
StopIteration

A fatal error occurred: The chip stopped responding.
Stub flasher running.
Changing baud rate to 921600...
Changed.


Hard resetting via RTS pin...
Failed uploading: uploading error: exit status 2

错误含义

看最后两行关键信息:

A fatal error occurred: The chip stopped responding.
  • 板子其实已经连上了(Connected to ESP32-S3)
  • 但在烧录过程中芯片不再响应(The chip stopped responding)
  • 日志里 Changing baud rate to 921600... 暴露了问题:波特率太高

这种情况在 ESP32-S3 上很常见,通常是因为通信速率过高或主板参数设置错误导致的。

为什么速率太高会失败

默认的 921600 波特率对某些开发板上的 USB 串口芯片(如 CH340)或者稍微劣质的数据线来说太快了,导致数据丢包、芯片死机。

解决步骤(按顺序尝试)

1. 降低上传速率(最常见解法)

  • 在 Arduino IDE 顶部菜单栏点击 Tools(工具)
  • 找到 Upload Speed(上传速率)
  • 将它从默认的 921600 降低到 115200
  • 再次尝试上传

2. 换一根数据线 / 换一个 USB 口

劣质数据线或前置 USB 口供电不稳,都可能丢包。

降速后成功:完整日志对比

把速率降到 115200 后,上传一路绿灯:

Sketch uses 300960 bytes (22%) of program storage space. Maximum is 1310720 bytes.
Global variables use 21992 bytes (6%) of dynamic memory, leaving 305688 bytes for local variables. Maximum is 327680 bytes.
esptool v5.3.0
Serial port /dev/cu.usbserial-110:
Connecting.....
Connected to ESP32-S3 on /dev/cu.usbserial-110:
Chip type:          ESP32-S3 (QFN56) (revision v0.2)
Features:           Wi-Fi, BT 5 (LE), Dual Core + LP Core, 240MHz, Embedded PSRAM 8MB (AP_3v3)
Crystal frequency:  40MHz
MAC:                28:84:85:4b:4d:d0

Uploading stub flasher...
Running stub flasher...
Stub flasher running.

Configuring flash size...

Writing '/Users/finnley/Library/Caches/arduino/sketches/ABCC6EC8669EE1E66CF526C95804CB3F/led.ino.bootloader.bin' at 0x00000000...
Flash will be erased from 0x00000000 to 0x00004fff...
Compressed 19984 bytes to 13014...

Writing at 0x00000000 [                              ]   0.0% 0/13014 bytes... 

Writing at 0x00004e10 [==============================] 100.0% 13014/13014 bytes... 
Wrote 19984 bytes (13014 compressed) at 0x00000000 in 1.4 seconds (112.8 kbit/s).
Verifying written data...
Hash of data verified.

Writing '/Users/finnley/Library/Caches/arduino/sketches/ABCC6EC8669EE1E66CF526C95804CB3F/led.ino.partitions.bin' at 0x00008000...
Flash will be erased from 0x00008000 to 0x00008fff...
Compressed 3072 bytes to 146...

Writing at 0x00008000 [                              ]   0.0% 0/146 bytes... 

Writing at 0x00008c00 [==============================] 100.0% 146/146 bytes... 
Wrote 3072 bytes (146 compressed) at 0x00008000 in 0.0 seconds (798.6 kbit/s).
Verifying written data...
Hash of data verified.

Writing '/Users/finnley/Library/Arduino15/packages/esp32/hardware/esp32/3.3.10/tools/partitions/boot_app0.bin' at 0x0000e000...
Flash will be erased from 0x0000e000 to 0x0000ffff...
Compressed 8192 bytes to 47...

Writing at 0x0000e000 [                              ]   0.0% 0/47 bytes... 

Writing at 0x00010000 [==============================] 100.0% 47/47 bytes... 
Wrote 8192 bytes (47 compressed) at 0x0000e000 in 0.0 seconds (2024.2 kbit/s).
Verifying written data...
Hash of data verified.

Writing '/Users/finnley/Library/Caches/arduino/sketches/ABCC6EC8669EE1E66CF526C95804CB3F/led.ino.bin' at 0x00010000...
Flash will be erased from 0x00010000 to 0x00059fff...
Compressed 301104 bytes to 164145...

Writing at 0x00010000 [                              ]   0.0% 0/164145 bytes... 

Writing at 0x0001bd3a [=>                            ]  10.0% 16384/164145 bytes... 

Writing at 0x00028957 [====>                         ]  20.0% 32768/164145 bytes... 

Writing at 0x0002e237 [=======>                      ]  29.9% 49152/164145 bytes... 

Writing at 0x00033f9d [==========>                   ]  39.9% 65536/164145 bytes... 

Writing at 0x000397c3 [=============>                ]  49.9% 81920/164145 bytes... 

Writing at 0x0003f1a6 [================>             ]  59.9% 98304/164145 bytes... 

Writing at 0x00044a59 [===================>          ]  69.9% 114688/164145 bytes... 

Writing at 0x0004d642 [======================>       ]  79.9% 131072/164145 bytes... 

Writing at 0x000534c1 [=========================>    ]  89.8% 147456/164145 bytes... 

Writing at 0x00059687 [============================> ]  99.8% 163840/164145 bytes... 

Writing at 0x00059830 [==============================] 100.0% 164145/164145 bytes... 
Wrote 301104 bytes (164145 compressed) at 0x00010000 in 16.2 seconds (148.7 kbit/s).
Verifying written data...
Hash of data verified.

Hard resetting via RTS pin...

看到 Writing ... 100.0%、Wrote ... bytes、Hash of data verified.、Hard resetting via RTS pin... 全部完成,说明程序成功烧入。

这段日志非常完美,没有任何报错。你可以看到进度条一路走到了 100.0%,并且每写完一部分都会提示 Hash of data verified(数据校验通过),最后一句 Hard resetting via RTS pin... 说明电脑已经给板子发了重启指令,你的程序(led.ino)现在已经在板子上跑起来了。如果你上传的是一个控制 LED 闪烁的程序,现在可以观察板子上的灯是否在闪烁。

效果演示:板载 LED 闪烁

对比:失败 vs 成功

阶段失败(921600)成功(115200)
连接芯片✅ Connected✅ Connected
上传 stub✅ 成功✅ 成功
开始写 Flash❌ StopIteration 崩溃✅ 逐段写入
进度条卡住不动0% → 100%
校验—✅ Hash verified

学习要点:Stub flasher running. 之后立刻 StopIteration,说明是传输中途断掉(速率过高丢包);而 Writing at ... 进度条能走起来、走到 100%,就说明链路是通的。

👉关联卡