【Beetle RP2350】摇杆控制自定义角度旋转舵机
一、硬件介绍
1、产品特点
Beetle RP2350【RP2350A_QFN60】是一款基于RP2350微控制器的高性能迷你开发板,双核双架构设计(支持 Arm Cortex-M33或Hazard3 RISC-V内核)为开发者提供灵活的性能配置。
双核双架构,性能自由切换
- 采用Raspberry Pi RP2350高性能微控制器,支持Arm Cortex-M33或Hazard3 RISC-V内核选择。
- 主频高达150MHz,配备520KB RAM和2MB Flash,可高效处理大量数据,满足高性能计算需求。
高度集成,硬币大小
- 尺寸仅为25mm x 20.5mm,相当于一枚硬币大小,适合空间受限的应用场景。
- 提供 11个IO接口、BAT接口和3.3V电源接口,满足多样化连接需求。
锂电池管理与监测
集成 锂电池充电管理 和 电池电压监测 功能,支持实时电量监控,确保设备在低电量时及时采取措施,确保持续运行。
易于编程与集成
- 支持 C/C++ 和 MicroPython 编程
2、功能引脚示意图 / 原理图
板载LED灯
IO25引脚控制
充电指示灯
指示充电状态的绿色LED灯
通过三种方式指示充电状态:
1、充满电或未接入电源时熄灭;
2、充电时常亮;
3、USB供电,未连接锂电池时高频闪烁;
用户按键
使用QSPI_SS引脚控制该按钮
引脚号 | 数字口 | 模拟口 | UART | I2C | SPI | 其它 |
---|---|---|---|---|---|---|
0 | D0 | TX1 | ||||
1 | D1 | RX1 | ||||
4 | D4 | SDA | ||||
5 | D5 | SCL | ||||
8 | D8 | TX2 | ||||
9 | D9 | RX2 | ||||
16 | D16 | SPI0/MISO | ||||
18 | D18 | SPI0/SCK | ||||
19 | D19 | SPI0/MOSI | ||||
26 | D26 | A0 | ||||
27 | D27 | A1 | ||||
BAT | 锂电池输入接口,IO29为电池电压检测引脚 | |||||
GND | 接地引脚 | |||||
VCC | 该引脚接在USB电源引脚,作为输出时电压为USB电压,通常为5V | |||||
3V3 | 3.3V稳压电源输出 |
主要原理图:
3、外部硬件
1、摇杆模块
该模块为一个双向的10K电阻器,随着摇杆方向变化,阻值也会随着变化,从而改变输出的值。
本模块可用 5V / 3.3V 供电,初始状态下X,Y读出电压为供电电压的1/2左右( 1.65V / 2.5V );
当随着X、Y方向移动,读出电压值减小(0V) / 增大(VCC);
其中X、Y方向输出的数据为模拟量,而Z轴输出的为数字量 (0 / 1)
模块引脚介绍:
模块引脚 | 功能 |
---|---|
+5V | 3.3V / 5V |
VRX | X方向模拟量(0~3.3v) 初始值: 1.65V |
VRY | Y方向模拟量(0~3.3v) 初始值: 1.65V |
SW | Z方向上的按键 (0 / 1) |
2、360°舵机模块【MG90S】
当接收到脉冲信号时,舵机会根据信号的脉宽计算需要转动的角度,并通过电机驱动器输出转动力矩,从而控制输出轴的旋转。
通过内部的位置反馈器,舵机可以检测电机当前的位置和角度,并精确地控制输出轴的角度和位置。
脉冲宽度(周期20ms) | 方向和速度 |
---|---|
0.5ms | 顺时针,速度快 |
1.0ms | 顺时针,速度慢 |
1.5ms | 停止 |
2.0ms | 逆时针,速度慢 |
2.5ms | 逆时针,速度快 |
二、硬件连接
模块与开发板引脚之间的连接方式如下:
RP2350开发板 | VCC | GND | D0 | D26(A0) | D27(A1) | D4 | 3V3 |
---|---|---|---|---|---|---|---|
舵机模块 | 5V | GND | 信号线 | - | - | - | - |
摇杆模块 | - | GND | - | VRX | VRY | SW | 3V3 |
实物效果搭建如下:
三、项目功能实现思想
【摇杆自定义旋转舵机】
实现效果:
通过摇杆旋转方向及范围以控制舵机运行的方向和与之对应的速度快慢;
当按下摇杆按键时,增大 / 减小此时运行的速度,并点亮 / 熄灭板载LED;
并且在串口上输出相关的运动信息;
开发板通过ADC引脚获取摇杆移动时的数据,并通过转换后将数据输出到PWM引脚上从而控制舵机运行;
运行流程图如下:
四、功能实现主要步骤
主要相关代码
1、LED控制部分
int Led_State = LOW;void Led_Init(){pinMode(LED_BUILTIN, OUTPUT);digitalWrite(LED_BUILTIN, Led_State);
}void Led_Control(){Led_State = !Led_State;digitalWrite(LED_BUILTIN, Led_State);
}
2、摇杆控制部分
int X_Pin = A0;
int Y_Pin = A1;
int Z_Pin = D4;
int X_Data = 0,Y_Data = 0,Z_Data = 1;
int X_Pos = 498,Y_Pos = 505,X_Min = 0,Y_Min = 0,X_Max = 1017,Y_Max = 1017;void Controller_Init(){pinMode(X_Pin, INPUT);pinMode(Y_Pin, INPUT);pinMode(Z_Pin, INPUT_PULLUP);
}void Controller_Get(){X_Data = analogRead(X_Pin);Y_Data = analogRead(Y_Pin);
}
3、舵机控制部分
#include <Servo.h>int speed = 0;
int percent = 0; int Servo_Pin = D0;
Servo myservo; void Servo_Init(){myservo.attach(Servo_Pin, 500, 2500); // 0.5ms ~ 2.5ms
}void Servo_Stop(){myservo.writeMicroseconds(1500); // STOP
}void Servo_Control(){Controller_Get();if(!digitalRead(Z_Pin)){delay(50);if(!digitalRead(Z_Pin)){Led_Control();}}else if(X_Data >X_Pos) //正向{if(Led_State){speed = map(Y_Data,0,1017,1500,500);myservo.writeMicroseconds(speed); // 顺时针Fastpercent = map(speed,500,1500,100,0);Serial.print("舵机加速顺时针运行速度为:");Serial.print(percent);Serial.println(" %");}else{speed = map(Y_Data,0,1017,1500,1000);myservo.writeMicroseconds(speed); // 顺时针SLOWpercent = map(speed,1000,1500,100,0);Serial.print("舵机顺时针运行速度为:");Serial.print(percent);Serial.println(" %");}}else if(X_Data < X_Pos){if(Led_State){speed = map(Y_Data,0,1017,1500,2500);myservo.writeMicroseconds(speed); // 逆时针Fastpercent = map(speed,1500,2500,0,100);Serial.print("舵机加速逆时针运行速度为:");Serial.print(percent);Serial.println(" %");}else{speed = map(Y_Data,0,1017,1500,2000); myservo.writeMicroseconds(speed); // 逆时针SLOW percent = map(speed,1500,2000,0,100);Serial.print("舵机逆时针运行速度为:");Serial.print(percent);Serial.println(" %");}}else if(X_Data == X_Pos || Y_Data == Y_Pos) //停止{Servo_Stop();Serial.println("舵机已停止");}
}
完整代码
#include <Servo.h>
int Led_State = LOW;
int X_Pin = A0;
int Y_Pin = A1;
int Z_Pin = D4;
int X_Data = 0,Y_Data = 0,Z_Data = 1;
int X_Pos = 498,Y_Pos = 505,X_Min = 0,Y_Min = 0,X_Max = 1017,Y_Max = 1017;int speed = 0;
int percent = 0;
int Servo_Pin = D0;
Servo myservo; void Led_Init(){pinMode(LED_BUILTIN, OUTPUT);digitalWrite(LED_BUILTIN, Led_State);
}void Led_Control(){Led_State = !Led_State;digitalWrite(LED_BUILTIN, Led_State);
}void Controller_Init(){pinMode(X_Pin, INPUT);pinMode(Y_Pin, INPUT);pinMode(Z_Pin, INPUT_PULLUP);
}void Controller_Get(){X_Data = analogRead(X_Pin);Y_Data = analogRead(Y_Pin);
}void Servo_Init(){myservo.attach(Servo_Pin, 500, 2500); // 0.5ms ~ 2.5ms
}void Servo_Stop(){myservo.writeMicroseconds(1500); // STOP
}void Servo_Control(){Controller_Get();if(!digitalRead(Z_Pin)){delay(50);if(!digitalRead(Z_Pin)){Led_Control();}}else if(X_Data >X_Pos) //正向{if(Led_State){speed = map(Y_Data,0,1017,1500,500);myservo.writeMicroseconds(speed); // 顺时针Fastpercent = map(speed,500,1500,100,0);Serial.print("舵机加速顺时针运行速度为:");Serial.print(percent);Serial.println(" %");}else{speed = map(Y_Data,0,1017,1500,1000);myservo.writeMicroseconds(speed); // 顺时针SLOWpercent = map(speed,1000,1500,100,0);Serial.print("舵机顺时针运行速度为:");Serial.print(percent);Serial.println(" %");}}else if(X_Data < X_Pos){if(Led_State){speed = map(Y_Data,0,1017,1500,2500);myservo.writeMicroseconds(speed); // 逆时针Fastpercent = map(speed,1500,2500,0,100);Serial.print("舵机加速逆时针运行速度为:");Serial.print(percent);Serial.println(" %");}else{speed = map(Y_Data,0,1017,1500,2000); myservo.writeMicroseconds(speed); // 逆时针SLOW percent = map(speed,1500,2000,0,100);Serial.print("舵机逆时针运行速度为:");Serial.print(percent);Serial.println(" %");}}else if(X_Data == X_Pos || Y_Data == Y_Pos) //停止{Servo_Stop();Serial.println("舵机已停止");}
}void setup() {Serial.begin(9600);while (!Serial);Led_Init();Controller_Init();Servo_Init();
}void loop() {Servo_Control();delay(200);
}
五、实现现象
通过移动摇杆的方向以及移动范围,从而控制舵机运行的方向以及运行速度;
按下按钮时,开启加速模式(开启板载LED) / 普通运行模式(关闭板载LED);
串口输出相关运动信息;