Добрый день любители самоделок! Сегодня расскажу вам о своём недавнем проекте – часы построенные на советских газоразрядных индикаторах ИН-12 под управлением Arduino Nano.
Для этого нам понадобится:
- Плата Arduino Nano
- Газоразрядные индикаторы ИН-12 – 4 штуки
- Колодки для индикаторов
- Модуль часов DS3231
- Микросхема дешифратор К155ИД1
- Блок питания на 12 вольт 0,5 ампер
- Кнопки – 3 штуки
- Стоечки и гайки для них
- Сетевой шнур и соединительные провода
- Прочие радиодетали по схеме
- Текстолит и вещи для травления печатной платы
- Паяльник и паяльные принадлежности
- Корпус, куда будут установлены часы
1. Прошивка микроконтроллера
Я постарался максимально понятно сделать комментарии в код. Единственное, что вам нужно будет сделать перед прошивкой – скачать и установить библиотеку для модуля часов <DS3231.h>. Можно заметить, что часть кода закомментирована то есть не используется - это мигание светодиодом каждую секунду, если такая функция нужна, то просто снимите // с этих строк.
Собственно вот сам код:
#include <DS3231.h> //библиотеки #include <Wire.h> // выводы для дешифратора int out1 = A3; int out2 = A1; int out4 = A0; int out8 = A2; // выводы для транзисторных ключей int key1= 4; int key2 = 6; int key3 = 7; int key4 = 8; // int led1=11;// вывод светодиода int keyb=A6;// пин для клавиатуры int keynum=0; //номер нажатой кнопки int mode =0; //0 - отображение текущего времени 1- установка времени int currentdigit = 0; //0 - установка часов 1- установка минут bool blinkflag = 0; // флаг для мигания цифр при установке времени bool timeout=false; // таймаут после нажатия кнопки (для устранения дребезга) unsigned long startTime; //для мигания светодиода unsigned long startTime2; // для опроса нажатых кнопок int sec; //переменная увеличивается каждые 500мс на единицу. Нужна для мигания секундных светодиодов, бывает в двух значениях 0 - светодиоды не горят, 1 - горят, если больше 1, то сбрасывается в 0 // переменные, необходимые для работы ds3231 DS3231 Clock; bool Century=false; bool h12; bool PM; byte ADay, AHour, AMinute, ASecond, ABits; bool ADy, A12h, Apm; //определяем глобальные переменные для различных параметров часов int second,minute,hour,date,month,year,temperature; int lastMinute; void setup() { // задаем частоту ШИМ на 9 выводе 30кГц TCCR1B=TCCR1B&0b11111000|0x01; analogWrite(9,130); // Start the I2C interface Wire.begin(); // Start the serial interface Serial.begin(9600); //задаем режим работы выходов микроконтроллера pinMode(out1,OUTPUT); pinMode(out2,OUTPUT); pinMode(out4,OUTPUT); pinMode(out8,OUTPUT); pinMode(key1,OUTPUT); pinMode(key2,OUTPUT); pinMode(key3,OUTPUT); pinMode(key4,OUTPUT); // pinMode(led1,OUTPUT); pinMode(keyb,INPUT); startTime = millis(); startTime2=startTime; sec = 0; // считываем текущее время ReadDS3231(); delay(1000); lastMinute = minute%10; } void ReadDS3231() //функция считывает в глобальные переменные minute и hour текущие значения { minute=Clock.getMinute(); hour=Clock.getHour(h12, PM); } void loop() { // put your main code here, to run repeatedly: int digits[3]; // массив для текущего значения времени на четыре цифры int keyval= analogRead(keyb); // считываем значение с клавиатуры //проверяем нажатые кнопки if(!timeout) //если разрешено, считываем нажатую кнопку { /*keyval - значение функции analogread * если нажата первая кнопка, то принимает значение около 200 * если нажата вторая кнопка то значение около 700 * если третья кнопка, то значение будет около 1000 * эти значения зависят от выбранных резисторов в клавиатуре */ if (keyval>150 && keyval<400) keynum=1; if (keyval>700 && keyval<900) keynum=2; if (keyval>960) keynum=3; } unsigned long currentTime = millis(); //текущее время с момента запуска программы if (currentTime>=(startTime2+200)) // если прошло 200мс посмотрим какая кнопка была нажата { timeout=false; //проверим нажатие кнопок if (keynum==3) // кнопка переключения между режимами "время" и "настройка" { timeout=true; // запрещаем считывать нажатия кнопок if (mode==0) mode=1; // если отображалось время, переходим в режим настроек else if (mode==1) mode=0; //если был режим настроек, переключаемся на текущее время } if (keynum==2) // кнопка переключения между часами и минутами { timeout=true; // запрещаем считывать нажатия кнопок // currentdigit либо 0 - настройка часов, либо 1 - настройка минут currentdigit++; if (currentdigit==2) currentdigit=0; } if (keynum==1 && mode==1) // кнопка увеличения количества часов или минут(при настройке) { blinkflag=true; // прекращаем мигать цифрами startTime=millis(); timeout=true; // запрещаем считывать нажатия кнопок if (currentdigit==0) // если меняем часы { if (hour<=22) hour++; else hour=0; Clock.setHour(hour); } if (currentdigit==1) // если меняем минуты { if (minute<=58) minute++; else minute=0; Clock.setMinute(minute);//Set the minute Clock.setSecond(0); } } keynum=0; //сбрасываем нажатую кнопку startTime2=millis(); } if (currentTime>=(startTime+500)) // если прошло 500мс { blinkflag=!blinkflag; // инвертируем флаг мигающей цифры /* if(sec<1) // светодиоды не горят { // зажечь светодиоды digitalWrite(led1,HIGH); Serial.println(blinkflag); Serial.print("Keyval="); Serial.println(keyval); } if(sec>=1) // светодиоды горят { // потушить светодиоды digitalWrite(led1,LOW); }*/ startTime = currentTime; ReadDS3231(); sec = (sec+1); if(sec>=2) sec=0; } digits[0] = hour/10; digits[1] = hour%10; digits[2] = minute/10; digits[3] = minute%10; //антиотравление if (minute%10!=lastMinute && mode == 0) { digits[3] = lastMinute; lastMinute = minute%10; Safe(digits); digits[3] = lastMinute; } // show(digits); // вывести цифры на дисплей } void show(int a[]) { //выведем цифру a[0] на первый индикатор setNumber(a[0]); if (!(mode==1&¤tdigit==0&&blinkflag==false)) //если мы в режиме настройки и происходит настройка часов, то в первая цифра будет мигать { digitalWrite(key1,HIGH); delay(2); //потушим первый индикатор digitalWrite(key1,LOW); delay(1); } //цифра a[1] на второй индикатор setNumber(a[1]); if (!(mode==1&¤tdigit==0&&blinkflag==false)) { digitalWrite(key2,HIGH); delay(2); //потушим второй индикатор digitalWrite(key2,LOW); delay(1); } //цифра a[2] на третий индикатор setNumber(a[2]); if (!(mode==1&¤tdigit==1&&blinkflag==false)) { digitalWrite(key3,HIGH); delay(2); //потушим третий индикатор digitalWrite(key3,LOW); delay(1); } //выведем цифру a[3] на четвертый индикатор setNumber(a[3]); if (!(mode==1&¤tdigit==1&&blinkflag==false)) { digitalWrite(key4,HIGH); delay(2); //потушим четвертый индикатор digitalWrite(key4,LOW); delay(1); } } // передача цифры на дешифратор void setNumber(int num) { switch (num) { case 0: digitalWrite (out1,LOW); digitalWrite (out2,LOW); digitalWrite (out4,LOW); digitalWrite (out8,LOW); break; case 1: digitalWrite (out1,HIGH); digitalWrite (out2,LOW); digitalWrite (out4,LOW); digitalWrite (out8,LOW); break; case 2: digitalWrite (out1,LOW); digitalWrite (out2,HIGH); digitalWrite (out4,LOW); digitalWrite (out8,LOW); break; case 3: digitalWrite (out1,HIGH); digitalWrite (out2,HIGH); digitalWrite (out4,LOW); digitalWrite (out8,LOW); break; case 4: digitalWrite (out1,LOW); digitalWrite (out2,LOW); digitalWrite (out4,HIGH); digitalWrite (out8,LOW); break; case 5: digitalWrite (out1,HIGH); digitalWrite (out2,LOW); digitalWrite (out4,HIGH); digitalWrite (out8,LOW); break; case 6: digitalWrite (out1,LOW); digitalWrite (out2,HIGH); digitalWrite (out4,HIGH); digitalWrite (out8,LOW); break; case 7: digitalWrite (out1,HIGH); digitalWrite (out2,HIGH); digitalWrite (out4,HIGH); digitalWrite (out8,LOW); break; case 8: digitalWrite (out1,LOW); digitalWrite (out2,LOW); digitalWrite (out4,LOW); digitalWrite (out8,HIGH); break; case 9: digitalWrite (out1,HIGH); digitalWrite (out2,LOW); digitalWrite (out4,LOW); digitalWrite (out8,HIGH); break; } } void Safe(int n[]) { int h1 = n[0]; int h2 = n[1]; int m1 = n[2]; int m2 = n[3]; n[0]++; while(n[0]!=h1) { for (int x=0;x<2;x++) { show(n); } n[0]++; if (n[0]>9) n[0]=0; } n[1]++; while(n[1]!=h2) { for (int x=0;x<2;x++) { show(n); } n[1]++; if (n[1]>9) n[1]=0; } n[2]++; while(n[2]!=m1) { for (int x=0;x<2;x++) { show(n); } n[2]++; if (n[2]>9) n[2]=0; } n[3]++; while(n[3]!=m2) { for (int x=0;x<2;x++) { show(n); } n[3]++; if (n[3]>9) n[3]=0; } }
2. Сборка, пайка настройка
После успешной прошивки переходим к сборке часов. Для начала необходимо вытравить печатные платы. Каждый это делает по своему, лично я рисую от руки специальным маркером, а после высыхания травлю в растворе хлорного железа. Да, способ древний как этот мир, но мне нравится. Вот сами печатные платы:

