Привет всем! Продолжение темы.
На макетке собрал схему, подключил регистры и дешифратор, научился по линейке из 14-ти светодиодов, подключенных к выходам 2х регистров пускать бегущий огонь и управлять выходами дешифратора на примере светодиодов. Подключил один индикатор через оптопару, как на схеме часов. Далее взял за основу скетч теста индикаторов nixieClock_2_test_v1.1 от Алекса Гайвера. Модифицировал, получилось перебирать цифры 0-9. Все хорошо, есть все 14 цифр перебирают синхронно одну и ту же последовательность. Но если перед текущим индикатором (в последовательности перебора анодов) просто включить другую цифру, но она будет фантомно отображаться на текущем инфикаторе. Перебирая значения параметров я добился минимальной яркости фантома, но он есть и виден. Как я понимаю это связано с быстродействием оптопары. Как можно побороться с этим эффектом? На текущий момент скетч выглядит так:
#define pinC 7 // управление регистрами
#define pinD 5 // управление регистрами
#define pinS 6 // управление регистрами
#define DECODER0 A2 // управление дешифратором
#define DECODER1 A3 // управление дешифратором
#define DECODER2 A4 // управление дешифратором
#define DECODER3 A5 // управление дешифратором
// распиновка ламп
byte digitMask[] = {8, 3, 2, 7, 6, 4, 5, 1, 9, 0}; // маска дешифратора платы in14
word opt[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192}; //Для регистров
#include "GyverHacks.h"
volatile byte indiDimm[14]; // величина диммирования (0-24)
volatile byte indiCounter[14]; // счётчик каждого индикатора (0-24)
volatile byte indiDigits[14]; // цифры, которые должны показать индикаторы (0-10)
volatile byte curIndi; // текущий индикатор (0-3) 0-13
void setDig(byte digit) {
digit = digitMask[digit];
setPin(DECODER3, bitRead(digit, 0));
setPin(DECODER1, bitRead(digit, 1));
setPin(DECODER0, bitRead(digit, 2));
setPin(DECODER2, bitRead(digit, 3));
}
void setup() {
Serial.begin(9600);
// настройка пинов на выход
pinMode(DECODER0, OUTPUT);
pinMode(DECODER1, OUTPUT);
pinMode(DECODER2, OUTPUT);
pinMode(DECODER3, OUTPUT);
pinMode (pinC, OUTPUT);
pinMode (pinD, OUTPUT);
pinMode (pinS, OUTPUT);
// перенастраиваем частоту ШИМ на пинах 3 и 11 на 7.8 кГц и разрешаем прерывания по совпадению
TCCR2B = (TCCR2B & B11111000) | 1; // делитель 8
TCCR2A |= (1 << WGM21); // включить CTC режим для COMPA
TIMSK2 |= (1 << OCIE2A); // включить прерывания по совпадению COMPA
// яркость индикаторов (0 - 24)
indiDimm[0] = 24;
indiDimm[1] = 24;
indiDimm[2] = 24;
indiDimm[3] = 24;
indiDimm[4] = 24;
indiDimm[5] = 24;
indiDimm[6] = 24;
indiDimm[7] = 24;
indiDimm[8] = 24;
indiDimm[9] = 24;
indiDimm[10] = 24;
indiDimm[11] = 24;
indiDimm[12] = 24;
indiDimm[13] = 24;
}
void loop() {
// тупо перебираем числа от 0 до 1
for (byte i = 0; i < 10; i++) {
indiDigits[0] = 6; // Установлено фиксированное число
indiDigits[1] = i; // Подключен этот индикатор
indiDigits[2] = i;
indiDigits[3] = i;
indiDigits[4] = i;
indiDigits[5] = i;
indiDigits[6] = i;
indiDigits[7] = i;
indiDigits[8] = i;
indiDigits[9] = i;
indiDigits[10] = i;
indiDigits[11] = i;
indiDigits[12] = i;
indiDigits[13] = i;
delay(1000);
}
}
// динамическая индикация в прерывании таймера 2
ISR(TIMER2_COMPA_vect) {
indiCounter[curIndi]++; // счётчик индикатора
if (indiCounter[curIndi] == indiDimm[curIndi]) // если достигли порога диммирования
//Отключаем аноды
{
setPin(pinS, LOW);
shiftOut(pinD, pinC, MSBFIRST, 0>>8);
shiftOut(pinD, pinC, MSBFIRST, 0);
setPin(pinS, HIGH);
}
if (indiCounter[curIndi] > 2) { // достигли порога в 25 единиц
indiCounter[curIndi] = 0; // сброс счетчика лампы
if (++curIndi >= 14) curIndi = 0; // смена лампы закольцованная
{
// отправить цифру из массива indiDigits согласно типу лампы
byte thisDig = digitMask[indiDigits[curIndi]];
setPin(DECODER3, bitRead(thisDig, 0));
setPin(DECODER1, bitRead(thisDig, 1));
setPin(DECODER0, bitRead(thisDig, 2));
setPin(DECODER2, bitRead(thisDig, 3));
// Еще раз отключаем аноды (метод тыка... )
setPin(pinS, LOW);
shiftOut(pinD, pinC, MSBFIRST, 0>>8);
shiftOut(pinD, pinC, MSBFIRST, 0);
setPin(pinS, HIGH);
// включить анод на текущую лампу
setPin(pinS, LOW);
shiftOut(pinD, pinC, MSBFIRST, opt[curIndi]>>8);
shiftOut(pinD, pinC, MSBFIRST, opt[curIndi]);
setPin(pinS, HIGH);
}
}
}
Буду благодарен за любую помощь.