Года 2 назад, я узнал о замечательных советских газоразрядных индикаторах. До этого, я конечно видел, что то подобное в старой советской технике, но никогда не задумывался, что такие индикаторы можно применить в быту, довольно таки в многочисленных проектах, в которых нужно выделить эдакую эстетическую изюминку. Свою популярность эти индикаторы вновь приобрели среди радиолюбителей несколько лет назад из за своего антикварного вида и довольно красивого визуального отображения индикации. В интернете уже сейчас можно найти прекрасные реализации часов на советских ИНках, но мне с самого начало хотелось разобраться с принципами построения таких часов, написать свою прошивку и сделать самодельный корпус из подручных материалов. Не давно я выкроил время и соорудил свои собственные часики на платформе arduino. Самым сложным оказалось достать эти индикаторы. В моем городе я так их и не нашел. Через форум сайта радиокот, нашел человека, который как раз был не далеко в г. Омске. Купил у него 6 ламп ИН-14 и 12 ламп ИН-12Б, а также 6 высоковольтных дешифратора К155ИД1.
Набросал вот такую схему, которую подглядел на каком то сайте. Здесь мы видим 2 высоковольтных дешефратора К155ИД1, 6 трубок ИН-14, преобразователь напряжения с 12 до 180В для питания анодов колб. Подсветку сделал с возможностью управлять через микроконтроллер, но ума так и не дал. Просто постоянно горит. Пищалку позднее я вообще подключил мимо транзистора напрямую к модулю с атмегой. Почти все компоненты используются в планарном исполнении.
Модуль с атмегой и часами реального времени ds1307 сделал на отдельной плате. Я использовал atmega168PA-AU, но в данном проекте можно смело использовать atmega8PA или atmega88PA (просто зашейте соответствующий bootloader), работающие от внутреннего осцилятора 8MHz.


