В прошлой статье мы разбирались с тем, как контролировать газоразрядные трубки при помощи Arduino. Сегодня мы построим полноценный проект при использовании данных трубок. И это будут интересные и очень необычные часы, которые обращают на себя внимание с первого взгляда.
Проект будет работать под управлением Arduino Mega. Также наши часы имеют светодиодную подсветку и блок кнопок, при помощи которых можно будет производить настройку без подключения к ПК.
Для начала прочитайте эту статью. Особенно обратите внимание на шаги 1-3. Из-за отсутствия 10К резисторов мне пришлось использовать по 2 5К резистора перед каждой трубкой.
Снова обращаемся к прошлой статье. Здесь мы не будем подробно рассматривать подключение, а только лишь обозначим шаги для создания готовых часов.
Для управления трубками мы использовали микросхемы K155ID1.
Для подключения потребуется отдельный чип для каждой трубки и отдельный выход на плате Arduino. Именно поэтому нам и понадобилась именно плата Arduino Mega, у которой больше портов ввода/вывода, чем у обычной платы Uno. Да, при таком подключении нам понадобиться 16 контактов, что для платы Mega не проблема.
Для подключения блока кнопок необходимо соединить “G” с питанием, а остальные контакты с аналоговыми выходами на плате. Были выбраны именно аналоговые выводы в связи с тем, что цифровые часто распознавали нажатую кнопку, когда на самом деле это было не так. И только установив значение действительно нажатой клавиши на 1023 (максимальное значение) на аналоговом выводе, удалось избавиться от этой проблемы.
После подключения микросхемы DS3231, трубок и светодиодов приступаем к программированию.
Прилагаю готовый код. «NixieJT1» - это полный код. «DS3231» поможет установить тактовый модуль.
#include <DS3231.h> DS3231 rtc(SDA, SCL); Time t; #define A1 25 #define A2 24 #define A3 23 #define A4 22 #define B1 29 #define B2 28 #define B3 27 #define B4 26 #define C1 35 #define C2 34 #define C3 33 #define C4 32 #define D1 39 #define D2 38 #define D3 37 #define D4 36 int light4[] = {A1,A2,A3,A4}; int light3[] = {B1,B2,B3,B4}; int light2[] = {C1,C2,C3,C4}; int light1[] = {D1,D2,D3,D4}; #define bled 2 #define rled 3 #define gled 4 //The RGB LED lights #define but1 0 #define but2 4 #define but3 1 #define but4 5 #define but5 2 #define but6 6 #define but7 3 #define but8 7 byte nowHour, nowMinute,nowSecond; byte digA, digB, digC, digD, oldDigA; byte modeNum = 0; byte oldModeNum = 22; int lightState = 0; byte b1,b2,b3,b4,b5,b6,b7,b8; void setup() { rtc.begin(); pinMode(48,OUTPUT); digitalWrite(48,HIGH); //For the button matrix for(int i=0; i<4; i++) { pinMode(light1[i],OUTPUT); pinMode(light2[i],OUTPUT); pinMode(light3[i],OUTPUT); pinMode(light4[i],OUTPUT); } pinMode(rled,OUTPUT);pinMode(gled,OUTPUT);pinMode(bled,OUTPUT); digitalWrite(rled,HIGH); digitalWrite(gled,HIGH); digitalWrite(bled,HIGH); oldDigA = 11; Serial.begin(9600); } void loop() { //Serial.println("Starting Loop"); ReadPins(); CheckSubs(); GetTime(); DisplayTime(); RunLED(modeNum); } void ReadPins() { if(analogRead(but1)>1020) b1=1; else b1=0; if(analogRead(but2)>1020) b2=1; else b2=0; if(analogRead(but3)>1020) b3=1; else b3=0; if(analogRead(but4)>1020) b4=1; else b4=0; if(analogRead(but5)>1020) b5=1; else b5=0; if(analogRead(but6)>1020) b6=1; else b6=0; if(analogRead(but7)>1020) b7=1; else b7=0; if(analogRead(but8)>1020) b8=1; else b8=0; } void CheckSubs() { byte delayTime = 150; if(b1==1 || b2==1 || b3==1 || b4 == 1) { ChangeTime(); delay(delayTime); } else if(b5 == 1|| b6==1 || b7==1) { ChangeLED(); delay(delayTime+50); } else if(b8==1) Eleven(); } void ChangeTime() { byte prevHour = t.hour; byte prevMin = t.min; byte prevSec = t.sec; int newHour, newMin; newHour = prevHour; newMin = prevMin; if(b1==1) {//Hour up by 1 newHour = prevHour+1; if(newHour>=24) newHour=0; } else if(b2==1) {//Hour down by one newHour=prevHour-1; if(newHour<=0) newHour=23; } if(b3==1) {//Minute up by one newMin = prevMin+1; if(newMin>59) newMin=0; } else if(b4==1) {//Minute down by one newMin=prevMin-1; if(newMin<0) newMin=59; } rtc.setTime(newHour,newMin,prevSec); GetTime(); oldDigA = 11; DisplayTime(); } void ChangeLED() { if(b7==1) modeNum = 0; if(b6==1) { if(modeNum==0 || modeNum>=6) modeNum = 1; else modeNum+=1; } if(b5==1) { if(modeNum==7) modeNum = 8; else modeNum = 7; } } void RunLED(byte modeNum) {//Remember, LOW means ON!! if(oldModeNum!=modeNum || modeNum>6) switch(modeNum) { case 0: //Lights off digitalWrite(rled,HIGH); digitalWrite(gled,HIGH); digitalWrite(bled,HIGH); break; case 1: //just red digitalWrite(rled,LOW); digitalWrite(gled,HIGH); digitalWrite(bled,HIGH); break; case 2: //green digitalWrite(rled,HIGH); digitalWrite(gled,LOW); digitalWrite(bled,HIGH); break; case 3: //blue digitalWrite(rled,HIGH); digitalWrite(gled,HIGH); digitalWrite(bled,LOW); break; case 4: //purple analogWrite(rled,180); digitalWrite(gled,HIGH); digitalWrite(bled,LOW); break; case 5: //orange analogWrite(rled,0); analogWrite(gled,180); analogWrite(bled,255); break; case 6: //white digitalWrite(rled,LOW); digitalWrite(gled,LOW); digitalWrite(bled,LOW); break; case 7: //smooth fade through all colors {int rgbColor[3]; rgbColor[0] = 0; rgbColor[1] = 255; rgbColor[2] = 255; for (int decColor = 0; decColor < 3; decColor += 1) { ReadPins(); if(b1>0||b2>0||b3>0||b4>0||b5>0||b6>0||b7>0||b8>0) return; int incColor = decColor == 2 ? 0 : decColor + 1; // cross-fade the two colors. for(int i = 255; i >0; i -= 1) { rgbColor[decColor] += 1; //maybe flip these back rgbColor[incColor] -= 1; setColorRgb(rgbColor[0], rgbColor[1], rgbColor[2]); ReadPins(); if(b1>0||b2>0||b3>0||b4>0||b5>0||b6>0||b7>0||b8>0) return; //if a button is pressed, quit this subroutine delay(15); } }} break; case 8: //fade orange/purple/orange/etc {analogWrite(rled,0); analogWrite(gled,180); analogWrite(bled,255); byte rnum = 0; byte gnum = 180; byte bnum = 255; byte delayNum = 7; for(int h = 0; h<255; h++) { rnum = h*.7; gnum = 179+h*.3; bnum = 255-h; analogWrite(rled,rnum); analogWrite(gled,gnum); analogWrite(bled,bnum); ReadPins(); if(b1>0||b2>0||b3>0||b4>0||b5>0||b6>0||b7>0||b8>0) return; delay(delayNum); } for(int h = 0; h<255; h++) { rnum = 180-h*.7; gnum = 255-h*.3; bnum = h; analogWrite(rled,rnum); analogWrite(gled,gnum); analogWrite(bled,bnum); ReadPins(); if(b1>0||b2>0||b3>0||b4>0||b5>0||b6>0||b7>0||b8>0) return; delay(delayNum); } ReadPins(); if(b1>0||b2>0||b3>0||b4>0||b5>0||b6>0||b7>0||b8>0) return; } break; default: break; } } void setColorRgb(unsig ned int red, unsigned int green, unsigned int blue) { analogWrite(rled, red); analogWrite(gled, green); analogWrite(bled, blue); } void Eleven() { DisplayNumber(1,light1); DisplayNumber(1,light2); DisplayNumber(1,light3); DisplayNumber(1,light4); digitalWrite(gled,LOW); digitalWrite(rled,HIGH); digitalWrite(bled,HIGH); delay(3000); oldDigA = 11; GetTime(); DisplayTime(); } void GetTime() { // Serial.print("Running GetTime... "); t=rtc.getTime(); nowHour = t.hour; nowMinute = t.min; nowSecond = t.sec; if(nowHour>12) nowHour=nowHour-12; if(nowHour == 0) nowHour = 12; //Change these around if things aren't working. digC = nowHour%10; //Second digit of the hour. digD = nowHour/10; //First digit of the hour (1 or 0) digA = nowMinute%10; //Second digit of the hour digB = nowMinute/10; //First digit of the hour (40, 30, 20 etc) if(digD==0) digD=3; //So that the first digit just won't be lit up at all. } void DisplayTime() { if(digA != oldDigA) { Serial.println("Changing Time!!\n\n\n\n"); DisplayNumber(digA,light1); DisplayNumber(digB,light2); DisplayNumber(digC,light3); if(digD==0) digD=3; //So that the first digit just won't be lit up at all. DisplayNumber(digD,light4); } oldDigA = digA; delay(50); } void DisplayNumber(int thisNum, int thesePins[4]) { switch(thisNum) { case 0: digitalWrite(thesePins[0],LOW); digitalWrite(thesePins[1],LOW); digitalWrite(thesePins[2],LOW); digitalWrite(thesePins[3],LOW); break; case 1: digitalWrite(thesePins[0],LOW); digitalWrite(thesePins[1],LOW); digitalWrite(thesePins[2],LOW); digitalWrite(thesePins[3],HIGH); break; case 2: digitalWrite(thesePins[0],LOW); digitalWrite(thesePins[1],LOW); digitalWrite(thesePins[2],HIGH); digitalWrite(thesePins[3],LOW); break; case 3: digitalWrite(thesePins[0],LOW); digitalWrite(thesePins[1],LOW); digitalWrite(thesePins[2],HIGH); digitalWrite(thesePins[3],HIGH); break; case 4: digitalWrite(thesePins[0],LOW); digitalWrite(thesePins[1],HIGH); digitalWrite(thesePins[2],LOW); digitalWrite(thesePins[3],LOW); break; case 5: digitalWrite(thesePins[0],LOW); digitalWrite(thesePins[1],HIGH); digitalWrite(thesePins[2],LOW); digitalWrite(thesePins[3],HIGH); break; case 6: digitalWrite(thesePins[0],LOW); digitalWrite(thesePins[1],HIGH); digitalWrite(thesePins[2],HIGH); digitalWrite(thesePins[3],LOW); break; case 7: digitalWrite(thesePins[0],LOW); digitalWrite(thesePins[1],HIGH); digitalWrite(thesePins[2],HIGH); digitalWrite(thesePins[3],HIGH); break; case 8: digitalWrite(thesePins[0],HIGH); digitalWrite(thesePins[1],LOW); digitalWrite(thesePins[2],LOW); digitalWrite(thesePins[3],LOW); break; case 9: digitalWrite(thesePins[0],HIGH); digitalWrite(thesePins[1],LOW); digitalWrite(thesePins[2],LOW); digitalWrite(thesePins[3],HIGH); break; default: digitalWrite(thesePins[0],HIGH); digitalWrite(thesePins[1],LOW); digitalWrite(thesePins[2],HIGH); digitalWrite(thesePins[3],LOW); break; } }
Несколько советов:
Данная статья является авторским переводом с сайта instructables.com.
Данная статья является собственностью Amperkot.ru. При перепечатке данного материала активная ссылка на первоисточник, не закрытая для индексации поисковыми системами, обязательна.
Комментарии