亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

Arduino Shield NCS314 NIXIE Tubes Clock IN-14

组件和用品

Shield Nixie Tubes IN-14 NCS314 Arduino for Nixie Tubes Clock etc .
数码管 IN-14 上的屏蔽
× 1
用于 xUSSR 数码管的屏蔽数码管时钟 IN-12 NCS312
× 1
Arduino UNO
Shield 支持 Arduino UNO/Genuino 或 Arduino MEGA
× 1
Arduino Mega 2560
Shield 支持 Arduino UNO/Genuino 或 Arduino MEGA
× 1
电源 12V 1A
× 1
SHIELD NCS314 亚克力外壳
Beautiful Acrylic Сase Model ACNS314 完全兼容 Nixie Arduino Shield NCS314 硬件版本 v1.X – 2 .X
× 1

应用和在线服务

Arduino IDE

关于这个项目

概览

最初,在我们获得了几乎取之不尽的优质苏联数码管 IN-12、IN-14 和 IN-18 供应后,我们打算将数码管简单地展示为 Arduino 的 Shield。当时我们已经有了 Arduino,所以这个案例仍然很小(所以我们当时是这么认为的)。那个时候我们对这样的灯怎么处理一无所知。

很快我们就在互联网上找到了为此类电子管供电的方案:

是的!它发光!我们看到的事实让我们惊呆了,就像一个小奇迹,我们意识到我们走在了正确的轨道上。立即开始拍照:

第二天,开始讨论未来项目的概念:为了简化和降低成本,决定使用动态显示原理的方案,但后来决定放弃它,转而支持完全的方案。静态显示模式。虽然对于 IN-14 数码管视觉上的差异并不明显,但是对于 IN-18 灯管来说差异是很明显的——在动态模式下,它们的工作并不那么明亮,其中很多都出现了,所谓的蓝点效应:

动态显示模式是每次不是所有灯管都点亮,只点亮一个(一次),同时点亮时也可以是其他种类,例如只有两个灯管。

在讨论该设备的未来时,一旦决定实现在来自计算机的灯管上显示信息的能力,它将允许发烧友创建自己的设备,该设备将显示在灯上,例如,灯管的数量未读消息或游戏中的回合数,例如辐射。

然后开始选择可以作为管中开关阴极(数字)的硬件。选择是显而易见的 - 带有 SPI 的移位寄存器以节省 MCU 引脚。但由于电源电压管非常高 - 高达 200 伏,选项并不多:HV513、HV5812、HV5122。当我们在每个芯片上构建设备时,我们停在了 HV5812(在新的 Shields 版本 NCS314 V2.X 和 NCS312 V1.X 中使用了 IC HV5122)。这个芯片非常方便,因为它可以让你同时控制两个灯,作为一个 20 位的寄存器。

要控制 6 个管,我们需要三个这样的电路串联连接。这允许一次通过 SPI 发送数据包并且不关心更新管上的信息,就像动态显示算法的情况一样。也就是说,换句话说——只要我们不需要改变管子上的信息,MCU可能会忙于其他任务,甚至睡觉!

我们想说一下SPI上的数据传输。 Arudino 可以一次传输,只有 8 位。我们需要 60,最接近的可被 8 整除的更高整数是 64,因此必须应用一点魔法 - 为每个寄存器形成一个 unsigned long long var64 位类型的大变量,并每次传递 8 次 8 位将变量内的所有位右移:

 SPI.transfer(var64); SPI.transfer(var64>>48); SPI.transfer(var64>>40); SPI.transfer(var64>>32); SPI.transfer(var64>>24); SPI.transfer(var64>>16); SPI.transfer(var64>>8); SPI.transfer(iTmp);  

