First start by defining arrays for your pins
// digital pins for pattern
const uint8_t patternPins[] = {2, 3, 4, 5, 6, 7, 8, 9};
// analog pins for reading
const uint8_t measPins[] = {A0, A1, A2, A3, A4, A5, A6, A7};
To know how many elements there are in any type of array (char, int, float, struct, ...), you can use a macro; add below to the top of your code
// calculate the number of elements in any type of array (char, int, float, struct, ...)
#define NUMELEMENTS(x) (sizeof(x) / sizeof(x[0]))
You have a certain pattern that you apply on the digital pins and you have an expected resulting pattern on the analog pins. Combine a stimulus pattern with the resulting pattern in e.g a struct or class. I'm still far more a C programmer than a C++ programmer and use a struct.
struct PATTERN
{
const uint8_t pattern[NUMELEMENTS(patternPins)]; // stimulus pattern on digital pins
const uint8_t expected[NUMELEMENTS(measPins)]; // expected pattern on analogRead
int16_t readings[NUMELEMENTS(measPins)]; // readings of analogRead
};
I've added a field for the analog readings. Using NUMELEMENTS makes that anything is scalable; if you only need 4 digital pins, change patternPins and pattern will follow. If you have different thresholds for a certain pattern, you can add a threshold field or an array of thresholds for every analog pin.
Now you can create an array of patterns.
PATTERN patterns[] = {
{{LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW}, // stimulus pattern
{LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW}, // expected pattern; LOW indicates below threshold
{0, 0, 0, 0, 0, 0, 0, 0}}, // initial measurement
{{HIGH, LOW, LOW, LOW, LOW, LOW, LOW, LOW},
{LOW, HIGH, LOW, LOW, LOW, LOW, LOW, LOW},
{0, 0, 0, 0, 0, 0, 0, 0}},
};
The above contains 2 patterns each having a stimulus pattern, an expected resulting pattern and initial values for the ananlog readings.
In setup(), you can now iterate through the patternPins and set them to output. You don't have to do anything for the ananlog pins.
void setup()
{
Serial.begin(115200);
Serial.println(F("Setting up pattern pins"));
for (uint8_t cnt = 0; cnt < NUMELEMENTS(patternPins); cnt++)
{
pinMode(patternPins[cnt], OUTPUT);
}
Serial.println(F("Tester ready"));
}
Note that this will immediately apply a pattern LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW to the output pins.
In loop() you can iterate through the patterns using e.g. a for-loop.
void loop()
{
for (uint8_t patternCnt = 0; patternCnt < NUMELEMENTS(patterns); patternCnt++)
{
Serial.println(F("Setting pattern"));
for (uint8_t pinCnt = 0; pinCnt < NUMELEMENTS(patternPins); pinCnt++)
{
...
...
}
Serial.println(F("Reading"));
for (uint8_t pinCnt = 0; pinCnt < NUMELEMENTS(measPins); pinCnt++)
{
...
...
}
Serial.println(F("Comparing"));
for (uint8_t pinCnt = 0; pinCnt < NUMELEMENTS(patterns[patternCnt].readings); pinCnt++)
{
...
...
}
}
}
For now, I'll leave the rest of the puzzle to you. This is just to give you the idea.
It will probably be better to write a function that handles one pattern and call that from loop() with e.g. an index to indicate the pattern to handle.