Railuino train going back and forth

hi again Paul,

I updated my code with your suggestions and it works....almost.
I am having a problem with the ending. I cannot making go back to the beginning of the loop ( and for it to detect the emergency press button).
Would you have a suggestion?

I tried to have my "END" state go to "IDLE" state, which made my start button being recognized, but then the Emergency is not detected. If I remove the go to "IDLE" state, it spins in the "END" state.

thanks

#include <Railuino.h>
enum State {
  IDLE,
  STARTING,
  GOINGFORWARD,
  PAUSING,
  GOINGBACK,
  END
};

// create a variable holding the current state

State state = IDLE;


const word    LOCO  = ADDR_MM2 + 78;

const boolean DEBUG = true;

TrackController ctrl(0xdf24, DEBUG);
const int SENSORFORWARDPin = A0;
const int SENSORBACKWARDPin = A1;
const int STARTPin = 12;
const int EmergencyPin = 4;

void setup()
{
  Serial.begin(9600);
  while (!Serial);
  pinMode(10, OUTPUT);
  digitalWrite(12, LOW);
  digitalWrite(A0, LOW);
  digitalWrite(A1, LOW);
  digitalWrite(4, LOW);

  ctrl.begin();
  Serial.println("Power on");
  ctrl.setPower(true);
}
// the loop just does a time slice without delay

void loop() {
  // read the button.

  if ( digitalRead(EmergencyPin) == HIGH) { /* the button has just been pressed */
    if ( digitalRead(SENSORBACKWARDPin) == HIGH) {
      Serial.println("emergency stop");
      ctrl.setLocoSpeed(LOCO, 0);
      delay(500);
      digitalWrite(EmergencyPin, LOW);
      digitalWrite(SENSORBACKWARDPin, LOW);
      state = END;
    }
    else {
      Serial.println("emergency return");
      ctrl.setLocoDirection(LOCO, DIR_REVERSE);
      ctrl.setLocoSpeed(LOCO, 1000);
      delay(800);

      // do the emergency stop stuff;
    }
  }
  else {
    switch (state) {
      case IDLE:
        if ( digitalRead(STARTPin) == HIGH) {
          Serial.println("idle ");
          ctrl.setPower(true);
          state = STARTING;
        }
        break;

      case STARTING:
        Serial.println("starting ");
        delay(1000);
        digitalWrite(10, HIGH);   // turn the Sound on
        delay(1000);
        Serial.println("HORN ");
        digitalWrite(10, LOW); // deactivate sound
        state = GOINGFORWARD;
        break;

      case GOINGFORWARD:
        if ( digitalRead(SENSORFORWARDPin) == HIGH) {
          Serial.println("sensor forward detection");
          state = PAUSING;
        }
        else {
          Serial.println("forward ");
          ctrl.setLocoDirection(LOCO, DIR_FORWARD);
          ctrl.setLocoSpeed(LOCO, 1000);
          delay(1100);
        }

        break;

      case PAUSING:
        digitalWrite(SENSORFORWARDPin, LOW);
        ctrl.setLocoSpeed(LOCO, 0);
        Serial.println("pause");
        delay(2000);
        state = GOINGBACK;
        break;

      case GOINGBACK:
        if ( digitalRead(SENSORBACKWARDPin) == HIGH) {
          Serial.println("sensor backward detection");
          ctrl.setLocoSpeed(LOCO, 0);
          delay(2000);
          state = END;

        }
        else {
          /* LOCO goes backward */
          Serial.println("reverse ");
          ctrl.setLocoDirection(LOCO, DIR_REVERSE);
          ctrl.setLocoSpeed(LOCO, 1000);
          delay(1100);


        }
        break;

      case END:
        ctrl.setPower(false);
        Serial.println("end ");
        break;







    }
  }
}

beninflux:
I updated my code with your suggestions and it works....almost.

But, you didn't post your code...

just to clarify my use of delay in my code,
without it my train would not be moving ( actually moving in very very small increments, not smoothly at all).
I would rather do away with delay as it does not always detect my PIR sensor at both ends. I might change to an IR sensor, as in the example here

thanks again

A PIR sensor to detect a train? That is odd.

aarg:
A PIR sensor to detect a train? That is odd.

Well, he did say that it didn't always work.

the PIR detects my train ok, just not when it goes too fast within the delay given. if I had a delay(50) it'd be no problem.
it's a model train and I have about a 1cm diameter hole in the tracks to sense any movement.
it cannot be seen by the public.

beninflux:
the PIR detects my train ok, just not when it goes too fast within the delay given. if I had a delay(50) it'd be no problem.
it's a model train and I have about a 1cm diameter hole in the tracks to sense any movement.
it cannot be seen by the public.

Then use a delay(50)?

with no delay I have a train that has the hiccups.
with a delay(50) it's not much different....

