энкодер и семисегментный индикатор
- Войдите на сайт для отправки комментариев
Сб, 12/11/2016 - 00:01
считываю обороты с оптического энкодера и вывожу данные на 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;
}
может с типами чисел где то ошибка...
буду признателен за совет.