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