Railwaycrossing school project

I need to make this railwaycrossing for school.
The program should read the sensors to close and open the crossing.
I struggle with the fact that i cant use multiple loops and cant use delay because it would stop the leds flashing so i tried Chrono timers.

But it wont compile because it says they are not defined,
And i might not be using them correctly either.

after X=2 and the railway closes again the LED’s are still flashing so could i use a timer to get back to
x=0 and go back to the default state (railwaycrossing OFF) ?

or is it possible to use the position of the servo’s to turn the LED’s off?

So it should be

Sensor L detects the train

  • LED’s start flashing with the piezo as an alarm
    -After a delay the crossing should close

Sensor R detects the train
-Crossing opens

  • LED’s keep flashing and the alarm is on until the crossing is open

Default state

  • crossing is open and LED’s and alarm are off

How could i realize this ?
I hope the program is clear enough because its written in dutch

#include <Chrono.h>
#include <LightChrono.h>
#include <Servo.h>
int LEDLi1=11;
int LEDLi2=10;
int LEDRe1=4;
int LEDRe2=3;

Servo servo1;
Servo servo2;
int pos1=70;
int pos2=70;

int sensePinL=0; // analog Pin A0 on the arduino
int sensePinR=8; // analog Pin A1 on the arduino

int piezopin=6;

int x=0;


