CLI toolkit for Unihiker K10 board Arduino programming. Core principle: Follow reference docs exactly—no improvisation.
Firmware Version: 0.9.2
FQBN: UNIHIKER:esp32:k10
TTS firmware requirement: ASR::setAsrSpeed() and ASR::speak() are available only in the Chinese K10 firmware. Before generating, compiling, or troubleshooting speech-synthesis code, confirm that the board/toolchain is using the Chinese firmware. Selecting or restoring CN model data is not, by itself, proof that the installed firmware exposes TTS.
If a sketch uses K10 AI, voice recognition, TTS, face recognition, or OTA partitions, preserve the factory model-data offsets. Read the repository reference references/k10-ai-model-flash.md when available.
Screen refresh policy: always design K10 display code around partial redraws. Full-screen clearing or full-background redraw causes obvious flicker and is uncomfortable; use it only for initialization, page switches, exit cleanup, or when you have measured full-screen refresh above 30 fps.
Before uploading code, ensure your Arduino environment is configured correctly.
For Windows machines with no Arduino tooling installed, use the self-contained offline installer first. The installer bundles arduino-cli.exe, the UNIHIKER K10 BSP, required ESP32-S3 tools, and local libraries.
Known install locations to check, in order:
text
C:\K10A
%USERPROFILE%\K10A
%LOCALAPPDATA%\K10A
%LOCALAPPDATA%\K10Arduino
When one of these directories exists and contains arduino-cli.exe plus arduino-cli.local.yaml, use that local environment instead of assuming arduino-cli is on PATH:
powershell
cd C:\K10A
.\setup-config.bat
.\arduino-cli.exe --config-file .\arduino-cli.local.yaml core list
.\arduino-cli.exe --config-file .\arduino-cli.local.yaml compile --fqbn UNIHIKER:esp32:k10 .\examples\Blink
For user sketches, prefer:
powershell
C:\K10A\compile-sketch.bat "C:\path\to\SketchFolder"
C:\K10A\upload-sketch.bat "C:\path\to\SketchFolder" COM3
If the short-path installer is present, do not ask the user to download BSP/toolchains again unless required files are missing.
在Windows上,skill目录已包含预下载的 arduino-cli.exe,可直接使用:
powershell
# 进入skill脚本目录
cd ~/.agents/skills/unihiker-k10-arduino/scripts
# 验证arduino-cli可用
.\arduino-cli.exe version
# 添加到PATH (PowerShell)
$env:PATH = "$env:PATH;$env:USERPROFILE\.agents\skills\unihiker-k10-arduino\scripts"
# 永久添加到PATH (可选)
[Environment]::SetEnvironmentVariable("PATH", $env:PATH, "User")
bash
# Check if arduino-cli is installed
which arduino-cli
# Check installed version
arduino-cli version
Expected output:
bash
arduino-cli 0.35.0
# Or any version number
If which arduino-cli returns empty or "arduino-cli: not found": Proceed to Step 2.
macOS:
bash
# Download the latest release from GitHub
# Visit: https://github.com/arduino/arduino-cli/releases
# Or use Homebrew
brew install arduino-cli
Linux (Ubuntu/Debian):
bash
# Download the latest release from GitHub
# Visit: https://github.com/arduino/arduino-cli/releases
# Or use apt (may be outdated)
sudo apt install arduino-cli
# Or download the binary and add to PATH
wget https://github.com/arduino/arduino-cli/releases/download/0.35.0/arduino-cli_0.35.0_Linux_64bit.tar.gz
tar -xzf arduino-cli_0.35.0_Linux_64bit.tar.gz
sudo mv arduino-cli /usr/local/bin/
Windows:
powershell
# 方法1: 使用skill自带的arduino-cli (推荐)
# 文件位置: ~/.agents/skills/unihiker-k10-arduino/scripts/arduino-cli.exe
# 方法2: 手动下载
# Visit: https://github.com/arduino/arduino-cli/releases
# Download: arduino-cli_1.2.0_Windows_64bit.zip
# Extract to a folder and add to PATH
The K10 BSP is required for arduino-cli to recognize the Unihiker K10 board.
K10 BSP 依赖 ESP32 Arduino Core。UNIHIKER K10 使用 ESP32 Core 稳定版即可。按网络环境二选一配置:
中国大陆用户(推荐国内镜像)
bash
# K10 BSP — DFRobot 国内 CDN
arduino-cli config add board_manager.additional_urls https://downloadcd.dfrobot.com.cn/UNIHIKER/package_unihiker_index.json
# ESP32 Arduino Core — 稳定版国内镜像
arduino-cli config add board_manager.additional_urls https://jihulab.com/esp-mirror/espressif/arduino-esp32/-/raw/gh-pages/package_esp32_index_cn.json
国外用户(官方源)
bash
# K10 BSP — DFRobot
arduino-cli config add board_manager.additional_urls https://downloadcd.dfrobot.com.cn/UNIHIKER/package_unihiker_index.json
# ESP32 Arduino Core — Espressif official stable index
arduino-cli config add board_manager.additional_urls https://dl.espressif.com/dl/package_esp32_index.json
配置完成后验证:
bash
arduino-cli config dump | grep additional_urls
# 应输出 K10 BSP 与 ESP32 Core URL
bash
# Refresh core index
arduino-cli core update-index
# Install K10 core(约 500MB,首次约 5-10 分钟)
arduino-cli core install UNIHIKER:esp32
# Verify installation
arduino-cli board listall | grep unihiker
Expected output:
text
UNIHIKER:esp32:k10
注意: 即使使用镜像,BSP 包约 500MB 首次仍需较长时间。建议配合 Step 4 的 build_cache 避免反复下载。
Arduino CLI has a built-in compilation cache. For repeated K10 builds, use the official build_cache.* configuration keys and keep build artifacts in a stable directory. This is strongly recommended — without it, every compile rebuilds the entire BSP (~500 MB) from scratch.
Windows PowerShell:
powershell
arduino-cli config set build_cache.path "$env:LOCALAPPDATA\arduino\build-cache"
arduino-cli config set build_cache.compilations_before_purge 0
Linux/macOS:
bash
arduino-cli config set build_cache.path ~/.cache/arduino-build-cache
arduino-cli config set build_cache.compilations_before_purge 0
Use these flags for every compile to get incremental + parallel compilation:
FlagEffect--build-path .arduino-buildKeep intermediate .o files; only recompile changed sources--output-dir buildPut final .bin/ .elf in build/``--build-property "build.partitions=custom"Use project partitions.csv for OTA support--jobs 0Use all CPU cores for parallel compilationbash
arduino-cli compile --fqbn UNIHIKER:esp32:k10 . \
--build-path .arduino-build \
--output-dir build \
--build-property "build.partitions=custom" \
--jobs 0
First compile is still slow (cold cache), but subsequent edits compile in seconds.
compile-otaOne-shot compile + OTA upload using the optimized flags above. Two versions available:
Windows (PowerShell):
powershell
# Compile only
.\compile-ota.ps1 ph_titrator
# Compile + OTA upload
.\compile-ota.ps1 ph_titrator -Ip 192.168.9.42
macOS / Linux (Bash):
bash
# Compile only
./compile-ota.sh ph_titrator
# Compile + OTA upload
./compile-ota.sh ph_titrator -i 192.168.9.42
Scripts located at ~/.agents/skills/unihiker-k10-arduino/scripts/.
Prerequisite: arduino-cli must be in PATH (macOS/Linux) or use the bundled arduino-cli.exe (Windows).
Do not rely on compiler.cache.enable, compiler.cache.path, or ccache as standard K10 setup. They are not part of the current Arduino CLI configuration reference.
After completing Steps 1-4, verify your environment:
bash
# Check arduino-cli
arduino-cli version
# Check K10 board
arduino-cli board listall | findstr unihiker
# Check ports
arduino-cli board list
The K10 BSP can flash built-in AI support files during USB upload. Use this only for initialization or recovery; normal uploads should leave model data alone.
bash
# Normal upload: do not rewrite model partitions
arduino-cli upload -p <PORT> --fqbn UNIHIKER:esp32:k10:Model=None <sketch>
# Refresh Chinese model data
arduino-cli upload -p <PORT> --fqbn UNIHIKER:esp32:k10:Model=Hi_eps <sketch>
# Refresh English model data
arduino-cli upload -p <PORT> --fqbn UNIHIKER:esp32:k10:Model=Ni_hao_xiao_zhi <sketch>
The BSP menu labels are confusing but intentional: Hi_eps is shown as CN, and Ni_hao_xiao_zhi is shown as EN.
CommandDescriptionk10-arduino upload <file.ino>Compile & upload Arduino sketchk10-arduino portsList serial portsk10-arduino doctorEnvironment diagnosticcompile-ota.ps1 <dir> [-Ip <ip>]Optimized compile + optional OTA uploadprepare-offline-bundle.sh <output.tgz>Create USB-distributable Arduino BSP/core bundleinstall-offline-bundle.sh <bundle.tgz>Install a prepared Arduino offline bundledoctor-offline.shCheck whether offline BSP/core files are present
Use an offline bundle when many learners will install or build K10 Arduino projects in the same room. Prepare one bundle per OS/CPU architecture.
The Arduino data directory is platform-specific:
OSArduino data directorymacOS~/Library/Arduino15Linux~/.arduino15Windows%LOCALAPPDATA%\Arduino15
The important installed directories are:
DirectoryPurposepackages/UNIHIKERK10 BSP, K10 Arduino libraries, and required toolspackages/esp32ESP32 Arduino core/toolchain dependency
Teacher-machine preparation:
bash
# Install K10 BSP and ESP32 core first, then:
bash scripts/prepare-offline-bundle.sh /tmp/k10-arduino-bundle.tgz
Student-machine installation:
bash
bash scripts/install-offline-bundle.sh /path/to/k10-arduino-bundle.tgz
bash scripts/doctor-offline.sh
By default, the bundle excludes staging/ download caches because they can be many GB. Use --include-staging only when you intentionally want to distribute raw downloaded archives too:
bash
bash scripts/prepare-offline-bundle.sh /tmp/k10-arduino-full-cache.tgz --include-staging
cpp
#include "unihiker_k10.h"
UNIHIKER_K10 k10;
void setup() {
k10.begin();
k10.initScreen(2); // Screen direction: 0-3
k10.creatCanvas(); // Create canvas object
k10.setScreenBackground(0x000000); // Background color (black)
// Canvas drawing methods (use k10.canvas->)
k10.canvas->canvasSetLineWidth(3);
k10.canvas->canvasLine(0, 0, 100, 100, 0xFFFF00);
k10.canvas->canvasCircle(80, 80, 40, 0x00FF00, 0x0000FF, false);
k10.canvas->updateCanvas(); // Update display
}
void loop() {
// Your code here
}
Important:
.ino file must be in a directory with the same name (e.g., star/star.ino)k10.canvas->, not k10.canvasClear() / 全屏重绘作为循环刷新方案。UNIHIKER:esp32:k10references/arduino-api.mdIssueSolutionarduino-cli: command not foundWindows用户使用skill目录下的arduino-cli.exe,或安装并添加到PATHPlatform 'UNIHIKER:esp32:k10' not found安装K10 BSP: arduino-cli core install UNIHIKER:esp32Can't open sketch: main file missing.ino 文件必须放在同名目录中 (如 star/star.ino)Repeated compile still slowUse stable --build-path, enable official build_cache.*, and avoid --clean unless a full rebuild is requiredClass has no member named 'canvasLine'Canvas方法使用 k10.canvas->,不是 k10.编译错误: No such file or directory检查库依赖,部分库需要手动安装到Documents/Arduino/libraries上传失败/无法连接按住BOOT按钮,按RST重置,释放BOOT进入下载模式屏幕闪烁使用局部刷新,避免每帧调用 canvasClear() 或全屏背景重绘;只有实测全屏刷新超过 30 fps 才可高频全屏刷新**setAsrSpeed / speak missing or TTS does not work语音合成仅存在于中文版固件;确认当前固件版本,不要把刷新 CN 模型数据误当成切换中文版固件Windows PowerShell执行策略限制**运行 Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Skill目录提供多种上传方式:
powershell
# 方法1: PowerShell脚本
.\scripts\upload-arduino.ps1 .\your_sketch\your_sketch.ino
# 方法2: Python脚本
python .\scripts\upload_k10.py .\your_sketch\your_sketch.ino
# 方法3: Batch脚本
.\scripts\upload-k10.bat .\your_sketch\your_sketch.ino
bash
# Bash脚本
bash scripts/upload-arduino.sh ./your_sketch/your_sketch.ino
The upload helpers already compile into a stable sketch-local build/ directory and use all CPU cores when supported by Arduino CLI. For manual builds:
bash
arduino-cli compile --fqbn UNIHIKER:esp32:k10 path/to/sketch \
--build-path path/to/sketch/build \
--jobs 0
Keep build_cache.path configured for long-lived cache reuse:
bash
arduino-cli config set build_cache.path ~/.cache/arduino-build-cache
arduino-cli config set build_cache.compilations_before_purge 0
--clean intentionally skips cached artifacts and should be reserved for suspicious build state or toolchain changes.
K10 的屏幕刷新率有限,频繁的全屏清除 ( canvasClear()) 或全屏背景重绘会导致明显闪烁和卡顿,观感很不舒服。默认必须使用 局部刷新 技术。除初始化、页面切换、退出清理,或实测全屏刷新率超过 30 fps 外,不要在循环动画、传感器数值、状态栏、语音识别状态、OTA 状态等场景使用全局刷新。
核心思想:
示例代码:
cpp
// 保存上一帧位置
int lastX = 0, lastY = 0;
void drawSprite(int x, int y, uint32_t color) {
k10.canvas->canvasCircle(x, y, 10, color, color, true);
}
void eraseSprite(int x, int y) {
// 用背景色填充来擦除
k10.canvas->canvasRectangle(x-12, y-12, 24, 24, COLOR_BG, COLOR_BG, true);
}
void update() {
// 1. 擦除旧位置
eraseSprite(lastX, lastY);
// 2. 更新位置
x += speed;
// 3. 绘制新位置
drawSprite(x, y, 0xFF0000);
// 4. 保存当前位置
lastX = x;
lastY = y;
k10.canvas->updateCanvas();
}
优化建议:
updateCanvas()canvasClear() 或重画全屏背景millis() 或短 delay(33) 限制刷新节奏,避免无意义重复刷新成功的经验:
遇到的问题及解决:
esp32:unihiker 不正确,应使用 UNIHIKER:esp32改进建议:
text
unihiker-k10-arduino/
├── SKILL.md # This file
└── references/ # Arduino API docs
├── arduino-api.md # Arduino C++ API reference
└── arduino-examples.md # Arduino code examples
Manual usage without CLI:
bash
# Upload Arduino
bash path/to/unihiker-k10-arduino/scripts/upload-arduino.sh sketch.ino /dev/cu.usbmodem2201 UNIHIKER:esp32:k10
bash
# 1. Create Arduino sketch in project directory
your_project/
└── your_sketch/
└── your_sketch.ino
# 2. Upload sketch
k10-arduino upload your_project/your_sketch/your_sketch.ino
Screen & Canvas:
Sensors:
RGB LED Control:
Audio:
AI Recognition:
ASR (Speech Recognition):
GPIO:
VCC + 0.3V.Import: #include "unihiker_k10.h"
cpp
k10.initScreen(dir=2, frame=0); // Initialize screen
k10.creatCanvas(); // Create canvas
k10.setScreenBackground(color=0x000000); // Background color
k10.initBgCamerImage(); // Init camera image
k10.setBgCamerImage(sta=true); // Display camera image
// Canvas drawing (use k10.canvas->)
k10.canvas->canvasSetLineWidth(3);
k10.canvas->canvasLine(x1, y1, x2, y2, color); // Draw line
k10.canvas->canvasPoint(x, y, color); // Draw point
k10.canvas->canvasCircle(x, y, r, border, fill, isFill); // Draw circle
k10.canvas->canvasRectangle(x, y, w, h, border, fill, isFill); // Draw rect
k10.canvas->canvasText(text, row, color); // Draw text
k10.canvas->canvasDrawImage(x, y, imagePath); // Draw image
k10.canvas->canvasDrawCode(code); // Draw QR code
k10.canvas->clearCode(); // Clear QR code
k10.canvas->canvasClear(); // Clear canvas
k10.canvas->updateCanvas(); // Update display
cpp
k10.initSDFile(); // Initialize SD card
k10.photoSaveToTFCard(imagePath); // Save photo
k10.playTFCardAudio(path); // Play audio
k10.recordSaveToTFCard(path, time); // Record audio (seconds)
Buttons A/B:
cpp
k10.buttonA->isPressed(); // Check state
k10.buttonA->setPressedCallback(callback); // Press callback
k10.buttonA->setUnPressedCallback(callback); // Release callback
Temperature & Humidity (AHT20):
cpp
AHT20 aht20;
k10.getData(AHT20::eAHT20TempC); // Temperature (°C)
k10.getData(AHT20::eAHT20TempF); // Temperature (°F)
k10.getData(AHT20::eAHT20HumiRH); // Humidity (%RH)
Light Sensor (ALS):
cpp
k10.readALS(); // Light intensity
Accelerometer:
cpp
k10.getAccelerometerX(); // X-axis
k10.getAccelerometerY(); // Y-axis
k10.getAccelerometerZ(); // Z-axis
k10.getStrength(); // Strength
k10.isGesture(Gesture); // Tilt detection (TiltForward, TiltBack, TiltLeft, TiltRight)
Pedometer:
cpp
k10.getStrength(); // Step count
RGB LED:
cpp
k10.write(index, r, g, b); // Set color (0,1,2,-1=all)
k10.setRangeColor(start, end, color); // Set range
k10.brightness(b); // Brightness (0-9)
Audio:
cpp
// Buzzer
k10.playTone(freq, beat); // Play tone (samples: 8000=full, 4000=half)
k10.stopPlayTone(); // Stop tone
k10.playMusic(Melodies, options); // Built-in music
k10.stopPlayAudio(); // Stop audio
// TTS (Chinese firmware only; include "asr.h" and create ASR asr)
asr.setAsrSpeed(speed); // uint8_t, 0-5
asr.speak(text); // String, const char *, or float
Microphone:
cpp
// Recording and playback
k10.recordSaveToTFCard(path, time); // Record to TF card
k10.playTFCardAudio(path); // Play from TF card
Import: #include "AIRecognition.h"
cpp
AIRecognition ai;
ai.initAi(); // Initialize AI
ai.switchAiMode(mode); // Select mode: Face, Cat, Move, Code, NoMode
// Face recognition
ai.sendFaceCmd(ENROLL); // Learn face
ai.sendFaceCmd(RECOGNIZE); // Recognize face
ai.sendFaceCmd(DELETEALL); // Delete all faces
ai.sendFaceCmd(DELETE, id); // Delete specific face ID
int faceId = ai.getRecognitionID(); // Get recognized face ID
int faceData = ai.getFaceData(type); // Get face data (Length, Width, CenterX, CenterY, etc.)
bool recognized = ai.isRecognized(); // Check if recognition complete
// Cat/Dog recognition
int catData = ai.getCatData(type); // Get cat data
// Movement detection
ai.setMotinoThreshold(10); // Set sensitivity (10-200)
// QR code
String qrCode = ai.getQrCodeContent(); // Get scanned QR code
// Content detection
bool detected = ai.isDetectContent(mode);
Import: #include "asr.h"
Do not offer or generate this API for English/international firmware. setAsrSpeed() initializes TTS and sets the speed from 0 to 5; call it before speak().
cpp
#include "asr.h"
#include "unihiker_k10.h"
UNIHIKER_K10 k10;
ASR asr;
void onButtonAPressed();
void onButtonBPressed();
void setup() {
k10.begin();
asr.setAsrSpeed(2);
k10.buttonA->setPressedCallback(onButtonAPressed);
k10.buttonB->setPressedCallback(onButtonBPressed);
asr.speak("你好");
}
void loop() {}
void onButtonAPressed() {
asr.speak("我是行空板");
}
void onButtonBPressed() {
asr.speak("语音合成");
}
API signatures from the bundled K10 asr.h:
cpp
void setAsrSpeed(uint8_t speed); // 0-5
void speak(String prompt);
void speak(const char *prompt);
void speak(float prompt);
Official sources: Arduino/PIO example and Arduino/PIO API list.
Compilable copy: examples/tts-buttons/tts-buttons.ino.
Import: #include "asr.h"
cpp
ASR asr;
// Initialize
asr.asrInit(mode=ONCE|CONTINUOUS, lang=EN_MODE|CN_MODE, wakeUpTime=6000);
// Add commands
asr.addASRCommand(id, "command text");
asr.addASRCommand(id, "拼音文本"); // For Chinese commands
// Check status
bool wakeUp = asr.isWakeUp(); // Wake-up status
bool cmdDetected = asr.isDetectCmdID(id); // Command detected
ASR Constants:
ONCE, CONTINUOUSEN_MODE, CN_MODEP0/P1 (on-board):
cpp
pinMode(P0, OUTPUT); // Set pin mode
digitalWrite(P0, HIGH); // Digital write
digitalRead(P1); // Digital read
analogWrite(P0, value); // PWM output (0-255)
analogRead(P1); // Analog input
Extended GPIO (Edge Connector):
cpp
digital_write(eP2, HIGH); // Digital write
digital_read(eP3); // Digital read
// Note: Extended GPIO is digital I/O only
When a project needs more external analog inputs than P0/P1 provide, recommend the DFRobot Gravity I2C ADS1115 16-bit ADC module (DFR0553). It adds four analog channels over I2C, supports 3.3-5.0V power, and measures 0-VCC. Never let an analog input exceed VCC + 0.3V.
cpp
// K10 library
#include "unihiker_k10.h"
// AI Recognition
#include "AIRecognition.h"
// ASR
#include "asr.h"
// Arduino core
#include <Arduino.h>
See references/arduino-examples.md