Если вы можете гарантировать, что опрос происходит чаще всего при самом быстром повороте на пол-оборота (180 °), то должны быть выполнены следующие соображения:
- абсолютная разница между текущим показанием ипоследний не может превышать пол оборота = 180 °
- Если абсолютная разница равна
>= 180°
, мы пересекли 0°
.Подсчет степени, которую мы переместили, рассчитывается путем сложения или вычитания полного поворота (360 °) в зависимости от текущего значения поворота (cw add, ccw subtract). - Если абсолютная разница равна
< 180°
и знак разницыположительно, мы сместились по часовой стрелке (угол приращения) - Если абсолютная разница равна
< 180°
, а знак разницы отрицательный, мы сместились против часовой стрелки (угол уменьшения) - Если разница
== 0
тогда никакого движения не произошло.
В коде:
int LastAngle = GetAngle(); // Init angle reading
bool bClockWise = true;
...
// polling or interrupt handler
int CurrAngle = GetAngle();
int diff = CurrAngle - LastAngle;
if (diff==0)
{
//No move
...
}
else if (abs(diff) < 180) //Angle changed from last read
{
//if we are here diff is not 0
//we update rotation accordingly with the sign
if (diff > 0)
bClockWise = true; //we were rotating clockwise
else
bClockWise = false; //we were rotating counterclockwise
}
//If absolute difference was > 180° we are wrapping around the 0
//in this case we simply ignore the diff sign and leave the rotation
//to the last known verse.
...
Если вы хотите считать ходы, вы можете кодировать:
int Turns = 0;
if ((diff != 0) && (abs(diff) > 180))
{
if (bClockWise)
Turns++; //Increase turns count
else
Turns--; //Decrease turns count
}
Следующие макросы могутиспользоваться для проверки движения и чувствительности вращения:
#define IsMoving (diff) //Give a value !=0 if there is a movement
#define IsCw (bClockWise) //Give true if clockwise rotation
#define IsWrap (abs(diff) >= 180) //Give true if knob wrapped
PS Обратите внимание, что переменная diff
является функциональной для определения и вращения, а не является абсолютнойразница в градусах между движениями .
Если вы хотите вычислить реальное движение, вы должны принять во внимание переходное значение:
int Angle = 0; //the real angle tracked from code start
if (diff != 0)
{
if (abs(diff) >= 180)
{
if (bClockWise)
Angle += diff + 360; //Adjust for positive rollover
else
Angle += diff - 360; //Adjust for negative rollover
}
else
Angle += diff;
}