Страница 1 из 1
Подключение 8-ми разрядного 7-ми сегментного индикатора к PRO MINI
Добавлено: 14 ноя 2016, 14:36
komandor
Подключил 7-ми сегментный 8-ми разрядный индикатор к PRO MINI. Использую только пять разрядов. Выводит нормально количество
импульсов (до 500 имп./сек.). Как ввести поправочный коэффициент счета (примерно 0.9-1.1) для нормального отображения на индикаторе.
Re: Подключение 8-ми разрядного 7-ми сегментного индикатора к PRO MINI
Добавлено: 14 ноя 2016, 17:28
Эдуард
Не совсем понятно.
Если речь идет об умножении целого числа на дробный коэффициент, то это делается так:
Код: Выделить всё
int numImp; // число импульсов, которое надо умножить на дробный коэффициент
numImp = (int) ( (float)numImp * 0.9 );
(float)numImp - явно преобразуем в тип float.
(float)numImp * 0.9 - умножаем на коэффициент
(int) ( (float)numImp * 0.9 ) - обратно преобразовываем в целочисленный тип
Если еще сделать округление:
Код: Выделить всё
numImp = (int) ( (float)numImp * 0.9 + 0.5);
Re: Подключение 8-ми разрядного 7-ми сегментного индикатора к PRO MINI
Добавлено: 14 ноя 2016, 22:20
komandor
Считываются импульсы (частотой 500гц.) оптическим энкодером и выводятся на 8-ми разрядный 7-ми сегментный индикатор
МАХ7219-MODUL. Как ввести поправочный коэффициент счета (примерно 0.9 - 1.1). Например, предварительно считал импульсы
и на индикаторе отобразилось 100.00 , а надо чтобы показания были 90.00 или 110.00. Импульсы умножить на поправочный
коэффициент и результат разложить для вывода на индикатор.
Вот используемый скетч:
Код: Выделить всё
#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;
int n1 = 0;
int n2 = 0;
int n3 = 0;
long n4 = 0;
long n5 = 0;
void setup()
{
lc.shutdown(0, false); // функция lc.shutdown(0,true); снова его включит
lc.setIntensity(0, 8); // яркость свечения, доступные значения от 0 до 15
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;
if (distance < 1000)
{
lc.setDigit(0, 1, n1, false);
lc.setDigit(0, 2, n2, false);
lc.setDigit(0, 3, n3, true);
lc.setChar(0, 4, ' ', false);
lc.setChar(0, 5, ' ', false);
}
if (distance >= 1000 && distance < 10000)
{
lc.setDigit(0, 1, n1, false);
lc.setDigit(0, 2, n2, false);
lc.setDigit(0, 3, n3, true);
lc.setDigit(0, 4, n4, false);
lc.setChar(0, 5, ' ', false);
}
if (distance >= 10000 && distance < 100000)
{
lc.setDigit(0, 1, n1, false);
lc.setDigit(0, 2, n2, false);
lc.setDigit(0, 3, n3, true);
lc.setDigit(0, 4, n4, false);
lc.setDigit(0, 5, n5, 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;
Re: Подключение 8-ми разрядного 7-ми сегментного индикатора к PRO MINI
Добавлено: 15 ноя 2016, 14:28
Эдуард
Все как я написал, только для переменной val.
После:
val = encoderValue / 4;
Скорректировать переменную val :
val = (long) ( (float)val * 0.9 );
Можно умножить на коэффициент в той же строке:
val = (long) ((float)(encoderValue / 4) * 0.9);
Re: Подключение 8-ми разрядного 7-ми сегментного индикатора к PRO MINI
Добавлено: 15 ноя 2016, 16:45
komandor
Спасибо, попробую.
Re: Подключение 8-ми разрядного 7-ми сегментного индикатора к PRO MINI
Добавлено: 16 ноя 2016, 15:05
komandor
Протестировал. С коэффициентом 0.9 работает отлично.
С коэффициентом 1.1 показания индикатора, как при коэффициенте 1.
Re: Подключение 8-ми разрядного 7-ми сегментного индикатора к PRO MINI
Добавлено: 16 ноя 2016, 17:17
Эдуард
Должно работать. Какая разница для умножения 0.9 или 1.1.
Если не работает при малых значениях, добавьте округление:
val = (long) ( (float)val * 0.9 + 0.5 );
А при каких значениях val работает не правильно? При любых? А если умножить не на 1.1, а на другие коэффициенты? Например 2.0.
Re: Подключение 8-ми разрядного 7-ми сегментного индикатора к PRO MINI
Добавлено: 16 ноя 2016, 21:21
komandor
Пробовал коэффициенты и 0.5 и 0.7. До 1 работает прекрасно. Ввожу 1, тоже отлично. Все, что больше 1 (пробовал и 2 и 10, и (1+0.1) и добавлял
округление) val во всем диапазоне работает с коэффициентом 1.
Re: Подключение 8-ми разрядного 7-ми сегментного индикатора к PRO MINI
Добавлено: 16 ноя 2016, 23:25
Эдуард
Выводите для отладки промежуточные данные в последовательный порт:
Код: Выделить всё
void loop()
{
val = encoderValue / 4;
// массштабирование с выводом в последовательный порт
Serial.print("val=");
Serial.print(val);
float x;
x = (float)val;
Serial.print(" x=");
Serial.print(x);
x= x * 1.1;
Serial.print(" ");
Serial.print(x);
val = (long)x;
Serial.print(" val=");
Serial.println(val);
delay(300);
Не забудьте в setup() вставить
Serial.begin(9600);
Запустите монитор последовательного порта Arduino IDE и увидите все промежуточные результаты вычислений.
Re: Подключение 8-ми разрядного 7-ми сегментного индикатора к PRO MINI
Добавлено: 17 ноя 2016, 14:45
komandor
Данные вывел в последовательный порт.
Коэффициент 0.5
val=1000 x=1000.00 500.00 val=500 показания на индикаторе 5.00
Коэффициент 1
val=1000 x=1000.00 1000.00 val=1000 показания на индикаторе 10.00
Коэффициент 1.1
val=1000 x=1000.00 1100.00 val=1100 показания на индикаторе 10.00 (а должно быть 11.00)
Re: Подключение 8-ми разрядного 7-ми сегментного индикатора к PRO MINI
Добавлено: 17 ноя 2016, 18:56
Эдуард
Переменная val типа long правильно умножилась на коэффициент 1.1.
Получается ошибка в программе преобразования двоичной переменной val в двоично-десятичный код для индикаторов.
Re: Подключение 8-ми разрядного 7-ми сегментного индикатора к PRO MINI
Добавлено: 17 ноя 2016, 19:28
komandor
Спасибо. Буду искать ошибку.
Re: Подключение 8-ми разрядного 7-ми сегментного индикатора к PRO MINI
Добавлено: 18 ноя 2016, 01:22
Эдуард
Ошибка в том, что преобразование двоичного кода из val в двоично-десятичный в n1,n2,n,3,n4,n5 корректно происходит только в случае, если за один проход цикла loop() val изменяется не больше чем на 1
Код: Выделить всё
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;
}
Команда val_old = val; в конце после первого же прохода делает равными переменные val_old и val. После этого код в теле if будет выполнен только при следующем изменении val. Т.е. не важно насколько изменился val, в любом случае n1,n2..,n5 изменится только на 1.
Надо не делать в каждом цикле val_old = val, а либо прибавлять 1 к val_old; либо вычитать 1. В val_old должен храниться двоичный эквивалент n1,n2,...,n5.
Или использовать другой способ преобразования двоичного кода в двоично-десятичный.