Rollercoaster station code review

Hello,

So a while ago I opened a topic for help on my code for the station of a K’nex rollercoaster.
But I got stuck and restarted (sorry for not posting anymore in that topic btw).
I found my own logic and now it works perfect :smiley:

But I’m sure my code is not wrote the way it should be :wink:
If someone has some time for a review, that would be great.

It does this:
train arrives
motor stops
after 2 seconds the gates open
the gates stay open for 5 seconds
2 seconds after the gates close, the motor starts again

// Station elevator lift

#include <Servo.h>

const int reedswitchStationPin = 2; // detects train in station
const int controlPin1 = 5; // pin 7 on the H-bridge
const int controlPin2 = 10;  // pin 2 on the H-bridge
const int enablePin = 11;  // pin 1 on the H-bridge
const int servoGatesPin = 12;
Servo servoGates;

// Reedswitch
int reedswitchStationState     = 0;
int lastReedswitchStationState = 0;

// Fixed durations
int millisBeforeGatesOpen = 2000;
int millisGatesOpen       = 8000; // actual time: gatesOpen - beforeGatesOpen
int millisMotorOff        = 10000;

// Millis
unsigned long currentMillis = 0;
unsigned long sensorOn      = 0;
unsigned long gatesWentOpen = 0;
unsigned long motorWentOff  = 0;

// Booleans
boolean gatesCanOpen    = false;
boolean gatesCanClose   = false;
boolean motorCanOff     = false;
boolean motorCanOn      = false;
boolean lastMotorCanOff = false;

// Motor gates
int motorEnabled = 0;
int motorSpeed   = 255;

// Positions servo gates
const int gatesClosed = 150;
const int gatesOpen   = 50;

void setup() {
  pinMode(reedswitchStationPin, INPUT);
  pinMode(controlPin1, OUTPUT);
  pinMode(controlPin2, OUTPUT);
  pinMode(enablePin, OUTPUT);
  servoGates.attach(servoGatesPin);
  
  digitalWrite(enablePin, HIGH);
  digitalWrite(controlPin1, HIGH);
  digitalWrite(controlPin2, LOW);
  servoGates.write(gatesClosed);
}

void loop() {
  currentMillis = millis();
  reedswitchStationState = digitalRead(reedswitchStationPin);
  motorStation();
  gatesStation();
  lastReedswitchStationState = reedswitchStationState;
  lastMotorCanOff = motorCanOff;
}

void motorStation() {
  if (reedswitchStationState != lastReedswitchStationState) {
    if (reedswitchStationState == HIGH) {
      sensorOn = currentMillis;
      motorWentOff = currentMillis;
      motorCanOff = true;
    }
  }
  
  if (motorCanOff == true) {
    analogWrite(enablePin, 0);
    motorCanOn = true;
  }
  
  if (motorCanOn == true) {
    if (currentMillis - motorWentOff >= millisMotorOff) {
      analogWrite(enablePin, motorSpeed);
      motorCanOff = false;
    }
  }
}

void gatesStation() {
  if (lastMotorCanOff != motorCanOff) {
    if (motorCanOff == true) {
      sensorOn = currentMillis;
      gatesWentOpen = currentMillis;
      gatesCanOpen = true;
    }
  }
  
  if (gatesCanOpen == true) {
    if (currentMillis - sensorOn >= millisBeforeGatesOpen) {
      servoGates.write(gatesOpen);
      gatesCanClose = true;
    }
  }
  
  if (gatesCanClose == true) {
    if (currentMillis - gatesWentOpen >= millisGatesOpen) {
      servoGates.write(gatesClosed);
      gatesCanOpen = false;
    }
  }
}

Thanks!

P.s. If you want to see the actual station and how it works: Video station

A state machine could make your code more clear.

In Idle state the arrival of a train is checked. When a train is detected, the motor is turned off and the time of arrival is stored. Then advance to WaitOpen state.

In WaitOpen state wait for the end of the 2 second delay, open the gate, remember the time and advance to the next state.

And so on…

Then loop() contains a switch(state), with the related tests and actions in the case branches. Eventually all timing can be based on the time of arrival, but it also looks okay as you did it already.

Ah interesting, I never thought of using a switch. But that would be a totally different program, no? For the moment I don't really have experience with it (but I'll learn :D)

But I have to make a program for the lift and brake as well. So I think I'm going to write these first to practice witch the switch.