Hasense.Yan 发表于 2015-1-7 17:13:34

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

本帖最后由 Hasense.Yan 于 2015-1-7 17:12 编辑

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

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

volatile unsigned long intspeed;    // 编码器旋转计数
unsigned long tStop1 ,tStop2;               
int intperiod;                               
boolean bState,bspeed;
boolean bRun,bStop;

void Step(unsigned int ratio)                // 驱动步进函数
{               
        digitalWrite(Plu,HIGH);
        delayMicroseconds(ratio);
        digitalWrite(Plu,LOW);
        delayMicroseconds(ratio);        
}
void Speed()                        //   定时中断函数
{
        if(intNspeed>0)
        {
          intspeed=intNspeed;
          
        }
        if(intPspeed>0)
        {
          intspeed=intPspeed;
          
        }
        intNspeed=0;
        intPspeed=0;
        //Serial.println(intspeed);        //**********AA 此处数据显示正常(0到200变化)
}
void setup()
{
        Serial.begin(9600);
        intperiod=500;

        pinMode(4, OUTPUT);
        pinMode(13, OUTPUT);
    pinMode(Plu, OUTPUT);
    pinMode(Dir, OUTPUT);
    pinMode(BtnS1, INPUT_PULLUP);
    pinMode(BtnS10, INPUT_PULLUP);
       

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

        bState=false;
        intNspeed=0;
        intPspeed=0;
        intspeed=0;

}

void loop()
{   

if(!bspeed)                                                                                                //
{
if(digitalRead(EA)==HIGH && bState==LOW)
{
       
    if(digitalRead(EB)==HIGH)
    {
                intNspeed++;
                digitalWrite(Dir,LOW);
      bRun=true;
    }
    else
    {
                intPspeed++;
                digitalWrite(Dir,HIGH);
                bRun=true;
      
    }
}
bState=digitalRead(EA);
}
//        判断旋转编码器停止
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)
{
          if(!bStop)
          {
                   tStop1=millis();
                   bStop=true;
          }
          tStop2=millis();       
          if((tStop2-tStop1)>100)
          {
          bStop=false;
                bRun=false;
          tStop1=0;
          tStop2=0;
          }
}
else
{
          bStop=false;
          tStop1=0;
          tStop2=0;
}

/////////////       
        if(bRun)
        {
                //Serial.println(intspeed);        //**********BB 显示不正常(0到20 不正确跳变)
                Step(intspeed);
               
        }

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

野鬼{ABO} 发表于 2015-1-7 19:26:44

何必去测转速呢?直接测A机的脉冲频率,发给第二个电机驱动不就玩了

Hasense.Yan 发表于 2015-1-8 08:50:13

野鬼{ABO} 发表于 2015-1-7 19:26 static/image/common/back.gif
何必去测转速呢?直接测A机的脉冲频率,发给第二个电机驱动不就玩了

先感谢您的回复.我的旋转编码器不是A机,是一个电子手轮,个人想通过手轮来调节步进马达位置...
而且我现在最纠结的是中断内与外部同一数据,为何显示结果不一样??
页: [1]
查看完整版本: UNO 用定时器测速旋转编码器,并及时驱动步进马达