PotentiometerEncoder库:将电位器变为编码器

发布时间 2024-01-04 23:23:41作者: Dapenson

PotentiometerEncoder库:将电位器变为编码器

最近在玩电位器电机,需要将电位器转换为编码器以获取更多的旋转信息。为了方便这一转换,我写了 PotentiometerEncoder 库,它能够轻松将任何360°电位器转变为高效的编码器。本文将深入介绍 PotentiometerEncoder 的关键功能和工作原理。

速度计算机制

PotentiometerEncoder 库引入了一个关键的函数 getSpeed(),用于计算旋转速度。下面是这个函数的关键代码:

float PotentiometerEncoder::getSpeed()
{
    static uint32_t timeLast = 0;
    static int positionLast = 0;

    uint32_t timeNow = micros();
    int positionCur = this->getCurrentPosition();
    uint32_t deltaT = timeNow - timeLast;
    int deltaA = positionCur - positionLast;

    // 假设两次测量之间的旋转不超过180°
    // 要求每一周至少两次测量(最好测4次)
    if (deltaA > _maxRawValue / 2)
        deltaA -= _maxRawValue;
    if (deltaA < -_maxRawValue / 2)
        deltaA += _maxRawValue;
    float speed = (deltaA * 1e6) / deltaT;

    timeLast = timeNow;
    positionLast = positionCur;

    return speed * 60.0 / _maxRawValue;
}

该函数通过测量两次旋转间的时间和位置变化,计算旋转速度。通过考虑可能的超过180°的旋转情况,并确保至少进行两次测量,可以获得更准确的结果。

位置累积算法

另一个核心函数是 update(),该函数用于更新累积位置。以下是其关键代码:

void PotentiometerEncoder::update()
{
    int currentValue = this->getCurrentPosition();

    // 整周顺时针旋转
    if (_lastValue > _maxRawValue / 2 && currentValue < (_lastValue - _maxRawValue / 2))
    {
        _accumulatedPosition = _accumulatedPosition + _maxRawValue - _lastValue + currentValue;
    }
    // 整周逆时针旋转
    else if (currentValue > _maxRawValue / 2 && _lastValue < (currentValue - _maxRawValue / 2))
    {
        _accumulatedPosition = _accumulatedPosition - _maxRawValue - _lastValue + currentValue;
    }
    else
    {
        _accumulatedPosition = _accumulatedPosition - _lastValue + currentValue;
    }
    _lastValue = currentValue;
    return;
}

update() 函数负责更新累积位置。通过检测旋转方向,并考虑可能的整周旋转情况,该函数能够确保累积位置的准确性。

如何使用 PotentiometerEncoder

首先,您需要将 PotentiometerEncoder 库添加到您的Arduino IDE中。接下来,可以使用以下简单的示例代码来开始使用 PotentiometerEncoder:

#include "PotentiometerEncoder.h"
#include <Ticker.h>

PotentiometerEncoder encoder(32);  // 将 '32' 替换为连接到电位器的模拟引脚
Ticker timer1;

void timer1_callback(void)
{
    encoder.update();
}

void setup()
{
    Serial.begin(115200);
    encoder.begin();
    timer1.attach_ms(50, timer1_callback);  // 每50毫秒更新一次编码器
}

void loop()
{
    delay(5);

    int currentPosition = encoder.getCurrentPosition();
    long accumulatedPosition = encoder.getAccumulatedPosition();

    static unsigned long lastPrintTime = 0;
    if (millis() - lastPrintTime > 100)
    {
        Serial.print("当前位置: ");
        Serial.print(currentPosition);
        Serial.print(" 累计位置: ");
        Serial.print(accumulatedPosition);
        Serial.print(" 圈数: ");
        Serial.print(encoder.getRevolutions());
        Serial.print(" 速度(r/min): ");
        Serial.println(encoder.getSpeed());

        lastPrintTime = millis();
    }
}

这个简单的示例演示了如何初始化 PotentiometerEncoder 实例,定期更新编码器,并获取当前位置、累积位置、圈数和速度信息。

总结

PotentiometerEncoder 库为您的项目提供了将电位器变为编码器的理想选择。通过使用库中提供的功能,您可以轻松获取旋转位置、累积位置和速度信息,为您的Arduino项目增添更多可能性。期待在未来的版本中为该库添加更多功能和改进,以满足更广泛的应用需求。