每逢假期的时候,我们都是在最后的时刻知道的放假通知,既不能出去走走,在家无聊的时候,只有陪陪孩子和搞搞自己的硬件设计,这次放假我把淘来的扫地机器人进行了一次大分解。
看到芯查查举办的拆卸活动,正好手头上有这台二手扫地机器人,借这个机会拆开看看,学习一下机器内部的驱动电路。
首先简单介绍一下:
这次拆卸的是智能清扫扫地机器人 SWR-T321,具有智能清扫,干湿两用,超长续航,强力干脱,超大吸力,TAC智能感应,自动回充功能;组成部件:红外信号接收头,保险杠,面板,垃圾盒,水箱/拖布,万向轮,左/右边刷,集尘盒,滤网等等部件(这个组成太多了,稍后一一进行介绍)
工具:万用表,电烙铁,焊锡丝,大十字螺丝刀,小螺丝刀套装
外部分解图片如下





内部电路板图片如下








一:充电基座及虚拟墙拆解
利用万用表测量一下输出充电电源正常,硬件电路如下

二:主机部分介绍:
2.1从正方向观察:
红外信号接收头:
显示窗/按键:显示当前的状态,按键操作机器人工作状态,
保险杠:当左/右保险杠触发到障碍物时候,可以触发该处的限位开关,从而电机改变运行方向。
面板:主要起到外壳支撑的作用,而且看起来比较美观。
中间盖:按下时,可以弹起,拿出垃圾盒。
2.2从底部将所有的螺丝拆掉,拖布拆掉,左右侧的保险杠拆掉
我拆的时候不小心把前面的开关弄坏了,不过没关系有电烙铁可以补救。
下面我简单介绍一下板子内部的结构和各个负载电机
1:小型喇叭:可以提示内部支持的语音包:比如:充电已完成,电量不足请及时充电等等。
2:左右轮电机:主要功能是将垃圾扫到电机的垃圾盒内,从而达到清扫的目的。
3:左右行走电机:此处电机为万向轮电机,可以实现任意角度的转向功能。
4:中间电机:此处也为万向轮电机,可以在任意角度下转向。
5:计数检测:两侧的行走电机具有计数检测功能,可以记录行走的距离。
2.3 介绍负载控制方式:
1:中间电机为直流电机,
2:两侧电机为步进电机,
显示电路分析:
显示电路使用的74HC595进行驱动,可以省下很多IO口。

软件驱动代码如下:
void Display_Out()
{
delay_cycles(32);
HC595_RCK(0);
delay_cycles(32);
HC595_RCK(1);
}
void HC595_WriteData(uint8_t data)
{
uint8_t i;
for(i = 0; i < 8; i++)
{
if((data & 0x80)>0){
HC595_DAT(1);
}
else {
HC595_DAT(0);
}
HC595_CLK(0);
delay_cycles(32);
HC595_CLK(1);
delay_cycles(32);
data <<= 1;
}
}
void HC595_SEND_DATA(uint8_t disp_num, uint8_t disp_bit)
{
HC595_WriteData(disp_num);
HC595_WriteData(1<<disp_bit);
Display_Out();
}
电机控制分析部分:
STM32上面有很多的定时器,控制左右两侧的行走电机,我觉得是利用PWM(等有时间利用芯查查兑换的示波器测试一下)
简单介绍一下PWM技术:
利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。 PWM是一种对模拟信号电平进行数字编码的方法。 通过高分辨率计数器的使用,方波的占空比被调制用来对一个 具体 模拟信号的电平进行编码。
扫地机器人的电机是带编码的电机,这种电机可以将实际的电机行走情况反馈给主控制器,从而实现左右行走,其原理如下:
其中左转,右转,都是根据两个轮子的速度差实现;
左轮速度>右轮速度;则向右边转弯;
左轮速度<右轮速度;则向左转弯;
速度差越大,转弯越大;因此可以设置速度差,实现大转弯和小转弯的目的;
当一个轮子的速度为0,另外一个轮子有速度的时候,会绕着速度为0的轮子转圈,转圈的半径为两个轮子的轮间距,但是实际上,会发生轮子打滑的情况,所以会有点偏移;
由于是步进电机作为动力,因此,可以控制电机的速度,进行小车的速度控制。因此,实际控制小车的几个动作,实际就转化为控制电机的速度。
硬件电路分析:

