虚幻的是灵魂 发表于 2024-8-3 10:23

关于平衡小车编码器知识总结

#申请原创# @21小跑堂
编码器组成

1、左侧的减速齿轮
2、中间的电机部分
3、右侧的电路板减速齿轮将电机转速通过齿轮按照一定比例进行降速。电路板

电路板中,包含了一个圆形磁体,还有两个霍尔传感器。电机转动时,圆形的磁体会同步进行转动,传动过程

1、电机转动时,中轴会转动
2、中轴和圆形磁铁是连在一起的,圆形磁铁也会同步转动
3、中轴的一端和减速齿轮连接在一起,中轴转动会带动齿轮按照一定的比例进行转动(减速比)。霍尔传感器

开发板中包括了两个霍尔传感器,一个磁铁。磁铁是由7对N极和S极组成的。1、当电机转动时,磁铁也转动。
2、当磁铁的N极正对霍尔传感器时,霍尔传感器会将这个信号转化为高电平。
3、当磁铁的S极正对霍尔传感器时,霍尔传感器会将这个信号转化为低电平。
4、通过记录高低电平变换次数,可以得到电机中轴转动的速度。重要的概念名称减速比和额定转速以下是以N20电机为例,N20的规格参数,其中我们关注额定转速和减速比。额定转速:rpm,全称Revolutions Per Minute,每分钟转动的圈数,说的时末端连接轴的转速。减速比:电机中轴连接了齿轮,当中轴转动时,齿轮随着中轴转动而转动,最终传导到末端连接轴。末端连接轴的速度,被减速齿轮降低了,末端连接轴和中轴的速度比就是减速比。例如rpm为300,减速比为50,那么电机中轴的转速为300*50 = 15000转/分
轮子行进速度我们知道,速度=距离/时间轮子是和末端连接轴连接在一起的,RPM为300时,轮子1分钟可以转300圈,那轮子可以走过的距离我们是可以求出来的。转一圈,就是轮子的一个周长,周长=2ΠR因此,在RPM为300时,轮子的速度为 300(rpm) x 43(直径) x Π / 60得出结果为 675.442409 mm/s,换算下来差不多为 0.6到0.7米/秒
霍尔传感器采样两个霍尔传感器加上磁铁,可以测出电机的转速和方向。1、当A传感器是上升沿时,如果B此时为低电平,那么就是反转。
2、当A传感器是上升沿时,如果B此时为高电平,那么就是正转。
3、产生一次上升沿或者下降沿,就记一次数,通过时间就可以测出当前的转速了。对于霍尔采样,我们可以通过外部中断方式进行实现,代码如下:外部中断实现电机计数功能#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "Usart.h"

#include "I2C.h"
#include "bsp_mpu6050.h"
#include "inv_mpu.h"
#include "inv_mpu_dmp_motion_driver.h"


FlagStatus pre = RESET;
int8_t dir = 1;
int32_t cnt = 0;

void Usart0_recv(uint8_t* data, uint32_t len) {
    printf("recv: %s\r\n", data);

}

static void EXTI8_config() {
    uint32_t extix = EXTI_8;
    uint32_t extix_irq = EXTI5_9_IRQn;
    uint32_t extix_irq_pre = 1;
    uint32_t extix_irq_sub = 1;

    uint32_t extix_trig = EXTI_TRIG_RISING;

    uint32_t extix_rcu = RCU_GPIOB;
    uint32_t extix_port = GPIOB;
    uint32_t extix_pin = GPIO_PIN_8;
    uint32_t extix_pupd = GPIO_PUPD_NONE;
    uint32_t extix_src_port = EXTI_SOURCE_GPIOB;
    uint32_t extix_src_pin = EXTI_SOURCE_PIN8;

    /*************** gpio ****************/
    // PA0,
    // 时钟初始化
    rcu_periph_clock_enable(extix_rcu);
    // 配置GPIO模式
    gpio_mode_set(extix_port, GPIO_MODE_INPUT, extix_pupd, extix_pin);

    /*************** exti ****************/
    // 时钟配置
    rcu_periph_clock_enable(RCU_SYSCFG);
    // 配置中断源
    syscfg_exti_line_config(extix_src_port, extix_src_pin);
    // 中断初始化
    exti_init(extix, EXTI_INTERRUPT, extix_trig);

    // 配置中断优先级
    nvic_irq_enable(extix_irq, extix_irq_pre, extix_irq_sub);
    // 使能中断
    exti_interrupt_enable(extix);
    // 清除中断标志位
    exti_interrupt_flag_clear(extix);
}

void EXTI5_9_IRQHandler() {
    // 判断寄存器状态
    if(SET == exti_interrupt_flag_get(EXTI_8)) {
      FlagStatus current = gpio_input_bit_get(GPIOB, GPIO_PIN_9);
      if(RESET == current && SET == pre) {
            pre = current;
            dir = 1;
            //cnt = 0;
      } else if(SET == current && RESET == pre) {
            pre = current;
            dir = -1;
            //cnt = 0;
      }
      cnt += dir;
      printf("cnt: %d\r\n", cnt);

      // 清除中断标志位
      exti_interrupt_flag_clear(EXTI_8);
    }

}

static void GPIO_config() {
    rcu_periph_clock_enable(RCU_GPIOB);
    gpio_mode_set(GPIOB, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_9);
}

int main(void)
{
    nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
    systick_config();
    GPIO_config();
    Usart_init();
    EXTI8_config();

    while(1) {

    }
}正交编码正交编码是一种用于测量旋转位置或速度的技术。它通常涉及到两个相位差90度的信号(A相和B相)。这两个信号通过光电传感器、磁性传感器或其他位置传感器生成。正交编码的主要原理是通过检测A相和B相信号的相对相位变化来确定旋转的方向和步数。
A相和B相信号: A相和B相信号是两个相位差90度的正弦波形或方波形。这两个信号的变化在旋转方向上具有差异。相位关系: 如果A相先于B相发生变化,系统会认为是顺时针旋转;如果B相先于A相发生变化,系统会认为是逆时针旋转。通过检测这两个信号的相对相位变化,可以确定旋转的方向。脉冲计数: 在正交编码器中,每个脉冲表示一个步进。通过计数脉冲的数量,可以确定旋转的总步数。增量式测量: 正交编码器提供的是增量式的测量,而不是绝对位置。为了得到绝对位置,通常需要在系统启动时将编码器归零,然后开始测量。当前的电机测速传感器满足这种结构和表现。在GD32中,配置正交编码如下:
正交编码配置// 输入配置
timer_ic_parameter_struct tips;
timer_channel_input_struct_para_init(&tips);
tips.icfilter = 10;
timer_input_capture_config(timerx, TIMER_CH_0, &tips);

timer_quadrature_decoder_mode_config(timerx,
                                     TIMER1_QUADRATURE_DECODER_MODE,
                                     TIMER1_QUADRATURE_DECODER_IC0,
                                     TIMER1_QUADRATURE_DECODER_IC1);对于正交编码采样逻辑如下:正交编码采样short Timer1_input_read() {
    uint32_t timerx = TIMER1;

    short value = 0;
    value = (short)timer_counter_read(timerx);
    timer_counter_value_config(timerx, 0);
    return value;
}





lulugl 发表于 2024-8-9 09:15

这个文档经典教程,看了以后明白如何测速与测方向。

地瓜patch 发表于 2024-8-12 21:43

这个编码器是自己做的么?成本多少?

地瓜patch 发表于 2024-8-13 23:14

和电机一起买的,还是单买编码器?

丙丁先生 发表于 2024-8-31 23:19

页: [1]
查看完整版本: 关于平衡小车编码器知识总结