第 8 章 机器人底盘Arduino端编码器驱动(自学二刷笔记)

news/2025/1/16 0:00:09/

重要参考:

课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ

讲义链接:Introduction · Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程

8.4.3 底盘实现_02Arduino端编码器驱动

测速是整个PID闭环控制中的必须环节,我们必须修改代码适配当前AB相编码器,虽然需要重写功能,但是测速部分内容已经封装,只需要实现编码器计数即可,大致实现流程如下:

  1. ROSArduinoBridge.ino 中需要注释之前的编码器驱动,添加自定义编码器驱动;
  2. encoder_driver.h 中设置编码器引脚并声明初始化函数以及中断函数;
  3. encoder_driver.ino 中实现编码器计数以及重置函数;
  4. ROSArduinoBridge.ino 中 setup 函数调用编码器初始化函数。
  5. 测试
1.定义编码器驱动

ROSArduinoBridge.ino需要添加编码器宏定义,代码如下:

#define USE_BASE      // Enable the base controller code
//#undef USE_BASE     // Disable the base controller code/* Define the motor controller and encoder library you are using */
#ifdef USE_BASE/* The Pololu VNH5019 dual motor driver shield *///#define POLOLU_VNH5019/* The Pololu MC33926 dual motor driver shield *///#define POLOLU_MC33926/* The RoboGaia encoder shield *///#define ROBOGAIA/* Encoders directly attached to Arduino board *///#define ARDUINO_ENC_COUNTER#define ARDUINO_MY_COUNTER/* L298 Motor driver*///#define L298_MOTOR_DRIVER#define L298P_MOTOR_DRIVER
#endif

先去除 #define L298P_MOTOR_DRIVER 的注释,否则后续编译会抛出异常。

2.修改encoder_driver.h文件

修改后内容如下:

/* *************************************************************Encoder driver function definitions - by James Nugen************************************************************ */#ifdef ARDUINO_ENC_COUNTER//below can be changed, but should be PORTD pins; //otherwise additional changes in the code are required#define LEFT_ENC_PIN_A PD2  //pin 2#define LEFT_ENC_PIN_B PD3  //pin 3//below can be changed, but should be PORTC pins#define RIGHT_ENC_PIN_A PC4  //pin A4#define RIGHT_ENC_PIN_B PC5   //pin A5
#elif defined ARDUINO_MY_COUNTER#define LEFT_A 21#define LEFT_B 20#define RIGHT_A 18#define RIGHT_B 19void initEncoders();void leftEncoderEventA();void leftEncoderEventB();void rightEncoderEventA();void rightEncoderEventB();
#endiflong readEncoder(int i);
void resetEncoder(int i);
void resetEncoders();
3.修改encoder_driver.ino 文件

主要添加内容如下:

#elif defined ARDUINO_MY_COUNTERvolatile long left_count = 0L;volatile long right_count = 0L;void initEncoders(){pinMode(LEFT_A,INPUT); // 21  --- 2pinMode(LEFT_B,INPUT); // 20  --- 3pinMode(RIGHT_A,INPUT);// 18  --- 5pinMode(RIGHT_B,INPUT);// 19  --- 4attachInterrupt(2,leftEncoderEventA,CHANGE);attachInterrupt(3,leftEncoderEventB,CHANGE);attachInterrupt(5,rightEncoderEventA,CHANGE);attachInterrupt(4,rightEncoderEventB,CHANGE);}void leftEncoderEventA(){if(digitalRead(LEFT_A) == HIGH){if(digitalRead(LEFT_B) == HIGH){left_count++;} else {left_count--;}} else {if(digitalRead(LEFT_B) == LOW){left_count++;} else {left_count--;}}}void leftEncoderEventB(){if(digitalRead(LEFT_B) == HIGH){if(digitalRead(LEFT_A) == LOW){left_count++;} else {left_count--;}} else {if(digitalRead(LEFT_A) == HIGH){left_count++;} else {left_count--;}}}void rightEncoderEventA(){if(digitalRead(RIGHT_A) == HIGH){if(digitalRead(RIGHT_B) == HIGH){right_count++;} else {right_count--;}} else {if(digitalRead(RIGHT_B) == LOW){right_count++;} else {right_count--;}}  }void rightEncoderEventB(){if(digitalRead(RIGHT_B) == HIGH){if(digitalRead(RIGHT_A) == LOW){right_count++;} else {right_count--;}} else {if(digitalRead(RIGHT_A) == HIGH){right_count++;} else {right_count--;}}  }long readEncoder(int i) {if (i == LEFT) return left_count;else return right_count;}/* Wrap the encoder reset function */void resetEncoder(int i) {if (i == LEFT){left_count=0L;return;} else { right_count=0L;return;}}
4.ROSArduinoBridge.ino 实现初始化

setup 添加语句:initEncoders();

