文章目录[隐藏]
一、概述
二、机器人平台设计之arduino基础
三、机器人平台设计之电机驱动
1.硬件_电机与电机驱动板
2.电机基本控制实现
/*
* 电机转动控制
* 1.定义接线中电机对应的引脚
* 2.setup 中设置引脚为输出模式
* 3.loop中控制电机转动
*
*/
int DIRA = 4;
int PWMA = 5;
void setup() {
//两个引脚都设置为 OUTPUT
pinMode(DIRA,OUTPUT);
pinMode(PWMA,OUTPUT);
}
void loop() {
//先正向转动3秒
digitalWrite(DIRA,HIGH);
analogWrite(PWMA,100);
delay(3000);
//停止3秒
digitalWrite(DIRA,HIGH);
analogWrite(PWMA,0);
delay(3000);
//再反向转动3秒
digitalWrite(DIRA,LOW);
analogWrite(PWMA,100);
delay(3000);
//停止3秒
digitalWrite(DIRA,LOW);
analogWrite(PWMA,0);
delay(3000);
/*
* 注意:
* 1.可以通过将DIRA设置为HIGH或LOW来控制电机转向,但是哪个标志位正转或反转需要根据需求判断,转向是相对的。
* 2.PWM的取值为 [0,255],该值可自己设置。
*
*/
}
电机测速01_理论
4.电机测速02_实现
/*
* 测速实现:
* 阶段1:脉冲数统计
* 阶段2:速度计算
*
* 阶段1:
* 1.定义所使用的中断引脚,以及计数器(使用 volatile 修饰)
* 2.setup 中设置波特率,将引脚设置为输入模式
* 3.使用 attachInterupt() 函数为引脚添加中断出发时机以及中断函数
* 4.中断函数编写计算算法,并打印
* A.单频统计只需要统计单相上升沿或下降沿
* B.2倍频统计需要统计单相的上升沿和下降沿
* C.4倍频统计需要统计两相的上升沿和下降沿
* 5.上传并查看结果
*
*
*/
int motor_A = 21;//中端口是2
int motor_B = 20;//中断口是3
volatile int count = 0;//如果是正转,那么每计数一次自增1,如果是反转,那么每计数一次自减1
void count_A(){
//单频计数实现
//手动旋转电机一圈,输出结果为 一圈脉冲数 * 减速比
/*if(digitalRead(motor_A) == HIGH){
if(digitalRead(motor_B) == LOW){//A 高 B 低
count++;
} else {//A 高 B 高
count--;
}
}*/
//2倍频计数实现
//手动旋转电机一圈,输出结果为 一圈脉冲数 * 减速比 * 2
if(digitalRead(motor_A) == HIGH){
if(digitalRead(motor_B) == HIGH){//A 高 B 高
count++;
} else {//A 高 B 低
count--;
}
} else {
if(digitalRead(motor_B) == LOW){//A 低 B 低
count++;
} else {//A 低 B 高
count--;
}
}
}
//与A实现类似
//4倍频计数实现
//手动旋转电机一圈,输出结果为 一圈脉冲数 * 减速比 * 4
void count_B(){
if(digitalRead(motor_B) == HIGH){
if(digitalRead(motor_A) == LOW){//B 高 A 低
count++;
} else {//B 高 A 高
count--;
}
} else {
if(digitalRead(motor_A) == HIGH){//B 低 A 高
count++;
} else {//B 低 A 低
count--;
}
}
}
void setup() {
Serial.begin(57600);//设置波特率
pinMode(motor_A,INPUT);
pinMode(motor_B,INPUT);
attachInterrupt(2,count_A,CHANGE);//当电平发生改变时触发中断函数
//四倍频统计需要为B相也添加中断
attachInterrupt(3,count_B,CHANGE);
}
void loop() {
//测试计数器输出
delay(2000);
Serial.println(count);
}
int reducation = 90;//减速比,根据电机参数设置,比如 15 | 30 | 60
int pulse = 11; //编码器旋转一圈产生的脉冲数该值需要参考商家电机参数
int per_round = pulse * reducation * 4;//车轮旋转一圈产生的脉冲数
long start_time = millis();//一个计算周期的开始时刻,初始值为 millis();
long interval_time = 50;//一个计算周期 50ms
double current_vel;
//获取当前转速的函数
void get_current_vel(){
long right_now = millis();
long past_time = right_now - start_time;//计算逝去的时间
if(past_time >= interval_time){//如果逝去时间大于等于一个计算周期
//1.禁止中断
noInterrupts();
//2.计算转速 转速单位可以是秒,也可以是分钟... 自定义即可
current_vel = (double)count / per_round / past_time * 1000 * 60;
//3.重置计数器
count = 0;
//4.重置开始时间
start_time = right_now;
//5.重启中断
interrupts();
Serial.println(current_vel);
}
}
void loop() {
delay(10);
get_current_vel();
}
5.电机调速01_PID控制理论
6.电机调速02_PID控制实现
/*
* PID 调速实现:
* 1.代码准备,复制并修改电机控制以及测速代码
* 2.包含PID头文件
* 3.创建PID对象
* 4.在setup中启用自动调试
* 5.调试并更新PWM
*
*/
#include <PID_v1.h>
int DIRA = 4;
int PWMA = 5;
int motor_A = 21;//中端口是2
int motor_B = 20;//中断口是3
volatile int count = 0;//如果是正转,那么每计数一次自增1,如果是反转,那么每计数一次自减1
void count_A(){
//单频计数实现
//手动旋转电机一圈,输出结果为 一圈脉冲数 * 减速比
/*if(digitalRead(motor_A) == HIGH){
if(digitalRead(motor_B) == LOW){//A 高 B 低
count++;
} else {//A 高 B 高
count--;
}
}*/
//2倍频计数实现
//手动旋转电机一圈,输出结果为 一圈脉冲数 * 减速比 * 2
if(digitalRead(motor_A) == HIGH){
if(digitalRead(motor_B) == HIGH){//A 高 B 高
count++;
} else {//A 高 B 低
count--;
}
} else {
if(digitalRead(motor_B) == LOW){//A 低 B 低
count++;
} else {//A 低 B 高
count--;
}
}
}
//与A实现类似
//4倍频计数实现
//手动旋转电机一圈,输出结果为 一圈脉冲数 * 减速比 * 4
void count_B(){
if(digitalRead(motor_B) == HIGH){
if(digitalRead(motor_A) == LOW){//B 高 A 低
count++;
} else {//B 高 A 高
count--;
}
} else {
if(digitalRead(motor_A) == HIGH){//B 低 A 高
count++;
} else {//B 低 A 低
count--;
}
}
}
int reducation = 90;//减速比,根据电机参数设置,比如 15 | 30 | 60
int pulse = 11; //编码器旋转一圈产生的脉冲数该值需要参考商家电机参数
int per_round = pulse * reducation * 4;//车轮旋转一圈产生的脉冲数
long start_time = millis();//一个计算周期的开始时刻,初始值为 millis();
long interval_time = 50;//一个计算周期 50ms
double current_vel;
//获取当前转速的函数
void get_current_vel(){
long right_now = millis();
long past_time = right_now - start_time;//计算逝去的时间
if(past_time >= interval_time){//如果逝去时间大于等于一个计算周期
//1.禁止中断
noInterrupts();
//2.计算转速 转速单位可以是秒,也可以是分钟... 自定义即可
current_vel = (double)count / per_round / past_time * 1000 * 60;
//3.重置计数器
count = 0;
//4.重置开始时间
start_time = right_now;
//5.重启中断
interrupts();
Serial.println(current_vel);
}
}
//-------------------------------------PID-------------------------------------------
//创建 PID 对象
//1.当前转速 2.计算输出的pwm 3.目标转速 4.kp 5.ki 6.kd 7.当输入与目标值出现偏差时,向哪个方向控制
double pwm;//电机驱动的PWM值
double target = 80;
double kp=1.5, ki=3.0, kd=0.1;
PID pid(¤t_vel,&pwm,&target,kp,ki,kd,DIRECT);
//速度更新函数
void update_vel(){
//获取当前速度
get_current_vel();
pid.Compute();//计算需要输出的PWM
digitalWrite(DIRA,HIGH);
analogWrite(PWMA,pwm);
}
void setup() {
Serial.begin(57600);//设置波特率
pinMode(18,INPUT);
pinMode(19,INPUT);
//两个电机驱动引脚都设置为 OUTPUT
pinMode(DIRA,OUTPUT);
pinMode(PWMA,OUTPUT);
attachInterrupt(2,count_A,CHANGE);//当电平发生改变时触发中断函数
//四倍频统计需要为B相也添加中断
attachInterrupt(3,count_B,CHANGE);
pid.SetMode(AUTOMATIC);
}
void loop() {
delay(10);
update_vel();
}
四、机器人平台设计之传感器
1.传感器_激光雷达简介
2.传感器_雷达使用
3.传感器_相机简介
4.传感器_相机使用
5.传感器_集成
版权声明:本文为CSDN博主「木筏筏筏」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Mufafafa/article/details/122754594
暂无评论