Hi guys,
My first post.
I have basic experience with a few programming languages writing pc programs but this is my first arduino project.
I've been been writing this code for a few weeks.
The board I'm using is a SparkFun Pro Micro 5V/16MHz.
I have used UnoArduSim heavily in the writing and testing of the code and it seems to give the same results as the Pro Micro on the breadboard.
My project is basically a fancy controller for an exhaust fan. 2 pull up momentary push buttons (pins 2 & 3) each with an indicator led (pins 4 & 5) and a relay to run the fan (pin 6).
Pressing the on button will turn on the on led and fan relay and will stay on indefinitely until the button is pressed again.
Pressing the timer button will blink the timer led and turn on the fan relay for a preset number of minutes then turn off.
You can freely switch between on and timer modes at any time.
Holding both buttons for at least 10 seconds will enter programming mode where the fan timer duration can be changed, holding buttons again will accept changes.
Programming mode will time out and cancel changes if no buttons are pressed for 60 seconds.
I intend to have it powered and running long term, years if possible.
Currently the code works well but I'm interested in getting your opinions on where it can be improved or optimised.
#include <EEPROM.h>
#define onbutton 2
#define timerbutton 3
#define onled 4
#define timerled 5
#define fanrelay 6
int onbuttonstate = HIGH;
int onbuttonpreviousstate = HIGH;
int timerbuttonstate = HIGH;
int timerbuttonpreviousstate = HIGH;
int onledstate = LOW;
int timerledstate = LOW;
int fanrelaystate = LOW;
unsigned long buttonholdstart = 0;
unsigned long buttonholdtime = 0;
unsigned long timertime = 0;
unsigned long timerprevioustime = 0;
unsigned long starttime = 0;
int timertempminutes = 1;
int timersetminutes = 1;
int flashcount = -5;
int mode = 0; // 0=off 1=on 2=timer 3=programming
void setup()
{
if ((EEPROM.read(0) == 0) || (EEPROM.read(0) > 30)) {
EEPROM.write(0, 1);
}
timertempminutes = EEPROM.read(0);
timersetminutes = EEPROM.read(0);
pinMode(onbutton, INPUT_PULLUP);
pinMode(timerbutton, INPUT_PULLUP);
pinMode(onled, OUTPUT);
pinMode(timerled, OUTPUT);
pinMode(fanrelay, OUTPUT);
}
void loop()
{
onbuttonstate = digitalRead(onbutton);
timerbuttonstate = digitalRead(timerbutton);
//hold both buttons detection
if ((timerbuttonstate != timerbuttonpreviousstate && timerbuttonstate == LOW) || (onbuttonstate != onbuttonpreviousstate && onbuttonstate == LOW)) {
buttonholdstart = millis();
}
if (timerbuttonstate == LOW && onbuttonstate == LOW) {
buttonholdtime = millis() - buttonholdstart;
if (buttonholdtime > 9995) {
while(digitalRead(onbutton) == LOW || digitalRead(timerbutton) == LOW) {
delay(10);
digitalWrite(onled, HIGH);
digitalWrite(timerled, HIGH);
}
if (mode == 3) {
mode = 0;
timersetminutes = timertempminutes;
EEPROM.update(0, timertempminutes);
} else {
mode = 3;
flashcount = -5;
starttime = millis();
timertempminutes = timersetminutes;
}
onbuttonstate = digitalRead(onbutton);
timerbuttonstate = digitalRead(timerbutton);
onbuttonpreviousstate = onbuttonstate;
timerbuttonpreviousstate = timerbuttonstate;
}
}
if (mode == 3) {
//in programming mode
fanrelaystate = LOW;
timertime = millis() - starttime;
if (onbuttonstate != onbuttonpreviousstate && onbuttonstate == HIGH) {
if (timertempminutes < 30) {
++timertempminutes;
}
starttime = millis();
flashcount = -5;
} else if (timerbuttonstate != timerbuttonpreviousstate && timerbuttonstate == HIGH) {
if (timertempminutes > 1) {
--timertempminutes;
}
starttime = millis();
flashcount = -5;
}
if (flashcount < (timertempminutes+1)) {
if (timertime - timerprevioustime >= 350) {
if (timerledstate == LOW && flashcount > 0) {
onledstate = HIGH;
timerledstate = HIGH;
} else {
onledstate = LOW;
timerledstate = LOW;
++flashcount;
}
timerprevioustime = timertime;
}
} else {
flashcount = -5;
}
// auto exit programming mode
if (timertime > 59995) {
mode = 0;
timertempminutes = timersetminutes;
}
} else {
// in normal mode
if (onbuttonstate != onbuttonpreviousstate && onbuttonstate == HIGH) {
if (mode == 1) {
mode = 0;
} else {
mode = 1;
}
} else if (timerbuttonstate != timerbuttonpreviousstate && timerbuttonstate == HIGH) {
if (mode == 2) {
mode = 0;
} else {
mode = 2;
starttime = millis();
timerledstate = HIGH;
}
}
if (mode == 0) {
onledstate = LOW;
timerledstate = LOW;
fanrelaystate = LOW;
timertime = 0;
timerprevioustime = 0;
} else if (mode == 1) {
onledstate = HIGH;
timerledstate = LOW;
fanrelaystate = HIGH;
timertime = 0;
timerledstate = LOW;
timerprevioustime = 0;
} else if (mode == 2) {
timertime = millis() - starttime;
onledstate = LOW;
fanrelaystate = HIGH;
if (timertime - timerprevioustime >= 1000) {
if (timerledstate == LOW) {
timerledstate = HIGH;
} else {
timerledstate = LOW;
}
timerprevioustime = timertime;
}
if ((timertime) >= (timersetminutes * 59995)) {
mode = 0;
}
}
}
onbuttonpreviousstate = onbuttonstate;
timerbuttonpreviousstate = timerbuttonstate;
digitalWrite(onled, onledstate);
digitalWrite(timerled, timerledstate);
digitalWrite(fanrelay, fanrelaystate);
delay(20);
}