wordpress访问子网站/建设网站流程
背景:
我准备用一些零件实现一个写字机器人,因此我开始思考如何去控制它。我准备用一个舵机来控制笔的抬笔、落笔动作,舵机很擅长处理这些因为它很容易集成,它带有反馈功能,总是能知道自己转过的角度。
我也许可以使用grbl,它可以输出步进脉冲和方向信号实现移动,舵机需要一个PWM信号驱动,主轴电机也是用pwm来控制速度的,这或许是个不错的开始。一个PWM信号包含频率和占空比,频率表示信号重复的频繁程度,占空比表示一个周期内逻辑高电平的时长(其余时间低电平)。舵机需要信号周期是20ms(50hz),占空比是1ms的时候在一端点,占空比是2ms的时候转到另一个端点。总结一下就是:
- 0°对应占空比是1ms
- 180°对应占空比是2ms
- 频率是50hz,周期是2ms

PWM被大部分包括arduino在内的微控制器使用,用来控制外围设备,它使用内置的定时器和CPU周期来生成,你只需要设置几个寄存器,并且不依赖代码。主轴使用的是timer2,所有其他定时器已经被grbl的其他功能使用了(在uno版本上),所以其他的是不能再重新定义的。timer2是一个8位的定时器,因此它最高能数到255,然后继续下一个循环。我们不得不面对两个问题:
- 分辨率:舵机的占空比(1ms~2ms)只是周期的一小部分(1ms/20ms),这使得我们只能使用256的1/20,这会限制分辨率,但在这个应用中我们只关心抬笔落笔动作也足够了。
- 频率:在arduino中你不能使用任意的频率,你只能使用一小部分频率,允许使用的频率分别是1/1, 1/8, 1/64, 1/256 & 1/1024,我们只能使用最接近50hz的那个频率。
设置频率:
设置频率的公式为:
Freq = F_CPU / (Prescaler * TimerResolution) Eq #1
- Freq:我们预期的频率50hz
- F_CPU:CPU时钟频率,大部分arduino是16M的
- Prescaler:预分频
- TimerResolution:定时器分辨率
我们可以把上面公式改写为:
Prescaler = F_CPU / Freq / TimerResolution Eq #2
Prescaler = 16 000 000 / 50 / 256 = 1250
1250这是我们期望的,但是没有可以选择的,我们只能选一个最接近的1024,如果我们带入公式1,就得到Freq=61hz,已经足够接近了。
判定占空比:
我们需要知道寄存器比较值,当舵机从一端到另一端时,一个单位的比较值被称为tick,每一个tick的计时器为:
Tick = 1 / (F_CPU / Prescaler) Eq#3
Tick = 1 / (16000000 / 1024) = 0.000064s
这时候我们就可以计算出从一端到另一端的tick数了:
- 0° = 0.001 / 0.000064 = 15.6向上取整得16
- 180° = 0.02 / 0.000064 = 31.25向下取整得31
设置寄存器:
这一部分需要你深入了解arduino的芯片(atmega328p)手册,不过我会做一些简短解释。
TCCR2A = (1<
- 第一行:TCCR2A(timer2的定时器/计数器控制寄存器A),WGM20&WGM21(Waveform Generation Modes)设置模式为Fast PWM模式,COM2A告诉CPU清除compare value当计数器满时。
- 第二行:TCCR2B(timer2的定时器/计数器控制寄存器B),CS22&CS21&CS20,时钟选择位,选择Prescaler为1024.
- 第三行:OCR2A(timer2的输出比较寄存器A),设置为31,控制timer2的占空比。
grbl使用一些别名让代码变得更清晰简单,使用的时候按照实际代码修改即可。
测试:
使用逻辑分析仪,看到结果是:

落笔
落笔时的占空比1.087ms 在61hz下

抬笔
抬笔是占空比为2.047ms 在61hz下