This post refers to a servo switch with a wire actuator and is a try to answer the following questions:
- Is it possible to lock the servo at its end position and dettach it from power and the arduino?
- How can the end positions (normal/thrown) be sensed?
- Is it possible to use a servo to switching a turnout without set its end positions in the arduino and without have to find the exact range and the exact middle point values?
Turnout servo machine locking with magnets 1 |
The pictures show different views of the switch machine. The bracket is made from a 40mm wide and 0.8 mm steel strip. The servo, the spdt switch and the two M4 hex bolts are attached by wood blocks. The neodymium magnets are glued on bolt caps and copper contacts glued on them.
The magenta wire is connected to the mcu ground. The two wires, from the copper plates on the magnets, are connected to the two of mcu pins. The spdt switch for the powering of the frog is connect as usual (NC a NO to dcc, common to the frog). A further improvement will be the sliding of the servo and the rest on the bracket so that the height will to be adjustable.
Turnout servo machine locking with magnets 2 |
So I need something to secure the servo when it reaches the end position and leaves it when is ordered to move to the opposite position. The answer is a neodymium magnet. In my design i use the wire of paper clips as shown in figure. It is strong end its elasticity offers a smooth landing on the magnets.
When the servo reaches its end position, the wire touches the magnet and is attracted.
The distance (r) between the magnet (S-N line) and the servo shaft is cca 1,0 cm, so the theoretically needed magnetic force is Fmag=Torque [Kg] =10*Torque [N]. The magnetic force has not be too big to avoid permanent deformation of the wire. We can increase the resisting torque, using the same magnet, by increasing the distance (r).
Turnout servo machine locking with magnets 3 |
Even the cheap servos without full 180 degree range can cover this range.
Lets name the lowest angle position "Left" and the higher "Right". Yes, I admit that the direction from the low angle to the high must be known. Lets assume the servo is at the left position and the middle position is 90 degrees (it is not, but is close to this). Lets assume the movement range -α/+α.
Then we can write a pseudo-code:
startup values:
servo [1..servos_num]//array
moving_increment[1..servos_num]=0
malfunction_flag[1..servos_num]=0 //array
LOOP:
for each servo call move_the_servo(servo, position=left/right)
END LOOP
startup values:
servo [1..servos_num]//array
moving_increment[1..servos_num]=0
malfunction_flag[1..servos_num]=0 //array
max_travel_time=5sec ie // if the servo doesn't reach an end pos in 5sec then a malfunction occurred
for each servo call move_the_servo(servo, position=left/right)
END LOOP
procedure move_the_servo(servo, position=left/right)
Begin
{If left switch=closed and position=right then //start moving from the left pos to the right
(set the moving_increment to +1; //at the startup the initial value for the increment has to be 0
//attach the servo;
move the servo to the angle=90-α/2 //first move from left to right. The initial angle is
//chosen to be in the interval, because the servo horn was approximately centered
set start_time=current_time) //time when the first move ordered
}
{If right switch=closed and position=left then //start moving from the right pos to the left
(set the moving_increment to -1;
attach the servo;
move the servo to the angle=90+α/2 //first move from right to left
set start_time=current_time) //time when the first move ordered
set start_time=current_time) //time when the first move ordered
}
{If right switch=open and left switch=open and moving_increment=0 then //servo at the start is in
//between its end positions for an uknown reason
{ If position=left then set the moving_increment to -1;
else set the moving_increment to +1
}
}
}
}
{If moving_increment<>0 then // servo is in between and moving
{If left switch=closed or right switch=closed then // position reached
(move the servo to the angle=angle + 2*sign(moving_increment); //a little pressure on the
//magnet
set the moving_increment to 0;
dettach the servo) else //keep moving
(set the angle=angle + moving_increment;
move the servo to the angle
{If current_time - start_time > max_travel_time then //servo can't reach the end pos
set malfunction_flag=1 //here can be called a mulfunction handler for the servo. It can turn on a red led or display the info or stop the train or ...
}
}{If current_time - start_time > max_travel_time then //servo can't reach the end pos
set malfunction_flag=1 //here can be called a mulfunction handler for the servo. It can turn on a red led or display the info or stop the train or ...
}
}
end
So, we can
So, we can
- lock a servo switch to its end positions using magnets and detach it from the power
- have a signal that shows the servo's position or malfunction
- setup a servo switch manually, but i believe it is better to find the 90 degree position with a controller
- handle a servo switch by setting only the angle range of move
The next step is to build a prototype and test it.😃
No comments:
Post a Comment