那些设定并实现的目标:

  • 基于移位寄存器的静态显示。
  • 老虎机(阿尼中毒)
  • 提供时钟、时钟、日期、时间、闹钟的标准功能。
  • 带电池 CR1220 的 RTC(实时时钟)。 (新版V1.2-2.X板采用高精度时间芯片RTC DS3231)。
  • 温度测量 DS18B20 [摄氏度或华氏度]。
  • 通过 IR 端口 TSOP4836 控制(仅适用于 Mega)。用遥控器索尼 RM-X151 检查,但它可能和其他频率为 36kHz 的遥控器。
  • 与外部 GPS 时间同步(仅适用于 Mega)
  • 简单的菜单。
  • 单独管理结肠(下点和上点)
  • RGB 背光颜色,平滑传输
  • RTTTL 闹钟铃声(铃声传输语言)
  • 老虎机(防止中毒指标)
  • 关于自测。 (检查每个显示器中从 0 到 9 的所有数字,检查所有 LED,一个串行开关颜色蓝色,红色,绿色,声音检查(铃声播放)

那些无法完全实现的任务。

  • 光传感器

代码

  • 无标题文件
无标题文件C/C++
const String FirmwareVersion="010000";//Format _X.XX__ //NIXIE CLOCK SHIELD NCS314 by GRA &AFCH ([email protected])//25.05.2016 #include #include #include #include #include #include const byte LEpin=7; //pin Latch Enabled 数据在 HI levelconst byte DHVpin=5 时被接受; // 关闭/开启 MAX1771 驱动器高电压 (DHV) 110-220V const byte RedLedPin=9; //红色 LED 的 MCU WDM 输出 9-gconst 字节 GreenLedPin=6; //MCU WDM 输出绿色 LED 6-bconst 字节 BlueLedPin=3; //蓝色 LED 的 MCU WDM 输出 3-rconst byte pinSet=A0;const byte pinUp=A2;const byte pinDown=A1;const byte pinBuzzer=2;const byte pinUpperDots=12; //HIGH 值点亮一个 dotsconst 字节 pinLowerDots=8; //HIGH值点亮一个dotsconst字fpsLimit=16666; // 1/60*1.000.000 // 限制最大刷新率 60 fpsString stringToDisplay="000000";// 该字符串的内容将显示在管上(必须是 6 个字符的长度)int menuPosition=0; // 0 - 时间 // 1 - 日期 // 2 - 闹钟 // 3 - 12/24 小时模式字节blinkMask=B00000000; //闪烁数字的位掩码(1 - 闪烁,0 - 常亮)//----------------------------------------0----- --1-----------2-----------3---------4--------5------ ---6---------7---------8---------9-----//byte lowBytesArray[]={B11111110,B11111101 ,B11111011,B11110111,B11101111,B11011111,B10111111,B01111111,B11111111,B11111111}; //字节highBytesArray [] ={B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111110,B11111101};字节dotPattern =B00000000; //用于分隔点的位掩码 //B00000000 - 关闭上下点 //B1100000 - 关闭所有点#define DS1307_ADDRESS 0x68byte zero =0x00; //解决问题#527int RTC_hours, RTC_minutes, RTC_seconds, RTC_day, RTC_month, RTC_year, RTC_day_of_week;//-- ------------0--------1--- -----2-------3--------4--------5--------6--------7 --------8--------9--------10-------11-------12------- 13-------14// 名称:时间、日期、闹钟、12/24 小时、分钟、秒、日、月、年、时、分、秒 alarm01 hours_format // 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1int parent[15]={ 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 4};int firstChild[15] ={4, 7, 10, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};int lastChild[15]={ 6, 9, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};int value[15]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24};int maxValue[15]={ 0, 0, 0, 0, 23, 59, 59, 31, 12, 99, 23, 59, 59, 1, 24};int minValue[ 15]={ 0, 0, 0, 12, 00, 00, 00, 1, 1, 00, 00, 00, 00, 0, 12};字节闪烁模式[15]={ B00000000, B00000000, B00000000 B00000011, B00001100, B00110000, B00000011, B00001100, B00110000, B00000011, B00001100, B00110000, B110000 00, B00001100};#define TimeIndex 0 #define DateIndex 1 #define AlarmIndex 2 #define hModeIndex 3 #define TimeHoursIndex 4 #define TimeMintuesIndex 5#define TimeSecondsIndex 6#define DateDayIndex 7#define DateMonthIndex 8#define DateYearIndex 9 #define AlarmHourIndex define AlarmMinuteIndex 11#define AlarmSecondIndex 12#define Alarm01 13#define hModeValueIndex 14bool editMode=false;long downTime=0;long upTime=0;const long settingDelay=150;bool BlinkUp=false;bool BlinkDown=false;unsigned long enterEditModeTime=0;bool RGBLedsOn=true;byte RGBLEDsEEPROMAddress=0; byte HourFormatEEPROMAddress=1;byte AlarmTimeEEPROMAddress=2;//3,4,5byte AlarmArmedEEPROMAddress=6; //按钮引脚声明ClickButton setButton(pinSet, LOW, CLICKBTN_PULLUP);ClickButton upButton(pinUp, LOW, CLICKBTN_PULLUP);ClickButton downButton(pinDown, LOW, CLICKBTN_PULLUP);////////////// ///Tonetone1;#define isdigit(n) (n>='0' &&n <='9')//char *song ="MissionImp:d=16,o=6,b=95:32d, 32d#,32d,32d#,32d,32d#,32d,32d#,32d,32d,32d#,32e,32f,32f#,32g,g,8p,g,8p,a#,p,c7,p, g,8p,g,8p,f,p,f#,p,g,8p,g,8p,a#,p,c7,p,g,8p,g,8p,f,p,f#,p,a#, g,2d,32p,a#,g,2c#,32p,a#,g,2c,a#5,8c,2p,32p,a#5,g5,2f#,32p,a#5,g5,2f, 32p,a#5,g5,2e,d#,8d";char *song ="PinkPanther:d=4,o=5,b=160:8d#,8e,2p,8f#,8g,2p,8d# ,8e,16p,8f#,8g,16p,8c6,8b,16p,8d#,8e,16p,8b,2a#,2p,16a,16g,16e,16d,2e";//char *song=" VanessaMae:d=4,o=6,b=70:32c7,32b,16c7,32g,32p,32g,32p,32d#,32p,32d#,32p,32c,32p,32c,32p,32c7,32b, 16c7,32g#,32p,32g#,32p,32f,32p,16f,32c,32p,32c,32p,32c7,32b,16c7,32g,32p,32g,32p,32d#,32p,32d#,32p 32c,32p,32c,32p,32g,32f,32d#,32d,32c,32d,32d#,32c,32d#,32f,16g,8p,16d7,32c7,32d7,32a#,32d7,372a,32d 32g,32d7,32d7,32p,32d7,3 2p,32d7,32p,16d7,32c7,32d7,32a#,32d7,32a,32d7,32g,32d7,32d7,32p,32d7,32p,32d7,32p,32g,32f,32d,32c,32d 32d#,32c,32d#,32f,16c";//char *song="DasBoot:d=4,o=5,b=100:d#.4,8d4,8c4,8d4,8d#4,8g4, a#.4,8a4,8g4,8a4,8a#4,8d,2f.,p,f.4,8e4,8d4,8e4,8f4,8a4,c.,8b4,8a4,8b4,8c,8e,2g。 ,2p";//char *song="Scatman:d=4,o=5,b=200:8b,16b,32p,8b,16b,32p,8b,2d6,16p,16c#.6,16p. ,8d6,16p,16c#6,8b,16p,8f#,2p.,16c#6,8p,16d.6,16p.,16c#6,16b,8p,8f#,2p,32p,2d6,16p ,16c#6,8p,16d.6,16p.,16c#6,16a.,16p.,8e,2p.,16c#6,8p,16d.6,16p.,16c#6,16b,8p, 8b,16b,32p,8b,16b,32p,8b,2d6,16p,16c#.6,16p.,8d6,16p,16c#6,8b,16p,8f#,2p.,16c#6,8p, 16d.6,16p.,16c#6,16b,8p,8f#,2p,32p,2d6,16p,16c#6,8p,16d.6,16p.,16c#6,16a.,16p.,8e ,2p.,16c#6,8p,16d.6,16p.,16c#6,16a,8p,8e,2p,32p,16f#.6,16p.,16b.,16p.";//char * song="爆米花:d=4,o=5,b=160:8c6,8a#,8c6,8g,8d#,8g,c,8c6,8a#,8c6,8g,8d#,8g,c,8c6 ,8d6,8d#6,16c6,8d#6,16c6,8d#6,8d6,16a#,8d6,16a#,8d6,8c6,8a#,8g,8a#,c6";//char *song="WeWishYou:d=4,o=5,b=200:d,g,8g,8a,8g,8f#,e,e,e,a,8a,8b,8a,8g,f#,d,d, b,8b,8c6,8b ,8a,g,e,d,e,a,f#,2g,d,g,8g,8a,8g,8f#,e,e,e,a,8a,8b,8a,8g,f#,d, d,b,8b,8c6,8b,8a,g,e,d,e,a,f#,1g,d,g,g,g,2f#,f#,g,f#,e,2d,a,b ,8a,8a,8g,8g,d6,d,d,e,a,f#,2g";#define OCTAVE_OFFSET 0char *p;int notes[] ={ 0,NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4 、NOTE_FS4、NOTE_G4、NOTE_GS4、NOTE_A4、NOTE_AS4、NOTE_B4、NOTE_C5、NOTE_CS5、NOTE_D5、NOTE_DS5、NOTE_E5、NOTE_F5、NOTE_FS5、NOTE_G5、NOTE_GS5、NOTE_A5、NOTE_AS5、NOTE_B5、NOTE_6、NOTE_6、NOTE_6NOTE_6NOTE_6 ,NOTE_G6,NOTE_GS6,NOTE_A6,NOTE_AS6,NOTE_B6,NOTE_C7,NOTE_CS7,NOTE_D7,NOTE_DS7,NOTE_E7,NOTE_F7,NOTE_FS7,NOTE_G7,NOTE_GS7,NOTE_A7,NOTE_AS7,NOTE_B7};int fireforks[0,0],={ 1 -1,0,0,//2 0,1,0,//3 0,0,-1,//4 1,0,0,//5 0,-1,0}; //带有RGB规则的数组(0 - 什么都不做,-1 - 减少,+1 - incresevoid setRTCDateTime(byte h, byte m, byte s, byte d, byte mon, byte y, byte w=1);int functionDownButton=0;int functionUpButton=0;/******************************************** ****************************************************** ***********Init Programm**************************************** ****************************************************** ****************/void setup() { digitalWrite(DHVpin, LOW); // 关闭 MAX1771 驱动器高电压 (DHV) 110-220V Wire.begin(); // setRTCDateTime(23,40,00,25,7,15,1); Serial.begin(115200); Serial.println(""); if (EEPROM.read(HourFormatEEPROMAddress)!=12) value[hModeValueIndex]=24; else value[hModeValueIndex]=12; if (EEPROM.read(RGBLEDsEEPROMAddress)!=0) RGBLedsOn=true; else RGBLedsOn=false; if (EEPROM.read(AlarmTimeEEPROMAddress)==255) value[AlarmHourIndex]=0; else value[AlarmHourIndex]=EEPROM.read(AlarmTimeEEPROMAddress); if (EEPROM.read(AlarmTimeEEPROMAddress+1)==255) value[AlarmMinuteIndex]=0; e lse value[AlarmMinuteIndex]=EEPROM.read(AlarmTimeEEPROMAddress+1); if (EEPROM.read(AlarmTimeEEPROMAddress+2)==255) value[AlarmSecondIndex]=0; else value[AlarmSecondIndex]=EEPROM.read(AlarmTimeEEPROMAddress+2); if (EEPROM.read(AlarmArmedEEPROMAddress)==255) value[Alarm01]=0; else value[Alarm01]=EEPROM.read(AlarmArmedEEPROMAddress);音调1.开始(pinBuzzer);歌曲=解析歌曲(歌曲); pinMode(LEpin,输出); pinMode(DHVpin,输出); pinMode(RedLedPin,输出); pinMode(GreenLedPin,输出); pinMode(BlueLedPin,输出); // SPI 设置 SPI.begin(); // SPI.setDataMode (SPI_MODE3); // 模式 3 SPI SPI.setClockDivider(SPI_CLOCK_DIV128); // SCK =16MHz/128=125kHz //按钮引脚初始化 pinMode(pinSet, INPUT_PULLUP); pinMode(pinUp, INPUT_PULLUP); pinMode(pinDown,INPUT_PULLUP); ////////////////////////// pinMode(pinBuzzer, OUTPUT); //按钮对象初始化 setButton.debounceTime =20; // 以毫秒为单位的去抖动计时器 setButton.multiclickTime =30; // 多次点击的时间限制 setButton.longClickTime =2000; // 直到“按住的点击”注册的时间 upButton.debounceTime =20; // 以毫秒为单位的去抖动计时器 upButton.multiclickTime =30; // 多次点击的时间限制 upButton.longClickTime =2000; // 直到“按住点击”的时间注册 downButton.debounceTime =20; // 以毫秒为单位的去抖动计时器 downButton.multiclickTime =30; // 多次点击的时间限制 downButton.longClickTime =2000; // 直到“按住点击”寄存器的时间 // digitalWrite(DHVpin, HIGH); // 在 MAX1771 驱动器高电压 (DHV) 110-220V //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!! //做测试(); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! getRTCTime(); setTime(RTC_hours, RTC_minutes, RTC_seconds, RTC_day, RTC_month, RTC_year);数字写入(DHVpin,低); // 关闭 MAX1771 驱动器高电压 (DHV) 110-220V setRTCDateTime(RTC_hours,RTC_minutes,RTC_seconds,RTC_day,RTC_month,RTC_year,1); //���������� ������ ��� ��������� ����� � RTC ����� �������� � ����� ���������� digitalWrite(DHVpin, HIGH); // 在 MAX1771 驱动器高电压 (DHV) 110-220V //p=song;}void rotateLeft(uint8_t &bits){ uint8_t high_bit =bits &(1 <<7) ? 1:0;位 =(位 <<1) | high_bit;}int 旋转器 =0; //使用RGB“规则”在数组中索引(每255个周期增加1)int cycle=0; //周期 counterint RedLight=255;int GreenLight=0;int BlueLight=0;unsigned long prevTime=0; // 激光管点亮时间unsigned long prevTime4FireWorks=0; //上次改变RGB的时间//int minuteL=0; //������� ����� �����/****************************** ****************************************************** ********************************主程序**************** ****************************************************** ************************************************/void loop() { p=游戏音乐(p);如果 ((millis()-prevTime4FireWorks)>5) {rotateFireWorks(); //改变颜色(1步) prevTime4FireWorks=millis();做指示(); setButton.Update(); upButton.Update(); downButton.Update();如果(editMode==false){blinkMask=B00000000; } else if ((millis()-enteringEditModeTime)>60000) { editMode=false; menuPosition=firstChild[menuPosition];眨眼面具=眨眼模式[menuPosition]; } if (setButton.clicks>0) //短按 { p=0; //关闭音乐)))tone1.play(1000,100);进入EditModeTime=millis(); menuPosition=menuPosition+1; if (menuPosition==hModeIndex+1) menuPosition=TimeIndex; Serial.print(F("menuPosition=")); Serial.println(menuPosition); Serial.print(F("value=")); Serial.println(value[menuPosition]);眨眼面具=眨眼模式[menuPosition]; if ((parent[menuPosition-1]!=0) and (lastChild[parent[menuPosition-1]-1]==(menuPosition-1))) { if ((parent[menuPosition-1]-1==1 ) &&(!isValidDate())) { menuPosition=DateDayIndex;返回;编辑模式=假; menuPosition=parent[menuPosition-1]-1; if (menuPosition==TimeIndex) setTime(value[TimeHoursIndex], value[TimeMintuesIndex], value[TimeSecondsIndex], day(), month(), year()); if (menuPosition==DateIndex) setTime(hour(), minute(), second(),value[DateDayIndex], value[DateMonthIndex], 2000+value[DateYearIndex]); if (menuPosition==AlarmIndex) {EEPROM.write(AlarmTimeEEPROMAddress,value[AlarmHourIndex]); EEPROM.write(AlarmTimeEEPROMAddress+1,value[AlarmMinuteIndex]); EEPROM.write(AlarmTimeEEPROMAddress+2,value[AlarmSecondIndex]); EEPROM.write(AlarmArmedEEPROMAddress, value[Alarm01]);}; if (menuPosition==hModeIndex) EEPROM.write(HourFormatEEPROMAddress, value[hModeValueIndex]);数字写入(DHVpin,低); //关闭MAX1771驱动器高电压(DHV) 110-220V setRTCDateTime(hour(),minute(),second(),day(),month(),year()%1000,1);数字写入(DHVpin,高); // 在 MAX1771 驱动器高电压 (DHV) 110-220V } value[menuPosition]=extractDigits(blinkMask); } if (setButton.clicks<0) //长按{tone1.play(1000,100); if (!editMode) { 进入EditModeTime=millis(); if (menuPosition==TimeIndex) stringToDisplay=PreZero(hour())+PreZero(minute())+PreZero(second()); //设置时临时启用24小时格式 } menuPosition=firstChild[menuPosition]; if (menuPosition==AlarmHourIndex) {value[Alarm01]=1; /*digitalWrite(pinUpperDots, HIGH);*/dotPattern=B10000000;} editMode=!editMode;眨眼面具=眨眼模式[menuPosition];值[menuPosition]=extractDigits(blinkMask); } if (upButton.clicks !=0) functionUpButton =upButton.clicks; if (upButton.clicks>0) { p=0; //关闭音乐)))tone1.play(1000,100);增量值(); } if (functionUpButton ==-1 &&upButton.depressed ==true) { BlinkUp=false; if (editMode==true) { if ( (millis() - upTime)> settingDelay) { upTime =millis();// + settingDelay;增量值(); } } } else BlinkUp=true; if (downButton.clicks !=0) functionDownButton =downButton.clicks; if (downButton.clicks>0) { p=0; //关闭音乐)))tone1.play(1000,100); dicrementValue(); } if (functionDownButton ==-1 &&downButton.depressed ==true) { BlinkDown=false; if (editMode==true) { if ( (millis() - downTime)> settingDelay) { downTime =millis();// + settingDelay; dicrementValue(); } } } else BlinkDown=true; if (!editMode) { if (upButton.clicks<0) {tone1.play(1000,100); RGBLedsOn=真; EEPROM.write(RGBLEDsEEPROMAddress,1); Serial.println("RGB=on"); } if (downButton.clicks<0) {tone1.play(1000,100); RGBLedsOn=假; EEPROM.write(RGBLEDsEEPROMAddress,0); Serial.println("RGB=off"); } } static bool updateDateTime=false; switch (menuPosition) { case TimeIndex://时间模式 stringToDisplay=updateDisplayString(); doDotBlink(); checkAlarmTime();休息; case DateIndex://日期模式 stringToDisplay=PreZero(day())+PreZero(month())+PreZero(year()%1000); dotPattern=B01000000;//打开较低的点/*digitalWrite(pinUpperDots, LOW);数字写入(pinLowerDots,高);*/ checkAlarmTime();休息; case AlarmIndex://报警模式 stringToDisplay=PreZero(value[AlarmHourIndex])+PreZero(value[AlarmMinuteIndex])+PreZero(value[AlarmSecondIndex]); if (value[Alarm01]==1) /*digitalWrite(pinUpperDots, HIGH);*/ dotPattern=B10000000; //打开上面的点 else { /*digitalWrite(pinUpperDots, LOW);数字写入(pinLowerDots,低);*/ dotPattern=B00000000; //关闭上方的点 } checkAlarmTime();休息; case hModeIndex://12/24 小时模式 stringToDisplay="00"+String(value[hModeValueIndex])+"00"; dotPattern=B00000000;//关闭所有点/*digitalWrite(pinUpperDots, LOW);数字写入(pinLowerDots,低);*/ checkAlarmTime();休息; }}String PreZero(int digit){ if (digit<10) return String("0")+String(digit); else return String(digit);}void rotateFireWorks(){ if (!RGBLedsOn) {analogWrite(RedLedPin,0);模拟写入(GreenLedPin,0);模拟写入(BlueLedPin,0);返回; } RedLight=RedLight+fireforks[rotator*3]; GreenLight=GreenLight+fireforks[旋转器*3+1];蓝光=蓝光+火叉[旋转器*3+2];模拟写入(RedLedPin,RedLight);模拟写入(GreenLedPin,GreenLight);模拟写入(BlueLedPin,BlueLight);周期=周期+1; if (cycle==255) { 旋转器=旋转器+1;周期=0; } if (rotator>5) rotator=0;}void doIndication(){ //静态字节b=B00000001;静态无符号长lastTimeInterval1Started; if ((micros()-lastTimeInterval1Started)>2; Var64|=tmpVar64; Var64=(Var64>>4);无符号整数 iTmp=0; iTmp=Var64>>56; SPI.transfer(iTmp); iTmp=Var64>>48; SPI.transfer(iTmp); iTmp=Var64>>40; SPI.transfer(iTmp); iTmp=Var64>>32; SPI.transfer(iTmp); iTmp=Var64>>24; SPI.transfer(iTmp); iTmp=Var64>>16; SPI.transfer(iTmp); iTmp=Var64>>8; SPI.transfer(iTmp); iTmp=Var64; SPI.transfer(iTmp);数字写入(LEpin,低); // 锁存数据 }byte CheckButtonsState(){ static boolean buttonsWasChecked;静态无符号长 startBuzzTime;静态无符号长lastTimeButtonsPressed; if ((digitalRead(pinSet)==0)||(digitalRead(pinUp)==0)||(digitalRead(pinDown)==0)) { if (buttonsWasChecked==false) startBuzzTime=millis(); buttonWasChecked=true; } 其他buttonsWasChecked=false; if (millis()-startBuzzTime<30) { digitalWrite(pinBuzzer, HIGH); } else { 数字写入(pinBuzzer,低); }}String updateDisplayString(){ static unsigned long lastTimeStringWasUpdated; if ((millis()-lastTimeStringWasUpdated)>1000) { //Serial.println("doDotBlink"); //doDotBlink(); lastTimeStringWasUpdated=millis(); if (value[hModeValueIndex]==24) return PreZero(hour())+PreZero(minute())+PreZero(second());否则返回 PreZero(hourFormat12())+PreZero(minute())+PreZero(second()); } return stringToDisplay;}void doTest(){ Serial.print(F("固件版本:")); Serial.println(FirmwareVersion.substring(1,2)+"."+FirmwareVersion.substring(2,4)); Serial.println(F("开始测试")); int adc=analogRead(A3);浮动 Uinput=4.6*(5.0*adc)/1024.0+0.7; Serial.print(F("U input=")); Serial.print(Uinput); p=歌曲; parseSong(p);模拟写入(RedLedPin,255);延迟(1000);模拟写入(RedLedPin,0);模拟写入(GreenLedPin,255);延迟(1000);模拟写入(GreenLedPin,0);模拟写入(BlueLedPin,255);延迟(1000); //同时(1);字符串 testStringArray[12]={"000000","111111","222222","333333","444444","555555","666666","777777","888888"9,"999"9 ""}; if (Uinput<10) testStringArray[10]="000"+String(int(Uinput*100));否则 testStringArray[10]="00"+String(int(Uinput*100)); testStringArray[11]=固件版本;国际延迟=500;布尔测试=1;字节 strIndex=0; unsigned long startOfTest=millis(); for (int i=0; i<12; i++) { if ((millis()-startOfTest)>dlay) { startOfTest=millis(); strIndex=strIndex+1;如果(strIndex==10)延迟=3000;如果(strIndex==12)测试=0; switch (strIndex) { /* case 10:SPI.transfer((b|B01000000)&B11111100);休息;案例11:SPI.transfer((b|B01000000)&B11001110);休息; */ //默认:SPI.transfer(b|B11000000);默认值:stringToDisplay=testStringArray[strIndex]; } } delayMicroseconds(2000); }; Serial.println(F("停止测试")); }void doDotBlink(){ static unsigned long lastTimeBlink=millis();静态布尔点状态=0; if ((millis()-lastTimeBlink)>1000) { lastTimeBlink=millis(); dotState=!dotState;如果 (dotState) { dotPattern=B11000000; /*digitalWrite(pinUpperDots, HIGH); digitalWrite(pinLowerDots, HIGH);*/ } else { dotPattern=B00000000; /*digitalWrite(pinUpperDots,低); digitalWrite(pinLowerDots, LOW);*/ } }}void setRTCDateTime(byte h, byte m, byte s, byte d, byte mon, byte y, byte w){ Wire.beginTransmission(DS1307_ADDRESS); Wire.write(零); //停止振荡器 Wire.write(decToBcd(s)); Wire.write(decToBcd(m)); Wire.write(decToBcd(h)); Wire.write(decToBcd(w)); Wire.write(decToBcd(d)); Wire.write(decToBcd(mon)); Wire.write(decToBcd(y)); Wire.write(零); //start Wire.endTransmission();}byte decToBcd(byte val){// 将普通十进制数转换为二进制编码的十进制数返回( (val/10*16) + (val%10) );}byte bcdToDec(byte val) ) {// 将二进制编码的十进制数转换为正常的十进制数 return ( (val/16*10) + (val%16) );}void getRTCTime(){ Wire.beginTransmission(DS1307_ADDRESS); Wire.write(零); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS, 7); RTC_seconds =bcdToDec(Wire.read()); RTC_minutes =bcdToDec(Wire.read()); RTC_hours =bcdToDec(Wire.read() &0b111111); //24 小时时间 RTC_day_of_week =bcdToDec(Wire.read()); //0-6 -> 周日 - 周六 RTC_day =bcdToDec(Wire.read()); RTC_month =bcdToDec(Wire.read()); RTC_year =bcdToDec(Wire.read());}word doEditBlink(int pos){ if (!BlinkUp) return 0;如果 (!BlinkDown) 返回 0; int lowBit=blinkMask>>pos; lowBit=lowBit&B00000001;静态无符号长 lastTimeEditBlink=millis();静态布尔闪烁状态=假;字掩码=0; static int tmp=0;//blinkMask; if ((millis()-lastTimeEditBlink)>300) { lastTimeEditBlink=millis();闪烁状态=!闪烁状态; /*Serial.print("blinkpattern="); Serial.println(blinkPattern[menuPosition]);如果(((blinkPattern[menuPosition]>>8)&1==1)&&blinkState==true)digitalWrite(pinLowerDots,HIGH);否则数字写入(pinLowerDots,低);如果(((blinkPattern[menuPosition]>>7)&1==1)&&blinkState==true)digitalWrite(pinUpperDots,HIGH);否则数字写入(pinUpperDots,低); */ 如果 (blinkState) tmp=0;否则 tmp=blinkMask; } if (((dotPattern&~tmp)>>6)&1==1) digitalWrite(pinLowerDots, HIGH);否则数字写入(pinLowerDots,低); if (((dotPattern&~tmp)>>7)&1==1) digitalWrite(pinUpperDots, HIGH);否则数字写入(pinUpperDots,低); if ((blinkState==true) &&(lowBit==1)) mask=0xFFFF;//mask=B11111111;返回掩码;}int extractDigits(byte b){ String tmp="1"; /*Serial.print("闪烁模式="); Serial.println(b); Serial.print("stringToDisplay="); Serial.println(stringToDisplay);*/ if (b==B00000011) { tmp=stringToDisplay.substring(0,2); /*Serial.print("stringToDisplay1="); Serial.println(stringToDisplay);*/ } if (b==B00001100) { tmp=stringToDisplay.substring(2,4); /*Serial.print("stringToDisplay2="); Serial.println(stringToDisplay);*/ } if (b==B00110000) { tmp=stringToDisplay.substring(4); /*Serial.print("stringToDisplay3="); Serial.println(stringToDisplay);*/ } /*Serial.print("stringToDisplay4="); Serial.println(stringToDisplay);*/ return tmp.toInt();}void injectionDigits(byte b, int value){ if (b==B00000011) stringToDisplay=PreZero(value)+stringToDisplay.substring(2); if (b==B00001100) stringToDisplay=stringToDisplay.substring(0,2)+PreZero(value)+stringToDisplay.substring(4); if (b==B00110000) stringToDisplay=stringToDisplay.substring(0,4)+PreZero(value);}bool isValidDate(){ int days[12]={31,28,31,30,31,30,31,31,30,31,30,31}; if (value[DateYearIndex]%4==0) days[1]=29; if (value[DateDayIndex]>days[value[DateMonthIndex]-1]) return false; else return true; }byte default_dur =4;byte default_oct =6;int bpm =63;int num;long wholenote;long duration;byte note;byte scale;char* parseSong(char *p){ // Absolutely no error checking in here // format:d=N,o=N,b=NNN:// find the start (skip name, etc) while(*p !=':') p++; // ignore name p++; // skip ':' // get default duration if(*p =='d') { p++; p++; // skip "d=" num =0; while(isdigit(*p)) { num =(num * 10) + (*p++ - '0'); } if(num> 0) default_dur =num; p++; // skip comma } // get default octave if(*p =='o') { p++; p++; // skip "o=" num =*p++ - '0'; if(num>=3 &&num <=7) default_oct =num; p++; // skip comma } // get BPM if(*p =='b') { p++; p++; // skip "b=" num =0; while(isdigit(*p)) { num =(num * 10) + (*p++ - '0'); } bpm =num; p++; // skip colon } // BPM usually expresses the number of quarter notes per minute wholenote =(60 * 1000L / bpm) * 4; // this is the time for whole note (in milliseconds) return p;} // now begin note loop static unsigned long lastTimeNotePlaying=0; char* playmusic(char *p) { if(*p==0) { return p; } if (millis()-lastTimeNotePlaying>duration) lastTimeNotePlaying=millis(); else return p; // first, get note duration, if available num =0; while(isdigit(*p)) { num =(num * 10) + (*p++ - '0'); } if(num) duration =wholenote / num; else duration =wholenote / default_dur; // we will need to check if we are a dotted note after // now get the note note =0; switch(*p) { case 'c':note =1;休息; case 'd':note =3;休息; case 'e':note =5;休息; case 'f':note =6;休息; case 'g':note =8;休息; case 'a':note =10;休息; case 'b':note =12;休息; case 'p':default:note =0; } p++; // now, get optional '#' sharp if(*p =='#') { note++; p++; } // now, get optional '.' dotted note if(*p =='.') { duration +=duration/2; p++; } // now, get scale if(isdigit(*p)) { scale =*p - '0'; p++; } else { scale =default_oct; } scale +=OCTAVE_OFFSET; if(*p ==',') p++; // skip comma for next note (or we may be at the end) // now play the note if(note) { tone1.play(notes[(scale - 4) * 12 + note], duration); if (millis()-lastTimeNotePlaying>duration) lastTimeNotePlaying=millis(); else return p; tone1.stop(); } else { return p; } Serial.println(F("Incorrect Song Format!"));返回0; //error } void incrementValue() { enteringEditModeTime=millis(); if (editMode==true) { if(menuPosition!=hModeValueIndex) // 12/24 hour mode menu position value[menuPosition]=value[menuPosition]+1; else value[menuPosition]=value[menuPosition]+12; if (value[menuPosition]>maxValue[menuPosition]) value[menuPosition]=minValue[menuPosition]; if (menuPosition==Alarm01) { if (value[menuPosition]==1) /*digitalWrite(pinUpperDots, HIGH);*/dotPattern=B10000000;//turn on all dots /*else digitalWrite(pinUpperDots, LOW); */ dotPattern=B00000000; //turn off all dots } injectDigits(blinkMask, value[menuPosition]); } } void dicrementValue(){ enteringEditModeTime=millis(); if (editMode==true) { if (menuPosition!=hModeValueIndex) value[menuPosition]=value[menuPosition]-1; else value[menuPosition]=value[menuPosition]-12; if (value[menuPosition]1000)) Alarm1SecondBlock=false; if (Alarm1SecondBlock==true) return; if ((hour()==value[AlarmHourIndex]) &&(minute()==value[AlarmMinuteIndex]) &&(second()==value[AlarmSecondIndex])) { lastTimeAlarmTriggired=millis(); Alarm1SecondBlock=true; Serial.println(F("Wake up, Neo!")); p=song; }}
Prog NIXIE Clock Tubes Shield NCS314
https://github.com/afch/NixeTubesShieldNCS314/

示意图


制造工艺

  1. Arduino pov 视觉时钟
  2. Web 操作的 DMX 控制器
  3. 简单字时钟(Arduino)
  4. 带有伊斯兰祈祷时间的 Arduino 时钟
  5. Arduino Spybot
  6. 主时钟
  7. 在 MDF 木箱中用 Arduino 制作数码时钟
  8. 7 段阵列时钟
  9. BLUE_P:无线 Arduino 编程扩展板
  10. Arduino Nano 的 TFT 扩展板 - 开始
  11. Arduino GrowBox 控制器
  12. 带 DS1302 RTC 的简单闹钟