// https://wokwi.com/projects/426815612664437761
// for https://forum.arduino.cc/t/programming-limit-switch/1368203
// to run 8 egg-turners intermittently with limit switches
// built from the Arduino "Knight rider" built-in-example
// https://wokwi.com/projects/410050175997074433
// Code from https://docs.arduino.cc/built-in-examples/control-structures/ForLoopIteration/
// Other simulations: https://forum.arduino.cc/t/wokwi-simulations-for-arduino-built-in-examples/1304754
struct EggTurners {
const int MotorPin;
const int LimitPin;
int lastLimitState; // for edge detection on the limit switch
bool isMoving; // state variable
uint32_t restStartMillis; // timing state variable
};
EggTurners eggTurners[] = {
{2, A0},
{3, A1},
{4, A2},
{5, A3},
{6, A4},
{7, A5},
{8, 11},
{9, 12},
};
const int NumTurners = sizeof(eggTurners) / sizeof(eggTurners[0]);
const int LIMITING = LOW; // Level of a limit switch when triggered
// =LOW: Wired as Normally Closed, Multiple switches in series lets one switch break the circuit
// =HIGH: Wired as Normally Open, multiple switches in parallel lets one switch make the circuit
const unsigned long PauseTime = 60000;
/////////////////////////////////////////////////////////////////
// iterating over the the number of turners (NumTurners)
void setupEggTurners() {
for (int ii = 0; ii < NumTurners ; ++ii) {
pinMode(eggTurners[ii].MotorPin, OUTPUT);
pinMode(eggTurners[ii].LimitPin, INPUT_PULLUP);
digitalWrite(eggTurners[ii].MotorPin, HIGH);
eggTurners[ii].isMoving = true;
eggTurners[ii].lastLimitState = digitalRead(eggTurners[ii].LimitPin);
}
}
void handleEggTurners() {
for (int ii = 0; ii < NumTurners ; ++ii) {
if (eggTurners[ii].isMoving) {
int limitState = digitalRead(eggTurners[ii].LimitPin);
if (limitState != eggTurners[ii].lastLimitState && limitState == LIMITING) {
// triggered a limit switch while moving
// stop moving and start resting
Serial.print(ii);
Serial.print("Limit->stop ");
digitalWrite(eggTurners[ii].MotorPin, LOW);
eggTurners[ii].restStartMillis = millis();
eggTurners[ii].isMoving = false;
}
eggTurners[ii].lastLimitState = limitState;
} else {
if ( millis() - eggTurners[ii].restStartMillis > PauseTime ) {
// rested long enough
// stop resting and start moving
Serial.print(ii);
Serial.print("Rested->Move ");
eggTurners[ii].isMoving = true;
digitalWrite(eggTurners[ii].MotorPin, HIGH);
}
}
}
}
//////////////////////////////////////////////////////////////////
// Using for(auto &thing : things) to iterate over an array
// this eases the index accounting
void setupEggTurnersV2() {
for (auto &eggTurner : eggTurners) {
pinMode(eggTurner.MotorPin, OUTPUT);
pinMode(eggTurner.LimitPin, INPUT_PULLUP);
digitalWrite(eggTurner.MotorPin, HIGH);
eggTurner.isMoving = true;
eggTurner.lastLimitState = digitalRead(eggTurner.LimitPin);
}
}
void handleEggTurnersV2() {
int ii = 1;
for (auto &eggTurner : eggTurners) {
if (eggTurner.isMoving) {
int limitState = digitalRead(eggTurner.LimitPin);
if (limitState != eggTurner.lastLimitState && limitState == LIMITING) {
// triggered a limit switch while moving
// stop moving and start resting
Serial.print(ii);
Serial.print("Limit->stop ");
digitalWrite(eggTurner.MotorPin, LOW);
eggTurner.restStartMillis = millis();
eggTurner.isMoving = false;
}
eggTurner.lastLimitState = limitState;
} else {
if ( millis() - eggTurner.restStartMillis > PauseTime ) {
// rested long enough
// stop resting and start moving
Serial.print(ii); // one way of counting
//Serial.print(&eggTurner - eggTurners); // another way of counting
Serial.print("Rested->Move ");
eggTurner.isMoving = true;
digitalWrite(eggTurner.MotorPin, HIGH);
}
++ii; // increment counter for next turner
}
}
}
////////////////////////////////////////////////////////////////////
void setup() {
Serial.begin(115200);
Serial.print(F(R"(Egg turner -- runs 8 motors & limit switches
motors run until they hit a limit switch and trigger the FALLING edge,
then pause for 60 seconds and recycle.
Below shows notes on the transitions:
)"));
setupEggTurnersV2();
}
void loop() {
handleEggTurnersV2();
}