Is there a way to clean up this code...or do some smart coding?
In this example I use 6 relays, in the final code it will be 10.
Also I now use 5 switches and that will be 8, each with an own led. Now I only stated 1 led.
The code reads a button, and a few relays will get a signal. Also the buttonled will go on. I will add more cases later. But I was wondering, is it possible/easier/just another way of writing the high/low to the relays and leds.
Can I somehow combine the LOWs or HIGHs within a case?
int relay1 = A5;
int relay2 = A4;
int relay3 = A3;
int relay4 = A2;
int relay5 = A1;
int relay6 = A0;
int led1 = 3;
int sw1 = 5;
int sw2 = 6;
int sw3 = 7;
int sw4 = 8;
int sw5 = 9;
int sw1Status, sw2Status, sw3Status, sw4Status, sw5Status;
int order = 1; // default is to set all relays off.
void setup() {
Serial.begin(9600);
pinMode(led1, OUTPUT);
pinMode(relay1, OUTPUT);
pinMode(relay2, OUTPUT);
pinMode(relay3, OUTPUT);
pinMode(relay4, OUTPUT);
pinMode(relay5, OUTPUT);
pinMode(relay6, OUTPUT);
// input pull-up, so default state of buttons is HIGH.
pinMode(sw1, INPUT_PULLUP);
pinMode(sw2, INPUT_PULLUP);
pinMode(sw3, INPUT_PULLUP);
pinMode(sw4, INPUT_PULLUP);
pinMode(sw5, INPUT_PULLUP);
}
void loop() {
// read the buttons status
sw1Status = digitalRead(sw1);
sw2Status = digitalRead(sw2);
sw3Status = digitalRead(sw3);
sw4Status = digitalRead(sw4);
sw5Status = digitalRead(sw5);
if (sw1Status == LOW) { // if button 1 pressed
order = 2; // go to case 2
}
if (sw2Status == LOW) {
order = 3;
}
if (sw3Status == LOW) {
order = 4;
}
if (sw4Status == LOW) {
order = 5;
}
if (sw5Status == LOW) { // button 4 toggle
if (order != 7) { // if order is not equal 5 turn on relay 1 & 4
order = 6;
}
else { // else go to case 1, which will turns off all relays
order = 1;
}
}
switch (order) {
case 1: // if order equals 1
digitalWrite(relay1, LOW);
digitalWrite(relay2, LOW);
digitalWrite(relay3, LOW);
digitalWrite(relay4, LOW);
digitalWrite(relay5, LOW);
digitalWrite(relay6, LOW);
digitalWrite(led1, LOW);
break;
case 2: // if order equals 2
digitalWrite(relay1, HIGH);
digitalWrite(relay2, LOW);
digitalWrite(relay3, HIGH);
digitalWrite(relay4, LOW);
digitalWrite(relay5, HIGH);
digitalWrite(relay6, LOW);
digitalWrite(led1, HIGH);
break;
case 3: // if order equals 3
digitalWrite(relay1, LOW);
digitalWrite(relay2, HIGH);
digitalWrite(relay3, LOW);
digitalWrite(relay4, HIGH);
digitalWrite(relay5, LOW);
digitalWrite(relay6, HIGH);
digitalWrite(led1, LOW);
break;
case 4: // if order equals 4
digitalWrite(relay1, HIGH);
digitalWrite(relay2, HIGH);
digitalWrite(relay3, HIGH);
digitalWrite(relay4, LOW);
digitalWrite(relay5, LOW);
digitalWrite(relay6, LOW);
digitalWrite(led1, LOW);
break;
case 5: // if order equals 5
digitalWrite(relay1, LOW);
digitalWrite(relay2, LOW);
digitalWrite(relay3, LOW);
digitalWrite(relay4, HIGH);
digitalWrite(relay5, HIGH);
digitalWrite(relay6, HIGH);
digitalWrite(led1, LOW);
break;
case 6: // if order equals 5
digitalWrite(relay1, LOW);
digitalWrite(relay2, LOW);
digitalWrite(relay3, HIGH);
digitalWrite(relay4, HIGH);
digitalWrite(relay5, LOW);
digitalWrite(relay6, LOW);
digitalWrite(led1, LOW);
break;
default: // if none of above cases is valid go to case 1
order = 1;
break;
}
}
2 Answers 2
If all are handled the same and they don't have individual names, arrays and for loops are what you are looking for.
const byte relayPins[] = { A5, A4, A3, A2, A1, A0};
const byte ledPin = 3;
const byte swPins[] = {5, 6, 7, 8, 9};
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
for (const byte relayPin: relayPins) pinMode(relayPin, OUTPUT);
for (const byte swPin: swPins) pinMode(swPin, INPUT_PULLUP);
}
Even arduino C++ nowadays understands the foreach syntax.
BTW: for your final pin count you'll need other/additional hardware. Either a Mega or shift registers or port expanders.
-
I also figured out that I run out of pins on my UNO boards, that is also why my code is not yet complete. Considering Arrays, it's completely new for my, and looks like a bit of magic to me. Could you give me a example on how to use this. How would it look if; for example Button1 is pushed...and relay 1, 3 & 5 is HIGH and 2,4 & 6 are LOWNiles– Niles2020年04月03日 06:34:01 +00:00Commented Apr 3, 2020 at 6:34
-
The simplest book on C or C++ should cover arrays in general. If your names are like
relay1
you could as well userelayPins[0]
instead, to deal with them individually. BTW: your question was about "smart coding" :)DataFiddler– DataFiddler2020年04月03日 12:31:15 +00:00Commented Apr 3, 2020 at 12:31
Arduino Uno has 3 ports. You can read and write the ports as 1 byte.
With all the switches on one port, you can read them all at once. For example, using D7 to D3 to read the switches:
switches = (PIND & 0b11111000) >>3; // read D7 to D0, mask off D2-1-0, move data to lower 5 bits
Then you could have case (switches): for the 0 to 31 cases that are possible.
With all the relays on one port, you can change them all at once. For example, using D14 to D19 for the relays:
PORTC = 0b00110011; // Dxx, Dxx, D19,18,17,16,15,14 or A5,A4,A3,A2,A1,A0
to turn on relays 1,2,5,6, and 3,4 off.
The LED would still be on its own.
case
relay values