#include <SPI.h>
class State_pb{
private:
bool cur_state;
bool last_state;
public:
State_pb(){
cur_state = LOW;
last_state = LOW;
}
bool is_true(){
return cur_state == LOW && last_state == HIGH;
}
void update_state(){
last_state = cur_state;
}
void set_cur_state(bool state){cur_state = state;}
void set_last_state(bool state){last_state = state;}
bool get_cur_state() const {return cur_state;}
bool get_last_state() const {return last_state;}
};
class BasePB{
private:
int pin;
State_pb *state;
public:
BasePB(int cur_pin){
pin = cur_pin;
state = new State_pb();
}
virtual ~BasePB(){
delete state;
}
void start_pb(){
pinMode(pin, INPUT_PULLUP);
}
void update_state(){
state->update_state();
}
bool is_true(){
return state->is_true();
}
void debounce(){
bool curr_status_pb = digitalRead(pin);
if( state->get_last_state() != curr_status_pb){
delay(5);
curr_status_pb = digitalRead(pin);
}
state->set_cur_state(curr_status_pb);
}
};
class Spi{
protected:
int pin;
public:
Spi(int pin_spi){
pin = pin_spi;
}
void begin(){
SPI.begin();
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
SPI.transfer(0);
digitalWrite(pin, HIGH);
digitalWrite(pin, LOW);
}
};
class SpiLed: public Spi{
private:
unsigned long time;
void rotateLeft(uint8_t &bits){
uint8_t high_bit = bits & (1 << 7) ? 1 : 0;
bits = (bits << 1) | high_bit;
}
public:
SpiLed(int pin) : Spi(pin){ time = 1500;}
void start(){
static uint8_t nomad = 1;
SPI.transfer(nomad);
digitalWrite(pin, HIGH);
digitalWrite(pin, LOW);
rotateLeft(nomad);
delay(time);
}
void set_time(unsigned long time_var){
time = time_var;
}
void off_led(){
digitalWrite(pin, LOW);
SPI.transfer(0);
digitalWrite(pin, HIGH);
digitalWrite(pin, LOW);
}
};
class InterfaceSpi{
private:
SpiLed *spi_one;
SpiLed *spi_two;
int count_spi_one;
int count_spi_two;
public:
InterfaceSpi(int pin_one_spi, int pin_two_spi){
spi_one = new SpiLed(pin_one_spi);
spi_two = new SpiLed(pin_two_spi);
count_spi_one = 0;
count_spi_two = 0;
}
virtual ~InterfaceSpi(){
delete spi_one;
delete spi_two;
}
void begin(){
spi_one->begin();
spi_two->begin();
}
void set_time(unsigned long time){
spi_one->set_time(time);
spi_two->set_time(time);
}
void work(){
if(count_spi_two != 8){
++count_spi_two;
spi_two->start();
if(count_spi_two == 8){
count_spi_one = 0;
spi_two->off_led();
}
}else{
++count_spi_one;
spi_one->start();
if(count_spi_one == 8){
count_spi_two = 0;
spi_one->off_led();
}
}
}
};
InterfaceSpi spi(8,7);
BasePB pb(2);
void change_time(){
static int time = 1000;
pb.debounce();
if(pb.is_true()){
spi.set_time(time);
time /= 2;
if(time == 0){
time = 1000;
}
}
pb.update_state();
}
void setup() {
// put your setup code here, to run once:
spi.begin();
attachInterrupt(0, change_time, FALLING);
pb.start_pb();
}
void loop() {
// put your main code here, to run repeatedly:
spi.work();
}