本帖最后由 云天 于 2026-2-5 11:48 编辑
最近在 DF 创客商城入手了刚上架的Arduino UNO Q ,开箱上手、调试编程的整个过程充满惊喜,不仅系统学习了 Linux 嵌入式、边缘 AI、双核心协同等前沿知识,还解锁了从传统单片机控制到智能视觉、语音识别的全新创作路径,无数创意点子在脑海里迸发。这块集经典兼容、Linux 系统、本地 AI、实时控制于一体的全能开发板,彻底打破了传统 Arduino 的性能边界,成为我手边又一件高效、好用、潜力无限的创客制作利器,未来的智能小车、环境监测站、交互装置、AI 小机器人 都有了更强大的硬件底座!
【Arduino UNO Q 简介】
Arduino UNO Q 是 Arduino 新一代高性能全能型开发板 ,专为创客、学生、开发者打造,既保留经典 UNO 的易用性,又搭载 “双大脑”,一步迈入 Linux 与边缘 AI 时代,是新手进阶、老玩家升级的首选主力板。
双核心 “神仙组合”
一边是STM32U585 实时单片机,精准控灯、舵机、传感器,延迟极低、稳如老狗;另一边是高通四核处理器,跑完整 Debian Linux,能跑 Python、跑 AI 模型、连 WiFi / 蓝牙,相当于把 “微型电脑 + 经典 Arduino” 焊在一块板上。 自带 Linux 系统,不用外接电脑也能开发
板载 2GB/4GB 内存 + 16GB/32GB 存储,预装 Linux 系统,可直接在板上运行 Arduino IDE、写代码、跑程序,接显示器鼠标就能当迷你开发机用,外出调试超方便。 原生支持边缘 AI,本地就能做人脸 / 物体识别
不用上云、不依赖服务器,本地直接跑目标检测、图像分类、关键词识别,做智能门禁、跟随机器人、语音交互装置门槛大幅降低。 完美兼容经典 UNO 生态
保留标准 UNO 接口尺寸,你手里现有的传感器、扩展板、模块直接插就能用,老项目无缝迁移,新项目直接起飞。 接口现代、联网齐全
标配USB-C(支持 PD 供电)、Qwiic 快连接口、高速 GPIO,自带WiFi 5 + 蓝牙 5.1,物联网、远程控制、无线传输一步到位。
它是能跑 Linux、能玩 AI、能精准控制硬件、兼容所有 UNO 配件的下一代 Arduino,从小白入门到高阶智能创作,一块板全覆盖,是当前最值得入手的创客全能神器。
【Arduino IDE】
Arduino UNO Q 兼容标准 Arduino IDE,可使用你熟悉的 Arduino 语言与生态系统对开发板进行编程。(Arduino UNO Q 搭载 双处理器:Arduino IDE 只能编程其中的 STM32 微控制器;如果要开发高通处理器部分,可使用 Arduino App Lab 。)
测试:使用点阵屏播放“Bad Apple”
1.安装 UNO Q 开发板核心
手动添加安装包啦。操作步骤:打开「文件」>「首选项」,把下面这个链接粘贴到「附加开发板管理器网址」的输入框里:
https://downloads.arduino.cc/packages/package_zephyr_index.json 复制代码 2.程序代码
使用UNO Q的”Arduino_LED_Matrix”——“video”示例
#include "Arduino_LED_Matrix.h"
#include "bad_apple.h"
Arduino_LED_Matrix matrix;
void setup() {
matrix.begin();
matrix.setGrayscaleBits(8);
}
void loop() {
matrix.playVideo(bad_apple, bad_apple_len);
} 复制代码
3.演示视频
【Arduino App Lab 】
Arduino App Lab 是一款一站式开发工具,把咱们熟悉的 Arduino 玩法拓展到了高性能计算领域。用它可以把 Arduino 代码、Python 脚本和 Linux 容器应用完美融合,全程开发不用来回切换工具。
它自带「Bricks(代码积木)」、现成的 AI 模型,以及集成化的任务编排功能,能做出从简单小原型到高算力复杂应用的各种作品,新手也能轻松上手。
根据官网操作文档, 下载Arduino App Lab,安装并连接UNO Q。
踩坑指南
1.Arduino App Lab卡在“检查更新”界面,这可能是由开发板固件版本过低 引起的。
按照官方指南使用arduino-flasher-cli工具重刷最新固件。
2.准备硬件时需要用一个母对母跳线短接两个特定引脚 ,其目的是让UNO Q进入特殊的刷机模式(类似“下载模式”或“恢复模式”),以便后续连接电脑刷写固件。
【示例体验】
1.“UNO Q Pin Toggle”
你可通过简洁的交互式开发板可视化界面,在浏览器中控制 Arduino UNO Q 的每一个引脚。拨动开关即可切换引脚的通断状态,且所有状态变化会实时反馈显示。本示例展示了一套简洁易用的实时控制面板,你可在此基础上扩展为功能更丰富的监控仪表盘与自动化控制系统。
2.“Weather forecast on LED matrix”
修改示例ino文件,在原单一显示程序中指定的城市天气,实现通过按钮切换多个城市天气显示。
// SPDX-FileCopyrightText: Copyright (C) ARDUINO SRL ([url]http://www.arduino.cc[/url])
//
// SPDX-License-Identifier: MPL-2.0
#include <Arduino_LED_Matrix.h>
#include <Arduino_RouterBridge.h>
#include "weather_frames.h"
// 1. 定义7个中国主要城市列表(拼音,适配open-meteo API)
String cities[] = {"Zhangjiakou","Beijing", "Shanghai", "Guangzhou", "Shenzhen", "Chengdu", "Chongqing"};
// 当前选中的城市索引(初始为0,对应张家口)
int currentCityIndex = 0;
// 城市总数
const int cityCount = sizeof(cities) / sizeof(cities[0]);
// 按钮相关定义
const int BUTTON_PIN = 4; // 按钮接引脚4
bool lastButtonState = LOW; // 上一次按钮状态(初始低电平)
unsigned long lastDebounceTime = 0; // 消抖时间记录
const unsigned long debounceDelay = 50; // 消抖延时(50ms)
Arduino_LED_Matrix matrix;
void setup() {
// 初始化LED点阵屏
matrix.begin();
matrix.clear();
// 初始化Bridge通信
Bridge.begin();
// 初始化按钮引脚(上拉输入模式,无需外接上拉电阻)
pinMode(BUTTON_PIN, INPUT_PULLUP);
// 启动时显示第一个城市(张家口)的天气
updateWeatherForecast();
}
void loop() {
// 检测按钮按下并切换城市
checkButtonPress();
// 持续播放当前城市的天气动画(无需频繁调用API,避免限流)
matrix.playSequence();
}
// 检测按钮按下(带消抖),切换城市并更新天气
void checkButtonPress() {
// 读取当前按钮状态(INPUT_PULLUP模式下,按下为HIGH,松开为LOW) 复制代码
【马到成功】
新年“马上”就要到了,马年祝大家,事事顺意,马到成功。
1.“LED Matrix Painter”
LED 矩阵绘制器示例提供了一个基于网页的交互界面,可实时绘制、制作动画并控制 Arduino UNO Q 内置的 LED 点阵屏。该工具具备像素编辑功能(支持 3 位色深 / 0-7 级亮度调节)、设计方案的数据库存储功能,还内置代码生成器,可将你设计的帧动画导出为可直接使用的 C++ 代码。
该应用支持你直接在浏览器中为 8×13 LED 点阵屏设计视觉效果。它借助 web_ui 功能模块搭建了一个图形化编辑器,你可在其中绘制单个像素点、调节像素亮度,还能对图案执行翻转、旋转等变换操作。你在浏览器中做出的每一处修改,都会即时同步到物理开发板上呈现。
演示视频
2.修改示例,实现一键“平移动画生成器”
它会根据当前编辑的图案,自动生成从左到右移动的多帧动画。
1) 首先在 HTML 中添加按钮在 index.html 文件中的 animation-options 部分添加一个新按钮:
<button id="generate-horizontal" class="anim-option-btn" title="生成水平移动动画"> <img src="img/arrow-right.svg" alt="水平移动" style="width: 16px; height: 16px;">
</button> 复制代码 2)在 CSS 中添加样式
在 style.css 中添加按钮样式:
/* 为生成动画按钮添加样式 */
#generate-horizontal {
border: 1px solid #C9D2D2;
border-radius: 8px;
padding: 6px;
background-color: transparent;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: #2C353A;
}
#generate-horizontal:hover {
background-color: rgba(0, 129, 132, 0.08);
}
#generate-horizontal img {
width: 16px;
height: 16px;
} 复制代码 3) 在 JavaScript 中实现核心功能 在 app.js 中添加以下代码:
// 获取生成水平移动动画的按钮
const generateHorizontalBtn = document.getElementById('generate-horizontal');
// 生成水平移动动画的函数
async function generateHorizontalAnimation() {
if (loadedFrameId === null) {
showError('请先选择一个帧作为基础图案');
setTimeout(hideError, 3000);
return;
}
// 询问用户要生成多少帧
const frameCountInput = prompt('请输入要生成的帧数(建议 13-39 帧,数字越大动画越流畅):', '26');
if (!frameCountInput) return;
const count = parseInt(frameCountInput, 10);
if (isNaN(count) || count < 5) {
showError('请输入至少 5 帧');
setTimeout(hideError, 3000);
return;
}
try {
// 获取当前帧的图案
const currentGrid = collectGridBrightness();
// 计算动画参数
// 图案宽度为 COLS (13列)
// 为了让图案从左侧外出现到右侧外消失,总共需要移动 COLS + 当前帧宽度步数
// 但实际上我们让图案从左侧外完全看不到,到完全进入,再到完全出去
const patternWidth = COLS; // 图案宽度
const totalMovement = patternWidth + COLS; // 完全进入 + 完全出去需要的步数
// 创建保存所有新帧的数组
const newFrames = [];
// 生成每一帧
for (let i = 0; i < count; i++) {
// 计算当前帧的偏移量
// 从完全在左侧外(-COLS)开始,到完全在右侧外(+COLS)结束
const progress = i / (count - 1); // 0 到 1 的进度
const offset = Math.floor(-COLS + progress * (2 * COLS));
// 创建新帧的图案
const newRows = [];
for (let r = 0; r < ROWS; r++) {
const newRow = [];
for (let c = 0; c < COLS; c++) {
// 计算图案中对应的列
const sourceCol = c - offset;
// 如果源列在图案范围内,则使用图案的值,否则为0
if (sourceCol >= 0 && sourceCol < patternWidth) {
newRow.push(currentGrid[r][sourceCol]);
} else {
newRow.push(0);
}
}
newRows.push(newRow);
}
// 添加新帧到数组
newFrames.push({
rows: newRows,
name: `水平移动 ${i + 1}/${count}`,
duration_ms: Math.max(30, Math.floor(1000 / count)) // 根据帧数计算合适的时长
});
}
// 批量保存所有新帧
for (let i = 0; i < newFrames.length; i++) {
const frame = newFrames[i];
await fetchWithHandling('/persist_frame', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
rows: frame.rows,
name: frame.name,
duration_ms: frame.duration_ms,
brightness_levels: BRIGHTNESS_LEVELS
})
}, 'json', `保存第 ${i + 1} 帧`);
}
// 刷新帧列表
await refreshFrames();
// 加载第一帧
if (sessionFrames.length > 0) {
// 找到最新创建的帧(最后保存的那个)
const latestFrame = sessionFrames[sessionFrames.length - 1];
// 但我们需要找到水平移动动画的第一帧
const horizontalFrames = sessionFrames.filter(f => f.name.startsWith('水平移动'));
if (horizontalFrames.length > 0) {
await loadFrameIntoEditor(horizontalFrames[0].id);
}
}
showError(`成功生成 ${count} 帧水平移动动画!`);
setTimeout(hideError, 3000);
} catch (error) {
console.error('生成水平移动动画失败:', error);
showError('生成动画失败: ' + error.message);
setTimeout(hideError, 5000);
}
}
// 为按钮添加事件***
if (generateHorizontalBtn) {
generateHorizontalBtn.addEventListener('click', generateHorizontalAnimation);
} 复制代码 4)演示视频