#include <TimerOne.h>
#include <string.h>
#include <EEPROM.h>
const bool testMode=1;
const char testPassword[]="Password";
enum STATE{Locked,Clock,Clock_set,Timer,Marquee};
const int pin_power[4]={3,2,18,19};
const int pin_set[7]={4,5,6,7,8,9,10};
const int pin_dot=11;
const int pin_button[4]={14,15,16,17};
const int MAX_string=99; //最大訊息字元
const bool Number[10][7]={{0,0,0,0,0,0,1},
{1,0,0,1,1,1,1},
{0,0,1,0,0,1,0},
{0,0,0,0,1,1,0},
{1,0,0,1,1,0,0},
{0,1,0,0,1,0,0},
{0,1,0,0,0,0,0},
{0,0,0,1,1,1,1},
{0,0,0,0,0,0,0},
{0,0,0,0,1,0,0},};
const bool LockedLED[7]={1,1,1,1,1,1,0};
unsigned long time=0;
bool timeFlag=0;
STATE State=Locked;
int LEDnumber[4]={0,0,0,0}; //各個LED的數字
bool dot_on[4]={0,0,0,0}; //各個LED的dot是否被點亮
int LEDon=0; //被點亮的LED
int dot_set=0; //設定中的按鈕
int buttonState[4]={0,0,0,0}; //按鈕前一刻的狀態
char stemp[MAX_string];
bool sflash=0; //檢測暫存字串是否被更新
void passwordSet(const char c[]){ //設定密碼
for(int t=0;t<MAX_string;t++){
if(c[t]=='\0') break;
EEPROM.write(t,c[t]);
}
}
void clearStemp(){ //清除stemp
for(int t=0;t<MAX_string;t++)
stemp[t]='\0';
}
void LEDReflash_Clock(){ //更新LED Clock version
digitalWrite(pin_power[LEDon],LOW);
if(LEDon==3) LEDon=0;
else LEDon++;
for(int t=0;t<7;t++)
digitalWrite(pin_set[t], Number[LEDnumber[LEDon]][t]);
digitalWrite(pin_dot,!dot_on[LEDon]);
digitalWrite(pin_power[LEDon],HIGH);
}
void LEDReflash_Locked(){ //更新LED Locked version
digitalWrite(pin_power[LEDon],LOW);
if(LEDon==3) LEDon=0;
else LEDon++;
for(int t=0;t<7;t++)
digitalWrite(pin_set[t],LockedLED[t]);
digitalWrite(pin_power[LEDon],HIGH);
}
int ButtonIsPush(const int n){ //判斷第n個按鈕是否被按一下(return 1)或被長按(return 2)
delay(40);
if(!digitalRead(pin_button[n-1])&&buttonState[n-1]!=1){
delay(40);
if(digitalRead(pin_button[n-1])) return ButtonIsPush(n);
for(int t=0;t<11;t++){
delay(40);
if(digitalRead(pin_button[n-1])&&buttonState[n-1]!=2){
buttonState[n-1]=1;
return 1;
}
if(digitalRead(pin_button[n-1])){
buttonState[n-1]=1;
return 0;
}
}
buttonState[n-1]=2;
return 2;
}
if(digitalRead(pin_button[n-1])) buttonState[n-1]=0;
return 0;
}
bool IsPassword(){ //判斷密碼與暫存字串是否吻合
const char p[7]={'p','a','s','s','w','d',' '};
for(int t=0;t<MAX_string;t++){
if(t<7){
if(p[t]!=stemp[t]) return 0;
}
else if(EEPROM.read(t-7)=='\0'&&stemp[t]=='\0') break;
else{
if(EEPROM.read(t-7)!=stemp[t]) return 0;
}
}
return 1;
}
bool IsTime(){ //判斷是否更改時間,是則進行更改
const char T[5]={'t','i','m','e',' '};
for(int t=0;t<5;t++)
if(stemp[t]!=T[t]) return 0;
time=(long(stemp[5])*600+stemp[6]*60+stemp[7]*10+stemp[8])*100-(long('0')*67100);
return 1;
}
bool IsSetPasswd(){ //判斷是否更改密碼,是則將密碼寫入
const char p[10]={'s','e','t','p','a','s','s','w','d',' '};
for(int t=0;t<MAX_string;t++){
if(t<10){
if(p[t]!=stemp[t]) return 0;
}
else if(stemp[t]=='\0') EEPROM.write(t-10,'\0');
else{
EEPROM.write(t-10,stemp[t]);
}
}
return 1;
}
bool IsLock(){ //判斷stemp==Lock
const char L[5]={'L','o','c','k','\0'};
for(int t=0;t<5;t++)
if(stemp[t]!=L[t]) return 0;
return 1;
}
void timeadd(){ //當timer運作時進行各項隨時間的更新
time++;
if(!(time%3)){ //每0.03秒更新時鐘顯示位數
if(State==Clock) LEDReflash_Clock();
else if(State==Locked) LEDReflash_Locked();
}
if(!(time%50)&&State==Clock){ //Clock下每0.5秒閃爍一次
dot_on[2]=!dot_on[2];
}
if(State==Clock&&!(time%100)){//每1秒更新時鐘
LEDnumber[2]=(time/6000)%10;
LEDnumber[3]=(time/60000)%10;
LEDnumber[0]=(time/100-(time/6000)*60)%10;
LEDnumber[1]=(time/100-(time/6000)*60)/10%10;
}
}
void serialEvent() { //偵測serial輸入並存入stemp
while(Serial.available()){
char temp=Serial.read();
if(temp=='\n') {sflash=1;break;}
for(int t=0;t<MAX_string;t++)
if(stemp[t]=='\0'){
stemp[t]=temp;
stemp[t+1]='\0';
t=MAX_string;
}
}
}
void stateInitial() { //回到初始狀態
for(int t=0;t<3;t++){
LEDnumber[t]=0;
dot_on[t]=0;
}
digitalWrite(pin_dot,HIGH);
sflash=0;
time=0;
State=Locked;
clearStemp();
}
void setup(){
if(testMode) {
for(int t=0;t<MAX_string;t++){
EEPROM.write(t,'\0');
}
passwordSet(testPassword);
}
clearStemp();
Serial.begin(9600);
Serial.println("Hello");
Timer1.initialize(10000);//0.01秒更新
Timer1.attachInterrupt(timeadd);
for(int t=0;t<4;t++){
pinMode(pin_power[t], OUTPUT);
digitalWrite(pin_power[t],LOW);
pinMode(pin_button[t], INPUT_PULLUP);
}
for(int t=0;t<7;t++){
pinMode(pin_set[t], OUTPUT);
digitalWrite(pin_set[t],LOW);
}
pinMode(pin_dot,OUTPUT);
digitalWrite(pin_dot,HIGH);
}
void loop(){
if(State==Locked){
if(sflash){
if(IsPassword()){
clearStemp();
State=Clock;
time=0;
}
}
}
else if(State==Clock){
if(sflash){
if(IsTime()){
clearStemp();
}
}
if(ButtonIsPush(2)){
State=Clock_set;
}
}
else if(State==Clock_set){
if(ButtonIsPush(2)){
State=Clock;
}
}
else if(State==Timer){
}
else if(State==Marquee){
}
if(timeFlag){ //清除無效的輸入
sflash=0;
timeFlag=0;
clearStemp();
}
if(sflash){
if(IsLock()){
stateInitial();
}
else if(State!=Locked&&IsSetPasswd()){
clearStemp();
}
else timeFlag=1;
}
}