【花雕学编程】Arduino BLDC 之基于红外矩阵的静态迷宫求解机器人
本文介绍了一种基于红外传感器和BLDC电机的自主迷宫求解机器人系统。该系统通过红外矩阵传感器检测迷宫路径,采用A*算法进行路径规划,并利用BLDC电机实现精确控制。主要特点包括高效动力系统、精确循线控制、迷宫地图构建和智能路径规划算法。该系统适用于机器人竞赛、教学实验和科研原型开发,需注意内存限制、传感器校准、控制算法优化等问题。文中还提供了一个基于Arduino的入门级实现方案,包含硬件配置和核

这是一个将迷宫求解算法与移动机器人技术相结合的系统。它利用安装在机器人底部或四周的红外传感器阵列来感知迷宫地面的黑白线条(或墙壁与通道的边界),通过精确的电机控制(使用BLDC驱动)和算法逻辑,使机器人能够自主探索迷宫并找到通往终点的最优路径。
一、 主要特点 (Key Features)
高效动力系统 (High-Efficiency Drive System):
核心: 采用BLDC电机及其驱动器(ESC或专用驱动IC)作为机器人的驱动单元。
功能:
高效率: 相比有刷电机,BLDC效率更高,有助于延长机器人在迷宫赛道上的续航时间,这对于需要多次运行(探索和冲刺)的竞赛尤为重要。
高扭矩/功率密度: 能够提供足够的驱动力,确保机器人在遇到轻微摩擦或需要快速加速/减速时仍能稳定运行。
精确控制: 易于实现精确的速度和位置控制,便于实现精确的直行、转弯和原地旋转等动作,提高循线精度和路径规划的准确性。
红外矩阵循线系统 (Infrared Matrix Line Following System):
核心: 由多个红外发射管和接收管(或集成的红外传感器模块)组成阵列,通常水平排列在机器人底盘下方,垂直于前进方向。
工作原理: 红外发射管发出光线,接收管根据反射光强度判断下方是黑色线条(高吸收,低反射)还是白色地面(高反射)。通过阵列中哪个传感器检测到黑线,可以判断机器人相对于黑线的位置偏差。
功能: 提供精确的横向位置反馈,是机器人实现“循线”(Line Following)的基础。传感器数量越多,分辨率越高,对路径的判断越精确。
迷宫地图构建与存储 (Maze Mapping & Storage):
核心: Arduino主控根据循线传感器的反馈和机器人的运动(通过编码器或简单的步数计数)来感知迷宫的结构(墙壁位置、通道走向、交叉路口、死胡同、终点)。
功能: 将探索过程中获得的迷宫信息存储在Arduino的内存(或外部存储器,如果内存不足)中,形成一个内部的迷宫地图。这是后续应用路径规划算法的前提。
迷宫探索与路径规划算法 (Maze Exploration & Path Planning Algorithms):
核心: Arduino运行迷宫探索策略(如右手法则、左手法则、Tremaux算法、递归回溯、强化学习等)来遍历迷宫,直到找到终点。找到终点后,通常会运行路径优化算法(如A*、Dijkstra,或简单的回溯标记最短路径)来计算从起点到终点的最快路径。
功能: 实现从“盲目探索”到“智能寻路”的转变,使机器人能够在后续运行(冲刺)中直接沿着最优路径快速到达终点。
闭环速度与方向控制 (Closed-Loop Speed & Direction Control):
核心: Arduino根据循线传感器的偏差信息,通过PID(比例-积分-微分)或其他控制算法,实时调整左右轮的速度差,实现精确的循线转向(PD控制常用于转向,PID用于速度控制)。
功能: 使机器人能够平滑、稳定地沿着黑线高速行驶,即使在弯道也能保持良好轨迹,减少出错概率。
二、 应用场景 (Application Scenarios)
机器人竞赛 (Robotics Competitions):
用途: 这是该类型机器人最常见的应用场景,如国际Micromouse竞赛(虽然传统上是墙壁感应,但循线版本也有)、全国大学生电子设计竞赛、各类地方性机器人竞速赛等。
价值: 检验学生的嵌入式系统设计、传感器应用、电机控制、算法编程和机械结构设计等综合能力。
教学与实验 (Education & Experimentation):
用途: 作为高等院校自动化、电子信息、计算机、机械工程等相关专业的课程设计、毕业设计或实验项目。
价值: 帮助学生理解传感器融合、闭环控制、路径规划、算法实现等机器人学核心概念。
科研原型 (Research Prototypes):
用途: 作为更复杂自主导航系统的基础研究平台,探索新的循线算法、路径规划策略或控制理论。
价值: 提供一个相对简单、可控的实验环境。
三、 需要注意的事项 (Considerations & Challenges)
Arduino内存限制 (Arduino Memory Limitations):
问题: 经典Arduino(如Uno)的SRAM(约2KB)和Flash(约32KB)对于存储大型迷宫地图(例如16x16或更大的网格)和运行复杂算法(如A*)可能非常紧张。
对策:
优化数据结构: 使用位图(bitmaps)而非字节数组来存储迷宫信息(每个格子用一位表示是否有墙)。
选择更强大主控: 如Arduino Mega 2560(SRAM更大),或ESP32、STM32等具有更大内存和更强处理能力的微控制器。
简化算法: 选择内存占用较少的探索或优化算法。
红外传感器性能与校准 (IR Sensor Performance & Calibration):
问题: 环境光线、地面材质、传感器安装高度、元件个体差异都可能影响传感器的灵敏度和准确性。
对策: 设计稳定的传感器支架,确保安装高度一致;进行现场校准,设置合适的阈值来区分黑白;选择性能稳定、抗干扰能力强的传感器。
循线控制算法与参数调优 (Line Following Control Algorithm & Parameter Tuning):
问题: PID控制器的参数(Kp, Ki, Kd)需要仔细调优,才能使机器人在高速运行时保持稳定循线,既不过冲也不反应迟钝。
对策: 使用Ziegler-Nichols方法或试凑法进行调参;在不同速度下可能需要不同的参数。
机械结构与运动学 (Mechanical Structure & Kinematics):
问题: 机器人的重心、轮距、轴距、轮胎摩擦力、电机响应速度等机械特性直接影响其循线性能和转弯能力。
对策: 进行精心的机械设计,确保结构稳固、重量分布合理;精确测量轮子直径和轮距,用于速度和位置估算。
迷宫探索策略的效率 (Efficiency of Maze Exploration Strategy):
问题: 不同的探索算法(如左手法则可能很慢)在探索时间上差异很大,影响整体成绩。
对策: 选择或设计更高效的探索算法,如结合记忆和优化的策略。
速度与稳定性的平衡 (Balancing Speed & Stability):
问题: 追求高速度容易导致机器人失控、脱线或撞墙,而过分追求稳定则会牺牲时间。
对策: 在不同路段(直道、弯道、交叉口)采用不同的速度策略;优化控制算法和机械结构以支持更高的稳定速度。
BLDC驱动器选择与控制 (BLDC Driver Selection & Control):
问题: 需要选择适合小功率、高精度控制的BLDC驱动器(ESC或专用IC)。标准ESC可能主要用于速度控制,对于需要精确位置/速度协同控制的机器人,可能需要更高级的驱动方案或使用有位置反馈的BLDC+编码器+专用驱动器。
对策: 选择支持精确控制的驱动器,或考虑使用步进电机作为替代(虽然效率可能略低,但控制更直接)。