void setup() {Serial.begin(BAUDRATE);// Initialize the motor controller if used */
#ifdef USE_BASE#ifdef ARDUINO_ENC_COUNTER//set as inputsDDRD &= ~(1<<LEFT_ENC_PIN_A);DDRD &= ~(1<<LEFT_ENC_PIN_B);DDRC &= ~(1<<RIGHT_ENC_PIN_A);DDRC &= ~(1<<RIGHT_ENC_PIN_B);//enable pull up resistorsPORTD |= (1<<LEFT_ENC_PIN_A);PORTD |= (1<<LEFT_ENC_PIN_B);PORTC |= (1<<RIGHT_ENC_PIN_A);PORTC |= (1<<RIGHT_ENC_PIN_B);// tell pin change mask to listen to left encoder pinsPCMSK2 |= (1 << LEFT_ENC_PIN_A)|(1 << LEFT_ENC_PIN_B);// tell pin change mask to listen to right encoder pinsPCMSK1 |= (1 << RIGHT_ENC_PIN_A)|(1 << RIGHT_ENC_PIN_B);// enable PCINT1 and PCINT2 interrupt in the general interrupt maskPCICR |= (1 << PCIE1) | (1 << PCIE2);#elif defined ARDUINO_MY_COUNTERinitEncoders();#endifinitMotorController();resetPID();
#endif/* Attach servos if used */#ifdef USE_SERVOSint i;for (i = 0; i < N_SERVOS; i++) {servos[i].initServo(servoPins[i],stepDelay[i],servoInitPosition[i]);}#endif}
5.测试

编译并上传程序,打开串口监视器,然后旋转车轮,在串口监视器中录入 e 即可查看左右编码器计数,录入命令 r 可以重置计数。


http://www.ppmy.cn/news/1461578.html

相关文章

1.柔性数组

1.柔性数组 我们先来介绍一下什么是柔性数组&#xff1a; 在C语言中&#xff0c;柔性数组&#xff08;Flexible Array&#xff09;并不是一个标准的术语&#xff0c;但它通常指的是结构体中最后一个元素是一个没有指定大小的数组。这种结构体设计允许在运行时动态分配数组的大…

【SpringSecurity源码】过滤器链加载流程

theme: smartblue highlight: a11y-dark 一、前言及准备 1.1 SpringSecurity过滤器链简单介绍 在Spring Security中&#xff0c;过滤器链&#xff08;Filter Chain&#xff09;是由多个过滤器&#xff08;Filter&#xff09;组成的&#xff0c;这些过滤器按照一定的顺序对进…

Mybatis使用PageHelper实现基本的分页查询

我们的分页查询其实是基于我们的SQL语句里面的limit来实现的 首先我们来使用一下我们Mybatis里面的分页查询 其实我们的Mybatis实现分页查询是用一个PageHelper插件 首先我们引入对应的Maven依赖 <dependency><groupId>com.github.pagehelper</groupId>&l…

CSRF 攻击实验:Token 不存在绕过验证

前言 CSRF&#xff08;Cross-Site Request Forgery&#xff09;&#xff0c;也称为XSRF&#xff0c;是一种安全漏洞&#xff0c;攻击者通过欺骗用户在受信任网站上执行非自愿的操作&#xff0c;以实现未经授权的请求。 CSRF攻击利用了网站对用户提交的请求缺乏充分验证和防范…

MongoDB聚合运算符:$toObjectId

MongoDB聚合运算符&#xff1a;$toObjectId 文章目录 MongoDB聚合运算符&#xff1a;$toObjectId语法使用举例 $toObjectId聚合运算符将指定的值转换为ObjectId。如果值无法被转换为ObjectId&#xff0c;则报错。 语法 {$toObjectId: <expression> }$toObjectId接受任何…

如何搭建本地DNS服务器

一、搭建本地DNS服务器 1.初始化设置 systemctl disable --now firewalld.service #关闭防火墙&#xff0c;并开机不自启 setenforce 0 #临时关闭selinux防火墙 vim /etc/selinux/config …

[AutoSar]BSW_Diagnostic_002 DCM模块介绍

目录 关键词平台说明背景一、DCM所处架构位置二、DCM 与其他模块的交互三、DCM 的功能四、DCM的内部子模块4.1 Diagnostic Session Layer (DSL)4.1 DSL 与其他模块的交互 4.2 Diagnostic Service Dispatcher (DSD)4.3 Diagnostic Service Processing (DSP)4.4 小结 关键词 嵌入…

Objective-C的对象复制与拷贝选项

对象复制与拷贝 文章目录 对象复制与拷贝copy与mutablecopycopy与mutablecopy的简介示例&#xff1a;不可变对象的复制可变对象的复制 NSCopying和NSMutableCopying协议深复刻和浅复刻浅拷贝&#xff08;Shallow Copy&#xff09;&#xff1a;深拷贝&#xff08;Deep Copy&…