Забегая вперед стоит сказать, что данную плату пришлось дорабатывать потому что преобразователю не хватало 5 вольт, которые на него приходили, поэтому если кто-то столкнётся с данной проблемой, необходимо перерезать дорожку где отмечено крестиком, а зелёные точки соединить резистором на 1 Ом 0,5 Вт. После подобных манипуляций через токоограничивающий резистор преобразователь получает 12 вольт и лампы светят довольно ярко.

После изготовления плат взглянем не схему и начнём установку деталей на свои места. Я советую начинать сборку в таком порядке: устанавливаем индикаторы на вторую плату, смотрим ровно ли получилось (у меня не очень но и так сойдёт), переходим на первую плату и ставим Arduino, а следом собираем преобразователь, включаем и смотрим чтобы он выдавал необходимые 170-200 вольт, а далее устанавливаем всё остальное.
На отдельной плате собираем резистивную клавиатуру:

Если всё работает как и должно быть, то устанавливаем платы друг на друга с помощью стоечек:
Далее нужно определиться чем питать это чудо инженерной мысли. Сначала была идея взять старый блок питания от зарядки Li-on аккумуляторов, вытащить из него плату и приделать её в корпус к часам, но позже это идея отпала потому что я нашёл в своих закромах такую вещь как IRM-03-12, и взял этот маленький блочок в качестве источника питания часов.
3. Изготовления корпуса
В этом плане особо говорить нечего тут у кого на что фантазии и средств хватает. Я делал эти часы себе в комнату, поэтому хотелось, чтобы они были в хорошем привлекательном корпусе, а не в консервной банке. Для этого в программе Компас-3D сделал 3D модель корпуса и отправил, чтобы мне его напечатали на 3D принтере, ибо такого аппарата у меня нет. Отверстия под кнопки настройки на задней стенке и отверстия крепления плат на передней стенке корпуса придётся сверлить вручную, потому что не идеально ровно это всё дело собрано. Вот сам корпус:
На этом у меня всё, будет интересно узнать ваше мнение об этом проекте. Всем удачных самоделок!











