极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12532|回复: 2

UNO 用定时器测速旋转编码器,并及时驱动步进马达

[复制链接]
发表于 2015-1-7 17:13:34 | 显示全部楼层 |阅读模式
本帖最后由 Hasense.Yan 于 2015-1-7 17:12 编辑

1.问题背景:用Arduino Uno测速旋转编码器,用得到的数据及时驱动步进马达旋转,希望达到速度同步,及编码器旋转速度快,则马达转速快.
2.编程思路: 在LOOP循环中实时检测编码器A B信号.完用定时器中断每隔500ms取一次计数值
3.现在问题: 在中断函数中查看计数值(代码备注中的//****AA处),数值显示正常,一旦跳出中断函数,在其它位置查看计数值(如备注中的//******BB处),则数据显示错误.
  1. #include "MsTimer2.h"

  2. const int Plu = 6;                //步进马达脉冲
  3. const int Dir = 7;                //步进马达方向
  4. const int BtnS1 = 4;
  5. const int BtnS10 = 3;
  6. const int EA = 8;                //   编码器信号A
  7. const int EB = 9;                //   编码器信号B
  8. volatile unsigned long intNspeed ;  // 编码器反向旋转计数
  9. volatile unsigned long intPspeed;   // 编码器正向旋转计数

  10. volatile unsigned long intspeed;    // 编码器旋转计数
  11. unsigned long tStop1 ,tStop2;               
  12. int intperiod;                               
  13. boolean bState,bspeed;
  14. boolean bRun,bStop;

  15. void Step(unsigned int ratio)                // 驱动步进函数
  16. {               
  17.         digitalWrite(Plu,HIGH);
  18.         delayMicroseconds(ratio);
  19.         digitalWrite(Plu,LOW);
  20.         delayMicroseconds(ratio);        
  21. }
  22. void Speed()                        //   定时中断函数
  23. {
  24.         if(intNspeed>0)
  25.         {
  26.           intspeed=intNspeed;
  27.           
  28.         }
  29.         if(intPspeed>0)
  30.         {
  31.           intspeed=intPspeed;
  32.           
  33.         }
  34.         intNspeed=0;
  35.         intPspeed=0;
  36.         //Serial.println(intspeed);        //**********AA 此处数据显示正常(0到200变化)
  37. }
  38. void setup()
  39. {
  40.         Serial.begin(9600);
  41.         intperiod=500;

  42.         pinMode(4, OUTPUT);
  43.         pinMode(13, OUTPUT);
  44.     pinMode(Plu, OUTPUT);
  45.     pinMode(Dir, OUTPUT);
  46.     pinMode(BtnS1, INPUT_PULLUP);
  47.     pinMode(BtnS10, INPUT_PULLUP);
  48.        

  49.          MsTimer2::set(intperiod, Speed); // 500ms period
  50.          MsTimer2::start();

  51.         bState=false;
  52.         intNspeed=0;
  53.         intPspeed=0;
  54.         intspeed=0;

  55. }

  56. void loop()
  57. {   

  58. if(!bspeed)                                                                                                //
  59. {
  60.   if(digitalRead(EA)==HIGH && bState==LOW)
  61.   {
  62.        
  63.     if(digitalRead(EB)==HIGH)
  64.     {
  65.                 intNspeed++;
  66.                 digitalWrite(Dir,LOW);
  67.         bRun=true;
  68.     }
  69.     else
  70.     {
  71.                 intPspeed++;
  72.                 digitalWrite(Dir,HIGH);
  73.                 bRun=true;
  74.       
  75.     }
  76.   }
  77.   bState=digitalRead(EA);
  78. }
  79. //        判断旋转编码器停止
  80.   if(((digitalRead(EA)==HIGH && digitalRead(EB)==HIGH) || (digitalRead(EA)==LOW && digitalRead(EB)==LOW)|| (digitalRead(EA)==HIGH && digitalRead(EB)==LOW)|| (digitalRead(EA)==LOW && digitalRead(EB)==HIGH))&& bRun)
  81.   {
  82.           if(!bStop)
  83.           {
  84.                    tStop1=millis();
  85.                    bStop=true;
  86.           }
  87.           tStop2=millis();       
  88.           if((tStop2-tStop1)>100)
  89.           {
  90.             bStop=false;
  91.                 bRun=false;
  92.             tStop1=0;
  93.             tStop2=0;
  94.           }
  95.   }
  96.   else
  97.   {
  98.           bStop=false;
  99.           tStop1=0;
  100.           tStop2=0;
  101.   }

  102.   /////////////       
  103.           if(bRun)
  104.         {
  105.                 //Serial.println(intspeed);        //**********BB 显示不正常(0到20 不正确跳变)
  106.                 Step(intspeed);
  107.                
  108.         }

  109. }
复制代码
求大神指点,为何两处显示同一数据,但值不一样
或有更好的方案处理旋转编码器实时驱动步进电机,谢谢...
回复

使用道具 举报

发表于 2015-1-7 19:26:44 | 显示全部楼层
何必去测转速呢?直接测A机的脉冲频率,发给第二个电机驱动不就玩了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-1-8 08:50:13 | 显示全部楼层
野鬼{ABO} 发表于 2015-1-7 19:26
何必去测转速呢?直接测A机的脉冲频率,发给第二个电机驱动不就玩了

先感谢您的回复.我的旋转编码器不是A机,是一个电子手轮,个人想通过手轮来调节步进马达位置...
而且我现在最纠结的是中断内与外部同一数据,为何显示结果不一样??
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-8 11:19 , Processed in 0.046454 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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