Model Railway Level Crossing

So basically I should build my sketch as an FSM?

majenko:
You basically need to have a variable in which you store the current angle of the boom. Then you slowly (by comparing another variable to millis()) increase / decrease that variable until you have the desired final angle. Every time you increase / decrease the angle, you do the servo.write call.

A little function such as (untested):

void moveTo(unsigned char angle)

{
  static unsigned char currentAngle = 0;
  if (currentAngle < angle) {
    currentAngle++;
    myservo.write(currentAngle);
    return;
  }
  if (currentAngle > angle) {
    currentAngle--;
    myservo.write(currentAngle);
    return;
  }
}




will only move the boom by one degree per call, if it needs to move it at all. In your main loop, you can do something like:


static unsigned long boomMoveTime = millis(); // These are either local static variables, or global non-static variables.
static unsigned char desiredBoomAngle = 0;
...
if (millis() - boomMoveTime > 10) {
  boomMoveTime = millis();
  moveTo(desiredBoomAngle);
}
...
if (whatever) {
  desiredBoomAngle = 45;
}




So, every 10 milliseconds you make a call to get the boom closer to its target angle, if it's not already there. At any time in your main loop, you can then set the variable desiredBoomAngle, and it will instantly start to move the boom slowly up or down, to whatever the desiredBoomAngle variable is set to.

Thanks for that Majenko.
I've been using delay with increments/decrements to get the motor on a model railway loco to accelerate/decelerate at a realistic rate. Your way looks easier and neater. I presume that it would be fairly easy to have the rate of change increase/decrease with time, ie not a straight line acceleration.

Yes, just change the > 10 in the function to compare with a variable, which sets the delay between increments.