| 在本篇文章中,我们将学习旋转编码器的工作原理以及如何将其与Arduino开发板一起使用。旋转编码器是一种位置传感器,用于确定旋转轴的角度位置。它根据旋转运动产生模拟或数字电信号。 
  有许多不同类型的旋转编码器,可通过输出信号或传感技术进行分类。在本篇文章中,我们使用的特定旋转编码器是增量式旋转编码器,它是测量旋转的最简单的位置传感器。 
  
 该旋转编码器也称为正交编码器或相对旋转编码器,其输出是一系列方波脉冲。 
 旋转编码器的工作原理 让我们详细了解编码器,看看它的工作原理。以下是方波脉冲的产生方式:编码器有一个带有均匀间隔的接触区的磁盘,它们连接到公共引脚C和另外两个独立的接触引脚A和B,如下图所示。 
  当磁盘逐步开始旋转时,引脚A和B将开始与公共引脚接触,并相应地产生两个方波输出信号。 
 如果我们只计算信号的脉冲,则可以使用两个输出中的任何一个来确定旋转位置。但是,如果我们想要确定旋转方向,我们需要同时考虑两个信号。 
 我们可以注意到两个输出信号相互错开了90度。如果编码器顺时针旋转,则输出A将在输出B之前。 
  
 因此,如果我们计算每次信号变化时的步数,从高到低或从低到高,我们可以注意到那时两个输出信号具有相反的值。反之亦然,如果编码器逆时针旋转,则输出信号具有相等的值。因此,考虑到这一点,我们可以轻松地对控制器进行编程,以读取编码器位置和旋转方向。 
 旋转编码器Arduino示例 让我们用Arduino开发板做一个实际的例子吧。我将用于此示例的特定模块位于分线板上,它有五个引脚。第一个引脚是输出A,第二个引脚是输出B,第三个引脚是Button引脚,当然另外两个引脚是VCC和GND引脚。 
  我们可以将输出引脚连接到Arduino开发板的任何数字引脚。 
 本篇文章所需的组件如下所示: ●    旋转编码器模块 ●    Arduino开发板 ●    面包板和跳线 
 源代码 以下是该示例的Arduino代码: 复制代码 #define outputA 6
 #define outputB 7
 int counter = 0; 
 int aState;
 int aLastState;  
 void setup() { 
   pinMode (outputA,INPUT);
   pinMode (outputB,INPUT);
   
   Serial.begin (9600);
   // Reads the initial state of the outputA
   aLastState = digitalRead(outputA);   
 } 
 void loop() { 
   aState = digitalRead(outputA); // Reads the "current" state of the outputA
   // If the previous and the current state of the outputA are different, that means a Pulse has occured
   if (aState != aLastState){     
     // If the outputB state is different to the outputA state, that means the encoder is rotating clockwise
     if (digitalRead(outputB) != aState) { 
       counter ++;
     } else {
       counter --;
     }
     Serial.print("Position: ");
     Serial.println(counter);
   } 
   aLastState = aState; // Updates the previous state of the outputA with the current state
 }
 代码描述:首先,我们需要定义编码器所连接的引脚,并定义程序所需的一些变量。在setup()函数部分,我们需要将两个引脚定义为输入,启动串行通信以在串行监视器上打印结果,以及读取输出A的初始值并将值放入变量aLastState中。 
 然后在loop()函数部分我们再次读取输出A,但现在我们将值放入aState变量。因此,如果我们旋转编码器并生成脉冲,则这两个值将不同,并且第一个“if”语句将变为true。在那之后使用第二个“if”语句,我们确定旋转方向。如果输出B状态与输出A状态不同,则计数器将增加1,否则它将减小。最后,在串行监视器上打印结果后,我们需要使用aState变量更新aLastState变量。 
 这就是我们在这个例子中所需要的一切。如果上传代码,启动串行监视器并开始旋转编码器,我们将开始获取串行监视器中的值。我拥有的特定模块每个完整周期计数30个。 
 示例2 - 使用旋转编码器控制步进电机 除了这个基本示例之外,我再举一个使用旋转编码器控制步进电机位置的例子。 
 
  
 以下是该示例的Arduino代码: 复制代码 #include <LiquidCrystal.h> // includes the LiquidCrystal Library 
 LiquidCrystal lcd(1, 2, 4, 5, 6, 7); // Creates an LC object. Parameters: (rs, enable, d4, d5, d6, d7) 
// defines pins numbers
 #define stepPin 8 
 #define dirPin  9
 #define outputA 10
 #define outputB 11
 int counter = 0;
 int angle = 0; 
 int aState;
 int aLastState;  
 
void setup() {
  // Sets the two pins as Outputs
  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);
  pinMode (outputA,INPUT);
  pinMode (outputB,INPUT);
  
  aLastState = digitalRead(outputA);
  lcd.begin(16,2); // Initializes the interface to the LCD screen, and specifies the dimensions (width and height) of the display } 
}
void loop() {
  aState = digitalRead(outputA);
  
  if (aState != aLastState){     
     if (digitalRead(outputB) != aState) { 
       counter ++;
       angle ++;
       rotateCW();  
     }
     else {
       counter--;
       angle --;
       rotateCCW(); 
     }
     if (counter >=30 ) {
      counter =0;
     }
     
     lcd.clear();
     lcd.print("Position: ");
     lcd.print(int(angle*(-1.8)));
     lcd.print("deg"); 
     lcd.setCursor(0,0);
     
   }
  aLastState = aState;
}
void rotateCW() {
  digitalWrite(dirPin,LOW);
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(2000);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(2000); 
}
void rotateCCW() {
  digitalWrite(dirPin,HIGH);
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(2000);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(2000);   
}
 以上就是本篇文章的全部内容,如果遇到任何问题,请随时在本帖下面进行回复。 |