一、应用场景
1.电子设备:由于AEDR-8400体积小、重量轻,非常适合应用在小型电子设备中,如可穿戴设备、智能手机、平板电脑等,用于实现旋转角度的检测和位置反馈。
2.机器人技术:机器人领域需要对关节和执行器进行精确控制,并获取准确的位置信息。
3.AEDR-8400x可以用于机器人关节的位置检测,从而实现精确的运动控制和路径规划。
4.自动化设备:在自动化设备中,光学编码器被广泛用于传送带、机床、印刷机等各种设备上,用于实时监测和控制位置、速度和加速度,以提高生产效率和质量。
5.医疗设备:AEDR-8400光学编码器的小尺寸和高分辨率使其非常适合用于医疗设备中,如手术机器人、影像设备等,用于精确的位置控制和手术操作。
6.智能家居:在智能家居领域,AEDR-8400可以用于控制家电设备、窗帘、门锁等的位置和运动,实现自动化控制和智能化操作。
对比磁性编码器有何优势?
反射式光学编码器有更高的分辨率(磁性编码器的最高上限约为150 LPI),在马达控制应用中,磁性编码器较低的分辨率会引起马达振动的转矩脉动,同时还会产生磁场,因此还需要增加磁场屏蔽功能以避免干扰邻近元器件的正常工作。------摘自通信与网络中的安华高推出业内最小的光学编码器
二、工作原理
AEDR-8400系列是采用反射技术进行运动控制的最小光学编码器。编码器将发射器和检测器组合在一个表面贴装无引线封装中。当与编码盘或线性编码条一起使用时,编码器将旋转或线性运动转换为数字输出。
原理框图如下:
为什么要和码盘或线性编码条一起使用?
这是因为编码盘(或线性编码条)上的刻度或图案通常是由黑色和白色等反射率不同的区域组成。当光照到黑白交替的区域时,光电传感器会产生相应的电信号变化,从而生成脉冲信号。而AEDR-8400光学编码器通常输出两路AB相位脉冲信号。我们根据脉冲信号的数量和相位变化,可以确定编码盘(或线性编码条)的转动角度和方向。通过计算和解析脉冲信号,可以精确测量位置、速度和加速度等参数。
输出波形图如下:
三、软件配置
1.初始化配置代码如下(示例):
根据上面的输出波形,我们选择高级定时器的定时器编码器模式
/*******************************************************************************
* 函数名:User_Time1_Init
* 描述 :定时器1编码器设置
* 输入 :void
* 输出 :void
* 调用 :初始化
* 备注 :
*******************************************************************************/
void User_Time1_Init(void)
{
gpio_init_type gpio_init_struct;
crm_clocks_freq_type crm_clocks_freq_struct;
/* get system clock */
crm_clocks_freq_get(&crm_clocks_freq_struct);
/* enable tmr1/gpioa clock */
crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
crm_periph_clock_enable(TIM_GPIO_CLOCK, TRUE);
/* timer1 output pin Configuration */
gpio_init_struct.gpio_pins = TIM_CH1Pin | TIM_CH2Pin;//PA8:CHA,PA9:CHB
gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
gpio_init(TIM_GPIO, &gpio_init_struct);
gpio_pin_mux_config(TIM_GPIO, GPIO_PINS_SOURCE8, GPIO_MUX_2);
gpio_pin_mux_config(TIM_GPIO, GPIO_PINS_SOURCE9, GPIO_MUX_2);
/* tmr1 encoder mode configuration //TMRL编码器模式配置
tmr1 ti1pf1 ,ti2fp2 as encoder input pin, tmr1 counter //TMRL ti1pf1 ,ti2fp2作为编码器输入引脚
changed each signal edge. */ //TMRL计数器改变了每个信号边缘
tmr_base_init(TMR1, 0xFF, 0);//初始化 TMR 周期、分频
tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);//设置 TMR 计数器计数方向
/* config encoder mode */
tmr_encoder_mode_config(TMR1, TMR_ENCODER_MODE_C, TMR_INPUT_BOTH_EDGE, TMR_INPUT_BOTH_EDGE);//配置 TMR 编码器模式
/* enable tmr1 */
tmr_counter_enable(TMR1, TRUE);
}
2.获取编码器计数代码如下(示例):
/*******************************************************************************
* 函数名:Time1_Encoder_count
* 描述 :返回定时器编码模式计数
* 输入 :void
* 输出 :uint32_t
* 调用 :初始化
* 备注 :
*******************************************************************************/
uint32_t Time1_Encoder_count(void)
{
return tmr_counter_value_get(TMR1);
}
3.光编码器应用识别代码如下(示例):
/*******************************************************************************
* 函数名:Encoder_application
* 描述 :编码器判断
* 输入 :void
* 输出 :void
* 调用 :100ms
* 备注 :
*******************************************************************************/
void Encoder_application(void)
{
Coarse.Last_Light_counting = Coarse.Light_counting;
// printf("Coarse.Last_Light_counting = %d\r\n",Coarse.Last_Light_counting);
Coarse.Light_counting = Time1_Encoder_count();
// printf("Coarse.Light_counting = %d\r\n",Coarse.Light_counting);
if (Coarse.First_Light_counting != Coarse.Light_counting) // 开始转动
{
if (Coarse.Light_counting != Coarse.Last_Light_counting)
{
if (Coarse.Light_counting > Coarse.Last_Light_counting) // 正向
{
// printf("+++ \r\n");
Coarse.Positive_count++;
Coarse.Counter_count = 0;
Coarse.Actual_Light_counting = Coarse.Light_counting - Coarse.Last_Light_counting;
if (Coarse.Positive_count >= Filtering_frequency)
{
Coarse.Positive_count = 0;
if (Coarse.Actual_Light_counting > Zero_Crossing)//过零情况 >200
{
Coarse.Actual_Light_counting = 1;
// printf("Coarse.Actual_Light_counting = %d\r\n",Coarse.Actual_Light_counting);
Send_Cmd6(Coarse.Actual_Light_counting);
}
else
{
// printf("Coarse.Actual_Light_counting = %d\r\n",Coarse.Actual_Light_counting);
Send_Cmd6(Coarse.Actual_Light_counting);
}
}
}
else
{
// printf("--- \r\n");
Coarse.Positive_count = 0;
Coarse.Counter_count++;
Coarse.Actual_Light_counting = abs(Coarse.Light_counting - Coarse.Last_Light_counting);
if (Coarse.Counter_count >= Filtering_frequency)
{
Coarse.Counter_count = 0;
if (Coarse.Actual_Light_counting > Zero_Crossing)//过零情况 >200
{
Coarse.Actual_Light_counting = 1;
// printf("Coarse.Actual_Light_counting = %d\r\n",Coarse.Actual_Light_counting);
Send_Cmd5(Coarse.Actual_Light_counting);
}
else
{
// printf("Coarse.Actual_Light_counting = %d\r\n",Coarse.Actual_Light_counting);
Send_Cmd5(Coarse.Actual_Light_counting);
}
}
}
}
else
{
Coarse.First_Light_counting = Coarse.Light_counting;
}
}
}
这段代码实现了一个光编码器应用的判断功能。在函数Encoder_application中,程序首先获取当前的光编码器计数并将其保存为Coarse.Last_Light_counting,然后再次获取当前的光编码器计数保存为Coarse.Light_counting。接着程序会检查光编码器计数是否发生变化,如果有变化则进行一系列判断:
1.如果光编码器计数递增(即正向转动),则增加Coarse.Positive_count计数,并重置Coarse.Counter_count为0。然后计算实际光编码器计数的变化量Coarse.Actual_Light_counting,并根据一定的条件进行处理和发送命令。
2.如果光编码器计数递减(即反向转动),则重置Coarse.Positive_count为0,增加Coarse.Counter_count计数,并计算实际光编码器计数的变化量Coarse.Actual_Light_counting,同样根据一定的条件进行处理和发送命令。
3.如果光编码器计数没有发生变化,则将当前的光编码器计数赋值给Coarse.First_Light_counting,以备下一次比较使用。
四、总结
以上讲了最小的光编码器AEDR-8400的原理和简单应用,有兴趣的可以看一看,感谢你的观看,谢谢!