不想错过我的推送,记得右上角-查看公众号-设为星标,摘下星星送给我
《命运石之门》里 “世界线变动率探测仪”,各种辉光管的作品,让热爱DIY的小伙伴欢喜,但是辉光管的价格又望而却步,并且现在已经很难买到了。怎么能难倒我们的工程师呢?拟辉光管时钟制作指南来了,先看一张效果图:
制作过程如下视频(英文原声,大家自行理解):
在分享制作过程之前,我们先来了解下LIXIE显示原理。
LIXIE的一端包含有LED,也可以是WS2812B智能LED,能根据需要改变显示颜色的。LED发出的光线被聚集到一叠树脂玻璃Plexiglas中。这类“端面照光”显示器利用全内反射的现象,可将光保持在树脂玻璃内刻蚀出图案的区域。每片代表一个数字,并且通常一次只照亮一张树脂玻璃片,从而显示出具体的数字。
在今天分享的时钟项目中,时钟和分钟的显示需要四位数,每位数需要雕刻出0-9这些数字,然后再添加两个圆点来区分小时和分钟,所以总共需要82个LED。这里指示数字使用蓝色LED灯,区分时分圆点的用白色LED灯。
除了82个LED之外,还需要以下器件:
ATmega328P,即Uno MCU
MCP23017 集成电路
两个 22pF 电容器
330 欧姆电阻
RTC 模块组件,DS3231
16 MHz 石英振荡器
蓝牙模块HC-05
EEPROM,CAT24C02WI-G
蜂鸣器
一些端子连接
所有这些 LED 与 Arduino 的接线,将相同行的阳极焊接在一起以获得 10 行和相同列的阴极。
之后,使用 Arduino 代码控制所需的数字就会非常容易。如果想了解如何控制相同矩阵的 LED ,大家可以去搜下光立方的控制方法。
制作的第一步:CAD 和硬件零件。
从激光雕刻和切割零件开始,使用 solidworks 软件制作了上述设计,可以从文末的下载链接获取 DXF 文件,此设计 100% 推荐用于帮助大家制作设备。
制作的第二步:电路图绘制。
整个控制电路图如下:
使用RTC模块组件进行校准时间和日期配置等,并且通过I2C与MCU建立通信以进行数据传输。在时钟里添加闹钟功能,可以通过蜂鸣器进行提示。为了与时钟接口,使用蓝牙模块,调用Android 应用程序,实时调整时间和日期。
制作的第三步:PCB焊接。
制作电路图后,将其转换为定制的PCB设计,并投板生产。
这就是仿辉光管LIXIE时钟所有的组件了:
一切准备就绪,下面就开始将电子元件焊接到 PCB 上,为此需要烙铁和焊芯线以及用于 SMD 元件的SMD rework(如果使用 RTC 模块,则不需要)。
下图是已经将每个组件焊接到其位置,可以使用PCB的两面来焊接电子元件。
接下来就是进入硬件焊接的第二部分,LED连接,大工程。
正如上面的照片中看到的,在设计中为每个 LED 创建了一个孔,因此只需使用一些胶水固定 LED,然后将相同行的所有阳极和相同列的阴极焊接在一起。完成之后,将有 14 根用于矩阵的电线,因此只需拧紧它们。
然后,将放置Plexiglas零件并拧紧连接点来继续组装。
制作的第四步:软件部分。
现在需要的只有软件代码,这个Arduino代码可以从文末的链接免费获得。代码做了注释,大家可以根据自己的需要进行调整。
/************************************************************************************************************************************************************************
* - Author : BELKHIR Mohamed *
* - Profession : (Electrical Ingineer) MEGA DAS owner *
* - Main purpose : Industrial Application *
* - Copyright (c) holder : All rights reserved *
* - License : BSD 2-Clause License *
* - Date : 08/15/2019 *
* ***********************************************************************************************************************************************************************/
/*********************************** NOTE **************************************/
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED
/* MMMMMMMXlxMMWXOkOkkOOOKWMMMMMMMMMMMMMMWKOkkOkkkOXMN0OkOkkOk0NMMMMMMN0000OkkOKNMXOOOOOkOk0WMWKOOOOOkkOO0000000OOOOO0NMMMOc
MMMMMMMXlxMMWK; ,0WMMMMMMMMMMMMMMWk' :XMNO, :XMMMMMMN000c .,okKWMXc .xWMNk' cO0000000kc. .kMMMOc
MMMMMMMXldMMMN: cWMMMMMMMMMMMMMMMMK, dMMMWx. 'OMMMMMMMMMO :oNMMMMMMo ;KMMM0' .xMMMMMMMMMWd. .kMMMOc
MMMMMMMXlxMMMN: cNMMMMMMMMMMMMMMMMK, dMMMMNl :XMMMMMMMX dkWMMMMMMMo ;KMMM0' .dMMMMMMMMMMNc .kMMMOc
MMMMMMMXlxMMMN: cNMMMMMMMMMMMMMMMMK, dMMMMMK, oWMMMMMW kkWMMMMMMMMo ,KMWM0' .xMMMMMMMMMMMx..kMMMOc
MMMMMMMXlxMMMN: cNMMMMMMMMMMMMMMMMK, dMMMMMMk. .OMMMMM 0xXMMMMMMMMMo ,KMMM0' .xMMMMMMMMMMM0'.kMMMOc
MMMMMMMXlxMMMN: cNMMMMMMMMMMMMMMMMK, dMMMMMMNl ;XMMM XxOMMMMMMMMMMo ,KMWM0' .xMMMMMMMMMMMN:.kMMMOc
MMMMMMMXlxMMMN: cNMMMMMMMMMMMMMMMMK, dMMMMMMMK; oWM WkkNMMMMMMMMMMo ,KMWM0' .xMMMMMMMMMMMWd.xMMMOc
MMMMMMMXlxMMMN: cNMMMMMMMMMMMMMMMMK, dMMMMMMMMk. .k MKxKMMMMMMMMMMMo ,KMWM0' .xMMMMMMMMMMMMNOXMMMOc
MMMMMMMXlxMMMN: cNMMMMMMMMMMMMMMMMK, dMMMMMMMMWl ;0kOWMMMMMMMMMMMo ,KMWM0' .xMMMMMMMMMMMMMMMMMMOc
MMMMMMMXlxMMMN: cNMMMMMMMMMMMMMMMMK, dMMMMMMMMMK; ,xNMMMMMMMMMMMMo ,KMWM0' .xMMMMMMNXWMMMMMMMMMOc
MMMMMMMXlxMMMN: cNMMMMMMMMMMMMMMMMK, dMMMMMMMMMMO. .xMMMMMMMMMMMMMo ,KMWM0' .xMMMMMK::KMMMMMMMMMOc
MMMMMMMXlxMMMN: cNMMMMMMMMMMMMMMMMK, dMMMMMMMMMMWo ;XMMMMMMMMMMMMo ,KMWM0' .xMMMMXc ,KMMMMMMMMMOc
MMMMMMMXlxMMMN: cNMMMMMMMMMMMMMMMMK, dMMMMMMMMMMMX; oWMMMMMMMMMMMo ,KMWM0' ckkxo' ,KMMMMMMMWMOc
MMMMMMMXlxMMMN: cNMMMMMMMMMMMMMMMMK, dMMMMMMMMMMMM . .kMMMMMMMMMMMo ,KMWM0' oKKKOo. ,KMMWWWWWWMOc
MMMMMMMXlxMMMN: cNMMMMMMMMMMMMMMMMK, dMMMMMMMMMMM Wo ;KMMMMMMMMMMo ,KMWM0' .xMWWWWx.,KMWWWWWWWMOc
MMMMMMMXlxMMMN: cNMMMMMMMMMMMMMMMMK, dMMMMMMMMMM MMk. oWMMMMMMMMMo ,KMWM0' .xMWWWWNkxXMWWWWWWWMOc
MMMMMMMXlxMWMN: :NMMMMMMMMMMMMMMMMK, dMMMMMMMMM MMXxo. .kMMMMMMMMMo ,KMWM0' .xMWWWWWWWWWWWWWWWWWOc
MMMMMMMXlxMWMN: :NMMMMMMMMMMMMMWWMK, dMMMMMMMM MMWkkWo ;KMMMMMMMMo ,KMWM0' .xMWWWWWWWWWWWWWWWWWOc
MMMMMMMXlxMWMN: :NMMMMMMMMMMMMXoxWK, dMMMMMMM MMMOxXMX; lNMMMMMMWo ,KMWM0' .xWWWWWWWWWWWWW0lOWWOc
MMMMMMMXlxMWMN: :NMWMMMMMMMMMMx.cWK, dMMMMMM MMMXx0MMMO. .kWMMMMMWo ,KWWW0' .dWWWWWWWWWWWWNc.kWWOc
MMMMMMMXlxMWMN: :NMWWWMWWWWMMWl cWK, dMMMMM MMMWkkWMMMWo ,KMMMMMWo ,KWWW0' .dWWWWWWWWWWWWK,.kWWO:
MMMMMMMXlxMWMN: :NMWWWWWWWWWMX; lWK, dMMMM MMMM0xXMMMMMX: lNMMMWWo ,KWWW0' .dWWWWWWWWWWWWO..kWWO:
MMMMMMMXlxWWWN: :NMWWWWWWWWWMO. lWK, dMMM MWWMXxOMMMMMMMO. .xWMMWWo ,KWWW0' .dWWWWWWWWWWWWo .kWWO:
MMMMMMMXlxWWWN: :NWWWWWWWWWWNc lW0' dMW MWWMWdlXWWMMMWWWd ,KMWWWo ,KWWW0' .dWWWWWWWWWWW0, .kWWO:
MMMMMMMXlxWWWN: :NWWWWWWWWWXl. cW0, oW WWMWM0''OWWWWMWWMX: cXWWWl ,0WNWO' dWWWWWWWWWNO; .kWWO:
MMMMMMMXlxWWW0l,,,,,,lOOOOOOOOOko;,,;xNOc,,,,,;lKWN0OOOd;;lkXWWWWWWNx;;;;,,:xXWKo;,,,,,:kNWNk:,,,,,;lkOOOOOOOOxc;,,c0WWO:*/
#if defined(ESP8266)
#include <pgmspace.h>
#else
#include <avr/pgmspace.h>
#endif
#include <Wire.h> // must be incuded here so that Arduino library object file references work
#include <RtcDS3231.h> // Include the RTC library
#include <EEPROM.h> // Include the EEPROM library needed for alarm handeling
#include "Adafruit_MCP23017.h" // Include the MCP library to interface the MCP iC
RtcDS3231 Rtc; // Create the RTC instance
RtcDateTime dateTimeData;
Adafruit_MCP23017 MyMCP; // Create the MCP instance
char SerialData; // Use this variable to read each caractere received through serial port
char SerialDataDecisison;
String dateData=""; // Store all serial caracters in this variable
String timeData=""; // Store all serial caracters in this variable
String alarmData=""; // Store all serial caracters in this variable
int monthNumber=13;
long int dotBlinkTime=millis();
int alarmHours=0;
int alarmMinutes=0;
int alarmSeconds=0;
int alarmActivate=0;
int alarmCounterControl=0;
int alarmCounter=0;
int displayDot=1;
long int buzzerTime=millis();
long int buzzerTimeControl=millis();
long int dispalDate=millis();
const int N0=1; // The first line of plexiglass LEDs 0
const int N1=0; // The second line of plexiglass LEDs 1
const int N2=15; // The third line of plexiglass LEDs 2
const int N3=14; // .
const int N4=13; // .
const int N5=12; // .
const int N6=11; // .
const int N7=9; // .
const int N8=10; // .
const int N9=8; // The last line of plexiglass LEDs 9
const int dig1=2; // Control of the first digit
const int dig2=3; // .
const int dig3=4; // .
const int dig4=5; // Control of the fourth digit
const int dot=6; // Control of the two dots
const int buzzer=3; // Control of the buzzer
const int delaySeq=5000;
void setup()
{
Serial.begin(9600);
Serial.setTimeout(100);
Wire.setClock(3400000);
pinMode(buzzer,OUTPUT);
digitalWrite(buzzer,LOW);
MyMCP.begin(1);
//--------RTC SETUP ------------
Rtc.Begin();
for(int i=0;i<16;i++)
{
MyMCP.pinMode(i,OUTPUT);
MyMCP.digitalWrite(i,LOW);
}
clearDisplay();
if (!Rtc.IsDateTimeValid())
{
// Common Cuases:
// 1) first time you ran and the device wasn't running yet
// 2) the battery on the device is low or even missing
Serial.println("RTC lost confidence in the DateTime!");
// following line sets the RTC to the date & time this sketch was compiled
// it will also reset the valid flag internally unless the Rtc device is
// having an issue
}
if (!Rtc.GetIsRunning())
{
Serial.println("RTC was not actively running, starting now");
Rtc.SetIsRunning(true);
}
Rtc.Enable32kHzPin(false);
Rtc.SetSquareWavePin(DS3231SquareWavePin_ModeNone);
dateTimeData=Rtc.GetDateTime();
if(EEPROM.read(0)==1)
{
alarmMinutes=EEPROM.read(1);
alarmHours=EEPROM.read(2);
alarmActivate=1;
}
}
void loop()
{
while(Serial.available()) // While serial data are available we store it
{
delay(10);
SerialDataDecisison=Serial.read();
if(SerialDataDecisison=='d')
{
monthNumber=Serial.parseInt();
switch (monthNumber)
{
case 1 : dateData+="Jan"; break;
case 2 : dateData+="Feb"; break;
case 3 : dateData+="Mar"; break;
case 4 : dateData+="Apr"; break;
case 5 : dateData+="May"; break;
case 6 : dateData+="Jun"; break;
case 7 : dateData+="Jul"; break;
case 8 : dateData+="Aug"; break;
case 9 : dateData+="Sep"; break;
case 10 : dateData+="Oct"; break;
case 11 : dateData+="Nov"; break;
case 12 : dateData+="Dec"; break;
}
while(Serial.available()) // While serial data are available we store it
{
delay(10);
SerialData=Serial.read();
dateData+=SerialData;
}
const char* newDate=dateData.c_str();
dateTimeData=Rtc.GetDateTime();
String TimeFromRTC=(String(dateTimeData.Hour())+":"+String(dateTimeData.Minute())+":"+String(dateTimeData.Second()));
const char* sameTime=TimeFromRTC.c_str();
Serial.println(sameTime);
RtcDateTime RtcConfig = RtcDateTime(newDate, sameTime);
Rtc.SetDateTime(RtcConfig);
}
if(SerialDataDecisison=='t')
{
while(Serial.available()) // While serial data are available we store it
{
delay(10);
SerialData=Serial.read();
timeData+=SerialData;
}
const char* newTime=timeData.c_str();
dateTimeData=Rtc.GetDateTime();
String DateFromRTC=(String(dateTimeData.Month())+" "+String(dateTimeData.Day())+" "+String(dateTimeData.Year()));
const char* sameDate=DateFromRTC.c_str();
Serial.println(sameDate);
RtcDateTime RtcConfig = RtcDateTime(sameDate, newTime);
Rtc.SetDateTime(RtcConfig);
}
if(SerialDataDecisison=='a')
{
while(Serial.available()) // While serial data are available we store it
{
delay(10);
SerialData=Serial.read();
alarmData+=SerialData;
}
alarmHours=getValue(alarmData, ':', 0).toInt();
alarmMinutes=getValue(alarmData, ':', 1).toInt();
alarmSeconds=getValue(alarmData, ':', 2).toInt();
EEPROM.write(0,1);
EEPROM.write(1,alarmMinutes);
EEPROM.write(2,alarmHours);
alarmActivate=1;
buzzerTime=millis();
}
}
dateData="";
timeData="";
alarmData="";
if(millis()-dotBlinkTime<1000&&displayDot==1)
{
MyMCP.digitalWrite(dot,HIGH);
}
if(millis()-dotBlinkTime>1000&&displayDot==1)
{
MyMCP.digitalWrite(dot,LOW);
if(millis()-dotBlinkTime>2000&&displayDot==1)
{
dotBlinkTime=millis();
}
}
RtcDateTime now = Rtc.GetDateTime();
if(millis()-dispalDate<10000)
{
displayMode(now.Minute(),"right");
displayMode(now.Hour(),"left");
displayDot=1;
}
if(millis()-dispalDate>10000)
{
displayDot=0;
MyMCP.digitalWrite(dot,LOW);
displayMode(now.Day(),"right");
displayMode(now.Month(),"left");
if(millis()-dispalDate>15000)
{
dispalDate=millis();
displayDot=1;
}
}
if(alarmActivate==1&&now.Hour()==alarmHours&&now.Minute()==alarmMinutes)
{
if(alarmCounterControl<8)
{
alarmControl();
}
else
{
alarmCounterControl=0;
alarmActivate=0;
EEPROM.write(0,0);
}
}
}
void alarmControl()
{
if(millis()-buzzerTime<65)
{
digitalWrite(buzzer,HIGH);
}
if(millis()-buzzerTime>65)
{
digitalWrite(buzzer,LOW);
if(millis()-buzzerTime>130&&alarmCounter<4)
{
buzzerTime=millis();
alarmCounter+=1;
}
if(millis()-buzzerTime>1000)
{
alarmCounter=0;
alarmCounterControl+=1;
}
}
}
void clearDisplay()
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
delay(0);
}
void displayMode(int value, String side)
{
if(side=="right")
{
switch (value%10)
{
case 0 :
{
MyMCP.digitalWrite(dig1,LOW);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N0,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N0,LOW);
}break;
case 1 :
{
MyMCP.digitalWrite(dig1,LOW);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N1,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N1,LOW);
}break;
case 2 :
{
MyMCP.digitalWrite(dig1,LOW);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N2,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N2,LOW);
}break;
case 3 :
{
MyMCP.digitalWrite(dig1,LOW);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N3,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N3,LOW);
}break;
case 4 :
{
MyMCP.digitalWrite(dig1,LOW);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N4,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N4,LOW);
}break;
case 5 :
{
MyMCP.digitalWrite(dig1,LOW);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N5,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N5,LOW);
}break;
case 6 :
{
MyMCP.digitalWrite(dig1,LOW);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N6,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N6,LOW);
}break;
case 7 :
{
MyMCP.digitalWrite(dig1,LOW);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N7,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N7,LOW);
}break;
case 8 :
{
MyMCP.digitalWrite(dig1,LOW);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N8,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N8,LOW);
}break;
case 9 :
{
MyMCP.digitalWrite(dig1,LOW);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N9,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N9,LOW);
}break;
}
switch (value/10)
{
case 0 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,LOW);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N0,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N0,LOW);
}break;
case 1 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,LOW);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N1,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N1,LOW);
}break;
case 2 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,LOW);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N2,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N2,LOW);
}break;
case 3 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,LOW);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N3,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N3,LOW);
}break;
case 4 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,LOW);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N4,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N4,LOW);
}break;
case 5 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,LOW);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N5,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N5,LOW);
}break;
case 6 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,LOW);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N6,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N6,LOW);
}break;
case 7 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,LOW);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N7,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N7,LOW);
}break;
case 8 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,LOW);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N8,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N8,LOW);
}break;
case 9 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,LOW);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N9,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N9,LOW);
}break;
}
}
if(side=="left")
{
switch (value%10)
{
case 0 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,LOW);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N0,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N0,LOW);
}break;
case 1 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,LOW);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N1,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N1,LOW);
}break;
case 2 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,LOW);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N2,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N2,LOW);
}break;
case 3 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,LOW);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N3,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N3,LOW);
}break;
case 4 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,LOW);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N4,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N4,LOW);
}break;
case 5 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,LOW);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N5,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N5,LOW);
}break;
case 6 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,LOW);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N6,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N6,LOW);
}break;
case 7 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,LOW);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N7,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N7,LOW);
}break;
case 8 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,LOW);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N8,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N8,LOW);
}break;
case 9 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,LOW);
MyMCP.digitalWrite(dig4,HIGH);
MyMCP.digitalWrite(N9,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N9,LOW);
}break;
}
switch (value/10)
{
case 0 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,LOW);
MyMCP.digitalWrite(N0,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N0,LOW);
}break;
case 1 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,LOW);
MyMCP.digitalWrite(N1,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N1,LOW);
}break;
case 2 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,LOW);
MyMCP.digitalWrite(N2,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N2,LOW);
}break;
case 3 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,LOW);
MyMCP.digitalWrite(N3,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N3,LOW);
}break;
case 4 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,LOW);
MyMCP.digitalWrite(N4,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N4,LOW);
}break;
case 5 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,LOW);
MyMCP.digitalWrite(N5,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N5,LOW);
}break;
case 6 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,LOW);
MyMCP.digitalWrite(N6,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N6,LOW);
}break;
case 7 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,LOW);
MyMCP.digitalWrite(N7,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N7,LOW);
}break;
case 8 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,LOW);
MyMCP.digitalWrite(N8,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(N8,LOW);
}break;
case 9 :
{
MyMCP.digitalWrite(dig1,HIGH);
MyMCP.digitalWrite(dig2,HIGH);
MyMCP.digitalWrite(dig3,HIGH);
MyMCP.digitalWrite(dig4,LOW);
MyMCP.digitalWrite(N9,HIGH);
delayMicroseconds(delaySeq);
MyMCP.digitalWrite(dig4,LOW);
MyMCP.digitalWrite(N9,LOW);
}break;
}
}
}
String getValue(String data, char separator, int index)
{
int found = 0;
int strIndex[] = { 0, -1 };
int maxIndex = data.length() - 1;
for (int i = 0; i <= maxIndex && found <= index; i++)
{
if (data.charAt(i) == separator || i == maxIndex)
{
found++;
strIndex[0] = strIndex[1] + 1;
strIndex[1] = (i == maxIndex) ? i+1 : i;
}
}
return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}
代码编译完成之后,就可以使用 Arduino IDE将代码上传到 ATmega328 MCU,然后将MCU 放置在 PCB 上的插座中即可。
最后,使用外部 5v 电源适配器给整个项目供电,就可以测试了。
当然,还可以创建了一个Android应用程序来使用它,同时设置时间,日期和时钟的闹钟。
虽然这个项目制作过程很简单,但整体来说是一个比较有趣,有实际意义的作品。这个作为一个引子,大家可以DIY自己的时钟,比如使用不同颜色的LED来显示数字。
好了,接下来的时间,交给大家了,高清原理图,源码,CAD文件,都在下面链接了。
原文链接:
https://www.hackster.io/diyguyChris/arduino-lixie-clock-6ce547
作者:DIY GUY Chris,达尔闻说编辑
项目资料下载 | 百度网盘链接:
https://pan.baidu.com/s/1WefAOvilbfU8NYAg6de8aA
提取码:y826
END