Let’s do an example of code development.
Let’s say that we are reading analog values for ranges and want to make decisions based on ranges to set ranges of values. We start with the following snippet. The `if` statements quickly become wordy and program flow maybe starts to become unclear. So lets look at some ways to unravel this with a subroutine.
reading = analogRead(1); int state = 0; if (reading > 0 && reading < 500){ state = 1; } if( reading > 499 && reading < 700) { state = 2; } if ( reading > 699 && reading < 1025) { state = 3; }
You could just write a small procedure to simplify this comparison test series…
bool inRange(int x, int y, int z){ if (x => y && x <= z) { return true; } else { return false; } }
and then call it with much easier to read process requests… like the following code.
//file inrange.ino // State 1: Connect analog pin to gnd // State 2: Connect analog pin to 3.3V // State 3: connect analog pin to 5V int reading; int state = 0; void setup() { // put your setup code here, to run once: Serial.begin(9600); } void loop() { // put your main code here, to run repeatedly: reading = analogRead(1); if(inRange(reading,0,500)) state = 1; if(inRange(reading,500,700)) state = 2; if(inRange(reading,700,1024)) state = 3; Serial.print("Reading "); Serial.println(reading); Serial.print("state: "); Serial.println(state); delay(1000); } //------------------------------------------------- // Notice the use of non-informative variable names // we should fix this. int inRange(int x, int y, int z){ bool val; if (x >= y && x <= z) { val = true; } else { val = false; } return(val); }
See? You really get some better logic flow this way.
New lets go a step further… using space saving `const` or constants.
// File: inrange1.ino // State 1: Connect analog pin to gnd // State 2: Connect analog pin to 3.3V // State 3: connect analog pin to 5V //=====[ CONSTANTS ]============================================================ //Still a bit wordy here... const int RED = 0; const int GREEN = 1; const int BLUE = 2; //=====[ PINS ]================================================================= int anPin = 1; //=====[ VARIABLES ]============================================================ int reading; int state = 0; void setup() { Serial.begin(9600); // Wait for USB on Leonardo and similar devices while (!Serial) { } } void loop() { reading = analogRead(anPin); // debugging code... Serial.print("Reading "); Serial.println(reading); if (inRange(reading, 0, 499)) state = RED; if (inRange(reading, 500, 699)) state = GREEN; if (inRange(reading, 700, 1024)) state = BLUE; ColorState(); delay(1000); } //============================================================================== int inRange(int passVal, int minVal, int maxVal) { if (passVal >= minVal && passVal <= maxVal) { return true; } else { return false; } } //============================================================================== void ColorState() { Serial.print("State: "); switch (state) { case RED: Serial.println("Red"); break; case GREEN: Serial.println("Green"); break; case BLUE: Serial.println("Blue"); break; default: break; } }
Now we start to see how to break out sections of code into useful re-usable subroutines. So lets take this one step further and refine it into a final version using the `enum` command. Notice how the code becomes even a tiny bit simpler.
// File: inrange3.ino // State 1: Connect analog pin to gnd // State 2: Connect analog pin to 3.3V // State 3: connect analog pin to 5V enum States { RED, GREEN, BLUE }; States state = RED; // use the enumeration and initialize to RED //=====[ PINS ]================================================================= int anPin = 1; //=====[ VARIABLES ]============================================================ int reading; void setup() { Serial.begin(9600); // Wait for USB on Leonardo and similar devices while (!Serial) { } } void loop() { reading = analogRead(anPin); if (inRange(reading, 0, 499)) state = RED; if (inRange(reading, 500, 699)) state = GREEN; if (inRange(reading, 700, 1024)) state = BLUE; ColorState(state); delay(1000); } //============================================================================== int inRange(int passVal, int minVal, int maxVal) { if (passVal >= minVal && passVal <= maxVal) { return true; } else { return false; } } //============================================================================== void ColorState(int range) { Serial.print("Condition: "); switch (range) { case RED: Serial.println(" Red"); break; case GREEN: Serial.println(" Green"); break; case BLUE: Serial.println(" Blue"); break; default: break; } }
So while this is not the best code, it definitely accomplishes the simplification goal in the main process loop.
Food for thought.