One button control of multi state switch - CODE

I am developing a sketch that will allow me to control my swamp cooler based on temperature, time of day and manual override.

Here is some code I have written (and tested) that controls the cooler with one button.

Some criteria I have included:

1 button to switch between 5 states (hi/lo speed with & without water pump plus off)

A delay so that the cooler does not switch with every button push, but instead, wait until I have finished pushing buttons to set the new cooler state.

Feedback on the cooler state with 3 LED’s (Hi, Lo, Water)

The ability to set any cooler state by sending a char from the host computer via the serial line (USB)

There are several situations where this code/logic could come in handy…

Enjoy

#define swampon 4
#define swamphi 5
#define swampwa 6
#define button 7
#define redled 8
#define yelled 9
#define grnled 10
#define rlydly 500

int buttonState = LOW;
int coostat = 0;
// 0 → Off
// 1 → Low Air
// 2 → Hi Air
// 3 → Low Cool
// 4 → Hi Cool

void setup() {
pinMode(swampon, OUTPUT);
pinMode(swamphi, OUTPUT);
pinMode(swampwa, OUTPUT);
pinMode(button, INPUT);
pinMode(redled, OUTPUT);
pinMode(grnled, OUTPUT);
pinMode(yelled, OUTPUT);
Serial.begin(9600);
}

void loop() {

if (chkbuttonpress()) {
coostat = coostat + 1;
if ( coostat == 5 ) coostat = 0;
setcooled(coostat);
for (int i = 0 ; i < 800 ; i++) {
delay(1);
if (chkbuttonpress()) {
coostat = coostat + 1;
if (coostat == 5) coostat = 0;
setcooled(coostat);
i = 0;
}
}
setcooler(coostat);
}

if (Serial.available() > 0) {
char incomingByte = Serial.read();
int myByte = int(incomingByte)-48;
if (myByte >= 0 && myByte <= 4){
setcooled(myByte);
setcooler(myByte);
}
}
}

int chkbuttonpress() {
int gothigh = 0;
for (int cc = 0; cc < 6; cc++){
delay(1);
buttonState = digitalRead(button);
if (buttonState == HIGH){
gothigh = 1;
} else {
if (gothigh == 1){
return HIGH;
} else {
return LOW;
}
}
}
return LOW;
}

void setcooled(int newsetting) {
// All Off
digitalWrite(redled,LOW);
digitalWrite(grnled,LOW);
digitalWrite(yelled,LOW);
switch(newsetting){
case 0:
break;
case 1:
ledon(redled);
break;
case 2:
ledon(yelled);
ledon(redled);
break;
case 3:
ledon(grnled);
ledon(redled);
break;
case 4:
ledon(grnled);
ledon(yelled);
ledon(redled);
break;
}
}

void setcooler(int newsetting) {
// All Off
digitalWrite(swampon,LOW);
digitalWrite(swamphi,LOW);
digitalWrite(swampwa,LOW);
switch(newsetting){
case 0:
break;
case 1:
setpin(swampon);
break;
case 2:
setpin(swamphi);
setpin(swampon);
break;
case 3:
setpin(swampwa);
setpin(swampon);
break;
case 4:
setpin(swampwa);
setpin(swamphi);
setpin(swampon);
break;
}
}

void setpin(int pin) {
digitalWrite(pin,HIGH);
delay(rlydly);
}

void ledon(int num){
digitalWrite(num, HIGH);
}

void ledoff(int num){
digitalWrite(num, LOW);
}

Thanks, nice job.

You could improve your code by using an enum - Arduino Playground - HomePage
The code will not change much except it becomes more readable, look at the snippet below

e.g.

enum COOSTATE { OFF, LOW_AIR, HIGH_AIR. LOW_COOL, HIGH_COOL };

...
COOSTATE state;

void setcooled(COOSTATE newsetting) {
  // All Off
  digitalWrite(redled,LOW);
  digitalWrite(grnled,LOW);
  digitalWrite(yelled,LOW);

  switch(newsetting)
  {
    case OFF: 
        break;
    case LOW_AIR:
        ledon(redled);
        break;
    case HIGH_AIR:
        ledon(yelled);
        ledon(redled);
        break;
    case LOW_COOL:
        ledon(grnled);
        ledon(redled);
        break;
    case HIGH_COOL:
        ledon(grnled);
        ledon(yelled);
        ledon(redled);
        break;
  }
}