ANYWAY that is not my problem at the moment...

it is to exit the END state and return at the beginning of loop().

ANYWAY that is not my problem at the moment...

Correct. The real problem is that only you can see the code that doesn't work.

?

Why even reply to say this kind of stuff?

beninflux:
?

Why even reply to say this kind of stuff?

Fear not. I won't be replying to you any more.

beninflux:
?

Why even reply to say this kind of stuff?

It's a hint. To you.

Not sure about you but high school petty stuff...

??

Why?

PaulMurrayCbr was super helpfull in pointing in the right direction

I assume that is why there is a forum .. those in the know helping those that know less.. and hopefully at some point the other way around.

But not even reading what the problem is and going on about nonsense... then thanks but no thanks.

BUT also thanks to those that take the time to help.
It is greatly greatly GREATLY appreciated.

beninflux:
Not sure about you but high school petty stuff...

??

Why?

Because reply #21 and #28 indicated the only option that can really help you, and you ignored it.

Another hint (or high school petty stuff, depending on your POV): We can't see YOUR CODE.

(was that too subtle?)

reply #20?

I'm seeing code

beninflux:
I'm seeing code

But we aren't. Post your most recent sketch.

code:

#include <Railuino.h>
enum State {
  IDLE,
  STARTING,
  GOINGFORWARD,
  PAUSING,
  GOINGBACK,
  END
};

// create a variable holding the current state

State state = IDLE;


const word    LOCO  = ADDR_MM2 + 78;

const boolean DEBUG = true;

TrackController ctrl(0xdf24, DEBUG);
const int SENSORFORWARDPin = A0;
const int SENSORBACKWARDPin = A1;
const int STARTPin = 12;
const int EmergencyPin = 4;

void setup()
{
  Serial.begin(9600);
  while (!Serial);
  pinMode(10, OUTPUT);
  digitalWrite(12, LOW);
  digitalWrite(A0, LOW);
  digitalWrite(A1, LOW);
  digitalWrite(4, LOW);

  ctrl.begin();
  Serial.println("Power on");
  ctrl.setPower(true);
}
// the loop just does a time slice without delay

void loop() {
  // read the button.

  if ( digitalRead(EmergencyPin) == HIGH) { /* the button has just been pressed */
    if ( digitalRead(SENSORBACKWARDPin) == HIGH) {
      Serial.println("emergency stop");
      ctrl.setLocoSpeed(LOCO, 0);
      delay(500);
      digitalWrite(EmergencyPin, LOW);
      digitalWrite(SENSORBACKWARDPin, LOW);
      state = END;
    }
    else {
      Serial.println("emergency return");
      ctrl.setLocoDirection(LOCO, DIR_REVERSE);
      ctrl.setLocoSpeed(LOCO, 1000);
      delay(800);

      // do the emergency stop stuff;
    }
  }
  else {
    switch (state) {
      case IDLE:
        if ( digitalRead(STARTPin) == HIGH) {
          Serial.println("idle ");
          ctrl.setPower(true);
          state = STARTING;
        }
        break;

      case STARTING:
        Serial.println("starting ");
        delay(1000);
        digitalWrite(10, HIGH);   // turn the Sound on
        delay(1000);
        Serial.println("HORN ");
        digitalWrite(10, LOW); // deactivate sound
        state = GOINGFORWARD;
        break;

      case GOINGFORWARD:
        if ( digitalRead(SENSORFORWARDPin) == HIGH) {
          Serial.println("sensor forward detection");
          state = PAUSING;
        }
        else {
          Serial.println("forward ");
          ctrl.setLocoDirection(LOCO, DIR_FORWARD);
          ctrl.setLocoSpeed(LOCO, 1000);
          delay(1100);
        }

        break;

      case PAUSING:
        digitalWrite(SENSORFORWARDPin, LOW);
        ctrl.setLocoSpeed(LOCO, 0);
        Serial.println("pause");
        delay(2000);
        state = GOINGBACK;
        break;

      case GOINGBACK:
        if ( digitalRead(SENSORBACKWARDPin) == HIGH) {
          Serial.println("sensor backward detection");
          ctrl.setLocoSpeed(LOCO, 0);
          delay(2000);
          state = END;

        }
        else {
          /* LOCO goes backward */
          Serial.println("reverse ");
          ctrl.setLocoDirection(LOCO, DIR_REVERSE);
          ctrl.setLocoSpeed(LOCO, 1000);
          delay(1100);


        }
        break;

      case END:
        ctrl.setPower(false);
        Serial.println("end ");
        break;







    }
  }
}

You've got delay()s in there, and you're worried about responsiveness?

      case END:
        ctrl.setPower(false);
        Serial.println("end ");
        break;

There's nothing there to change the state. Shouldn't it go to IDLE?

I tried but when I do the emergency button cannot be triggered again.