Далее написал вот такую простенькую прошивку с помощью Arduino IDE 1.0.3. Как видим в начале скетча идет определение пинов К155ИД1, анодов и другой периферии Так, что кто захочет извратится и сделать такую схему на макетке с обычной ардуиной можете переназначить на другие удобные вам порты. Есть 2 режима отображения: время и дата, настройка часов, 1 анимация. Я немного пытался оптимизировать исходный код, некоторым новичкам может потребоваться время на его осмысление. Советую почитать вот это для начала.
#include <Wire.h> #include "RTClib.h" RTC_DS1307 RTC; // К155ИД1 (1) uint8_t Pin_1_a = 14; uint8_t Pin_1_b = 16; uint8_t Pin_1_c = 17; uint8_t Pin_1_d = 15; // К155ИД1 (2) uint8_t Pin_2_a = 5; uint8_t Pin_2_b = 7; uint8_t Pin_2_c = 8; uint8_t Pin_2_d = 6; // Анодные пины uint8_t Pin_a_1 = 11;//колбы 1, 4 uint8_t Pin_a_2 = 10;//колбы 2, 5 uint8_t Pin_a_3 = 9; //колбы 3, 6 #define DOT_ON PORTB|=1<<PINB4 // Точки Вкл #define DOT_OFF PORTB&=~(1<<PINB4) //Точки Выкл #define LIGHT_ON PORTD|=1<<PIND4 // Подсветка Вкл #define LIGHT_OFF PORTD&=~(1<<PIND4) //Подсветка Выкл #define SPEAKER_ON PORTB|=1<<PINB5 // Пищалка Вкл #define SPEAKER_OFF PORTB&=~(1<<PINB5) //Пищалка Выкл //Подтверждение настроек #define TIME_UP (PIND & (1<<PIND3))//Считывание значения кнопки на порту 3 //Перебор настроек #define TIME_SET (PIND & (1<<PIND2))//Считывание значение кнопки на порту 2 static const uint8_t bits[2][4] = { {Pin_1_d, Pin_1_c, Pin_1_b, Pin_1_a},// К155ИД1 (1) {Pin_2_d, Pin_2_c, Pin_2_b, Pin_2_a }// К155ИД1 (2) }; uint8_t mode = 0; //Массив для управления анодами ламп static const uint8_t anods[3] = {Pin_a_1, Pin_a_2, Pin_a_3}; //Массив с помощью которого дешефратору задаются цифры static const uint8_t numbers[11][4] = { { 0, 0, 0, 1 }, //0 { 0, 0, 0, 0 }, //1 { 1, 0, 0, 1 }, //2 { 1, 0, 0, 0 }, //3 { 0, 1, 1, 1 }, //4 { 0, 1, 1, 0 }, //5 { 0, 1, 0, 1 }, //6 { 0, 1, 0, 0 }, //7 { 0, 0, 1, 1 }, //8 { 0, 0, 1, 0 }, //9 { 1, 1, 0, 1 } //Чисто }; // Массив для анимации, перебор всех цифр в колбе static const uint8_t nixie_level[10] = { 1, 2, 6, 7, 5, 0, 4, 9, 8, 3 }; //Массив для 6 колб int NumberArray[6]={0,0,0,0,0,0}; uint8_t Mins = 0; uint8_t Seconds = 0; uint8_t j=0, z=0; uint8_t timeset = 0; boolean ok =false; boolean up =false; boolean animate =false; boolean sec=true; void setup() { Wire.begin();//Инициализация шины I2C RTC.begin();//Инициализация микросхемы часиков ds1307 DDRD = B11110010; // назначаем выводы 1,4,5,6,7 как выходы, вывод 0,2,3 - входы DDRB = DDRB | B00111111; // назначаем выводы 8,9,10,11,12,13 как выходы DDRC = DDRC | B00001111; // назначаем выводы 14,15,16,17 как выходы PORTD = B00001100; //Подтягивающие резисторы для кнопок на портах 2, 3. LIGHT_ON;// Включаем подсветку ламп. Ума не дал этой функции :) } static void setNixieNum(uint8_t tube, uint8_t num) { for(uint8_t i=0; i<4; i++) { digitalWrite(bits[tube][i], LOW);//боримся против глюков - обнуляем if (!animate) digitalWrite(bits[tube][i], numbers[num][i]); if (animate) digitalWrite(bits[tube][i], numbers[nixie_level[j]][i]); } } void DisplayNumberSet(uint8_t anod, uint8_t num1, uint8_t num2 ) { setNixieNum(0, num1); setNixieNum(1, num2); digitalWrite(anods[anod], HIGH); delay(3); digitalWrite(anods[anod], LOW); } void loop() { ///Счетчик для анимации/// if (z==8) { j++; z=0; } if (j==10) {animate=false; j=0; z=0;} if (animate) z++; /////////////////// DateTime now = RTC.now(); Seconds = now.second(); Mins=now.minute(); //Режимы часов Время, дата switch(mode) { case 0: NumberArray[0] = now.hour() / 10; //Первый знак часа NumberArray[1] = now.hour() % 10; //Второй знак часа NumberArray[2] = Mins / 10; //Первый знак минут NumberArray[3] = Mins % 10; //Второй знак минут NumberArray[4] = Seconds / 10; //Первый знак секунд NumberArray[5] = Seconds % 10; //Второй знак секунд //Вырубаем точки if (timeset==0) { DOT_OFF; } break; case 1: NumberArray[0] = now.day() / 10; //Первый знак дня NumberArray[1] = now.day() % 10; //Второй знак дня NumberArray[2] = now.month() / 10; //Первый знак месяца NumberArray[3] = now.month() % 10; //Второй знак месяца NumberArray[4] = (now.year() / 10) % 10;//Первый знак года NumberArray[5] = now.year() % 10; //Второй знак года //Если не в настройках то мигаем всеми точками if (timeset==0) { //Если знак секунды четный то включаем иначе выкл if ((Seconds % 10)%2==0) { DOT_ON; } else { DOT_OFF; } } break; } if (timeset==0){ //Каждые пол часа пищим if ((Mins == 0)&&sec||(Mins == 30)&&sec) { playTone(200, 2500); sec=false; } if ((Mins == 1)&&!sec||(Mins == 31)&&!sec) { sec=true; } //Каждые 55 секунд включаем время if (Seconds==55) { mode=0; animate=true; } //Включаем дату на 48 секунду if (Seconds==48) { mode=1; animate=true; } //Переключаем режимы if (!TIME_UP&&!up) { up=true; animate=true; playTone(80, 2800); mode++; mode %= 2; } if (TIME_UP&&up) { up=false; } } /**********Установка времени**********************/ //Перебор настоек if (!TIME_SET&&!ok) { ok=true; timeset++; if (timeset>=7) { timeset=0; mode=0; } playTone(80, 2800); } if (TIME_SET&&ok) { ok=false; } switch (timeset) { //Установка часов case 1: DOT_ON; mode=0; NumberArray[2] = 10; NumberArray[3] = 10; NumberArray[4] = 10; NumberArray[5] = 10; if (!TIME_UP&&!up) { up=true; DateTime adjust (now.unixtime() + 3600); // + 1 Час RTC.adjust(adjust); playTone(80, 2800); } if (TIME_UP&&up) up=false; break; //Установка минут case 2: NumberArray[0] = 10; NumberArray[1] = 10; NumberArray[4] = 10; NumberArray[5] = 10; if (!TIME_UP&&!up) { up=true; DateTime adjust (now.unixtime() + 60); // + 1 минута RTC.adjust(adjust); playTone(80, 2800); } if (TIME_UP&&up) up=false; break; //Установка секунд case 3: NumberArray[0] = 10; NumberArray[1] = 10; NumberArray[2] = 10; NumberArray[3] = 10; if (!TIME_UP&&!up) { up=true; DateTime adjust (now.unixtime() + 1); //+ 1 секунда RTC.adjust(adjust); playTone(80, 2800); } if (TIME_UP&&up) up=false; break; //Установка дня case 4: mode=1; NumberArray[2] = 10; NumberArray[3] = 10; NumberArray[4] = 10; NumberArray[5] = 10; if (!TIME_UP&&!up) { up=true; DateTime adjust (now.unixtime() + 86400L); //+ 1 день RTC.adjust(adjust); playTone(80, 2800); } if (TIME_UP&&up) up=false; break; // Установка месяца case 5: mode=1; NumberArray[0] = 10; NumberArray[1] = 10; NumberArray[4] = 10; NumberArray[5] = 10; if (!TIME_UP&&!up) { up=true; DateTime adjust (now.unixtime() + (86400L*31)); //+ 1 месяц RTC.adjust(adjust); playTone(80, 2800); } if (TIME_UP&&up) up=false; break; //Установка года case 6: mode=1; NumberArray[0] = 10; NumberArray[1] = 10; NumberArray[2] = 10; NumberArray[3] = 10; if (!TIME_UP&&!up) { up=true; DateTime adjust (now.unixtime() + (86400L*365)); //+ 1 год RTC.adjust(adjust); playTone(80, 2800); } if (TIME_UP&&up) up=false; break; } // Вывод данных на ИН-14. DisplayNumberString( NumberArray ); } //Функция "пищалки" void playTone(long duration, int freq) { duration *= 1000; int period = (1.0 / freq) * 1000000; long elapsed_time = 0; while (elapsed_time < duration) { SPEAKER_ON; delayMicroseconds(period / 2); SPEAKER_OFF; delayMicroseconds(period / 2); elapsed_time += (period); } } void DisplayNumberString( int* array ) { DisplayNumberSet(0,array[0],array[3]); DisplayNumberSet(1,array[1],array[4]); DisplayNumberSet(2,array[2],array[5]); }

