Turnout control by servo - my experiences

Do you have a problem? Here is the place to appeal for help
User avatar
gregh
Trainee Driver
Trainee Driver
Posts: 566
Joined: Sun Apr 01, 2018 5:44 am
Location: Sydney, Australia
Contact:

Re: Turnout control by servo - my experiences

Post by gregh » Tue May 08, 2018 10:54 am

tom_tom_go wrote: Tue May 08, 2018 7:28 am Thanks Rik/Greg.
Can I have the code for one signal please as I am not familiar with Picaxe (I think that's another reason I prefer Ardunio as it uses C/C++ functions which I understand being an IT bod for my sins).
Picaxe uses a modified Basic. It's maths capability is very limited.
Hope you can follow some of this code. It's 4 years since I wrote it, so it's not real obvious to me!
I obtained the initial 'bounce' equations from a frame by frame analysis of the 'real signal' clips shown in the 1st video. I finally figured the obvious that going to Stop was const acceleration under gravity and going to clear was constant speed of a signal wire being pulled. I started with a const speed for both and it was quite amazing how it looked 'wrong'.

Then I just had to translate them to servo 'counts'. SERVO is a command that just needs the width of the servo pulse in 10 us units to set the servo in a given position and it runs in the background once started - used in the init: routine. But when I'm changing position, I use the PULSOUT command which also just needs the pulse width in 10us units, but has to be refreshed every 20ms or so. I use it where the servo is moving/bouncing.
Note that it's for a servo arm that goes clockwise to Stop. If the servo is the 'other way around', it needs a rewrite!

Code: Select all

'semaphore signal driven by servo with bounce
'bouncesemaphore v1.bas				2/6/14

' ( based on  testbounce signal4.bas         2/6/14)

'assumes a constant acceleration going to STOP,  
'constant speed going to clear (down)
'maybe in future can control 2 signals ??? but will not have 2nd servo command,
'so will need to refresh it all the time

'raising bounce equations are:
'for initial rise: R=160t*t-50 degs	for  t<0.56s
'1st bounce down and up:  R=87(t-1.04)^2-20 degs  for 0.56<t<1.52s
'2nd bounce down and up:  R=68(t-1.84)^2-7 degs	  for  1.52<t<2.16


'this is for Clockwise rotation direction to raise arm to STOP
'pin0=
'pin1=an input for sig1	'1=stop, 0=clear
'pin2 is servo output
'pin3=another input for sig1 if used

'constants for raising
symbol lowered=170 	'10us counts  NB coincidence of equation coeff of t squared!!!
symbol raised=110		'counts

symbol initcoeff=160	'coeff of t squared in equation for counts =50/0.56^2
symbol bounce1coeff=87
symbol mincounts1=132	'min counts of first bounce  (raised+22)
symbol bounce2coeff=68
symbol mincounts2=118	'min counts of 2nd bounce  (raised+8)

'constants for lowering:
symbol bouncelow=	176		'counts for 72deg
symbol bouncelowup=158		'counts for 40deg

'variables:
symbol sig1state=b0	'0=clear(down), 1=stop (up)
symbol t=w1		'time in ms
symbol t1=w2	'intermediate value in eqns
symbol S=b6		'location of servo in 10us counts
symbol k=b7		'loop counter
'--------------------------------------

init:
	S=raised
	if pin1=0 then 
	servo 2,lowered
	sig1state=0
	else
	servo 2, raised
	sig1state=1
	endif

starter:
	if pin1=1 and sig1state=0 then 'need to go to stop
	goto raiseit		
	elseif pin1=0 and sig1state=1 then
	goto lowerit
	endif
	pause 100

	goto starter

raiseit:
'for initial rise: R=initcoefft*t-initdegs  in degs  with t in sec
'so R=initcoeff/1000000 *t*t-initdegs degs  for t in ms
'to convert to counts,   
'	R=initcoef/1000000*t*t-lowered

	servo 2,off
	if S<raised then firstbounce	
	t=t+25	'add 25 ms   but pause later is less than this to make it go faster
	S=t/10*initcoeff/100*t/1000
	S=lowered-S
	pulsout 2,S
	pause 17
	goto raiseit

firstbounce:
'S=-bounce1coeff x (t-1.04)^2 + mincounts1

	S=raised
FB2:

	if S<raised then secondbounce
	t=t+25
	if t<1050 then
	t1=1050-t
	else
	t1=t-1050
	endif

	t1=t1/5*t1/100			'square it
	t1=t1*bounce1coeff/2000		'intermediate num
	S=mincounts1-t1
	pulsout 2,S
	pause 16
	goto FB2	'firstbounce

	

secondbounce:
'S=-bounce2coeff x (t-1.84)^2 + mincounts2

	if t>2140 then finished
	t=t+25
	if t<1850 then
	t1=1850-t
	else
	t1=t-1850
	endif

	t1=t1/4*t1/50		'square it
	t1=t1*bounce2coeff/5000
	S=mincounts2-t1
	pulsout 2,S
	pause 15
	goto secondbounce	


finished:
	t=0
	servo 2, raised
	sig1state=1
	goto starter
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'lowering linearly

'takes  580ms to go from horiz to -55  deg, bounces up to -40  deg in 380ms
'then drops to -50 deg in 380ms, and stops there. total 1340ms

'these just a copy of actual declarations at top, for ease of reference....
'symbol bouncelow=176		'counts for 55deg
'symbol bouncelowup=158		'counts for 40deg
'symbol lowered=170		'counts for 50deg
'symbpl raised=110		'counts for horizontal  0 deg

lowerit:			
	servo 2,off	
	for k=raised to bouncelow step 3	'66/3 counts in 580ms gives 26 ms/count
	pulsout 2,k
	pause 20
	next k

	'pause 100

	for k=bouncelow to bouncelowup step-1 	'18 counts in 380ms gives 21 ms/count
	pulsout 2,k
	pause 18
	next k
	'pause 100

	for k= bouncelowup to lowered		'12 counts in 380ms gives 31ms/count
	pulsout 2,k
	pause 27
	next k

	servo 2,lowered
	sig1state=0		'is now lowered
	goto starter	
Greg from downunder.
The Sandstone & Termite's website: https://members.optusnet.com.au/satr/satr.htm

metalmuncher
Cleaner
Cleaner
Posts: 95
Joined: Sat Oct 20, 2012 4:15 pm

Re: Turnout control by servo - my experiences

Post by metalmuncher » Tue May 08, 2018 2:31 pm

I've had a bit of a play with using an Arduino to make a servo bounce.



The code is just hacked together to make something that works - could do with many improvements. Floating point makes it slower than it needs to be, and as written the code only works in one direction. As it is now the position never really settles, but the fractional part gets truncated on the servo write I think, so it doesn't make much difference.

It does take use deltatime so if you end up doing occasional heavy computations in the loop the movement timings won't be affected too much. With most servos needing a 50Hz update rate, you've got about 320,000 instructions to play with in between, probably enough for some pretty complicated physics simulation if one was so inclined.

Code: Select all

/* Bouncy Servo Signal Prototype

*/

#define SERVO_PIN 9 // pin the servo is connected to
#define SW_PIN 3    // pin to be used as a switch

#define POS_LOW 45.0   // servo position for 'low' - falls with accel/bounce
#define POS_HIGH 135.0 // servo positionf for 'high' - slow rise to this pos

#define RISE_SPEED 0.05   //deg/ms? - constant rise from low to high pos
#define FALL_ACCEL -0.001 //deg/ms2? - constant accel from high to low pos

#define BOUNCEFACTOR 0.5 // factor for velocity retained on each bounce

double velo = 0.0;     // current velocity
double pos  = POS_LOW; // current position

unsigned long loopTimer = 0; // how long it took to complete the loop
unsigned int  dtMs      = 0; // how long the last loop took

#include <Servo.h>

Servo servo;

void setup() {
    servo.attach( SERVO_PIN );
    pinMode( SW_PIN, INPUT_PULLUP );
}

void loop() {
    loopTimer = millis();

    if ( digitalRead( SW_PIN ) ) { // simple test of the switch input to determine required state
        if ( pos < POS_HIGH ) {    // should be rising
            velo = RISE_SPEED;
        } else {
            velo = 0; // already at top position
        }
    } else {
        if ( pos < POS_LOW + 1 ) { // if its hit the bottom stop
            velo *= -BOUNCEFACTOR; // bounce
        }
        velo += FALL_ACCEL * dtMs; //accel affects velocity
    }

    pos += velo * dtMs;                        //velocity affects position
    pos = constrain( pos, POS_LOW, POS_HIGH ); //just make sure the position doesnt go outside bounds
    servo.write( pos );

    delay( 20 );                 // no point in faster than about 50hz
    dtMs = millis() - loopTimer; // save dt for next frame
}

User avatar
gregh
Trainee Driver
Trainee Driver
Posts: 566
Joined: Sun Apr 01, 2018 5:44 am
Location: Sydney, Australia
Contact:

Re: Turnout control by servo - my experiences

Post by gregh » Sat May 12, 2018 1:09 am

metalmuncher wrote: Tue May 08, 2018 2:31 pm I've had a bit of a play with using an Arduino to make a servo bounce.
Nice to see someone else motivated. Nicely done. But that's two for Arduino and one (me) for picaxe. Though Rik is using Picaxe too.
Arduino seems to be taking over - there are shelves and shelves of stuff for it in my local electronics shop. BUt seems over the top for my needs. And I've always used Basic language, so Picaxe had a head start.

For anyone interested in learning more about Picaxe, I've written some Tutorials on how to control motors, servos, and make diesel and steam sounds.
see here...
http://www.trainweb.org/SaTR/Picaxe%20tutes.htm
Greg from downunder.
The Sandstone & Termite's website: https://members.optusnet.com.au/satr/satr.htm

User avatar
philipy
Moderator
Moderator
Posts: 5033
Joined: Sun Jan 30, 2011 3:00 pm
Location: South Northants

Re: Turnout control by servo - my experiences

Post by philipy » Sat May 12, 2018 7:04 am

gregh wrote: Sat May 12, 2018 1:09 am
Nice to see someone else motivated. Nicely done. But that's two for Arduino and one (me) for picaxe. Though Rik is using Picaxe too.
Arduino seems to be taking over - there are shelves and shelves of stuff for it in my local electronics shop. BUt seems over the top for my needs. And I've always used Basic language, so Picaxe had a head start.

For anyone interested in learning more about Picaxe, I've written some Tutorials on how to control motors, servos, and make diesel and steam sounds.
see here...
If you include Rik in the Picaxe group ( and why not?), you can make that 2&1/2 for Picaxe! I've looked at both Arduino and Picaxe in the past but never had an incentive to get my head around either. However, your threads and tutorials, plus Rik's blogs, and the Picaxe manuals, between them have, I think, allowed me to cobble together a fairly simple program! I'm away atm so won't know for sure if it works for another couple of weeks or so, though.
Philip

User avatar
tom_tom_go
Driver
Driver
Posts: 4824
Joined: Wed Feb 23, 2011 3:08 am
Location: Kent, UK
Contact:

Re: Turnout control by servo - my experiences

Post by tom_tom_go » Sat May 12, 2018 8:07 am

Keep us informed Phil!

User avatar
philipy
Moderator
Moderator
Posts: 5033
Joined: Sun Jan 30, 2011 3:00 pm
Location: South Northants

Re: Turnout control by servo - my experiences

Post by philipy » Fri May 25, 2018 11:39 am

tom_tom_go wrote: Sat May 12, 2018 8:07 am Keep us informed Phil!
After quite a few hours of playing around, I confess myself stumped!
However to avoid messing up Greg's thread I'll start one of my own on "Help" and if anyone can, I'll be grateful.
Philip

Post Reply

Who is online

Users browsing this forum: No registered users and 3 guests