我要提问
ARTICLE DETAIL

资讯详情

前沿编程新知与开发实战干货的深度解读。

基于Jetson Nano与STM32的嵌入式AI视觉伺服系统实战

基于Jetson Nano与STM32的嵌入式AI视觉伺服系统实战 简介本资源是一套面向嵌入式AI开发者的端侧智能控制实战项目聚焦Jetson Nano与STM32协同实现垃圾分类模型推理及舵机物理响应的完整链路适用于具备基础C语言编程与嵌入式开发经验的进阶学习者。项目覆盖数据集准备含图像增强与划分、PyTorch/TensorFlow模型训练与TensorRT优化部署、Jetson Nano端推理服务封装、UART串口通信协议设计、STM32F10x系列C语言固件开发含TIM/PWM舵机驱动、USART收发逻辑等关键环节。压缩包共110个文件含38个C源码如stm32f10x_usart.c、stm32f10x_tim.c、40个头文件、8个汇编启动文件以及Paddle Lite模型文件.pdmodel/.pdiparams、Keil工程.uvprojx、Python脚本与实操演示mp4视频整体大小142.82MB。已有1812人学习下载提供从模型训练到硬件联动的全栈代码、可直接烧录的STM32固件、Jetson端部署脚本及通信调试说明显著降低边缘AI落地门槛。1. 项目概述从数据到动作的嵌入式AI闭环最近在折腾一个挺有意思的项目核心目标是把一个深度学习模型从“纸上谈兵”变成“真刀真枪”的物理动作。具体来说就是让Jetson Nano这个边缘计算小盒子能够识别摄像头里的目标然后把识别结果告诉一块STM32单片机最后由STM32精准地控制舵机转动指向目标。听起来像是机器人视觉伺服或者智能追踪云台的雏形对吧这正是边缘AI落地的典型场景——让智能发生在数据产生的地方并即时产生物理世界的反馈。这个项目适合所有对嵌入式AI、物联网硬件交互感兴趣的开发者无论你是想为机器人增加“眼睛”还是想做一个自动追踪装置这个流程都是通用的。整个过程串联了AI模型部署、异构硬件通信、底层电机控制三个关键环节任何一个环节卡住整个系统就“瘫痪”了。我把自己从准备数据到最终让舵机动起来的完整过程包括踩过的坑和验证有效的技巧都梳理在这里。你会发现难点往往不在算法本身而在如何让算法稳定、高效地与硬件“对话”。2. 项目整体设计与思路拆解2.1 核心需求与方案选型这个项目的需求非常明确实时视觉感知驱动物理执行机构。拆解开来就是三个子任务视觉感知在Jetson Nano上运行一个目标检测或分类模型实时处理摄像头视频流。决策与通信Jetson Nano根据识别结果如目标类别、位置坐标生成控制指令。执行控制STM32接收指令解析并生成相应的PWM信号驱动舵机转动到指定角度。为什么选择Jetson Nano STM32这个组合这是基于性能和成本的权衡。Jetson Nano拥有128核的GPU足以在本地实时运行经过优化的轻量级深度学习模型如YOLOv5s MobileNet SSD避免了将所有视频流上传到云端带来的延迟和隐私问题。然而Jetson Nano的GPIO引脚驱动能力和实时性对于需要精确时序控制的舵机而言并非最佳选择。舵机控制要求稳定、无抖动的PWM信号任何由操作系统调度或后台进程引起的时间抖动都会导致舵机抖动或定位不准。STM32恰恰弥补了这个短板。作为经典的微控制器它在处理确定性的、周期性的任务如生成PWM方面具有天然优势中断响应快几乎没有抖动。因此分工协作是最优解Jetson Nano负责“思考”AI推理STM32负责“执行”精准控制。两者之间通过串口UART通信这是一种简单、可靠、被广泛支持的通信方式。2.2 技术栈与工具链准备工欲善其事必先利其器。以下是整个项目涉及的核心技术栈和工具我会说明每个选择的理由。Jetson Nano侧操作系统 NVIDIA官方提供的JetPack SDK基于Ubuntu 18.04/20.04 LTS。这是必须的因为它包含了CUDA、cuDNN、TensorRT等核心AI计算库的预配置版本省去了大量手动配置的麻烦。深度学习框架PyTorch。虽然TensorFlow也有Jetson版本但PyTorch在研究和快速原型开发中更流行其模型转换为TensorRT的流程也相对成熟。我们的模型训练将在PC端完成然后部署到Nano。推理加速引擎TensorRT。这是NVIDIA官方的高性能深度学习推理SDK。它能将训练好的模型进行优化包括层融合、精度校准、内核自动调优并转换为在Jetson上高效运行的引擎显著提升推理速度并降低延迟。通信库 Python的pyserial库。用于实现Jetson Nano通过串口与STM32通信。摄像头 官方推荐的Raspberry Pi Camera V2CSI接口或通用的USB摄像头。CSI摄像头延迟更低占用CPU资源少是首选。STM32侧开发板 任意一款带有UART和至少一个定时器用于产生PWM的STM32系列开发板如STM32F103C8T6蓝色药丸板、STM32F407等。F103系列性价比高资源足够。开发环境STM32CubeIDE ST官方推出的免费集成开发环境集成了STM32CubeMX图形化配置工具和调试器。它可以通过图形界面配置引脚、时钟、外设UART 定时器自动生成初始化代码极大提升了开发效率特别适合初学者和快速开发。STM32CubeMX 独立的引脚和时钟配置工具可以生成多种IDE的工程代码。如果习惯Keil或IAR可以用它生成代码。编程框架HAL库。相对于标准外设库HAL库抽象层次更高代码可移植性更好虽然效率略有牺牲但开发速度更快更不容易出错对于本项目完全够用。通信协议设计这是连接两大核心的“语言”设计的好坏直接决定系统稳定性。我们需要定义一个简单、高效、容错的串口通信协议。 我设计了一个基于ASCII字符的文本协议格式如下[指令头],[参数1],[参数2],...\n例如控制舵机转到90度S,90\nS 指令头代表“Set Servo angle”。90 参数代表目标角度。\n换行符 作为帧结束符方便接收方解析。为什么用文本协议而不是二进制文本协议直观易于在调试串口助手上查看和模拟出现问题时排查方便。虽然效率略低于二进制但对于“角度值”这种低频、小数据量的传输完全不是瓶颈。关键在于一定要有明确的帧结束符避免数据粘包问题。3. 核心环节一数据集准备与模型训练3.1 数据采集与标注策略模型要准数据先行。如果你的目标是识别特定物体比如一个红色的球、一个人脸、一种手势就需要自己采集和标注数据。采集 直接在Jetson Nano上连接摄像头用PythonOpenCV写个脚本录制视频或抓拍图片。尽可能在最终部署的环境光照、背景、角度变化下采集数据增强模型的鲁棒性。采集几百到几千张图片作为起点。标注 使用标注工具如LabelImg、CVAT或Roboflow。对于目标检测需要框出物体并打上标签。标注格式通常选择PASCAL VOC XML或更流行的YOLO格式每个图片对应一个.txt文件内容为类别id x_center y_center width height坐标是归一化后的值。数据增强 在数据量不足时通过旋转、缩放、裁剪、调整亮度对比度、添加噪声等方式人工扩充数据集能有效防止模型过拟合。Roboflow等在线平台提供了便捷的增强功能。注意 标注的一致性至关重要。同一个物体在所有图片中的边界框要紧密度、类别名称必须完全一致。混乱的标注是模型性能不佳的首要原因。3.2 模型选择、训练与优化对于Jetson Nano这类边缘设备模型必须轻量化。模型选择目标检测YOLOv5n/s或SSD-MobileNetV2/V3。YOLOv5n是YOLO系列中最轻量的速度极快精度尚可SSD-MobileNet系列在精度和速度上平衡得很好且与TensorRT的兼容性非常成熟。图像分类MobileNetV2/V3或EfficientNet-Lite。这些是专为移动和边缘设备设计的网络。 我本次以YOLOv5s为例它在Nano上配合TensorRT优化后可以达到接近实时的帧率15-30 FPS取决于输入分辨率。训练环境 在拥有NVIDIA GPU的PC或服务器上进行训练。使用PyTorch框架和YOLOv5官方仓库。# 克隆YOLOv5仓库 git clone https://github.com/ultralytics/yolov5 cd yolov5 pip install -r requirements.txt # 准备好自己的数据集按照YOLO格式组织 # 修改data/custom.yaml定义自己的类别和路径 # 开始训练 python train.py --img 640 --batch 16 --epochs 100 --data data/custom.yaml --weights yolov5s.pt关键训练参数--img 640 输入图像尺寸。更小的尺寸如320速度更快但精度可能下降。640是一个较好的平衡点。--batch 批大小。根据你的GPU显存调整。--epochs 训练轮数。观察训练损失和验证集精度曲线在过拟合前停止。模型导出 训练完成后得到的最佳模型是.pt文件。需要将其导出为TensorRT可用的格式。通常先导出为ONNX格式再转换为TensorRT引擎。# 导出为ONNX python export.py --weights runs/train/exp/weights/best.pt --include onnx --img 640 --dynamic这里--dynamic参数允许动态的批处理大小在部署时更灵活。4. 核心环节二Jetson Nano上的模型部署与推理4.1 TensorRT引擎生成与优化这是提升边缘端推理性能的关键一步。我们将ONNX模型转换为TensorRT引擎。安装TensorRT JetPack已包含TensorRT但可能需要确认版本。使用dpkg -l | grep tensorrt查看。使用trtexec工具转换 TensorRT自带命令行工具trtexec可以方便地进行转换和性能基准测试。# 基本转换命令生成FP16精度的引擎显著提升速度且精度损失很小 trtexec --onnxbest.onnx --saveEnginebest_fp16.engine --fp16 --workspace1024--fp16 启用半精度浮点数推理速度大幅提升是Jetson上的首选。--workspace 设置GPU内存工作空间大小MB复杂模型可能需要更大空间。还可以添加--int8进行INT8量化速度最快但需要校准数据集过程更复杂精度损失可能更大。编写Python推理脚本 使用TensorRT的Python API加载引擎并进行推理。import tensorrt as trt import pycuda.driver as cuda import pycuda.autoinit import numpy as np import cv2 class TrtModel: def __init__(self, engine_path): # 加载引擎创建执行上下文 with open(engine_path, rb) as f, trt.Runtime(trt.Logger(trt.Logger.WARNING)) as runtime: self.engine runtime.deserialize_cuda_engine(f.read()) self.context self.engine.create_execution_context() # 分配输入输出内存绑定 self.bindings [] for binding in self.engine: size trt.volume(self.engine.get_binding_shape(binding)) * self.engine.max_batch_size dtype trt.nptype(self.engine.get_binding_dtype(binding)) # 分配页锁定内存以提高传输效率 host_mem cuda.pagelocked_empty(size, dtype) device_mem cuda.mem_alloc(host_mem.nbytes) self.bindings.append(int(device_mem)) # ... 将输入输出绑定与指针关联 def infer(self, input_image): # 图像预处理缩放、归一化、BGR2RGB、转换为CHW格式 # 将数据从主机拷贝到设备 cuda.memcpy_htod(self.bindings[0], input_data.ravel()) # 执行推理 self.context.execute_v2(bindingsself.bindings) # 将结果从设备拷贝回主机 cuda.memcpy_dtoh(host_output, self.bindings[1]) # 后处理解析YOLO输出应用置信度阈值和NMS return boxes, scores, class_ids实操心得 图像预处理如归一化到0-1之间和后处理解析检测框、非极大值抑制NMS的代码必须与模型训练时的设置严格一致否则结果会完全错误。这部分代码可以借鉴原训练仓库中的dataset.py和utils.general.py。4.2 实时视频流处理与通信逻辑推理脚本需要嵌入到一个视频捕获循环中并加入通信逻辑。import cv2 import serial import time # 初始化串口 # 注意Jetson Nano的串口设备通常是 /dev/ttyTHS1 或 /dev/ttyUSB0 ser serial.Serial(/dev/ttyTHS1, 115200, timeout1) # 波特率需与STM32匹配 # 初始化摄像头 cap cv2.VideoCapture(0) # 对于CSI摄像头可能是 cap cv2.VideoCapture(nvarguscamerasrc ! ...) GStreamer管道 cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) # 初始化TensorRT模型 model TrtModel(best_fp16.engine) while True: ret, frame cap.read() if not ret: break # 执行推理 detections model.infer(frame) # 假设我们只追踪一个主要目标如置信度最高的 if len(detections) 0: # 获取目标在图像中的中心点x坐标 (0~640) x_center (detections[0][0] detections[0][2]) / 2 # (x1 x2) / 2 # 将像素坐标转换为舵机角度 (例如0~640像素 映射到 0~180度) # 这里是一个简单的线性映射你可能需要更复杂的策略如PID控制 target_angle int((x_center / 640) * 180) target_angle max(0, min(180, target_angle)) # 限制在舵机有效范围 # 生成控制指令并发送 command fS,{target_angle}\n ser.write(command.encode(ascii)) print(fSent: {command.strip()}) # 显示结果可选 # draw_boxes(frame, detections) # cv2.imshow(Detection, frame) # if cv2.waitKey(1) 0xFF ord(q): # break cap.release() cv2.destroyAllWindows() ser.close()关键点解析串口初始化 确保端口号和波特率这里是115200与STM32端完全一致。timeout参数设置了读操作的超时时间。坐标映射 将检测框的中心x坐标像素值线性映射到舵机的角度范围0-180度。这是最简单的“比例控制”。在实际应用中如果要求云台平滑稳定地跟踪可能需要引入PID控制器根据目标位置与当前位置的误差来动态计算控制量避免舵机抖动和超调。指令发送 务必在指令末尾加上换行符\n这是STM32端解析帧的结束标志。5. 核心环节三STM32的通信与舵机控制5.1 STM32开发环境搭建与外设配置使用STM32CubeMX创建工程选择你的MCU型号如STM32F103C8Tx。配置时钟树 将HCLK系统时钟设置到最大允许频率对于F103是72MHz以获得最佳性能。配置USART使能一个USART如USART1。模式选择为“Asynchronous”异步。波特率设置为115200与Jetson Nano一致。字长8位停止位1无校验。开启全局中断方便使用中断接收数据。配置定时器用于PWM使能一个通用定时器如TIM2。选择一个通道如Channel 1为“PWM Generation CH1”。根据舵机要求配置PWM频率。标准舵机控制信号是周期20ms50Hz的PWM波。在72MHz系统时钟下计算预分频器PSC和自动重载值ARR以产生50Hz频率。定时器时钟 72MHz / (PSC 1)计数频率 定时器时钟 / (ARR 1)目标 计数频率 50Hz。例如设置PSC7199ARR199。则定时器时钟72MHz/720010kHz计数频率10kHz/20050Hz。生成代码 选择工具链为STM32CubeIDE生成初始化代码。在STM32CubeIDE中编写业务逻辑 生成的代码已经完成了外设的初始化HAL_UART_Init,HAL_TIM_PWM_Init。我们主要需要在main.c中编写串口接收中断回调函数和舵机控制函数。5.2 串口数据解析与舵机PWM控制实现串口数据接收中断方式 我们使用串口空闲中断Idle Interrupt来接收不定长数据。当一帧数据以\n结尾接收完毕总线空闲时会触发空闲中断此时我们可以处理已接收的数据。// 在main.c的USER CODE BEGIN PV区域定义缓冲区 uint8_t uart_rx_buffer[64]; uint8_t uart_rx_len 0; // 在main函数初始化后开启串口接收和空闲中断 HAL_UART_Receive_IT(huart1, uart_rx_buffer, 1); // 先启动接收一个字节 __HAL_UART_ENABLE_IT(huart1, UART_IT_IDLE); // 使能空闲中断 // 在stm32f1xx_it.c中找到USART1_IRQHandler函数添加空闲中断处理 void USART1_IRQHandler(void) { if(__HAL_UART_GET_FLAG(huart1, UART_FLAG_IDLE) ! RESET) { __HAL_UART_CLEAR_IDLEFLAG(huart1); // 停止本次DMA传输获取接收到的数据长度 // 注意如果用的是中断接收而非DMA处理方式略有不同 HAL_UART_DMAStop(huart1); uart_rx_len sizeof(uart_rx_buffer) - __HAL_DMA_GET_COUNTER(hdma_usart1_rx); // 处理数据 uart_rx_buffer[0...uart_rx_len-1] process_uart_command(uart_rx_buffer, uart_rx_len); // 重新启动接收 memset(uart_rx_buffer, 0, sizeof(uart_rx_buffer)); HAL_UART_Receive_DMA(huart1, uart_rx_buffer, sizeof(uart_rx_buffer)); } HAL_UART_IRQHandler(huart1); }注意 上述代码示例使用了DMA空闲中断这是最高效的方式。如果使用普通中断模式需要在每次字节接收中断中填充缓冲区并在收到\n字符时认为一帧结束。数据解析与舵机控制函数void process_uart_command(uint8_t* buf, uint16_t len) { // 1. 转换为字符串并确保以\0结尾 buf[len] \0; char* command (char*)buf; // 2. 简单的字符串解析 (例如 S,90) char* token strtok(command, ,); if(token NULL) return; if(strcmp(token, S) 0) { // 舵机角度设置指令 token strtok(NULL, ,); if(token ! NULL) { int angle atoi(token); // 将字符串转换为整数 angle (angle 0) ? 0 : (angle 180) ? 180 : angle; // 限幅 set_servo_angle(angle); } } // 可以扩展其他指令如 C 用于校准等 } void set_servo_angle(uint16_t angle) { // 将角度0-180映射到PWM占空比对应的比较寄存器值CCR // 舵机控制脉宽通常为0.5ms(0度) ~ 2.5ms(180度)周期20ms // 占空比 脉宽 / 周期 (0.5 angle * 2.0 / 180) / 20 // CCR值 占空比 * (ARR 1) // 根据之前计算的ARR199定时器计数200对应20ms // 0度对应脉宽0.5ms - 计数值 0.5 / 20 * 200 5 // 180度对应脉宽2.5ms - 计数值 2.5 / 20 * 200 25 // 因此映射公式 ccr 5 angle * (20 / 180) 5 angle / 9 uint16_t ccr 5 angle / 9; // 简化计算注意整数除法 __HAL_TIM_SET_COMPARE(htim2, TIM_CHANNEL_1, ccr); // 设置TIM2 Channel1的CCR值 }关键点解析PWM计算 舵机控制的核心是生成一个周期为20ms50Hz高电平脉宽在0.5ms到2.5ms之间的PWM信号。CCR捕获/比较寄存器的值直接决定了高电平的时间。上述映射公式ccr 5 angle / 9是基于ARR199即200个计数周期对应20ms推导出的线性映射。不同的舵机型号或定时器配置这个公式需要重新计算。启动PWM输出 在main函数中初始化后需要启动PWM输出HAL_TIM_PWM_Start(htim2, TIM_CHANNEL_1);。稳定性 直接映射角度可能导致舵机运动不平滑。在实际应用中可以加入软件滤波如移动平均或更高级的控制算法如梯形速度曲线让舵机缓慢加速、减速运动更平稳减少机械冲击。6. 系统联调与性能优化实战6.1 硬件连接与上电调试步骤物理连接Jetson Nano与STM32 将Jetson Nano的UART TX引脚如/dev/ttyTHS1对应的引脚通常是板子上的第8脚连接到STM32的USART RX引脚如PA10。将Jetson Nano的UART RX引脚连接到STM32的USART TX引脚如PA9。务必共地连接两者的GND引脚。STM32与舵机 STM32的PWM输出引脚如TIM2_CH1对应的PA0连接到舵机的信号线通常是橙色或白色线。舵机的VCC红色线和GND棕色线连接到一个独立的5V电源。切勿使用STM32开发板的3.3V或5V引脚直接给舵机供电尤其是大扭矩舵机启动电流很大会导致单片机复位或损坏。使用外接电源并与STM32共地。摄像头 将CSI摄像头排线插入Jetson Nano的CSI接口或者插入USB摄像头。上电与调试顺序先给STM32和舵机的外接电源上电。再启动Jetson Nano。这个顺序可以避免通信引脚在未知状态时产生乱码干扰STM32启动。分步调试法第一步测试STM32 PWM。先不连接Jetson在STM32代码中写一个简单的角度循环变化程序用示波器或逻辑分析仪测量PWM引脚输出确认脉宽随角度变化正确0.5ms~2.5ms。观察舵机是否跟随转动。第二步测试串口通信。将STM32通过USB转TTL模块连接到电脑用串口助手如Putty SecureCRT发送S,90\n格式的指令观察舵机是否转动到90度。同时STM32可以回传一些调试信息到串口助手确认接收解析正常。第三步测试Jetson Nano推理。暂时注释掉串口发送代码运行推理脚本确保摄像头打开模型能正确识别并输出目标坐标。第四步全系统联调。连接Jetson Nano与STM32的串口运行完整的Jetson程序。观察舵机是否跟随目标移动。6.2 通信稳定性与系统性能优化通信稳定性问题与解决问题数据丢包或错乱。排查 在Jetson端和STM32端都加入打印语句将发送和接收到的原始数据打印出来或通过另一个串口回传到电脑。检查波特率是否绝对一致115200检查电平是否匹配Jetson Nano是3.3V TTLSTM32也是3.3V可以直接连接。解决 在通信协议中加入校验和。例如指令改为S,90,99\n其中99是前面字符的累加和取模。STM32端收到后重新计算校验和如果不匹配则丢弃该帧。还可以加入应答机制Jetson发送指令后等待STM32回复“OK”超时则重发。系统性能优化Jetson Nano推理速度模型优化 使用TensorRT的FP16或INT8量化是最大的性能提升手段。输入分辨率 将模型输入分辨率从640降低到320速度会成倍提升但精度下降。需要权衡。视频流解码 对于CSI摄像头使用GStreamer管道nvarguscamerasrc配合nvv4l2decoder进行硬件解码比OpenCV的cv2.VideoCapture软件解码效率高得多。Python性能 避免在推理循环中进行不必要的内存分配和拷贝。使用预分配的缓冲区。控制响应平滑度直接映射的抖动问题 摄像头检测的坐标会有噪声直接映射会导致舵机高频微抖。解决方案低通滤波 对Jetson计算出的目标角度进行移动平均滤波。死区控制 设定一个角度死区如±2度只有当误差超过死区时才发送新指令减少不必要的通信和运动。PID控制 在STM32端实现一个简单的PID位置控制。Jetson只发送目标角度STM32以固定频率如100Hz读取当前舵机角度如果舵机带位置反馈或估算角度通过PID计算PWM输出使运动更平滑、精准。这是工业级的做法。6.3 常见问题排查速查表问题现象可能原因排查步骤与解决方案Jetson Nano无法打开摄像头摄像头驱动问题/端口占用1. 检查摄像头连接。2. 对于CSI摄像头尝试官方GStreamer示例。3. 使用ls /dev/video*查看设备节点。4. 确保没有其他程序占用摄像头。模型推理速度极慢1 FPS未使用TensorRT/模型未优化1. 确认使用的是.engine文件而非.pt或.onnx。2. 使用jetson-statsjtop工具监控GPU、CPU使用率确认推理时GPU是否工作。3. 检查是否误用了CPU模式。STM32舵机不转动电源/PWM信号/代码问题1.首要检查电源舵机是否独立供电电压是否足5V电流是否足够建议2A以上2. 用示波器检查PWM引脚是否有输出脉宽是否正确。3. 检查代码中定时器PWM输出是否已启动HAL_TIM_PWM_Start。4. 检查舵机信号线是否接反。舵机抖动或啸叫电源功率不足/PWM信号不稳定1.最常见原因电源功率不足换用更大电流的电源。2. PWM信号受到干扰确保信号线远离电源线。3. STM32的PWM频率不稳定检查系统时钟和定时器配置确保生成精确的50Hz。串口通信无反应接线错误/波特率不匹配/未共地1. 检查TX-RX是否交叉连接。2. 双方波特率、数据位、停止位、校验位设置是否完全一致。3.必须共地4. 使用USB转TTL工具在电脑上模拟一端分段测试。舵机角度不准PWM脉宽计算错误/舵机个体差异1. 用示波器测量0度和180度时的实际脉宽修正代码中的映射公式。2. 不同品牌舵机的中位脉宽可能不是1.5ms需要进行校准。可以在代码中增加校准指令通过串口发送测试脉宽来找到舵机的实际极限和中位值。最后的个人体会 这个项目麻雀虽小五脏俱全。它把AI、嵌入式、控制三个领域串了起来。最大的挑战往往不是某个高深算法而是跨平台、跨语言的协同调试。我的经验是一定要分模块、分步骤验证每个环节都确保独立工作正常再连起来调。比如先用串口助手调通STM32再用简单的Python脚本发数据最后上完整的AI模型。另外硬件项目电源是“祖宗”一大半的诡异问题都源于供电不足或干扰。给舵机一个独立、充沛的电源能省去后面无数的麻烦。当看到舵机随着你手里的物体平稳转动的那一刻你会觉得所有这些折腾都是值得的。这个框架可以轻松扩展比如把舵机换成步进电机做更精确的控制或者让STM32驱动多个舵机组成机械臂Jetson Nano则作为视觉大脑那就能玩出更多花样了。本文还有配套的精品资源点击获取
返回列表