void setup() {
  // put your setup code here, to run once:

// Instantiate Chronos
Chrono chronoA; 
Chrono chronoB;
Chrono chronoC;
  
servo1.attach(12);
servo2.attach(13);
pinMode(LEDLi1,OUTPUT);
pinMode(LEDLi2,OUTPUT);
pinMode(LEDRe1,OUTPUT);
pinMode(LEDRe2,OUTPUT);
pinMode(sensePinL,INPUT);
pinMode(sensePinR,INPUT);

Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  

int detectR = digitalRead(8);// lezen van sensors
int detectL = digitalRead(0);

Serial.print("x=  ");
Serial.println(x);

// sensors
if(detectL == LOW){ // sensors setten een variabele die gebruikt worden om aan te sturen
  x=1;
}

if(detectR == LOW){
 x=2; 
}

//Defaultstate
while(x == 0){
pos1=180;
servo1.write(pos1);

pos2=180;
servo2.write(pos2);

  
digitalWrite(LEDLi1,LOW);
digitalWrite(LEDRe1,LOW);
noTone (piezopin);
digitalWrite(LEDLi2,LOW);
digitalWrite(LEDRe2,LOW);
}


// sensor L neemt obstakel waar
// slagboom gaat dicht
while (x == 1){ //X is 1 bij de eerste sensor dit laat de overgang dichtgaan

if (chronoB.hasPassed(2000) {  //slagboom gaat dicht na 2s
 pos1=70;
  servo1.write(pos1);

pos2=70;
  servo2.write(pos2);    
chronoA.restart();            //..and restart the chrono

if (chronoA.hasPassed(500) {  //Every 0,5 seconds..
digitalWrite(LEDLi1,HIGH);// LED's en geluid
digitalWrite(LEDRe1,HIGH);
tone (piezopin,1000);
digitalWrite(LEDLi2,LOW);
digitalWrite(LEDRe2,LOW);           
chronoA.restart();            //..and restart the chrono
}
else {
digitalWrite(LEDLi1,LOW);
digitalWrite(LEDRe1,LOW);
tone (piezopin,500);
digitalWrite(LEDLi2,HIGH);
digitalWrite(LEDRe2,HIGH);  
}
// sensor R neemt obstakel waar
//lichten blijven branden
while(x == 2){

if (chronoA.hasPassed(500) {  //Every 0,5 seconds..
digitalWrite(LEDLi1,HIGH);// LED's en geluid
digitalWrite(LEDRe1,HIGH);
tone (piezopin,1000);
digitalWrite(LEDLi2,LOW);
digitalWrite(LEDRe2,LOW);           //..toggle..
chronoA.restart();            //..and restart the chrono

else {
digitalWrite(LEDLi1,LOW);
digitalWrite(LEDRe1,LOW);
tone (piezopin,500);
digitalWrite(LEDLi2,HIGH);
digitalWrite(LEDRe2,HIGH);
}
if (chronoC.hasPassed(2000) {  //slagboom gaat open na 2s
 pos1=70;
  servo1.write(pos1);

pos2=70;
  servo2.write(pos2);    
chronoC.restart();
}}

But it wont compile because it says they are not defined,

What says that what are not defined?

I'm guessing that you haven't bothered downloading and installing the library(s) you are trying to use. Prove me wrong.

Creating instances of the Chrono class in setup() is pointless.

while(x == 0){
pos1=180;
servo1.write(pos1);

pos2=180;
servo2.write(pos2);

 
digitalWrite(LEDLi1,LOW);
digitalWrite(LEDRe1,LOW);
noTone (piezopin);
digitalWrite(LEDLi2,LOW);
digitalWrite(LEDRe2,LOW);
}

While that piss-poorly indented block of code is running, what part of that is going to cause a change to the value in x, that would enable the while statement to end?

You do not need the Chrono library to not use delay(). The blink without delay example shows how to do something, like blinking an LED, without impacting the rest of the program, using millis().

What says that what are not defined?

"They" refers too the Chrono timers

Obviously i know this is a bad code and im not experienced with programming because this is my first real project..
I did download and install the library though.
And yes it seems like i placed those chrono instances wrong. they should come before setup

But the point of this thread is GUIDANCE.

Also,
The sensors change the value of X
and the program is not complete because it still has to exit the while x=2 statement back too the default state x=0

if i knew how to code it, i would not be on this forum.

i could use millis() but then i would still need a delay for the servo's. so that they dont instantly close the crossing.

Have a look at how the code is organized in Several Things at a Time

It flashes LEDs and operates a servo.

Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.

…R

I don't know this chrono library, and good chance you simply don't need it. I've done way more complex things than this without it. No problem.

To have the lights flash without using delay, look at the "Blink Without Delay" example. That shows you how to blink an LED using millis() timing. You can of course copy that block three times, use different intervals, and have three LEDs blink at different speed, all independent from one another. Play a bit with it and you'll quickly understand what's going on.

Next you implement a finite state machine, this is normally done using switch/case statements (see also the Several Things at a Time example, linked in the reply above). You use the timing methods from the first step to flash the lights, control the movement of your servos (so the barriers close nice and slowly, without chopping down an unsuspecting cyclist that just happened to cross), and how long to wait after the train has passed before continuing to the next state.
Default state: crossing open.
Train detected, enter state: crossing closing. Barriers go down, lights flash.
When the barriers are down, enter state: crossing closed. Lights flash.
Train passed, enter state: train gone. Lights flash.
After some time, enter state: crossing opening. Barriers go up, lights flash.
When barriers are up, enter state: crossing open. Lights off.

Another thing, use the autoformat function of the IDE. Makes your code a lot more readable.

This is very similar to the "pedestrian crossing" problem. If you could ever figure out how my code works for that, you could use various parts of it :grinning: :

// Pedestrian crossing lights

const int led13Pin =  13;    // LED pin number
const int PgrnPin =  6;
const int PredPin =  5;
const int RgrnPin =  4;
const int RyelPin =  3;
const int RredPin =  2;
const int button1 =  10;

int led13State = LOW;        // initialise the LED
int PgrnState = LOW;
int PredState = LOW;
int RgrnState = LOW;
int RyelState = LOW;
int RredState = LOW;
char bstate1 = 0;
boolean press = false;

unsigned long count1 = 0;   // will store last time LED was updated
unsigned long count2 = 0;
unsigned long count3 = 0;
unsigned long count4 = 0;
unsigned long count5 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check 
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) { 
    *marker += interval;    // move on ready for next interval
    return true;       
  } 
  else return false;
}

void setout(unsigned long *marker) {
  *marker = millis();             // initialise
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far, 
    if (button == HIGH) return false; // Nothing happening!
    else { 
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far, 
    if (button == LOW) return false; // Nothing happening!
    else { 
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else 
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else 
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    {  
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}


void setleds() {
  digitalWrite(led13Pin, led13State);
  digitalWrite(PredPin, PredState);
  digitalWrite(PgrnPin, PgrnState);
  digitalWrite(RredPin, RredState);
  digitalWrite(RyelPin, RyelState);
  digitalWrite(RgrnPin, RgrnState);
}

boolean ispress() { // One-directional read of button - sets but does not clear!
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    press = true;
  } 
  return(press);
}

void setup() {
  Serial.begin(9600);
  pinMode(led13Pin, OUTPUT);      
  pinMode(PgrnPin, OUTPUT);      
  pinMode(PredPin, OUTPUT);      
  pinMode(RgrnPin, OUTPUT);      
  pinMode(RyelPin, OUTPUT);      
  pinMode(RredPin, OUTPUT);      
  pinMode(button1, INPUT);      
  digitalWrite(button1,HIGH);        // internal pullup all versions
  press = false;
  Serial.println("Starting ...");
}

void loop() {
  // All red phase
  RredState = HIGH;
  RyelState = LOW; 
  RgrnState = LOW; 
  PredState = HIGH;
  PgrnState = LOW; 
  setleds();
  Serial.println("Red phase");
  setout(&count3);  
  while (!timeout(&count3, 3000UL )) {
    ispress();  // Check on the button
  }

  // Road Green
  RredState = LOW;
  RyelState = LOW; 
  RgrnState = HIGH; 
  PredState = HIGH;
  PgrnState = LOW; 
  setleds();
  Serial.println("Road green");
  setout(&count3);  
  while (!timeout(&count3, 8000UL )) { // Reasonable time on green
    ispress();  // Check on the button
  }
  Serial.println("Green stale, wait on button");

  while ( press == false )  // Now wait for the button 
  {
    if (timeout(&count2, 300UL )) {
      if (led13State == LOW) {
        led13State = HIGH;
      }
      else {
        led13State = LOW; 
      } 
      digitalWrite(led13Pin, led13State);
    }
    ispress();   
  }
  led13State = LOW; 
  digitalWrite(led13Pin, led13State);

  Serial.println("Button sensed");
  setout(&count3);  
  while (!timeout(&count3, 4000UL )) { // Do not respond immediately!
  }

  // Road Yellow
  RredState = LOW;
  RyelState = HIGH; 
  RgrnState = LOW; 
  PredState = HIGH;
  PgrnState = LOW; 
  setleds();
  Serial.println("Road yellow");
  setout(&count3);  
  while (!timeout(&count3, 5000UL )) {
  }

  // Road Red
  RredState = HIGH;
  RyelState = LOW; 
  RgrnState = LOW; 
  PredState = HIGH;
  PgrnState = LOW; 
  setleds();
  Serial.println("Road red");
  setout(&count3);  
  while (!timeout(&count3, 3000UL )) {
  }

  // Walk Green
  RredState = HIGH;
  RyelState = LOW; 
  RgrnState = LOW; 
  PredState = LOW;
  PgrnState = HIGH; 
  setleds();
  press = false;  
  Serial.println("Walk");
  setout(&count3);  
  while (!timeout(&count3, 6000UL )) {
  }

  // Flash Don't Walk
  RredState = HIGH;
  RyelState = LOW; 
  RgrnState = LOW; 
  PgrnState = LOW; 
  Serial.println("Flash Don't Walk");
  setout(&count3);  
  while (!timeout(&count3, 7000UL )) {
    if (timeout(&count2, 500UL )) {
      if (PredState == LOW) {
        PredState = HIGH;
      }
      else {
        PredState = LOW; 
      } 
      setleds();
    }
    ispress();  // Check on the button
  }

}

I made a new code with millis() i already got the flashing and alarm working. but i dont know how to code the servo so that it has a delay and it moves slower.
i know the code right now is wrong because it does not have the right timing.
Also should i just use the first timing (delay)to set a variable like Servo=1
and make an if statement if Servo=1 too move the servo at a set speed (degrees) with an interval (ms) ??

I also seem to have a problem with the State variable that does not change with the sensors and that part used too work before.

const int led_Interval = 500;
const int blinkDuration = 500;
const int Hefboom_vertraging = 3000; // servo delay
const int Hefboom_snelheid = 1; // servospeed


unsigned long currentMillis = 0;    // stores the value of millis() in each iteration of loop()
unsigned long previousLed_Millis = 0;
unsigned long previousServo_Millis = 0;


#include <Servo.h>
int LEDsL = 11;
int LEDsR = 10;

byte led_A_State = LOW;
byte led_B_State = LOW;

Servo servo1;
Servo servo2;
int pos = 70;
int Servomax = 180;
int Servomin = 70;

//sensors
int sensePinL = 0;
int sensePinR = 8;
// piezo
int piezopin = 6;

int State = 0;


void setup() {
  // put your setup code here, to rce:
  servo1.attach(12);
  servo2.attach(13);
  pinMode(LEDsL, OUTPUT);
  pinMode(LEDsR, OUTPUT);
  pinMode(sensePinL, INPUT);
  pinMode(sensePinR, INPUT);
  Serial.begin(9600);
}

void loop() {
  currentMillis = millis();

  int detectR = digitalRead(8);// lezen van sensors
  int detectL = digitalRead(0);
  Serial.println(State);
  //Serial.println(detectL);
  if (detectL == LOW) {
    State = 1;
  }

  if (detectR == LOW) {
    State = 2;
  }



  // STATES
  switch (State) {
    case 0:
      Overgang_UIT (); // crossing off
      break;
    case 1:
      Flashing ();
      Overgang_DICHT (); // close crossing
      break;
    case 2:
      Flashing ();
      Overgang_OPEN ();// open crossing
      Eindeloop (); // goes back to state=0 after servo has reached pos=70
      break;
  }
}





void Flashing () {
  digitalWrite(LEDsR, led_A_State);
  digitalWrite(LEDsL, led_B_State);


  if (led_B_State == LOW) {
    if (currentMillis - previousLed_Millis >= led_Interval) { 
      led_B_State = HIGH;
      tone (piezopin, 1000);
      led_A_State = LOW;
      previousLed_Millis += led_Interval;
    }
  }
  else {
    if (currentMillis - previousLed_Millis >= blinkDuration) {
      led_B_State = LOW;
      tone (piezopin, 500);
      led_A_State = HIGH;
      previousLed_Millis += blinkDuration;
    }
  }
}

void Overgang_OPEN () {

  if (currentMillis - previousServo_Millis >= Hefboom_vertraging) { // should be a servo delay
    if (currentMillis - previousServo_Millis >= Hefboom_snelheid) { // should be servo speed
      for (int pos = 70; pos <= 180; pos += 1) {
        servo1.write(pos);
        servo2.write(pos);
        previousServo_Millis = currentMillis;
      }
    }
  }
}

void Overgang_DICHT () {

  if (currentMillis - previousServo_Millis >= Hefboom_vertraging) {
    if (currentMillis - previousServo_Millis >= Hefboom_snelheid) {
      for (int pos = 180; pos <= 70; pos -= 1) {
        servo1.write(pos);
        servo2.write(pos);
      }
    }
  }
}

void Overgang_UIT () {
  led_B_State = LOW;
  noTone (piezopin);
  led_A_State = LOW;
  pos=70;
}

void Eindeloop () { // should switch of leds if the servo is at its position
  if (pos == 70) {
    State = 0;
  }
}

Anon1993:
I made a new code with millis() i already got the flashing and alarm working. but i dont know how to code the servo so that it has a delay and it moves slower.

The code in the link I gave you in Reply #3 implements a slow-moving servo.

...R

The Servo library examples in the IDE also show you how to slowly move a servo.

Basically don't set it to the final point right away, but make it move one step at a time, with appropriate interval.

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

How have you got your sensors wired?

Thanks.. Tom... :slight_smile:

TomGeorge:
Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

How have you got your sensors wired?

Thanks.. Tom... :slight_smile:

Robin2:
The code in the link I gave you in Reply #3 implements a slow-moving servo.

...R

ow i see it now, so i should be able to make that part work. but im still confused on how to make the servo start after a certain amount of time and make it go slow. because it uses the millis() function twice.

Anon1993:

I hope you're not seriously doing it like that. 9V block battery; two servos; breadboard; no power for the Arduino - that's not going to work. Unreadable markings (if there in the first place) are also not helpful.

That's why we ask for a circuit diagram aka schematic. Not Fritzing spaghetti.

wvmarle:
I hope you're not seriously doing it like that. 9V block battery; two servos; breadboard; no power for the Arduino - that's not going to work. Unreadable markings (if there in the first place) are also not helpful.

That's why we ask for a circuit diagram aka schematic. Not Fritzing spaghetti.

Well ofcourse im plugging the arduino in aswell. And i only have the Fritzing spaghetti.
the circuit runs fine though.
its the code for the State and having the servo start after a certain amount of time
after the LED's thats the problem.
and switching back to default state.

Im not sure if this works

void Eindeloop () { // should switch of leds if the servo is at its position
if (pos == 70) {
State = 0;
}
}

and why the sensors dont change the State variable.

Anon1993:
ow i see it now, so i should be able to make that part work. but im still confused on how to make the servo start after a certain amount of time and make it go slow. because it uses the millis() function twice.

Then your state machine needs more states.

I am a little concerned with the code you posted in reply #6. You read the two inputs and jump immediately to state 1 or 2. (Can you give those states names?) But this "breaks" the state machine because it does not consider what state it was in. Maybe you are in one of the slowly-moving states and jumping to state 1 will slam your servos back to the starting position.

You should read all of the inputs at the top of the loop. (millis() is also an input.) Then look at what state you are in and which state you should move to, based on those inputs.

You will end up with many states. If you receive an input while you are in the middle of a movement and you need to remember to go to a different state at the end of the movement then you will need to add another state like "moving up with left triggered". This allows it to do the correct action after the movement even if that input is no longer active.

Anon1993:
Im not sure if this works

void Eindeloop () { // should switch of leds if the servo is at its position
if (pos == 70) {
State = 0;
}
}.

Good question. Look at thr code which is expected to put pos at 70…

      for (int pos = 180; pos <= 70; pos -= 1) {

servo1.write(pos);
        servo2.write(pos);
      }

First int pos will create a new local variable called pos. This may have the same name as a global variable but changes to this local one won’t change the global one.

Second, =180 sets it to 180. Which is greater than 70, last time I checked. So the rest of the loop never runs anyway.

If it did run (like maybe you started at 0) then pos <= 70 means that it will run one last time when pos is equal to 70, which increments pos, leaving it at 71 after the loop completes. So your questionable code will never find pos equal to 70.

Third, there is no delay so this loop will run in just a few microseconds and your servos will drive towards 70 as quickly as they can.

Fourth, this is blocking code. You need to break the movement down into tiny steps that take milliseconds to complete so it can return to loop() and look at the inputs again. So you need a “wait before moving” state, a “moving up” state that changes the global pos and a “waiting with arms up” state that knows the next move is going to be “wait to move down.”

Finally, F**ing does have a schematic view. Use it.

MorganS:
Then your state machine needs more states.

I am a little concerned with the code you posted in reply #6. You read the two inputs and jump immediately to state 1 or 2. (Can you give those states names?) But this “breaks” the state machine because it does not consider what state it was in. Maybe you are in one of the slowly-moving states and jumping to state 1 will slam your servos back to the starting position.

You should read all of the inputs at the top of the loop. (millis() is also an input.) Then look at what state you are in and which state you should move to, based on those inputs.

You will end up with many states. If you receive an input while you are in the middle of a movement and you need to remember to go to a different state at the end of the movement then you will need to add another state like “moving up with left triggered”. This allows it to do the correct action after the movement even if that input is no longer active.

Well the states are always in the same order because the train only goes one way in my example.

So its 0,1,2,0
and the switch case should perform the loops that have to be active at that time.
the servo movement should have ended by the time the next State starts.

Im pretty new to programming so i dont want too make something too complex.
because im probably already in over my head because most classmates are just using the delay() function to do stuff and have no timings.
but i realy need a good grade.
the deadline is within 2 days.
if i made a even more complex program i would also have to explain how it works.

so is there no simple way to make my current program work ?

Yea the previous code was flawed.
This is the new one.

this does have an interval for the servo speed.
but i did not know that the int in the FOR command made a new int.
so can i just remove the int or should i not use the FOR command but something else ?

const int led_Interval = 500;
const int blinkDuration = 500;
const int Hefboom_vertraging = 3000; // servo delay
const int Hefboom_snelheid = 80; // servospeed


unsigned long currentMillis = 0;    // stores the value of millis() in each iteration of loop()
unsigned long previousLed_Millis = 0;
unsigned long previousServo_Millis = 0;


#include <Servo.h>
int LEDsL = 11;
int LEDsR = 10;

byte led_A_State = LOW;
byte led_B_State = LOW;

Servo servo1;
Servo servo2;
int pos = 70;
int Servomax = 180;
int Servomin = 70;

//sensors
int sensePinL = 0;
int sensePinR = 8;
// piezo
int piezopin = 6;

int State = 0;


void setup() {
  // put your setup code here, to rce:
  servo1.attach(12);
  servo2.attach(13);
  pinMode(LEDsL, OUTPUT);
  pinMode(LEDsR, OUTPUT);
  pinMode(sensePinL, INPUT);
  pinMode(sensePinR, INPUT);
  Serial.begin(9600);
}

void loop() {
  currentMillis = millis();

  int detectR = digitalRead(8);// lezen van sensors
  int detectL = digitalRead(0);
  Serial.println(State);
  Serial.println(detectL);
  if (detectL == LOW) {
    State = 1;
  }

  if (detectR == LOW) {
    State = 2;
  }



  // STATES
  switch (State) {
    case 0:
      Overgang_UIT (); // crossing off
      break;
    case 1:
      Flashing ();
      Overgang_DICHT (); // close crossing
      break;
    case 2:
      Flashing ();
      Overgang_OPEN ();// open crossing
      break;
  }
}





void Flashing () {
  digitalWrite(LEDsR, led_A_State);
  digitalWrite(LEDsL, led_B_State);


  if (led_B_State == LOW) {
    if (currentMillis - previousLed_Millis >= led_Interval) {
      led_B_State = HIGH;
      tone (piezopin, 1000);
      led_A_State = LOW;
      previousLed_Millis += led_Interval;
    }
  }
  else {
    if (currentMillis - previousLed_Millis >= blinkDuration) {
      led_B_State = LOW;
      tone (piezopin, 500);
      led_A_State = HIGH;
      previousLed_Millis += blinkDuration;
    }
  }
}

void Overgang_OPEN () {


  if (currentMillis - previousServo_Millis >= Hefboom_snelheid) { // should be servo speed
    for (int pos = 180; pos <= 70; pos += 1) {
      servo1.write(pos);
      servo2.write(pos);
      previousServo_Millis += Hefboom_snelheid;
    }
  }
}


void Overgang_DICHT () {


  if (currentMillis - previousServo_Millis >= Hefboom_snelheid) {
    for (int pos = 70; pos <= 180; pos -= 1) {
      previousServo_Millis += Hefboom_snelheid;
      servo1.write(pos);
      servo2.write(pos);
    }
  }
}


void Overgang_UIT () {
  led_B_State = LOW;
  noTone (piezopin);
  led_A_State = LOW;
  pos = 70;
}

void Eindeloop () { // should switch of leds if the servo is at its position
  if (pos == 70) {
    State = 0;
  }
}

Not if you want to make the lights blink nicely and so.

I gave you a list of states already, in #4. You need at least five states, not just three, to make it work. And yes, DO name them, it makes life a lot easier, also for yourself. Using an enum is the nice way; using a list of variables does the job as well and is easier to understand.

Understand how states work, understand how blink-without-delay works, and it will all come together. Consider each state a separate program.

Flashing your lights - that IS blink without delay. Put it in a separate subroutine, so you can simply call it from the states you want the lights to flash.

Moving the servo slowly - look at the sweep example. It uses delay, so you have to convert that to millis() based timing instead. Make it do a sweep, in both directions - that code you can then instantly move into a state.

So to add a bit to your code in #6:

// Define the states - giving them names. Makes adding states a lot easier later!

const byte SPOORWEG_OPEN = 0;
const byte SPOORWEG_SLUIT = 1;
const byte SPOORWEG_GESLOTEN = 2;
const byte SPOORWEG_OPENT = 3;

void loop() {

  switch (State) {
    case SPOORWEG_OPEN:
      Overgang_UIT (); // crossing off
      // read sensor; if triggered: change state.
      break;

    case SPOORWEG_SLUIT:
      Flashing ();
      // sweep-without-delay code to move servo down.
      // when down: change state.

      break;
    case SPOORWEG_GESLOTEN:
      Flashing ();
      // read sensor; if triggered: change state.
      break;

    case SPOORWEG_OPENT:
      Flashing ();
      // sweep-without-delay code to move servo down.
      // when down: change state.

      break;
  }
}

void Flashing () {
  // This is the "blink without delay" code
}

Another thing: sweep-without-delay will NOT use a for loop. Instead you use a global counter (e.g. your variable pos) which you increase based on the millis() counter, use to set your servo and then check whether the limit was reached - so basically the same as a for loop does, without it being a closed loop, a for loop is "blocking": you're stuck in that loop, can't do anything else in between.

It is of course possible to do this in a separate function but that adds complexity and is unnecessary here.

Flashing your lights - that IS blink without delay. Put it in a separate subroutine, so you can simply call it from the states you want the lights to flash.

I don’t agree with this. The problem starts when you leave one of the flashing states. The lights may be on or off at that point - the “big” state machine doesn’t know and should not have to know.

I would always call the flashing function. It will have access to the state of the big state machine so it will know when it is supposed to flash or not flash. When it sees that it is in one of the non-flashing states, it can digitalWrite() the correct settings.

so can i just remove the int or should i not use the FOR command but something else ?

Yes, just removing “int” will force the for() to use and update the global variable. But you should not be using for() anyway.

void Overgang_OPEN () {


  if (currentMillis - previousServo_Millis >= Hefboom_snelheid) { // should be servo speed
    previousServo_Millis += Hefboom_snelheid;
    if(pos <= 70) {
      pos++;
      servo1.write(pos);
      servo2.write(pos);
    } //else we are at the top
  }
}