Skip to main content
Arduino

Return to Answer

Note about initialization, removed redundant calls to millis()
Source Link
Edgar Bonet
  • 45.1k
  • 4
  • 42
  • 81

This should workwill start in the MOVING_CW state, but ityou have to actually start the movement in setup(). It has the drawback of having long delay()s in the loop, which is undesirable if you have other tasks to perform. These delays can be removed by "remembering" that you are waiting as two extra states:

void loop() {
 static enum {MOVING_CW, MOVING_CCW, STOPPED_CW, STOPPED_CCW} state;
 static unsigned long time_stopped;
 unsigned long now = millis();
 switch (state) {
 case MOVING_CW:
 if (digitalRead(LM2) == LOW) { // hit switch
 digitalWrite(CW, LOW); // stop
 state = STOPPED_CW;
 time_stopped = millis();now;
 }
 break;
 case MOVING_CCW:
 if (digitalRead(LM1) == LOW) { // hit switch
 digitalWrite(CCW, LOW); // stop
 state = STOPPED_CCW;
 time_stopped = millis();now;
 }
 break;
 case STOPPED_CW:
 if (now - time_stopped >= 5000) {
 digitalWrite(CCW, HIGH); // restart
 state = MOVING_CCW;
 }
 break;
 case STOPPED_CCW:
 if (now - time_stopped >= 5000) {
 digitalWrite(CW, HIGH); // restart
 state = MOVING_CW;
 }
 break;
 }
}

This should work, but it has the drawback of having long delay()s in the loop, which is undesirable if you have other tasks to perform. These delays can be removed by "remembering" that you are waiting as two extra states:

void loop() {
 static enum {MOVING_CW, MOVING_CCW, STOPPED_CW, STOPPED_CCW} state;
 static unsigned long time_stopped;
 unsigned long now = millis();
 switch (state) {
 case MOVING_CW:
 if (digitalRead(LM2) == LOW) { // hit switch
 digitalWrite(CW, LOW); // stop
 state = STOPPED_CW;
 time_stopped = millis();
 }
 break;
 case MOVING_CCW:
 if (digitalRead(LM1) == LOW) { // hit switch
 digitalWrite(CCW, LOW); // stop
 state = STOPPED_CCW;
 time_stopped = millis();
 }
 break;
 case STOPPED_CW:
 if (now - time_stopped >= 5000) {
 digitalWrite(CCW, HIGH); // restart
 state = MOVING_CCW;
 }
 break;
 case STOPPED_CCW:
 if (now - time_stopped >= 5000) {
 digitalWrite(CW, HIGH); // restart
 state = MOVING_CW;
 }
 break;
 }
}

This will start in the MOVING_CW state, but you have to actually start the movement in setup(). It has the drawback of having long delay()s in the loop, which is undesirable if you have other tasks to perform. These delays can be removed by "remembering" that you are waiting as two extra states:

void loop() {
 static enum {MOVING_CW, MOVING_CCW, STOPPED_CW, STOPPED_CCW} state;
 static unsigned long time_stopped;
 unsigned long now = millis();
 switch (state) {
 case MOVING_CW:
 if (digitalRead(LM2) == LOW) { // hit switch
 digitalWrite(CW, LOW); // stop
 state = STOPPED_CW;
 time_stopped = now;
 }
 break;
 case MOVING_CCW:
 if (digitalRead(LM1) == LOW) { // hit switch
 digitalWrite(CCW, LOW); // stop
 state = STOPPED_CCW;
 time_stopped = now;
 }
 break;
 case STOPPED_CW:
 if (now - time_stopped >= 5000) {
 digitalWrite(CCW, HIGH); // restart
 state = MOVING_CCW;
 }
 break;
 case STOPPED_CCW:
 if (now - time_stopped >= 5000) {
 digitalWrite(CW, HIGH); // restart
 state = MOVING_CW;
 }
 break;
 }
}
Source Link
Edgar Bonet
  • 45.1k
  • 4
  • 42
  • 81

Normally you use state machine for this kind of programming: you have a state variable that remembers what you are doing, and depending on the current state you decide what to do next. Below is an example with two states. I have embedded a few assumptions about the wiring of your motor and your switches, which may be wrong, so you have to check the code.

void loop() {
 static enum {MOVING_CW, MOVING_CCW} state;
 switch (state) {
 case MOVING_CW:
 if (digitalRead(LM2) == LOW) { // hit switch
 digitalWrite(CW, LOW); // stop
 delay(5000);
 digitalWrite(CCW, HIGH); // restart
 state = MOVING_CCW;
 }
 break;
 case MOVING_CCW:
 if (digitalRead(LM1) == LOW) { // hit switch
 digitalWrite(CCW, LOW); // stop
 delay(5000);
 digitalWrite(CW, HIGH); // restart
 state = MOVING_CW;
 }
 break;
 }
}

This should work, but it has the drawback of having long delay()s in the loop, which is undesirable if you have other tasks to perform. These delays can be removed by "remembering" that you are waiting as two extra states:

void loop() {
 static enum {MOVING_CW, MOVING_CCW, STOPPED_CW, STOPPED_CCW} state;
 static unsigned long time_stopped;
 unsigned long now = millis();
 switch (state) {
 case MOVING_CW:
 if (digitalRead(LM2) == LOW) { // hit switch
 digitalWrite(CW, LOW); // stop
 state = STOPPED_CW;
 time_stopped = millis();
 }
 break;
 case MOVING_CCW:
 if (digitalRead(LM1) == LOW) { // hit switch
 digitalWrite(CCW, LOW); // stop
 state = STOPPED_CCW;
 time_stopped = millis();
 }
 break;
 case STOPPED_CW:
 if (now - time_stopped >= 5000) {
 digitalWrite(CCW, HIGH); // restart
 state = MOVING_CCW;
 }
 break;
 case STOPPED_CCW:
 if (now - time_stopped >= 5000) {
 digitalWrite(CW, HIGH); // restart
 state = MOVING_CW;
 }
 break;
 }
}
lang-cpp

AltStyle によって変換されたページ (->オリジナル) /