插件窝 干货文章 不同的方法来理解编码器的绝对定位

不同的方法来理解编码器的绝对定位

编码器 encoderPos 位置 格雷码 701    来源:    2024-10-15

编码器是一种常用的位置传感器,可以用来测量旋转和线性运动的位移,并将其转换为数字信号。编码器的绝对定位功能可以让我们精确地知道物体的位置,因此在许多领域都有广泛的应用,比如机器人、汽车、医疗仪器等等。

理解编码器绝对定位的方法有很多种,其中比较常见的有以下几种:

  1. 二进制编码方法

二进制编码方法是一种将物理运动转换为数字信号的方式。编码器通过一个位置传感器来检测物体是否移动,并根据物体运动的位置改变其输出的数字编码。每个数字编码对应的是一个唯一的物理位置,因此我们可以通过读取编码器的输出来确定物体的位置。

下面是一个用Arduino实现的二进制编码器示例代码:

const int encoderPinA = 2;
const int encoderPinB = 3;
volatile int encoderPos = 0;
volatile bool aSet = false;
volatile bool bSet = false;

void setup() {
  pinMode(encoderPinA, INPUT);
  pinMode(encoderPinB, INPUT);
  attachInterrupt(digitalPinToInterrupt(encoderPinA), updateEncoderA, CHANGE);
  attachInterrupt(digitalPinToInterrupt(encoderPinB), updateEncoderB, CHANGE);
}

void loop() {
  // 读取编码器当前位置
  int newPos = encoderPos;
  Serial.println(newPos);
}

void updateEncoderA() {
  aSet = digitalRead(encoderPinA);
  if (aSet && !bSet) {
    encoderPos++;
  } else if (!aSet && bSet) {
    encoderPos--;
  }
  bSet = digitalRead(encoderPinB);
}

void updateEncoderB() {
  bSet = digitalRead(encoderPinB);
  if (bSet && !aSet) {
    encoderPos--;
  } else if (!bSet && aSet) {
    encoderPos++;
  }
  aSet = digitalRead(encoderPinA);
}
  1. 格雷码编码方法

格雷码是一种二进制编码的变体,它的优点在于只有一个位置的变化会导致一个编码位的变化。格雷码编码器的输出与二进制编码器类似,但在对编码进行解码之前需要将其转换为二进制表示。这可以通过查找一个转换表来完成,或使用特定的解码器芯片来自动完成转换。

下面是一个使用Shift Register 74HC595实现的格雷码编码器示例代码:

const int encoderPinClock = 4;
const int encoderPinData = 5;
const int encoderPinLatch = 6;

unsigned int encoderValue = 0;

void setup() {
  pinMode(encoderPinClock, OUTPUT);
  pinMode(encoderPinData, OUTPUT);
  pinMode(encoderPinLatch, OUTPUT);
}

void loop() {
  // 读取编码器当前位置
  unsigned int newPos = 0;
  for (int i = 0; i < 16; i++) {
    digitalWrite(encoderPinLatch, LOW);
    shiftOut(encoderPinData, encoderPinClock, MSBFIRST, 1 << i);
    digitalWrite(encoderPinLatch, HIGH);
    delayMicroseconds(10);
    newPos |= digitalRead(encoderPinData) << i;
  }
  encoderValue = newPos;
  Serial.println(encoderValue);
}
  1. PWM编码方法

PWM编码方法利用了脉冲宽度调制的原理,将编码器的输出信号转换为脉冲信号。每个脉冲宽度对应一个位置,因此我们可以通过读取脉冲宽度来确定位置。

下面是一个使用ESP32的PWM模块实现的PWM编码器示例代码:

const int encoderPin = 5;
volatile int encoderPos = 0;
volatile unsigned long lastPulseTime = 0;

void IRAM_ATTR pulseHandler() {
  unsigned long pulseTime = micros();
  if (pulseTime - lastPulseTime > 10) {
    if (digitalRead(encoderPin) == HIGH) {
      encoderPos--;
    } else {
      encoderPos++;
    }
    lastPulseTime = pulseTime;
  }
}

void setup() {
  pinMode(encoderPin, INPUT);
  attachInterrupt(encoderPin, pulseHandler, CHANGE);
  ledcSetup(null, 5000, 8);
  ledcAttachPin(encoderPin, 0);
}

void loop() {
  // 读取编码器当前位置
  int newPos = map(ledcRead(0), 0, 255, -100, 100);
  encoderPos = newPos;
  Serial.println(encoderPos);
}

总结

以上是三种常见的编码器绝对定位方法的代码示例。通过理解编码器的工作原理,我们可以更好地了解如何应用它来实现精确定位,从而在机器人、汽车、医疗仪器等领域提高生产效率和质量。