#define _A 0
#define _B 1
#define _C 2
#define _D 3
#define _E 4
#define _F 5
#define _G 6
enum STS {STS_READY,
STS_CODE,
STS_OTP,
STS_ALARM};
STS sts = STS_READY;
uint8_t num[] = { 0b00111111, // 0
0b00000110, // 1
0b01011011, // 2
0b01001111, // 3
0b01100110, // 4
0b01101101, // 5
0b01111101, // 6
0b00000111, // 7
0b01111111, // 8
0b01101111, // 9
0b00001000, // _, 10
0b01000000 // - , 11
};
#define ORGT1 62000 //
int32_t sn = 0;
uint8_t idx = 0;
int last_key = -1;
volatile int _key = -1;
uint32_t last_time = 0;
uint32_t last_check_key = 0;
bool flash = false;
uint16_t hypen_cnt = 0;
uint8_t hypen_idx = 0;
uint8_t pos = 0;
uint8_t rest_time = 9;
volatile uint32_t otp_code = 0;
const uint32_t auth_code = 777888;
void disp()
{
uint8_t n[6];
int32_t tmp = sn;
if (sts == STS_READY)
{
hypen_cnt ++;
if (hypen_cnt > 20)
{
hypen_cnt = 0;
n[hypen_idx] = num[11];
hypen_idx++;
if (hypen_idx >3)
{
n[0] = 0; n[1] = 0; n[2] = 0; n[3] = 0; n[4] = 0; n[5] = 0;
hypen_idx = 0;
}
}
}else if (sts == STS_CODE || sts == STS_OTP)
{
n[0] = 0; n[1] = 0; n[2] = 0; n[3] = 0; n[4] = 0; n[5] = 0;
if (sts==STS_OTP)
{
hypen_cnt ++;
if (hypen_cnt > 70)
{
hypen_cnt = 0;
if (rest_time == 0)
{
sts = STS_ALARM;
rest_time = 9;
}
rest_time --;
}
}
if (tmp > 0)
{
while (tmp >=100000)
{
n[5]++;
tmp -= 100000;
}
while (tmp >=10000)
{
n[4]++;
tmp -= 10000;
}
while (tmp >=1000)
{
n[3]++;
tmp -= 1000;
}
while (tmp >=100)
{
n[2]++;
tmp -= 100;
}
while (tmp >=10)
{
n[1]++;
tmp -= 10;
}
n[0] = num[tmp];
n[1] = n[1] + n[2] + n[3] + n[4] + n[5] == 0 ? 0 : num[n[1]];
n[2] = n[2] + n[3] + n[4] + n[5] == 0 ? 0 : num[n[2]];
n[3] = n[3] + n[4] + n[5] == 0 ? 0 : num[n[3]];
n[4] = n[4] + n[5] == 0 ? 0 : num[n[4]];
n[5] = n[5] == 0 ? 0 : num[n[5]];
if (sts == STS_OTP)
{
n[5] = num[rest_time];
}
}else{
n[0] = flash ? num[10] : 0;
if (sts == STS_OTP)
{
n[5] = num[rest_time];
}
}
}else if (sts==STS_ALARM)
{
if (flash)
{
n[0] = 0; n[1] = 0; n[2] = 0; n[3] = 0; n[4] = 0; n[5] = 0;
}else{
n[0] = num[8]; n[1] = num[8]; n[2] = num[8]; n[3] = num[8]; n[4] = num[8]; n[5] = num[8];
}
}
check_key();
PORTB = 0b111110;
bitSet(PORTC,4);
PORTD = (bitRead(PIND,0) ? _BV(0) : 0) |
(bitRead(PIND,1) ? _BV(1) : 0);
PORTD = (bitRead(PIND,0) ? _BV(0) : 0) |
(bitRead(PIND,1) ? _BV(1) : 0) |
(bitRead(n[idx], _A) ? _BV(2) : 0) |
(bitRead(n[idx], _B) ? _BV(3) : 0) |
(bitRead(n[idx], _C) ? _BV(4) : 0) |
(bitRead(n[idx], _D) ? _BV(5) : 0) |
(bitRead(n[idx], _E) ? _BV(6) : 0) |
(bitRead(n[idx], _F) ? _BV(7) : 0);
PORTB = (bitRead(n[idx], _G) ? _BV(0) : 0) |
(idx == 0 ? 0 : _BV(2)) |
(idx == 1 ? 0 : _BV(1)) |
(idx == 5 ? 0 : _BV(3)) |
(idx == 3 ? 0 : _BV(5)) |
(idx == 4 ? 0 : _BV(4));
bitWrite(PORTC, 4 , idx!=2);
idx++;
idx %= 6;
}
void check_key()
{
PORTD = (bitRead(PIND,0) ? _BV(0) : 0) |
(bitRead(PIND,1) ? _BV(1) : 0);
PORTB = 0;
uint8_t i = 0;
_key = -1;
for (i = 0; i < 4; i++)
{
PORTB = 0;
bitSet(PORTB, i + 1); // row1
if (PINC & _BV(3))
{
_key = 1 + i*3; break;
}else if (PINC & _BV(2))
{
_key = 2 + i*3; break;
}else if (PINC & _BV(1))
{
_key = 3 + i*3; break;
}
}
PORTB = 0;
}
void On_Key(int k)
{
if (k == 11) k = 0;
if (k != 10 && k != 12)
{
if (sn == -1) sn = 0;
if (sn < 100000)
sn = sn *10 + k;
}else if (k == 10)
{
if (sts==STS_READY || sts == STS_CODE)
{
sts = STS_CODE;
sn = -1;
}
}else if (k == 12)
{
if (sts==STS_CODE)
{
if (sn == auth_code)
{
sts = STS_OTP;
sn = -1;
otp_code = random(100,9999);
while (otp_code > 9999)
{
otp_code = random();
} Serial.print("OTP Code: ");
/*
*/
Serial.println(otp_code);
}else if (sn == -1)
{
sts = STS_READY;
bitClear(PORTC,0);
}
}else if (sts==STS_OTP)
{
if (sn == otp_code) // open door..
{
sts = STS_READY;
rest_time = 9;
sn = -1;
bitSet(PORTC,0);
Serial.println("Correct!");
}else{
sts = STS_ALARM;
bitClear(PORTC,0);
}
}
}
}
void setup() {
// Timer1 Configuration for 2ms
DDRD = 0b11111110;
DDRB = 0b111111;
DDRC = 0b110001;
Serial.begin(115200);
TCNT1 = ORGT1;
TCCR1B |= _BV(CS10);
TIMSK1 |= _BV(TOIE1);
sei();
}
void loop() {
if (millis() - last_check_key > 20)
{
if (_key == -1 && last_key > 0)
{
On_Key(last_key);
}
last_key = _key;
last_check_key = millis();
}
if (millis() - last_time > 250)
{
flash = !flash;
last_time = millis();
if (sts == STS_ALARM)
{
bitWrite(PORTC,5, flash);
}else{
bitSet(PORTC,5);
}
//Serial.println(_key);
}
}
ISR(TIMER1_OVF_vect) // repeat every 2ms
{
TCNT1 = ORGT1;
disp();
}