控制PWM输出应该时利用的某个定时器的硬件PWM输出功能。
下面我简单介绍下TIM的PWM输出测试:
函数分为:定时器的初始化,重设PWM的输出频率函数
/*****************************************************************************************
重新设定PWM脉冲频率值
重新设定保持占空比不变
输入参数iFre:目标频率值(单位0.1HZ)
需要经过计算,将目标频率值转换成分频系数
TIM5 Frequency = TIM5 counter clock/(iFre + 1)
*****************************************************************************************/
void ReSetPulseFre(int iFre)
{
int k;
/* -----------------------------------------------------------------------
TIM5 Configuration: generate 1 PWM signals at 50%:
TIM5CLK = 36 MHz, Prescaler = 0x0, TIM5 counter clock = 36 MHz
TIM5 ARR Register = 999 => TIM5 Frequency = TIM5 counter clock/(ARR + 1)
TIM5 Frequency = 36 KHz.
TIM5 Channel1 duty cycle = (TIM5_CCR1/ TIM5_ARR)* 100 = 50%
----------------------------------------------------------------------- */
// k =360000000/iFre;
k =36000000/iFre; //10分频
TIM5_TimeBaseStructure.TIM_Period = k - 1;
TIM_TimeBaseInit(TIM5, &TIM5_TimeBaseStructure);
TIM5_OCInitStructure.TIM_Pulse = k/2;
TIM5_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM5, &TIM5_OCInitStructure);
}
/*************************************************************************
SetServoMotorSpeed
设置伺服电机速度
输入参数:速度,0-500.0 mm/min 的升降速度,需要将其转化成电机速度值
执行结果:将速度值转换成脉冲速率,然后根据脉冲速率计算PWM分频系数
执行本函数后,无需重新启动电机即可生效。
注意一个关键常量PULSERPM,编码器与电机旋转角度对应关系。
*************************************************************************/
void SetServoMotorSpeed(int iSpeed)
{
//将速度转换成每秒脉冲数
int PulsePerS;
int Motorrpm;
Motorrpm = iSpeed * iEELoadSpeedScale/100.0; //
PulsePerS = (Motorrpm * iEEMotorSpeedScale)/60.0;
CURRsiMotor2OutSpeed = iSpeed;
ReSetPulseFre(PulsePerS); //设定PWM频率(包含1位小数)
}
/*************************************************************************************
PulseGenerator_TIMxInit
脉冲发生器的TIM5定时器初始化
功能:初始化O1HS输出口,使其具备产生频率可调的脉冲配置
默认的PWM频率:36K (电机默认速度)
注意:仅仅完成初始化,不启动PWM输出
*************************************************************************************/
void PulseGenerator_TIMxInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* -----------------------------------------------------------------------
TIM5 Configuration: generate 1 PWM signals at 50%:
TIM5CLK = 36 MHz, Prescaler = 0x0, TIM5 counter clock = 36 MHz
TIM5 ARR Register = 999 => TIM5 Frequency = TIM5 counter clock/(ARR + 1)
TIM5 Frequency = 36 KHz.
TIM5 Channel1 duty cycle = (TIM5_CCR1/ TIM5_ARR)* 100 = 50%
----------------------------------------------------------------------- */
/* Time base configuration */
TIM5_TimeBaseStructure.TIM_Period = 999;
TIM5_TimeBaseStructure.TIM_Prescaler = 9; //10分频
TIM5_TimeBaseStructure.TIM_ClockDivision = 0;
TIM5_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM5, &TIM5_TimeBaseStructure);
/* PWM1 Mode configuration: Channel1 */
TIM5_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM5_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM5_OCInitStructure.TIM_Pulse = TIM5DefaultCCR1_Val;
TIM5_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM5, &TIM5_OCInitStructure);
TIM_OC1PreloadConfig(TIM5, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM5, ENABLE);
//TIM5 CH1 IO config
/*GPIOA Configuration: TIM5 channel 1 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*GPIOA Configuration: PA1 作为方向选择端子*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
u8CurrMotorRunDir = 0;
}
后记:
如果说没有芯查查举办的这次拆卸活动,估计我也不去拆卸这台二手扫地机器人,显然是几年前的产品,利用的还是STM32的主控。现在国产32的崛起,国内平台也越来越完善,不过ST32里电机驱动部分是值得我们去学习的。类似于APM32的低压电机评估版一样,不仅仅有电压控制,还有电流检测,霍尔计数等等,这些功能国内已经有很多厂家可以做到,甚至比
STM32做的还要好,等有时间自己也做一个电机控制小车,借鉴这次拆卸的机会和之前参加APM32积累下来的经验,难度应该是不大。
这些就是我拆卸家用扫地机器人的全部过程,图片和视频资料,当然拆卸的过程中我家的小伙伴也是在一旁帮我,真的很感谢她,要不我早就写好了……
全部评论