I am working on a sequence of light strings that blink in sequence on the quarter hour and in unison on the hour like the bells in a clock tower.
I have it working in a sketch using the Alarm.delay but that is holding up the rest of the program. I have been trying for the past two days to get a state machine working and I just can't figure it out.
The code below has a simulated clock so I can to testing without waiting a full 15 min. I am using a RTC in the project. This code does not work and I am getting confused.
unsigned long TaskWait;
unsigned long HourTime;
unsigned long MinuteTime;
unsigned long FlashTime;
unsigned long PrintTime;
unsigned long LEDTime;
unsigned long currentmillis;
int lightString;
int Blink;
int mincount;
int min;
int hour = 19;
int minute = 0;
enum LightStates {
AllOn, AllOff, OneOn, TwoOn, ThreeOn, FourOn, BlinkSequence, Blink15, Blink30, Blink45, Blink0
};
LightStates lState = AllOff; //we start out in this machine state
void setup() {
Serial.begin(9600);
pinMode(13, OUTPUT);
Serial.println("Start New Program");
FlashTime = millis();
TaskWait = millis();
HourTime = millis();
PrintTime = millis();
// start from first step
lightString = OneOn;
Blink = 5;
min = 15;
lState = AllOff; //we start out in this machine state
}
//Delay time expired function
boolean CheckTime(unsigned long &lastMillis, unsigned long wait)
{
//is the time up for this task?
if (currentmillis - lastMillis >= wait)
{
lastMillis += wait; //get ready for the next iteration
return true;
}
return false;
}
//END of CheckTime()
void loop() {
currentmillis = millis(); //leave at top
//just some code to see if the sketch is blocking
if (CheckTime(LEDTime, 300UL))
{
digitalWrite(13, !digitalRead(13));
Serial.print("Time");
Serial.print(hour);
Serial.print(":");
Serial.println(minute);
}
// END blocking check
clockCount();
blinkClock();
//nightLights();
// Blink15Min();
}
// perform the expected action(s) for the specified step number
void Blink4Times() {
}
void blinkClock() {
//Check machine state and do things that must be done accordingly
switch (lState)
{
//***************************
case AllOff:
{
if (CheckTime(PrintTime, 300UL)) {
PrintTime = millis();
Serial.print(F("ALL OFF"));
Serial.println();
}
}
break; //end case stateStart:
//***************************
case AllOn:
{
if (CheckTime(PrintTime, 300UL))
{
PrintTime = millis();
Serial.print(F("ALL ON"));
Serial.println();
}
}
break; //end case AllOn:
//***************************
case blink15:
if (CheckTime(TaskWait, 30000UL))
{
Serial.println(F("Blink 15 min"));
lstate = BlinkSequence;
Blink = 4;
}
case blink30:
if (CheckTime(TaskWait, 30000UL))
{
Serial.println(F("Blink 30 min"));
lstate = BlinkSequence;
Blink = 3;
}
case blink45:
if (CheckTime(TaskWait, 30000UL))
{
Serial.println(F("Blink 30 min"));
lstate = BlinkSequence;
Blink = 2;
}
case blink0:
if (CheckTime(TaskWait, 30000UL))
{
Serial.println(F("Blink 00 min"));
lstate = BlinkSequence;
Blink = 1;
}
}
case BlinkSequence:
{
if (Blink <=4 ) {
//We will stay in this mState until some things are done
switch (lightString) {
case OneOn:
if (CheckTime(FlashTime, 300UL))
{
Serial.println("Blink String 1");
FlashTime = millis(); //initialize the next wait time
lightString = TwoOn;
}
break;
case TwoOn:
if (CheckTime(FlashTime, 300UL))
{
Serial.println("Blink String 2");
FlashTime = millis(); //initialize the next wait time
lightString = ThreeOn;
}
break;
case ThreeOn:
if (CheckTime(FlashTime, 300UL))
{
Serial.println("Blink String 3");
FlashTime = millis(); //initialize the next wait time
lightString = FourOn;
}
break;
case FourOn:
if (CheckTime(FlashTime, 300UL))
{
Serial.println("Blink String 4");
FlashTime = millis(); //initialize the next wait time
lightString = OneOn;
//Blink++;
nightLights();
}
break;
default:
// this is just to help debugging
Serial.println("Unexpected step number!");
break;
}
break;
} //end case BlinkSequence:
}
}
}
void nightLights() {
if ( hour >= 19 && hour <= 24) {
lState = AllOn;
}
else if ( hour >= 0 && hour < 5) {
lState = AllOn;
}
else {
lState = AllOff;
}
}
void clockCount ()
{
if (hour > 24) {
hour = 0;
}
if (minute > 60) {
minute = 0;
}
if (CheckTime(HourTime, 60000UL))
{
HourTime = millis(); //initialize the next wait time
hour++;
}
if (CheckTime(MinuteTime, 1000UL))
{
MinuteTime = millis(); //initialize the next wait time
minute++;
}
}
void checkif15min ()
{
if ( (minute % 15) == 0) {
lState = BlinkSequence;
else {
nightlights();
}
}
}
Here is the series of if statements that currently work in the project with a RTC with the Alarm.delay. I can't figure out how to translate this code into a series of cases.
void blinkClock() {
if ( (minute() % 15) == 0) {
Blink15Min();
}
}
void Blink15Min() {
if (minute() == 15 && has15run == 0) {
n = 1;
blinkCount();
has15run = 1;
has00run = 0;
}
else if (minute() == 30 && has30run == 0) {
n = 2;
blinkCount();
has30run = 1;
}
else if (minute() == 45 && has45run == 0) {
n = 3;
blinkCount();
has45run = 1;
has30run = 0;
}
else if (minute() == 0 && has00run == 0) {
n = 4;
blinkCount();
blinkHour();
has00run = 1;
has45run = 0;
}
}
void blinkCount() {
for (i = 0; i < n; i++) {
Blink4Times();
}
}
void Blink4Times() {
// Serial.println("Alarm: - turn lights on and off in sequence at 15 minutes");
turnOffLights ();
Alarm.delay(1000); // wait one second
digitalWrite(lightPin1, LOW);
Alarm.delay(1000); // wait one second
digitalWrite(lightPin1, HIGH);
digitalWrite(lightPin2, LOW);
Alarm.delay(1000); // wait one second
digitalWrite(lightPin2, HIGH);
digitalWrite(lightPin3, LOW);
Alarm.delay(1000); // wait one second
digitalWrite(lightPin3, HIGH);
digitalWrite(lightPin4, LOW);
Alarm.delay(1000); // wait one second
digitalWrite(lightPin4, HIGH);
Alarm.delay(2000); // wait two seconds
turnOffLights ();
}
void blinkHour() {
hr = (hour());
if (hr > 12) {
hr == hr - 12;
}
for (i = 0; i < hr; i++) {
blinkAll();
}
}
void blinkAll () {
turnOnLights ();
Alarm.delay(2000); // wait one second between clock display
turnOffLights ();
Alarm.delay(1000); // wait one second between clock display
}
void turnOffLights () {
digitalWrite(lightPin1, HIGH); // Make sure all lights are off
digitalWrite(lightPin2, HIGH); // Make sure all lights are off
digitalWrite(lightPin3, HIGH); // Make sure all lights are off
digitalWrite(lightPin4, HIGH); // Make sure all lights are off
}
void turnOnLights () {
digitalWrite(lightPin1, LOW); // Make sure all lights are on
digitalWrite(lightPin2, LOW); // Make sure all lights are on
digitalWrite(lightPin3, LOW); // Make sure all lights are on
digitalWrite(lightPin4, LOW); // Make sure all lights are on
}
void nightLights() {
if ( hour() > 19 && hour() <= 24) {
turnOnLights ();
}
else if ( hour() >= 0 && hour() < 5) {
turnOnLights ();
}
else {
turnOffLights ();
}
}
Thank you.