#include <STM32RTC.h>
/* Get the rtc object */
STM32RTC& rtc = STM32RTC::getInstance();
#define ON 1
#define OFF 0
#define redPin A2
#define bluePin A0
#define greenPin A1
int zero[] = {1,1,1,1,1,1,0};
int one[] = {0,1,1,0,0,0,0};
int two[] = {1,1,0,1,1,0,1};
int three[] = {1,1,1,1,0,0,1};
int four[] = {0,1,1,0,0,1,1};
int five[] = {1,0,1,1,0,1,1};
int six[] = {1,0,1,1,1,1,1};
int seven[] = {1,1,1,0,0,0,0};
int eight[] = {1,1,1,1,1,1,1};
int nine[] = {1,1,1,0,0,1,1};
int A[] = {ON,ON,ON,OFF,ON,ON,ON};
int B[] = {OFF,OFF,ON,ON,ON,ON,ON};
int C[] = {OFF,OFF,OFF,ON,ON,OFF,ON};
int D[] = {OFF,ON,ON,ON,ON,OFF,ON};
int E[] = {ON,OFF,OFF,ON,ON,ON,ON};
int F[] = {ON,OFF,OFF,OFF,ON,ON,ON};
int G[] = {ON,OFF,ON,ON,ON,ON,OFF};
int H[] = {OFF,ON,ON,OFF,ON,ON,ON};
int h[] = {OFF,OFF,ON,OFF,ON,ON,ON};
int I[] = {OFF,OFF,OFF,OFF,ON,ON,OFF};
int J[] = {OFF,ON,ON,ON,OFF,OFF,OFF};
int L[] = {OFF,OFF,OFF,ON,ON,ON,OFF};
int M[] = {ON,OFF,ON,OFF,ON,OFF,OFF};
int N[] = {ON,ON,ON,OFF,ON,ON,OFF};
int n[] = {OFF,OFF,ON,OFF,ON,OFF,ON};
int O[] = {ON,ON,ON,ON,ON,ON,ON,OFF};
int o[] = {OFF,OFF,ON,ON,ON,OFF,ON};
int P[] = {ON,ON,OFF,OFF,ON,ON,ON};
int Q[] = {ON,ON,ON,OFF,OFF,ON,ON};
int R[] = {OFF,OFF,OFF,OFF,ON,OFF,ON};
int S[] = {ON,OFF,ON,ON,OFF,ON,ON};
int T[] = {OFF,OFF,OFF,ON,ON,ON,ON};
int U[] = {OFF,ON,ON,ON,ON,ON,OFF};
int u[] = {OFF,OFF,ON,ON,ON,OFF,OFF};
int Y[] = {OFF,ON,ON,ON,OFF,ON,ON};
int Z[] = {ON,ON,OFF,ON,ON,OFF,ON};
int space[] = {OFF,OFF,OFF,OFF,OFF,OFF,OFF};
int K[] = {ON,OFF,ON,OFF,ON,ON,ON};
int W[] = {OFF,ON,OFF,ON,OFF,ON,OFF};
int timeLed[3] = {0,255,255};
int dateLed[3] = {255,0,255};
int battLed[3] = {255,255,0};
int stopwatchLed[3] = {0,255,0};
int alarmLed[3] = {0,0,255};
int display0Buffer[7];
int display1Buffer[7];
int ledValues[3];
bool virtualGrid = 0;
unsigned long currentTime;
unsigned long timingHelper;
unsigned long stopwatchStartTime;
int incrementTracker = 0;
bool reversal = false;
int menuScreen;
int item;
bool button1State;
bool button2State;
bool button1Increment;
bool button2Increment;
bool stopwatchRunning;
int hoursRunning;
int minutesRunning;
int secondsRunning;
int incrementPosition;
void setup()
{
Serial.begin(9600);
Serial.println("Begin");
pinMode(0, OUTPUT);
pinMode(1, OUTPUT);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
//pinMode(7, INPUT_PULLDOWN);
//pinMode(8, INPUT_PULLDOWN);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);
pinMode(A0, OUTPUT);
pinMode(A1, OUTPUT);
pinMode(A2, OUTPUT);
pinMode(A3, INPUT);
pinMode(A4, INPUT);
pinMode(A5, INPUT);
attachInterrupt(digitalPinToInterrupt(A4),button2Pressed,RISING);
attachInterrupt(digitalPinToInterrupt(A3),button1Pressed,RISING);
menuScreen = 0;
item = 0;
timingHelper = millis();
rtc.begin(); // initialize RTC 24H format
rtc.setClockSource(STM32RTC::LSE_CLOCK);
rtc.setHours(11);
rtc.setMinutes(23);
rtc.setSeconds(34);
// Set the date
rtc.setWeekDay(0);
rtc.setDay(7);
rtc.setMonth(7);
rtc.setYear(24);
}
void loop()
{
displayBufferManager();
display();
sleepChecker();
buttonHandler();
buttonReset();
}
void buttonReset()
{
if(button1State)
{
if(!digitalRead(A3))
{
button1State = false;
button1Increment = false;
}
}
if(button2State)
{
if(!digitalRead(A4))
{
button2State = false;
button2Increment = false;
}
}
}
void button1Pressed()
{
if(!button1State)
{
Serial.println("B1");
button1State = true;
button1Increment = false;
}
}
void button2Pressed()
{
if(!button2State)
{
Serial.println("B2");
button2State = true;
button2Increment = false;
}
}
void buttonHandler()
{
if(button1State == true && button1Increment == false)
{
button1Increment = true;
switch(menuScreen)
{
case 0: //Main row of applications
switch(item)
{
case 0: //time
break;
case 1: //date
break;
case 2: //batt
break;
case 3: //stopwatch
menuScreen = 1;
item = 0;
Serial.println("Stopwatch app");
clearDisplayBuffer();
incrementTracker = 0;
reversal = false;
timingHelper = millis();
break;
case 4: //alarm
break;
}
break;
}
}
if(button2State == true && button2Increment == false)
{
button2Increment = true;
switch(menuScreen)
{
case 0: //Main row of applications
switch(item)
{
case 0: //time
item = 1;
timingHelper = millis();
Serial.println("date");
clearDisplayBuffer();
incrementTracker = 0;
reversal = false;
break;
case 1: //date
item = 2;
timingHelper = millis();
Serial.println("batt");
clearDisplayBuffer();
incrementTracker = 0;
reversal = false;
break;
case 2: //batt
item = 3;
timingHelper = millis();
Serial.println("stopwatch");
incrementTracker = 0;
reversal = false;
break;
case 3: //stopwatch
item = 4;
timingHelper = millis();
Serial.println("alarm");
incrementTracker = 0;
reversal = false;
break;
case 4: //alarm
item = 0;
timingHelper = millis();
Serial.println("time");
incrementTracker = 0;
reversal = false;
break;
}
break;
}
}
}
void sleepChecker()
{
if(millis() - timingHelper > 1000 && menuScreen != 1)
{
Serial.println("Sleep time");//put vvvariables here to start boot from start when awoken
}else if(millis() - timingHelper > 5000 && menuScreen == 1 && stopwatchRunning != true)
{
Serial.println("stopwatch inactive, Sleep time");
}
}
void ledWrite(int red,int green,int blue)
{
// analogWrite(redPin,255-red);
// analogWrite(greenPin,255-green);
// analogWrite(bluePin,255-blue);
}
void displayBufferManager() //manages the content in the screen buffers based on the item and menu variables
{
switch(menuScreen)
{
case 0: //Main row of applications
switch(item)
{
case 0: //time
if(timingHelper + 10 < millis())
{
if(reversal)
{
if(incrementTracker>0)
{
incrementTracker--;
timingHelper = millis();
}
}else
{
incrementTracker++;
timingHelper = millis();
}
if(incrementTracker <= 100)
{
ledWrite(map(incrementTracker,0,37,0,timeLed[0]),map(incrementTracker,0,37,0,timeLed[1]),map(incrementTracker,0,37,0,timeLed[2]));
}
}
switch(incrementTracker)
{
case 0:
clearDisplayBuffer();
break;
case 5:
clearDisplayBuffer();
display0Buffer[0] = ON;
display1Buffer[0] = ON;
break;
case 10:
display0Buffer[0] = OFF;
display1Buffer[0] = OFF;
display0Buffer[2] = OFF;
display1Buffer[2] = OFF;
display0Buffer[1] = ON;
display1Buffer[1] = ON;
break;
case 15:
display0Buffer[1] = OFF;
display1Buffer[1] = OFF;
display0Buffer[3] = OFF;
display1Buffer[3] = OFF;
display0Buffer[2] = ON;
display1Buffer[2] = ON;
break;
case 20:
display0Buffer[2] = OFF;
display1Buffer[2] = OFF;
display0Buffer[4] = OFF;
display1Buffer[4] = OFF;
display0Buffer[3] = ON;
display1Buffer[3] = ON;
break;
case 25:
display0Buffer[3] = OFF;
display1Buffer[3] = OFF;
display0Buffer[5] = OFF;
display1Buffer[5] = OFF;
display0Buffer[4] = ON;
display1Buffer[4] = ON;
break;
case 30:
display0Buffer[4] = OFF;
display1Buffer[4] = OFF;
display0Buffer[0] = OFF;
display1Buffer[0] = OFF;
display0Buffer[5] = ON;
display1Buffer[5] = ON;
break;
case 35:
clearDisplayBuffer();
display0Buffer[0] = ON;
display1Buffer[0] = ON;
break;
case 40:
writeToBuffer(0, rtc.getHours()/10);
writeToBuffer(1, rtc.getHours()%10);
break;
case 90:
clearDisplayBuffer();
break;
case 140:
writeToBuffer(0, rtc.getMinutes()/10);
writeToBuffer(1, rtc.getMinutes()%10);
break;
case 190:
clearDisplayBuffer();
reversal = true;
incrementTracker = 36;
break;
}
break;
case 1: //Date
if(timingHelper + 10 < millis())
{
if(reversal)
{
if(incrementTracker>0)
{
incrementTracker--;
timingHelper = millis();
}
}else
{
incrementTracker++;
timingHelper = millis();
}
if(incrementTracker <= 100)
{
ledWrite(map(incrementTracker,0,37,0,dateLed[0]),map(incrementTracker,0,37,0,dateLed[1]),map(incrementTracker,0,37,0,dateLed[2]));
}
}
switch(incrementTracker)
{
case 0:
clearDisplayBuffer();
break;
case 5:
clearDisplayBuffer();
display0Buffer[0] = ON;
display1Buffer[0] = ON;
break;
case 10:
display0Buffer[0] = OFF;
display1Buffer[0] = OFF;
display0Buffer[2] = OFF;
display1Buffer[2] = OFF;
display0Buffer[1] = ON;
display1Buffer[1] = ON;
break;
case 15:
display0Buffer[1] = OFF;
display1Buffer[1] = OFF;
display0Buffer[3] = OFF;
display1Buffer[3] = OFF;
display0Buffer[2] = ON;
display1Buffer[2] = ON;
break;
case 20:
display0Buffer[2] = OFF;
display1Buffer[2] = OFF;
display0Buffer[4] = OFF;
display1Buffer[4] = OFF;
display0Buffer[3] = ON;
display1Buffer[3] = ON;
break;
case 25:
display0Buffer[3] = OFF;
display1Buffer[3] = OFF;
display0Buffer[5] = OFF;
display1Buffer[5] = OFF;
display0Buffer[4] = ON;
display1Buffer[4] = ON;
break;
case 30:
display0Buffer[4] = OFF;
display1Buffer[4] = OFF;
display0Buffer[0] = OFF;
display1Buffer[0] = OFF;
display0Buffer[5] = ON;
display1Buffer[5] = ON;
break;
case 35:
clearDisplayBuffer();
display0Buffer[0] = ON;
display1Buffer[0] = ON;
break;
case 40:
memcpy(display0Buffer,five,28);
memcpy(display1Buffer,six,28);
break;
case 90:
clearDisplayBuffer();
break;
case 140:
memcpy(display0Buffer,seven,28);
memcpy(display1Buffer,eight,28);
break;
case 190:
clearDisplayBuffer();
reversal = true;
incrementTracker = 36;
break;
}
break;
case 2: //battery
if(timingHelper + 10 < millis())
{
if(reversal)
{
if(incrementTracker>0)
{
incrementTracker--;
timingHelper = millis();
}
}else
{
incrementTracker++;
timingHelper = millis();
}
if(incrementTracker <= 100)
{
ledWrite(map(incrementTracker,0,37,0,battLed[0]),map(incrementTracker,0,37,0,battLed[1]),map(incrementTracker,0,37,0,battLed[2]));
}
}
switch(incrementTracker)
{
case 0:
clearDisplayBuffer();
break;
case 5:
clearDisplayBuffer();
display0Buffer[0] = ON;
display1Buffer[0] = ON;
break;
case 10:
display0Buffer[0] = OFF;
display1Buffer[0] = OFF;
display0Buffer[2] = OFF;
display1Buffer[2] = OFF;
display0Buffer[1] = ON;
display1Buffer[1] = ON;
break;
case 15:
display0Buffer[1] = OFF;
display1Buffer[1] = OFF;
display0Buffer[3] = OFF;
display1Buffer[3] = OFF;
display0Buffer[2] = ON;
display1Buffer[2] = ON;
break;
case 20:
display0Buffer[2] = OFF;
display1Buffer[2] = OFF;
display0Buffer[4] = OFF;
display1Buffer[4] = OFF;
display0Buffer[3] = ON;
display1Buffer[3] = ON;
break;
case 25:
display0Buffer[3] = OFF;
display1Buffer[3] = OFF;
display0Buffer[5] = OFF;
display1Buffer[5] = OFF;
display0Buffer[4] = ON;
display1Buffer[4] = ON;
break;
case 30:
display0Buffer[4] = OFF;
display1Buffer[4] = OFF;
display0Buffer[0] = OFF;
display1Buffer[0] = OFF;
display0Buffer[5] = ON;
display1Buffer[5] = ON;
break;
case 35:
clearDisplayBuffer();
display0Buffer[0] = ON;
display1Buffer[0] = ON;
break;
case 40:
memcpy(display0Buffer,eight,28);
memcpy(display1Buffer,nine,28);
break;
case 90:
clearDisplayBuffer();
reversal = true;
incrementTracker = 36;
break;
}
break;
case 3: //stopwatch
if(timingHelper + 10 < millis())
{
if(reversal)
{
if(incrementTracker>0)
{
incrementTracker--;
timingHelper = millis();
}
}else
{
incrementTracker++;
timingHelper = millis();
}
if(incrementTracker <= 100)
{
ledWrite(map(incrementTracker,0,37,0,stopwatchLed[0]),map(incrementTracker,0,37,0,stopwatchLed[1]),map(incrementTracker,0,37,0,stopwatchLed[2]));
}
switch(incrementTracker)
{
case 0:
clearDisplayBuffer();
break;
case 5:
clearDisplayBuffer();
display0Buffer[0] = ON;
display1Buffer[0] = ON;
break;
case 10:
display0Buffer[0] = OFF;
display1Buffer[0] = OFF;
display0Buffer[2] = OFF;
display1Buffer[2] = OFF;
display0Buffer[1] = ON;
display1Buffer[1] = ON;
break;
case 15:
display0Buffer[1] = OFF;
display1Buffer[1] = OFF;
display0Buffer[3] = OFF;
display1Buffer[3] = OFF;
display0Buffer[2] = ON;
display1Buffer[2] = ON;
break;
case 20:
display0Buffer[2] = OFF;
display1Buffer[2] = OFF;
display0Buffer[4] = OFF;
display1Buffer[4] = OFF;
display0Buffer[3] = ON;
display1Buffer[3] = ON;
break;
case 25:
display0Buffer[3] = OFF;
display1Buffer[3] = OFF;
display0Buffer[5] = OFF;
display1Buffer[5] = OFF;
display0Buffer[4] = ON;
display1Buffer[4] = ON;
break;
case 30:
display0Buffer[4] = OFF;
display1Buffer[4] = OFF;
display0Buffer[0] = OFF;
display1Buffer[0] = OFF;
display0Buffer[5] = ON;
display1Buffer[5] = ON;
break;
case 35:
clearDisplayBuffer();
display0Buffer[0] = ON;
display1Buffer[0] = ON;
break;
case 40:
memcpy(display0Buffer,S,28);
memcpy(display1Buffer,W,28);
break;
case 140:
clearDisplayBuffer();
reversal = true;
incrementTracker = 36;
break;
}
}
break;
case 4: //alarm
if(timingHelper + 10 < millis())
{
if(reversal)
{
if(incrementTracker>0)
{
incrementTracker--;
timingHelper = millis();
}
}else
{
incrementTracker++;
timingHelper = millis();
}
if(incrementTracker <= 100)
{
ledWrite(map(incrementTracker,0,37,0,alarmLed[0]),map(incrementTracker,0,37,0,alarmLed[1]),map(incrementTracker,0,37,0,alarmLed[2]));
}
switch(incrementTracker)
{
case 0:
clearDisplayBuffer();
break;
case 5:
clearDisplayBuffer();
display0Buffer[0] = ON;
display1Buffer[0] = ON;
break;
case 10:
display0Buffer[0] = OFF;
display1Buffer[0] = OFF;
display0Buffer[2] = OFF;
display1Buffer[2] = OFF;
display0Buffer[1] = ON;
display1Buffer[1] = ON;
break;
case 15:
display0Buffer[1] = OFF;
display1Buffer[1] = OFF;
display0Buffer[3] = OFF;
display1Buffer[3] = OFF;
display0Buffer[2] = ON;
display1Buffer[2] = ON;
break;
case 20:
display0Buffer[2] = OFF;
display1Buffer[2] = OFF;
display0Buffer[4] = OFF;
display1Buffer[4] = OFF;
display0Buffer[3] = ON;
display1Buffer[3] = ON;
break;
case 25:
display0Buffer[3] = OFF;
display1Buffer[3] = OFF;
display0Buffer[5] = OFF;
display1Buffer[5] = OFF;
display0Buffer[4] = ON;
display1Buffer[4] = ON;
break;
case 30:
display0Buffer[4] = OFF;
display1Buffer[4] = OFF;
display0Buffer[0] = OFF;
display1Buffer[0] = OFF;
display0Buffer[5] = ON;
display1Buffer[5] = ON;
break;
case 35:
clearDisplayBuffer();
display0Buffer[0] = ON;
display1Buffer[0] = ON;
break;
case 40:
memcpy(display0Buffer,A,28);
memcpy(display1Buffer,L,28);
break;
case 140:
clearDisplayBuffer();
reversal = true;
incrementTracker = 36;
break;
}
}
break;
}
break;
case 1: //stopwatch
{
if(stopwatchRunning)
{
}else
{
if(timingHelper + 10 < millis())
{
if(reversal)
{
if(incrementTracker>0)
{
incrementTracker--;
timingHelper = millis();
}
}else
{
incrementTracker++;
timingHelper = millis();
}
if(incrementTracker <= 100)
{
ledWrite(map(incrementTracker,0,37,0,stopwatchLed[0]),map(incrementTracker,0,37,0,stopwatchLed[1]),map(incrementTracker,0,37,0,stopwatchLed[2]));
}
}
if(hoursRunning >= 1 || minutesRunning >= 1 || secondsRunning >= 1)
{
switch (incrementTracker - incrementPosition)
{
case 0:
if(hoursRunning == 0)
{
incrementTracker = incrementTracker + 100;
Serial.println("skipping hours");
}else
{
writeToBuffer(0, hoursRunning/10);
writeToBuffer(1, hoursRunning%10);
ledWrite(255,0,0);
Serial.println("showing hours");
}
break;
case 100:
if(minutesRunning == 0)
{
incrementTracker = incrementTracker + 100;
Serial.println("skipping minutes");
}else
{
writeToBuffer(0, minutesRunning/10);
writeToBuffer(1, minutesRunning%10);
ledWrite(255,255,0);
Serial.println("showing minutes");
}
break;
case 200:
if(minutesRunning == 0)
{
incrementTracker = incrementTracker + 75;
Serial.println("shortening second display");
}
writeToBuffer(0, secondsRunning/10);
writeToBuffer(1, secondsRunning%10);
ledWrite(0,255,0);
Serial.println("showing seconds");
break;
case 300:
incrementPosition = incrementTracker;
break;
}
}else
{
//stopwatchStartTime = millis();
memcpy(display0Buffer,zero,28);
memcpy(display1Buffer,zero,28);
}
}
unsigned long stopwatchTime = millis() - stopwatchStartTime;
hoursRunning = (stopwatchTime / (1000*60*60)) % 24;
minutesRunning = (stopwatchTime / (1000*60)) % 60;
secondsRunning = (stopwatchTime / 1000) % 60 ;
/*Serial.print("milliseconds:");
Serial.println(stopwatchTime);
Serial.print("hours:");
Serial.println(hoursRunning);
Serial.print("minutes:");
Serial.println(minutesRunning);
Serial.print("seconds:");
Serial.println(secondsRunning);*/
}
break;
case 2: //alarm
break;
case 3: //alarm ringer selection
break;
case 4: //settings
break;
}
}
void clearDisplayBuffer()
{
memcpy(display0Buffer,space,sizeof(space));
memcpy(display1Buffer,space,sizeof(space));
}
void display() //writes the content of the screen buffers to the displays
{
if(currentTime+100<millis())
{
currentTime = millis();
virtualGrid = !virtualGrid;
int i = 0;
if(virtualGrid == 0)
{
digitalWrite(0,0);
digitalWrite(1,0);
digitalWrite(2,0);
digitalWrite(3,0);
digitalWrite(4,0);
digitalWrite(5,0);
digitalWrite(6,0);
while(i < 7)
{
writeSegment(i,display0Buffer[i]);
i++;
}
}else{
digitalWrite(7,0);
digitalWrite(8,0);
digitalWrite(9,0);
digitalWrite(10,0);
digitalWrite(11,0);
digitalWrite(12,0);
digitalWrite(13,0);
while(i < 7)
{
writeSegment(i,display1Buffer[i]);
i++;
}
}
}
}
void writeSegment(int seg,int state)
{
if(virtualGrid == 0)
{
switch(seg)
{
case 0:
digitalWrite(9,state);
break;
case 1:
digitalWrite(A0,state);
break;
case 2:
digitalWrite(A1,state);
break;
case 3:
digitalWrite(11,state);
break;
case 4:
digitalWrite(12,state);
break;
case 5:
digitalWrite(13,state);
break;
case 6:
digitalWrite(10,state);
break;
}
}else if(virtualGrid == 1)
{
switch(seg)
{
case 0:
digitalWrite(4,state);
break;
case 1:
digitalWrite(1,state);
break;
case 2:
digitalWrite(0,state);
break;
case 3:
digitalWrite(2,state);
break;
case 4:
digitalWrite(5,state);
break;
case 5:
digitalWrite(6,state);
break;
case 6:
digitalWrite(3,state);
break;
}
}
}
void writeToBuffer(int tube, int num)
{
switch(num)
{
case 0:
if(tube == 0)
{
memcpy(display0Buffer,zero,28);
}else
{
memcpy(display1Buffer,zero,28);
}
break;
case 1:
if(tube == 0)
{
memcpy(display0Buffer,one,28);
}else
{
memcpy(display1Buffer,one,28);
}
break;
case 2:
if(tube == 0)
{
memcpy(display0Buffer,two,28);
}else
{
memcpy(display1Buffer,two,28);
}
break;
case 3:
if(tube == 0)
{
memcpy(display0Buffer,three,28);
}else
{
memcpy(display1Buffer,three,28);
}
break;
case 4:
if(tube == 0)
{
memcpy(display0Buffer,four,28);
}else
{
memcpy(display1Buffer,four,28);
}
break;
case 5:
if(tube == 0)
{
memcpy(display0Buffer,five,28);
}else
{
memcpy(display1Buffer,five,28);
}
break;
case 6:
if(tube == 0)
{
memcpy(display0Buffer,six,28);
}else
{
memcpy(display1Buffer,six,28);
}
break;
case 7:
if(tube == 0)
{
memcpy(display0Buffer,seven,28);
}else
{
memcpy(display1Buffer,seven,28);
}
break;
case 8:
if(tube == 0)
{
memcpy(display0Buffer,eight,28);
}else
{
memcpy(display1Buffer,eight,28);
}
break;
case 9:
if(tube == 0)
{
memcpy(display0Buffer,nine,28);
}else
{
memcpy(display1Buffer,nine,28);
}
break;
}
}