#define NumberInGroup 18
#define button 0
#define SEG1 5
#define SEG2 4
#define SEG3 3
#define SEG4 2
#define SEGA 6
#define SEGB 7
#define SEGC 8
#define SEGD 9
#define SEGE 10
#define SEGF 12
#define SEGG 11
#define SEGDOT 13
#define Buzzer A0
#define FPS 250 //max for millis 250Hz
#define FT 1000/(FPS*4) //Delay for each segment
int secondsCount = 0;
unsigned long previousTime = 0;
unsigned long button_timer_prev = 0;
unsigned long display_timer_prev = 0;
bool modeState = false; //false == 0, show NumberInGroup; true == 1, show timer
void updateDisplay(int);
void bin2SEG(byte);
void runStopwatch();
bool scanButton();
void doBuzz();
int main()
{
init(); //to make millis() and other built-in functions work
// DDRD0 - Button, PORTD0 = 0 when pressed
// DDRD2-5 -> segments 1-4
// SEG4-1: HIGH == OFF, LOW == ON
// A-H: HIGH == ON, LOW == OFF
// DDRD6-7 -> A, B
// DDRB0-5 -> C, D, E, G, F, Dot
pinMode(button, INPUT_PULLUP);
pinMode(SEG1, OUTPUT);
pinMode(SEG2, OUTPUT);
pinMode(SEG3, OUTPUT);
pinMode(SEG4, OUTPUT);
digitalWrite(SEG1, HIGH);
digitalWrite(SEG2, HIGH);
digitalWrite(SEG3, HIGH);
digitalWrite(SEG4, HIGH);
pinMode(SEGA, OUTPUT);
pinMode(SEGB, OUTPUT);
pinMode(SEGC, OUTPUT);
pinMode(SEGD, OUTPUT);
pinMode(SEGE, OUTPUT);
pinMode(SEGF, OUTPUT);
pinMode(SEGG, OUTPUT);
pinMode(SEGDOT, OUTPUT);
digitalWrite(SEGDOT, LOW);
pinMode(Buzzer, OUTPUT);
// Serial.begin(19200);
while(true)
{
if (modeState == false)
updateDisplay(NumberInGroup);
else if (modeState == true)
{
updateDisplay(secondsCount);
runStopwatch();
}
}
return 0;
}
void updateDisplay (int number)
{
byte num[4];
num[0] = number / 1000;
num[1] = (number / 100) % 10;
num[2] = (number / 10) % 10;
num[3] = number % 10;
digitalWrite(SEG1, HIGH);
digitalWrite(SEG2, HIGH);
digitalWrite(SEG3, HIGH);
digitalWrite(SEG4, HIGH);
for(byte i = 0; i < FPS; i++) //byte since 250 FPS max
{
if(number >= 1000 && ((millis() - display_timer_prev) >= FT) )
{
digitalWrite(SEG1, HIGH);
digitalWrite(SEG2, HIGH);
digitalWrite(SEG3, HIGH);
bin2SEG(num[0]);
digitalWrite(SEG4, LOW);
display_timer_prev = millis();
}
if(number >= 100 && ((millis() - display_timer_prev) >= FT) )
{
digitalWrite(SEG1, HIGH);
digitalWrite(SEG2, HIGH);
digitalWrite(SEG4, HIGH);
bin2SEG(num[1]);
digitalWrite(SEG3, LOW);
display_timer_prev = millis();
}
if(number >= 10 && ((millis() - display_timer_prev) >= FT) )
{
digitalWrite(SEG1, HIGH);
digitalWrite(SEG3, HIGH);
digitalWrite(SEG4, HIGH);
bin2SEG(num[2]);
digitalWrite(SEG2, LOW);
display_timer_prev = millis();
}
if(number >= 0 && ((millis() - display_timer_prev) >= FT) )
{
digitalWrite(SEG2, HIGH);
digitalWrite(SEG3, HIGH);
digitalWrite(SEG4, HIGH);
bin2SEG(num[3]);
digitalWrite(SEG1, LOW);
display_timer_prev = millis();
}
if (scanButton())
break;
}
}
void runStopwatch()
{
if ( (millis() - previousTime) >= 1000)
{
secondsCount++;
// Serial.print(secondsCount);
// Serial.println('s');
previousTime = millis();
}
}
bool scanButton()
{
if ((millis() - button_timer_prev) >= 50)
{
if (digitalRead(button))
{
modeState = modeState;
button_timer_prev = millis();
}
else if (!digitalRead(button)) // button pressed -> switch modes
{
modeState = !modeState;
// if (modeState == false)
// Serial.println("Number mode");
// else if(modeState == true)
if(modeState)
{
secondsCount = 0;
previousTime = millis();
// Serial.println("Timer mode");
}
doBuzz();
button_timer_prev = millis();
return true; //Switched state
}
}
return false; //Stays the same
}
void doBuzz()
{
tone(Buzzer, 440, 150);
}
void bin2SEG(byte number)
{
switch(number)
{
case 0:
//ABCDEF
digitalWrite(SEGA, HIGH);
digitalWrite(SEGB, HIGH);
digitalWrite(SEGC, HIGH);
digitalWrite(SEGD, HIGH);
digitalWrite(SEGE, HIGH);
digitalWrite(SEGF, HIGH);
digitalWrite(SEGG, LOW);
break;
case 1:
//BC
digitalWrite(SEGA, LOW);
digitalWrite(SEGB, HIGH);
digitalWrite(SEGC, HIGH);
digitalWrite(SEGD, LOW);
digitalWrite(SEGE, LOW);
digitalWrite(SEGF, LOW);
digitalWrite(SEGG, LOW);
break;
case 2:
//ABDEG
digitalWrite(SEGA, HIGH);
digitalWrite(SEGB, HIGH);
digitalWrite(SEGC, LOW);
digitalWrite(SEGD, HIGH);
digitalWrite(SEGE, HIGH);
digitalWrite(SEGF, LOW);
digitalWrite(SEGG, HIGH);
break;
case 3:
//ABCDG
digitalWrite(SEGA, HIGH);
digitalWrite(SEGB, HIGH);
digitalWrite(SEGC, HIGH);
digitalWrite(SEGD, HIGH);
digitalWrite(SEGE, LOW);
digitalWrite(SEGF, LOW);
digitalWrite(SEGG, HIGH);
break;
case 4:
//BCFG
digitalWrite(SEGA, LOW);
digitalWrite(SEGB, HIGH);
digitalWrite(SEGC, HIGH);
digitalWrite(SEGD, LOW);
digitalWrite(SEGE, LOW);
digitalWrite(SEGF, HIGH);
digitalWrite(SEGG, HIGH);
break;
case 5:
//ACDFG
digitalWrite(SEGA, HIGH);
digitalWrite(SEGB, LOW);
digitalWrite(SEGC, HIGH);
digitalWrite(SEGD, HIGH);
digitalWrite(SEGE, LOW);
digitalWrite(SEGF, HIGH);
digitalWrite(SEGG, HIGH);
break;
case 6:
//ACDEFG
digitalWrite(SEGA, HIGH);
digitalWrite(SEGB, LOW);
digitalWrite(SEGC, HIGH);
digitalWrite(SEGD, HIGH);
digitalWrite(SEGE, HIGH);
digitalWrite(SEGF, HIGH);
digitalWrite(SEGG, HIGH);
break;
case 7:
//ABC
digitalWrite(SEGA, HIGH);
digitalWrite(SEGB, HIGH);
digitalWrite(SEGC, HIGH);
digitalWrite(SEGD, LOW);
digitalWrite(SEGE, LOW);
digitalWrite(SEGF, LOW);
digitalWrite(SEGG, LOW);
break;
case 8:
//ABCDEFG
digitalWrite(SEGA, HIGH);
digitalWrite(SEGB, HIGH);
digitalWrite(SEGC, HIGH);
digitalWrite(SEGD, HIGH);
digitalWrite(SEGE, HIGH);
digitalWrite(SEGF, HIGH);
digitalWrite(SEGG, HIGH);
break;
case 9:
//ABCFG
digitalWrite(SEGA, HIGH);
digitalWrite(SEGB, HIGH);
digitalWrite(SEGC, HIGH);
digitalWrite(SEGD, LOW);
digitalWrite(SEGE, LOW);
digitalWrite(SEGF, HIGH);
digitalWrite(SEGG, HIGH);
break;
}
}