Nixie_clock.zip (165,1 КиБ, 4 794 загрузок)

Ну и последняя часть часиков это конечно внешний вид — корпус. Я его сделал из остатка сосновой плахи пятерки. В принципе никаких специальных навыков я не имею. Бывало на школьных уроках труда делал указки и на токарном станке скалку точил, но это было уже больше 12 лет назад. Просто нужно терпением запастись и несколькими инструментами. Итак понадобятся: лобзик или ножовка, стамеска, напильник, мелкая шкурка, морилка на алкидной основе дубового или другого цвета, деревяха подходящего размера. Подробный фото отчет изготовления корпуса я не запечатлел, так как изготавливал его на одном дыхании. Вкратце на словах несколько этапов:
1) Ножовкой или лобзиком облагораживаем наш без форменный кусок дерева до состояния прямоугольника близкого к идеальному :).
2) Cтамеской снизу выдалбливаем прямоугольник меньшего размера.
3) Cверху где лампы будут торчать, выдалбливаем, выпиливаем длинный и узкий овал по размеру ламп.
4) Шкурим, придаем углам овальности.
5) Делаем 6 отверстий для дна из простой деревоплиты или фанеры тонкой.
6) Покрываем корпус морилкой на 2 раза.
Вообще если у вам нет времени на это безумие я советую добежать до ближайшей столярки и вам за не большую плату из палена на фрейзере сделают необходимые преобразования.





Как обычно в заключении выкладываю видео работы готовых часиков.
Los Blancos have been tracking?the starlet for some time and are keen to see how he performs in the Champions League last-16 against rivals Atletico Madrid.
http://www.benimalem.com/spidresrinoo grayjahsa odakota a30b5ac58e