![]()
Добрый день любители самоделок! Сегодня расскажу вам о своём недавнем проекте - часы построенные на советских газоразрядных индикаторах ИН-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 принтере, ибо такого аппарата у меня нет. Отверстия под кнопки настройки на задней стенке и отверстия крепления плат на передней стенке корпуса придётся сверлить вручную, потому что не идеально ровно это всё дело собрано. Вот сам корпус:
![]()
![]()
На этом у меня всё, будет интересно узнать ваше мнение об этом проекте. Всем удачных самоделок!
Становитесь автором сайта, публикуйте собственные статьи, описания самоделок с оплатой за текст.
Подробнее здесь.