byte ledpins[] = {2, 3, 4, 5, 6, 7, 8, 9, //led
A0, A1, A2, A3, A4, A5, A6,// sevseg
12, 13};//digit
int code[] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F };
int N = 4;
int count = N;
int MSB = 1 << N;
class Port{
byte* pins;
byte length;
bool level;
public:
Port(byte length, bool level)
: length(length), level(level){}
void connect(byte* pins, int mode){
this->pins = pins;
for(int i = 0; i < length; i++){
pinMode(pins[i], mode);
}
}
void Write(byte v){
if(level == 0) v = ~v;
for(int i = 0; i < length; i++){
digitalWrite(pins[i], (v >> i) & 1);
}
}
void Set(int index) {digitalWrite(pins[index], level ? 1 : 0);}
void Reset(int index) {digitalWrite(pins[index], level ? 0 : 1);}
};
class Process{
public:
int value;
virtual void Init();
virtual void Next();
virtual bool EoP() { return count == 0;}
public:
bool run(Port& port){ // false la xong, true la chay tiep
count == N ? Init() : Next();
port.Write(value);
return !EoP();
}
};
class single1 : public Process {
public:
void Init() override { value = 1;}
void Next() override { value <<= 1;}
};
class single2 : public Process {
public:
void Init() override { value = MSB >> 1;}
void Next() override { value >>= 1; }
};
class Fill1 : public single1 {
public:
void Next() override { value |= value << 1;}
};
class Fill2 : public single2 {
public:
void Next() override { value |= value >> 1;}
};
class Clear1 : public Process {
public:
void Init() override { value = MSB - 1;}
void Next() override { value >>= 1; }
};
class Clear2 : public Process {
public:
void Init() override { value = MSB - 1;}
void Next() override { value <<= 1; }
};
class blink : public Process {
public:
void Init() override { value = 0b10101010;}
void Next() override { value = ~value;}
bool EoP() override { return count == -10; }
};
int index = 0;
Process* procs[] = {
new single1(), new single2(),
new single2(), new single1(),
new Fill1(), new Fill2(),
new Clear1(), new Clear2(),
new blink(), new blink(),
0
};
Port le(N, 1);
Port ri(N, 1);
Port led(7, 0);
Port ctr(2, 1);
void Display(int n, int digit){
led.Write(code[n]);
ctr.Set(digit);
delay(1);
ctr.Reset(digit);
}
void setup() {
le.connect(ledpins, OUTPUT);
ri.connect(ledpins + N, OUTPUT);
byte* pinled = ledpins + (N << 1);
led.connect(pinled, OUTPUT);
ctr.connect(pinled + 7, OUTPUT);
}
void loop() {
Process* p = procs[index];
if(p == 0) p = procs[index = 0];
p->run(le);
p = procs[index + 1];
if(!p->run(ri)){
count = N;
index += 2;
}
else{
--count;
}
delay(1000);
}