Railway with two stations

Hi

I know my code is a mess, but I'm a newbie with this.. I'm trying to make a train go to one station, wait for 5 sek and then go the other direction and stop for 5 sek. This will go on until I stop it. I cant seem to make the motor start again when it reaches one of the stations.
I'm using a ultrasonic distance sensor to tell me where the train is.
Any tips?

const int LEDGREEN = 5;
const int LEDYELLOW = 4;
const int LEDBLUE = 3;
const int LEDRED = 2;
const int POTMETER = A0;
const int START = 8;
const int TRIGGERPIN = 7;
const int ECOPIN = 6;
const int controlPin1 = 13;
const int controlPin2 = 9;
const int enablePin = 10;

int motorEnabled = 0;
int motorSpeed = 0;
int motorDirection = 1;
int STARTSwitchState = 0;
int previousSTARTSwitchState = 0;
int distanceThreshold = 0;
int cm = 0;
int inches = 0;
int ledState = HIGH;                 // the current state of the output pin
int buttonState;                     // the current reading from the input pin
int lastButtonState = LOW;           // the previous reading from the input pin
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers
long readUltrasonicDistance(int TRIGGERPIN, int ECOPIN) {
  pinMode(TRIGGERPIN, OUTPUT);  // Clear the trigger
  digitalWrite(TRIGGERPIN, LOW);
  delayMicroseconds(2);
  // Sets the trigger pin to HIGH state for 10 microseconds
  digitalWrite(TRIGGERPIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGGERPIN, LOW);
  pinMode(ECOPIN, INPUT);
  // Reads the echo pin, and returns the sound wave travel time in microseconds
  return pulseIn(ECOPIN, HIGH);
}
void setup() {

  pinMode(START, INPUT);
  pinMode(POTMETER, INPUT);
  pinMode(LEDYELLOW, OUTPUT);
  pinMode(LEDGREEN, OUTPUT);
  pinMode(LEDBLUE, OUTPUT);
  pinMode(LEDRED, OUTPUT);
  pinMode(controlPin1, OUTPUT);
  pinMode(controlPin2, OUTPUT);
  pinMode(enablePin, OUTPUT);

  digitalWrite(enablePin, LOW);
}

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(START);
  STARTSwitchState = digitalRead(START);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }
  {
    motorSpeed = analogRead(POTMETER) / 4;
    if (STARTSwitchState != previousSTARTSwitchState) {
      if (STARTSwitchState == HIGH) {
        motorEnabled = !motorEnabled;
      }
    }
  }

  if (motorDirection = !motorDirection) {
    digitalWrite(controlPin1, HIGH);
    digitalWrite(controlPin2, LOW);
  } else {
    digitalWrite(controlPin1, LOW);
    digitalWrite(controlPin2, HIGH);
  }
  if (motorEnabled == 1) {
    analogWrite(enablePin, motorSpeed);
  }
  previousSTARTSwitchState = STARTSwitchState;
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;
    }
  }
  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;
  {
    // set threshold distance to activate LEDs
    distanceThreshold = 300;
    // measure the ping time in cm
    cm = 0.01723 * readUltrasonicDistance(7, 6);
    // convert to inches by dividing by 2.54
    if (cm > distanceThreshold) {
      digitalWrite(5, LOW);
      digitalWrite(4, LOW);
      digitalWrite(3, LOW);
    }
    if (cm <= distanceThreshold - 10 && cm > distanceThreshold - 50) {
      digitalWrite(5, LOW);
      digitalWrite(4, LOW);
      digitalWrite(3, HIGH);
    }
    if (cm <= distanceThreshold - 150 && cm > distanceThreshold - 200) {
      digitalWrite(5, LOW);
      digitalWrite(4, HIGH);
      digitalWrite(3, LOW);
    }
    if (cm <= distanceThreshold - 250 && cm > distanceThreshold - 290) {
      digitalWrite(5, HIGH);
      digitalWrite(4, LOW);
      digitalWrite(3, LOW);
    }
    {
      if (cm <= distanceThreshold - 20 && cm > distanceThreshold - 40) {
        digitalWrite(controlPin1, LOW);
        digitalWrite(controlPin2, LOW);
        delay(5000);
        digitalWrite(controlPin2, HIGH);
        digitalWrite(controlPin1, LOW);
      }
    }
    {
      if (cm <= distanceThreshold - 260 && cm > distanceThreshold - 280) {
        digitalWrite(controlPin1, LOW);
        digitalWrite(controlPin2, LOW);
        delay(5000);
        digitalWrite(controlPin1, LOW);
        digitalWrite(controlPin2, HIGH);
      }
    }
  }
}

A 9V battery of that type will not run a motor. Replace it with 6xAA cells.

The motor is running OK until it stops at the top/bottom of the rail. It wont start up again, that's my issue. If I move it out from the UDS detection in the program it starts running again

Like I said, a 9V battery won't run a motor, at least not reliably. Are you running this circuit in an emulator? If so, you will find things are different with real components.

I find your code difficult to follow. Please remove any pairs of { } that are not needed and then click Auto Format.

Yes, I'm using ThinkerCad to test it out.

I'll try to clean up the code as well as I'm able to..

If the line before { is a } or a ; then that { is not needed and can be removed, along with the } that matches it.

Why is the same input read twice and stored in 2 different variables?

One is to make it a push and go button, and the other is to start the motor. If I'm remember correctly.

I know images of code is usually frowned on, but I pasted it into the IDE to get a better view of it, and then did autoformat and got rid of some blank lines. I think it's easier for us both to consider a screen shot in this case:


Did you intend the code in the red rectangle to be run every time round loop, or is there an 'else' missing from the beginning of line 66?

It's just me not being good at coding. They're not suppose to be there, thanks for pointing it out

It is not necessary to read the input twice and store in 2 variables in order to achieve 2 functions.

I wonder if your coding skills are at a sufficient level for the project to are trying to make.

I do doubt that, but this is what our teacher want us to figure out. Guess its just to see how good we are before starting our lessons..

But if anyone got any tips how to get it to change direction I’d love to see how it’s done. As I said, it stops in both directions but It does not start up again going backwards to the first station.

Well, that means the forum can't really help you, otherwise the teacher won't get to know how good you are, only how good we are.

What is the roll of the button? You have elements of code for properly reacting to the fact that a button has become pressed, rather than being in a pressed condition, and it looks like you've found and attempted to employ measures to overcome the fact that pushbuttons bounce.

But it is spread out and/or duplicated or just not coherent somehow.

You could just take that out for now. I am guessing it is to start and or stop something.

Can you say, for example, what you intended here? I do stuff like that in my code, but I usually knkw why I've written statements that don't do anything at all:

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH)
        ;

If you do use this code with a real sensor, please get to know how the sensor works IRL by using an examlpe sketch of the utmost simplicity - one that just reads the sensor and reports but makes no steps towards making the train run on time or whatever.

HTH

a7

Show a picture of the railtrack with details like the US sensor.

The sensor is suppose to be in the bottom of the track here.

Maybe I shouldn't post before I've had my first coffee, but...
Why is the track at an angle and what exactly does the heavy duty motor do ?

It’s suppose to be a funicular railway. The motor pulls the string which is attached to the train. I’m using the small motor in thinkercad just to check if the code works and makes the motor go from cw to ccw after the delay