极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 34105|回复: 9

中断方式产生高频舵机信号

[复制链接]
发表于 2012-11-12 17:54:05 | 显示全部楼层 |阅读模式
本帖最后由 johnsonzzd 于 2012-11-14 21:10 编辑

arduino自带的舵机库产生的标准舵机信号频率50Hz,周期20ms。如果希望控制系统的响应速度更快,以更高的频率控制舵机或者电调之类的装置,50Hz是不够的。很多舵机和电调可以接受更高的控制频率,比如好盈电调信号频率为50-432Hz,数码舵机可以到333Hz。下面的程序用中断的方式产生244Hz舵机信号,改变设置后可以达到487Hz。
参考:http://scolton.blogspot.com/2010 ... -servo-routine.html


  1. // servo PWM value
  2. //  |-----------|-----------|
  3. // 250         375         500
  4. // 1ms        1.5ms        2ms
  5. unsigned int servopwm;
  6. const int pwm_pin=9;


  7. void setup()
  8. {
  9.         Serial.begin(9600);        // opens serial port, sets data rate to 9600 bps

  10.         cli();      // disable interrupts while messing with their settings

  11.         // TIMER1 SETUP FOR SERVOS
  12.         // set Timer1 to clk/64 and 10-bit fast PWM
  13.         // this is a period of 4.1ms for 16MHz clk. 16000000/(64*(1+2^10))=243.9Hz, 4.1mm
  14.         // 好盈电调响应频率范围50Hz—432Hz;若设为clk/64,10-bit,则487Hz,超出电调响应能力。
  15.         // -----------------------
  16.         // Timer 1 register: WGM12, WGM11 and WGM10 sets Fast PWM, 10-bit mode.
  17.         //"ATmega4_88_168_328_DataSheet,Table 16-4"
  18.         TCCR1A = 0;
  19.         TCCR1A =  _BV(WGM12) | _BV(WGM11) | _BV(WGM10);
  20.         // Set the prescaler to 64
  21.         TCCR1B = 0;
  22.         TCCR1B = _BV(WGM12) | _BV(CS11) | _BV(CS10);
  23.         // enable Timer1 compare match and overflow interrupts
  24.         TIMSK1 =  _BV(OCIE1A) | _BV(TOIE1);

  25.         sei();       // turn interrupts back on

  26.         pinMode(pwm_pin, OUTPUT);
  27. }

  28. // timer1比较中断,控制高电平脉宽。
  29. // --------------------------
  30. ISR(TIMER1_COMPA_vect)
  31. {
  32.         // interrupt on Timer1 compare match
  33.         // (end of the servo pulse)

  34.         digitalWrite(pwm_pin, LOW);

  35.         // set the compare match to the new servo pulse duration
  36.         OCR1AH = servopwm >> 8;
  37.         OCR1AL = servopwm & 0xFF;

  38.         return;
  39. }

  40. //timer1溢出中断,控制总周期
  41. ISR(TIMER1_OVF_vect)
  42. {
  43.         // interrupt on Timer1 overflow
  44.         // start of the next servo pulse

  45.         digitalWrite(pwm_pin, HIGH);

  46.         return;
  47. }

  48. void loop()
  49. {
  50.         static int i=250;
  51.         Serial.println(i);

  52.         i+=2;
  53.         if(i<=400)
  54.                 servopwm = i;
  55.         else
  56.                 i=250;
  57.        
  58.         delay(500);
  59. }
复制代码


下面是用示波器观察到的servopwm=375时产生的1.5ms脉冲


====================================================
重复造轮子了。在动力老男孩的网页上看到可以直接修改自带的舵机库达到这个目的。自带的servo库默认的频率是50Hz,但是可以在它的头文件Servo.h中修改。修改下面这行可以把PWM频率升到400Hz:
#define REFRESH_INTERVAL 2500
刷新间隔改为2.5ms,但是这时就只能容纳一个舵机的信号了。servo库也是通过上面这种中断方式实现的

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复

使用道具 举报

发表于 2012-11-12 19:12:43 | 显示全部楼层
其实真看不懂
回复 支持 反对

使用道具 举报

发表于 2012-11-12 19:29:23 | 显示全部楼层
这里厉害~~~学习了~~~~
回复 支持 反对

使用道具 举报

发表于 2012-11-12 20:07:59 | 显示全部楼层
示波器很贵
回复 支持 反对

使用道具 举报

发表于 2012-11-12 20:22:27 | 显示全部楼层
学习学习学习
回复 支持 反对

使用道具 举报

发表于 2013-8-6 19:49:42 | 显示全部楼层
”刷新间隔改为2.5ms,但是这时就只能容纳一个舵机的信号了“,不太明白这就话是什么意思。如果刷新间隔改为5毫秒,是不是就可以容纳2个舵机的信号了?是芯片的速度的原因吗?
回复 支持 反对

使用道具 举报

发表于 2013-8-6 19:52:58 | 显示全部楼层
另外,我理解一个舵机的PWM频率应该是出厂设计好的,而不是可以随意设置的。对吗?
回复 支持 反对

使用道具 举报

发表于 2013-8-7 08:43:24 | 显示全部楼层
zintiger 发表于 2013-8-6 19:49
”刷新间隔改为2.5ms,但是这时就只能容纳一个舵机的信号了“,不太明白这就话是什么意思。如果刷新间隔改为 ...

20ms长度的舵信号,只有前2.5ms的各种高电平时间是控制字,后面(20-2.5)全是低电平时间!所以50HZ的舵机控制信号单次周期内,理论上可以容纳20/2.5=8个,刚刚正好......
回复 支持 反对

使用道具 举报

发表于 2013-8-11 20:57:56 | 显示全部楼层
拾瑞 发表于 2013-8-7 08:43
20ms长度的舵信号,只有前2.5ms的各种高电平时间是控制字,后面(20-2.5)全是低电平时间!所以50HZ的舵机控 ...


谢谢。可以理解为20ms的信号周期内,高电平的时间不小于2.5ms吧。
回复 支持 反对

使用道具 举报

发表于 2017-5-26 09:02:06 | 显示全部楼层
这个厉害,刚好最近在弄舵机~
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 需要先绑定手机号

Archiver|联系我们|极客工坊

GMT+8, 2024-4-26 22:25 , Processed in 0.051236 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表