энкодер и семисегментный индикатор

Нет ответов
vvadim
Offline
Зарегистрирован: 23.05.2012

считываю обороты с оптического энкодера и  вывожу данные на 8 разрядный семисегментный индикатор.
для работы с индикатором использую библиотеку  LedControl.
есть контрольный прибор с таким же энкодером.
всё хорошо.

ввожу корректировочный коэффициент в виде числа float.
считываю импульсы, складываю в число (long), потом умножаю на коэф и полученный результат раскладываю для вывода на индикатор

если коэф сразу прописываю то счёт идёт корректно


#include "LedControl.h"
LedControl lc = LedControl(11, 13, 10, 1);

int encoderPin1 = 2;
int encoderPin2 = 3;
volatile long lastEncoded = 0;
volatile long encoderValue = 0;
long lastencoderValue = 0;
long lastMSB = 0;
long lastLSB = 0;
long val;
long val_old = 0;



long distance = 0;
long DIST = 0;
float koef = 0.9210;

int n1 = 0;
int n2 = 0;
int n3 = 0;
long n4 = 0;
long n5 = 0;

int a1 = 0;
int a2 = 0;
int a3 = 0;
long a4 = 0;
long a5 = 0;

void setup()
{
  lc.shutdown(0, false);   
  lc.setIntensity(0, 8);   
  lc.clearDisplay(0);

  pinMode(encoderPin1, INPUT);
  pinMode(encoderPin2, INPUT);
  digitalWrite(encoderPin1, HIGH);
  digitalWrite(encoderPin2, HIGH);
  attachInterrupt(0, updateEncoder, CHANGE);
  attachInterrupt(1, updateEncoder, CHANGE);
}

void loop()
{
  val = encoderValue / 4;
  if (val > val_old)
  {
    n1 ++;
    if (n1 > 9)
    {
      n1 = 0;
      n2 ++;
    }
    if (n2 > 9)
    {
      n2 = 0;
      n3 ++;
    }
    if (n3 > 9)
    {
      n3 = 0;
      n4 ++;
    }
    if (n4 > 9)
    {
      n4 = 0;
      n5 ++;
    }
    if (n5 > 9)
    {
      n5 = 0;
    }
    val_old = val;
  }

  if (val < val_old)
  {
    if ( distance > 0)
    {
      n1 --;
      if (n1 < 0)
      {
        n1 = 9;
        n2 --;
      }
      if (n2 < 0)
      {
        n2 = 9;
        n3 --;
      }
      if (n3 < 0)
      {
        n3 = 9;
        n4 --;
      }
      if (n4 < 0)
      {
        n4 = 9;
        n5 --;
      }
    }
    val_old = val;
  }

  distance = n1 + n2 * 10 + n3 * 100 + n4 * 1000 + n5 * 10000;  
  DIST = distance * koef;

  a1 = DIST % 10;
  a2 = (DIST / 10) % 10;
  a3 = (DIST / 100) % 10;
  a4 = (DIST / 1000) % 10;
  a5 = (DIST / 10000) % 10;

 if (DIST < 1000)
  {
    lc.setDigit(0, 1, a1, false);
    lc.setDigit(0, 2, a2, false);
    lc.setDigit(0, 3, a3, true);
    lc.setChar(0, 4, ' ', false);
    lc.setChar(0, 5, ' ', false);
  }
  if (DIST >= 1000 && DIST < 10000)
  {
    lc.setDigit(0, 1, a1, false);
    lc.setDigit(0, 2, a2, false);
    lc.setDigit(0, 3, a3, true);
    lc.setDigit(0, 4, a4, false);
    lc.setChar(0, 5, ' ', false);
  }
  if (DIST >= 10000 && DIST < 100000)
  {
    lc.setDigit(0, 1, a1, false);
    lc.setDigit(0, 2, a2, false);
    lc.setDigit(0, 3, a3, true);
    lc.setDigit(0, 4, a4, false);
    lc.setDigit(0, 5, a5, false);
  }
}

////////////////  енкодер ////////////////

void updateEncoder()
{
  int MSB = digitalRead(encoderPin1);
  int LSB = digitalRead(encoderPin2);

  int encoded = (MSB << 1) | LSB;
  int sum  = (lastEncoded << 2) | encoded;

  if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011)
    encoderValue ++;
  if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000)
    encoderValue --;

  lastEncoded = encoded;
}