1、基础红外矩阵+A路径规划(入门级)
功能:通过4x4红外矩阵检测障碍物,构建8x8静态迷宫地图,用A算法计算最短路径,控制BLDC电机差速转向。
硬件:Arduino UNO、2个带霍尔编码器的BLDC电机、L298N驱动器、TCRT5000红外矩阵传感器、OLED显示屏。
代码逻辑:
地图初始化:预设静态迷宫(#代表墙,.代表通道);
A*寻路:优先队列管理Open List,曼哈顿距离作为启发式函数;
电机控制:根据路径方向(上下左右)调整左右轮PWM占空比。
#include <QueuePriority.h> // 优先队列库(需安装)
#include <Adafruit_SSD1306.h>
// 引脚定义
#define IR_ROWS 4, IR_COLS 4 // 红外矩阵行列数
#define MOTOR_LEFT_IN1 D5, MOTOR_LEFT_IN2 D6, MOTOR_LEFT_EN A1
#define MOTOR_RIGHT_IN1 D7, MOTOR_RIGHT_IN2 D8, MOTOR_RIGHT_EN A2
// 全局变量
const int MAZE_SIZE = 8; // 迷宫大小
char maze[MAZE_SIZE][MAZE_SIZE] = { // 预设静态迷宫
{'.', '.', '.', '.', '.', '.', '.', '.'},
{'.', '#', '#', '#', '#', '#', '#', '.'},
{'.', '#', '.', '.', '.', '.', '#', '.'},
{'.', '#', '.', '#', '#', '.', '#', '.'},
{'.', '#', '.', '#', '.', '.', '#', '.'},
{'.', '#', '.', '#', '.', '#', '#', '.'},
{'.', '#', '.', '.', '.', '#', '.', '.'},
{'.', '.', '.', '.', '.', '.', '.', '.'}
};
struct Node { // A*节点结构体
int x, y;
float g, h, f; // g:起点到当前代价, h:启发式函数, f:g+h
Node* parent;
};
bool operator<(const Node& a, const Node& b) { return a.f > b.f; } // 优先队列排序
// A*算法实现
vector<Node> aStar(Node start, Node goal) {
QueuePriority<Node> openList;
set<pair<int, int>> closedList;
start.h = abs(goal.x - start.x) + abs(goal.y - start.y); // 曼哈顿距离
start.f = start.g + start.h;
openList.push(start);
while (!openList.empty()) {
Node current = openList.top(); openList.pop();
if (current.x == goal.x && current.y == goal.y) { // 到达终点
vector<Node> path;
while (current.parent != nullptr) {
path.push_back(current);
current = *current.parent;
}
reverse(path.begin(), path.end());
return path;
}
closedList.insert({current.x, current.y});
// 生成邻居节点(上下左右)
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
for (int i=0; i<4; i++) {
int nx = current.x + dx[i], ny = current.y + dy[i];
if (nx >=0 && nx < MAZE_SIZE && ny >=0 && ny < MAZE_SIZE && maze[nx][ny] != '#') {
if (closedList.find({nx, ny}) == closedList.end()) {
Node neighbor;
neighbor.x = nx; neighbor.y = ny;
neighbor.g = current.g + 1;
neighbor.h = abs(goal.x - nx) + abs(goal.y - ny);
neighbor.f = neighbor.g + neighbor.h;
neighbor.parent = new Node(current);
openList.push(neighbor);
}
}
}
}
return {}; // 无路径返回空
}
// 执行路径(电机控制)
void followPath(vector<Node>& path) {
if (path.empty()) return;
for (Node node : path) {
int dir = getDirection(node.parent->x, node.parent->y, node.x, node.y);
switch (dir) {
case UP: moveForward(150); break; // 前进速度150/255
case DOWN: moveBackward(120); break;
case LEFT: turnLeft(100); break; // 左转速度差
case RIGHT: turnRight(100); break;
}
delay(800); // 每步停留时间
}
}
// 主函数
void setup() {
Serial.begin(9600);
Node start = {0, 0, 0, 0, nullptr}; // 起点(0,0)
Node goal = {MAZE_SIZE-1, MAZE_SIZE-1, 0, 0, nullptr}; // 终点(7,7)
vector<Node> path = aStar(start, goal);
if (!path.empty()) followPath(path);
}
void loop() {}
2、动态更新红外数据+实时避障(进阶级)
功能:实时读取红外矩阵数据更新迷宫地图,结合A算法处理动态障碍物(如人为临时放置的物体)。
硬件:Arduino Mega、8x8红外矩阵传感器、TB6612FNG驱动器、超声波传感器(辅助测距)。
代码逻辑:
实时建图:每秒扫描红外矩阵,标记新障碍物;
重规划机制:当检测到地图变化时,重新计算A路径;
安全校验:超声波检测前方距离,避免碰撞。
#include <NewPing.h>
#include <QueuePriority.h>
// 引脚定义
#define IR_ROWS 8, IR_COLS 8
#define SONAR_TRIG D9, SONAR_ECHO D10
NewPing sonar(SONAR_TRIG, SONAR_ECHO, 200); // 超声波最大测距2m
// 全局变量
char dynamicMaze[MAZE_SIZE][MAZE_SIZE]; // 动态地图
unsigned long lastUpdateTime = 0;
// 更新迷宫地图(基于红外矩阵)
void updateMaze() {
for (int i=0; i<MAZE_SIZE; i++) {
for (int j=0; j<MAZE_SIZE; j++) {
if (readIRSensor(i, j)) { // 读单个红外传感器值
dynamicMaze[i][j] = '#'; // 障碍物
} else {
dynamicMaze[i][j] = '.'; // 通道
}
}
}
}
// 主循环
void loop() {
if (millis() - lastUpdateTime > 500) { // 每500ms更新一次地图
updateMaze();
lastUpdateTime = millis();
}
// 超声波校验:若前方距离<30cm则暂停并重规划
if (sonar.ping_cm() < 30) {
stopMotors();
vector<Node> newPath = aStar(currentPosition, goal);
followPath(newPath);
}
delay(10);
}
3、多传感器融合+视觉辅助(高级级)
功能:结合OpenMV Cam识别迷宫目标(如终点旗帜),红外矩阵检测近距离障碍物,毫米波雷达测距,实现高精度导航。
硬件:Arduino Mega、OpenMV Cam、毫米波雷达MR60B、16x16红外矩阵、双BLDC电机系统。
代码逻辑:
视觉定位:OpenMV识别终点颜色,输出坐标;
雷达校准:毫米波雷达测量目标距离,修正视觉误差;
融合决策:红外数据构建局部地图,A*规划全局路径,最终对准终点。
#include <SoftwareSerial.h>
#include <KalmanFilter.h>
// 串口通信
SoftwareSerial openmvSerial(12, 13); // OpenMV通信端口
SoftwareSerial radarSerial(8, 9); // 雷达通信端口
// 卡尔曼滤波器(融合视觉与雷达数据)
KalmanFilter kf;
float targetX = 0, targetY = 0;
// 解析OpenMV数据(JSON格式:"{x:100,y:200}")
void readVisualData() {
if (openmvSerial.available()) {
String data = openmvSerial.readString();
int x = data.indexOf('x');
int y = data.indexOf('y');
if (x != -1 && y != -1) {
targetX = data.substring(x+2, data.indexOf(',', x)).toFloat();
targetY = data.substring(y+2, data.indexOf(',', y)).toFloat();
}
}
}
// 雷达数据处理
void readRadarData() {
if (radarSerial.available()) {
float distance = radarSerial.parseFloat();
// 用卡尔曼滤波融合视觉与雷达数据
kf.update({targetX, targetY});
kf.predict();
targetX = kf.statePost[0];
targetY = kf.statePost[1];
}
}
// 主循环
void loop() {
readVisualData();
readRadarData();
// 根据融合后的坐标更新A*目标点
Node goal = {int(targetX), int(targetY), 0, 0, nullptr};
vector<Node> path = aStar(currentPosition, goal);
followPath(path);
delay(100);
}
要点解读
- A*算法的关键设计
启发式函数选择:曼哈顿距离(适合网格迷宫)、欧几里得距离(适合连续空间);
Open List实现:优先队列(QueuePriority库)保证每次取出最小f(n)节点;
Closed List优化:用哈希集合(set<pair<int, int>>)快速判断节点是否已访问。 - 红外矩阵的使用技巧
消抖处理:机械抖动会导致误触发,需在软件中加入延时或多次采样取平均;
布局策略:将红外传感器均匀分布在机器人四周(前/后/左/右),确保全方位检测;
阈值校准:调节TCRT5000的电位器,使白色地面与黑色障碍物的反射光强差异明显。 - BLDC电机的控制难点
速度闭环:利用霍尔编码器的脉冲信号计算转速,通过PID调节PWM占空比稳定速度;
差速转向:左右轮独立调速,转弯时内外侧车轮速度差与转向半径成反比;
堵转保护:监测电流突变(INA219模块),超过阈值时切断电源并报警。 - 动态环境的适应性
增量式重规划:仅当检测到地图变化时才重新计算A路径,减少计算量;
多层避障策略:底层用红外矩阵快速反应近距离障碍物,高层用A规划宏观路径;
传感器冗余:同时使用红外、超声波、雷达等多种传感器,提高系统鲁棒性。 - 调试与优化建议
可视化调试:通过OLED显示实时地图和路径,方便观察算法运行状态;
参数整定:调整A*的启发式函数权重、PID控制器的比例系数,平衡速度与稳定性;
功耗管理:空闲时降低红外传感器采样频率,使用低功耗模式延长续航。

4、基础红外矩阵迷宫求解(8x8 网格)
#include <SimpleFOC.h>
#include <QueueArray.h> // 用于A*的优先队列
// 电机与传感器定义
BLDCMotor motorLeft(7), motorRight(8);
#define IR_MATRIX_SIZE 8
int irMatrix[IR_MATRIX_SIZE][IR_MATRIX_SIZE]; // 红外矩阵数据(模拟)
// 迷宫地图(0=通路,1=墙壁)
int maze[IR_MATRIX_SIZE][IR_MATRIX_SIZE] = {
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 1, 1, 0, 1, 1, 0},
{0, 1, 0, 0, 0, 0, 1, 0},
{0, 1, 0, 1, 1, 0, 1, 0},
{0, 0, 0, 0, 1, 0, 0, 0},
{0, 1, 1, 0, 1, 1, 1, 0},
{0, 1, 0, 0, 0, 0, 1, 0},
{0, 0, 0, 1, 0, 0, 0, 0}
};
// A* 节点结构
struct Node {
int x, y, g, h;
Node* parent;
bool operator<(const Node& other) const { return g + h > other.g + other.h; }
};
// A* 算法实现
QueueArray<Node*> openSet;
bool closedSet[IR_MATRIX_SIZE][IR_MATRIX_SIZE];
Node* aStar(int startX, int startY, int targetX, int targetY) {
// 初始化开放集和关闭集
memset(closedSet, 0, sizeof(closedSet));
openSet.setPrinter(Serial);
Node* startNode = new Node{startX, startY, 0, heuristic(startX, startY, targetX, targetY), nullptr};
openSet.push(startNode);
while (!openSet.isEmpty()) {
Node* current = openSet.pop();
if (current->x == targetX && current->y == targetY) return current;
closedSet[current->x][current->y] = true;
// 检查四个方向
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
for (int i = 0; i < 4; i++) {
int nx = current->x + dx[i];
int ny = current->y + dy[i];
if (nx >= 0 && nx < IR_MATRIX_SIZE && ny >= 0 && ny < IR_MATRIX_SIZE &&
!closedSet[nx][ny] && maze[nx][ny] == 0) {
int tentative_g = current->g + 1;
Node* neighbor = new Node{nx, ny, tentative_g, heuristic(nx, ny, targetX, targetY), current};
openSet.push(neighbor);
}
}
}
return nullptr; // 无路径
}
int heuristic(int x, int y, int tx, int ty) {
return abs(x - tx) + abs(y - ty); // 曼哈顿距离
}
void moveToNextNode(Node* next) {
// 根据节点坐标差控制电机
int dx = next->x - currentX;
int dy = next->y - currentY;
if (dx == 1) { // 前进
motorLeft.move(1.0); motorRight.move(1.0);
} else if (dy == 1) { // 右转
motorLeft.move(0.5); motorRight.move(-0.5);
} else if (dy == -1) { // 左转
motorLeft.move(-0.5); motorRight.move(0.5);
}
delay(500); // 模拟移动时间
}
void setup() {
Serial.begin(9600);
motorLeft.init(); motorRight.init();
// 初始化红外矩阵(模拟数据)
for (int i = 0; i < IR_MATRIX_SIZE; i++) {
for (int j = 0; j < IR_MATRIX_SIZE; j++) {
irMatrix[i][j] = (maze[i][j] == 1) ? 0 : 1; // 1=通路,0=墙壁
}
}
}
void loop() {
// 1. 规划路径
Node* pathEnd = aStar(0, 0, 7, 7); // 从(0,0)到(7,7)
// 2. 执行路径
while (pathEnd != nullptr) {
moveToNextNode(pathEnd);
pathEnd = pathEnd->parent;
}
}
5、红外矩阵 + 编码器闭环控制
#include <SimpleFOC.h>
#include <Encoder.h>
// 电机与编码器
BLDCMotor motorLeft(7), motorRight(8);
Encoder encLeft(2, 3), encRight(4, 5);
// 红外矩阵(简化版,模拟8个方向)
#define IR_FRONT A0
#define IR_LEFT A1
#define IR_RIGHT A2
// 迷宫地图(动态更新)
int maze[IR_MATRIX_SIZE][IR_MATRIX_SIZE] = {0};
void updateMazeWithIR() {
// 读取红外传感器并更新迷宫地图
int front = analogRead(IR_FRONT) > 500 ? 0 : 1; // 阈值判断
int left = analogRead(IR_LEFT) > 500 ? 0 : 1;
int right = analogRead(IR_RIGHT) > 500 ? 0 : 1;
// 根据当前位置和方向更新地图(需结合编码器定位)
// (代码略,需实现坐标推算逻辑)
}
void moveWithFeedback(int targetX, int targetY) {
// 结合编码器反馈实现精确移动
long encLeftStart = encLeft.getCount();
long encRightStart = encRight.getCount();
while (abs(encLeft.getCount() - encLeftStart) < 1000) { // 假设1000脉冲=1格
motorLeft.move(0.8); motorRight.move(0.8);
}
motorLeft.move(0); motorRight.move(0);
}
void setup() {
Serial.begin(9600);
motorLeft.init(); motorRight.init();
encLeft.init(); encRight.init();
}
void loop() {
updateMazeWithIR();
Node* path = aStar(0, 0, 7, 7);
if (path) moveWithFeedback(path->x, path->y);
}
6、红外矩阵 + 超声波避障(混合传感器)
#include <SimpleFOC.h>
#include <NewPing.h>
// 电机与传感器
BLDCMotor motorLeft(7), motorRight(8);
NewPing sonar(12, 13, 200); // 超声波测距
#define IR_MATRIX_SIZE 4
int irMatrix[IR_MATRIX_SIZE][IR_MATRIX_SIZE];
void hybridAvoidance() {
// 1. 红外矩阵检测墙壁
for (int i = 0; i < IR_MATRIX_SIZE; i++) {
for (int j = 0; j < IR_MATRIX_SIZE; j++) {
irMatrix[i][j] = (analogRead(A0 + i * 4 + j) > 500) ? 0 : 1; // 模拟多路红外
}
}
// 2. 超声波检测动态障碍物
int dist = sonar.ping_cm();
if (dist > 0 && dist < 20) {
// 触发局部避障(如绕行)
motorLeft.move(-0.5); motorRight.move(0.5); // 左转避障
delay(300);
}
}
void setup() {
Serial.begin(9600);
motorLeft.init(); motorRight.init();
}
void loop() {
hybridAvoidance();
Node* path = aStar(0, 0, 3, 3); // 小型迷宫
if (path) {
motorLeft.move(1.0); motorRight.move(1.0);
delay(500); // 模拟移动
}
}
要点解读
红外矩阵数据解析
多路红外复用:通过模拟多路复用(如 CD74HC4067 芯片)读取 8x8 矩阵,或直接使用多个 GPIO 口。
阈值校准:红外信号需动态调整阈值(如 analogRead() > 500),避免环境光干扰。
迷宫地图构建
静态地图初始化:直接在代码中定义迷宫布局(如 maze[][])。
动态地图更新:通过红外矩阵实时扫描,更新 maze[][] 中的墙壁信息。
A 算法优化*
优先队列实现:使用 QueueArray 库管理开放集,提升搜索效率。
启发函数选择:曼哈顿距离(|x1-x2| + |y1-y2|)适合网格迷宫,欧氏距离适合自由空间。
BLDC 运动控制
开环 vs 闭环:案例5结合编码器实现闭环控制,案例4为简化开环控制。
差速转向模型:通过左右轮速度差实现精确转向(如 motorLeft.move(0.5), motorRight.move(-0.5))。
传感器融合策略
红外 + 超声波:红外检测墙壁,超声波检测动态障碍物(如其他机器人)。
冗余设计:当红外信号不可靠时(如阳光直射),超声波作为备用方案。
注意,以上案例只是为了拓展思路,仅供参考。它们可能有错误、不适用或者无法编译。您的硬件平台、使用场景和Arduino版本可能影响使用方法的选择。实际编程时,您要根据自己的硬件配置、使用场景和具体需求进行调整,并多次实际测试。您还要正确连接硬件,了解所用传感器和设备的规范和特性。涉及硬件操作的代码,您要在使用前确认引脚和电平等参数的正确性和安全性。

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)