если кнопкой переключаю режимы с разными коэф то получается  погрешность да 3 процентов

#include "OneButton.h"
#include "LedControl.h"

LedControl lc = LedControl(11, 13, 10, 1);
OneButton button(9, true);  

int encoderPin1 = 2;
int encoderPin2 = 3;
volatile long lastEncoded = 0;
volatile long encoderValue = 0;
long lastencoderValue = 0;
long lastMSB = 0;
long lastLSB = 0;
long val;
long val_old = 0;

long distance = 0;
long DIST = 0;
float koef;

int n1 = 0;
int n2 = 0;
int n3 = 0;
long n4 = 0;
long n5 = 0;

int a1 = 0;
int a2 = 0;
int a3 = 0;
long a4 = 0;
long a5 = 0;

int state = 0;

void setup()
{
  lc.shutdown(0, false);   
  lc.setIntensity(0, 8);   
  lc.clearDisplay(0);

  pinMode(encoderPin1, INPUT);
  pinMode(encoderPin2, INPUT);
  digitalWrite(encoderPin1, HIGH);
  digitalWrite(encoderPin2, HIGH);
  attachInterrupt(0, updateEncoder, CHANGE);
  attachInterrupt(1, updateEncoder, CHANGE);

  button.attachClick(Click);
}

void loop()
{
  button.tick();

  val = encoderValue / 4;

  if (val > val_old)
  {
    n1 ++;
    if (n1 > 9)
    {
      n1 = 0;
      n2 ++;
    }
    if (n2 > 9)
    {
      n2 = 0;
      n3 ++;
    }
    if (n3 > 9)
    {
      n3 = 0;
      n4 ++;
    }
    if (n4 > 9)
    {
      n4 = 0;
      n5 ++;
    }
    if (n5 > 9)
    {
      n5 = 0;
    }
    val_old = val;
  }

  if (val < val_old)
  {
    if ( distance > 0)
    {
      n1 --;
      if (n1 < 0)
      {
        n1 = 9;
        n2 --;
      }
      if (n2 < 0)
      {
        n2 = 9;
        n3 --;
      }
      if (n3 < 0)
      {
        n3 = 9;
        n4 --;
      }
      if (n4 < 0)
      {
        n4 = 9;
        n5 --;
      }
    }
    val_old = val;
  }

  ///////////////////////////////

  if (state == 0)
    koef = 0.9210;
  else if (state == 1)
    koef = 1.0000;

  lc.setDigit(0, 7, state, false);


  ///////////////////////////////////////


  distance = n1 + n2 * 10 + n3 * 100 + n4 * 1000 + n5 * 10000;

  DIST = distance * koef;

  a1 = DIST % 10;
  a2 = (DIST / 10) % 10;
  a3 = (DIST / 100) % 10;
  a4 = (DIST / 1000) % 10;
  a5 = (DIST / 10000) % 10;

  /////////////////////////////////////////////////////////////////


  if (DIST < 1000)
  {
    lc.setDigit(0, 1, a1, false);
    lc.setDigit(0, 2, a2, false);
    lc.setDigit(0, 3, a3, true);
    lc.setChar(0, 4, ' ', false);
    lc.setChar(0, 5, ' ', false);
  }
  if (DIST >= 1000 && DIST < 10000)
  {
    lc.setDigit(0, 1, a1, false);
    lc.setDigit(0, 2, a2, false);
    lc.setDigit(0, 3, a3, true);
    lc.setDigit(0, 4, a4, false);
    lc.setChar(0, 5, ' ', false);
  }
  if (DIST >= 10000 && DIST < 100000)
  {
    lc.setDigit(0, 1, a1, false);
    lc.setDigit(0, 2, a2, false);
    lc.setDigit(0, 3, a3, true);
    lc.setDigit(0, 4, a4, false);
    lc.setDigit(0, 5, a5, false);
  }
}

////////////////  енкодер ////////////////

void updateEncoder()
{
  int MSB = digitalRead(encoderPin1);
  int LSB = digitalRead(encoderPin2);

  int encoded = (MSB << 1) | LSB;
  int sum  = (lastEncoded << 2) | encoded;

  if (sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011)
    encoderValue ++;
  if (sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000)
    encoderValue --;

  lastEncoded = encoded;
}

void Click()
{
  state = 1 - state;
}

может с типами чисел где то ошибка...

буду признателен за совет.