' {$STAMP BS2} ' {$PBASIC 2.5} ' Dump4everV3.bs2 as of 2009dec14 ' Written for an Education Board: 4 Servos are hard wired to pins 12-15 ' V1 started in 2009November ' V2 Changed Positioner code to try to get the push bar to place car OVER brake ' V3 Changed Pusher bar to a Coupler Grabber ' Controls four servos of an automated HO scale rotary dumper ' 1. Dumper motor is a Parallax Futaba limitless servo. ' It has a PULSOUT dead band (758..761 x2usec) 1515..1522. ' Values near the deadband control the speed that reachs a maximum ' of about 60RPM at PULSOUT values of about +/-40. 1 RevPerSecond. ' The travel limits are controlled with a single flapper switch ' flapped at 2 positions Reverse and StopatTop ' 2. Positioner motor is a Parallax Futaba limitless servo. ' It has a PULSOUT dead band (756 TO 760 x2usec) 1512 to 1520 . ' 'ditto' has 2 flapper switches :PositionerAtEnd and PositionerBack ' 3. Positioner Arm motor is a Parallax Futaba servo. ' It rides on the Positioner cart and raises - lowers its arm ' to be the positioner car coupler grabber ' 4. Brake is an old Futaba servo. ' It is under the track and raises its arm ' to hold the car in the correct position. ' The red green LEDs will be flashing when system is powered up ' and a reset cycle has been done. It will flash idiot lights ' when the system is waiting for a train 'After Initialization-Power on - the cars are placed in position ' Three Buttons on a Servo extension in a bashed Coalgon StartButton PIN 0 'white-yel wire 'Just in case EmergencyStopBtn PIN 1 'red wire 'Used when done to dump last car(s) pulled onto dumper by other loco RotateDumper1Btn PIN 2 'black wire 'Flapper switches for servo movement limits 'Positioner limits PositionerAtEnd PIN 3 'black wire Positioner Near Dumper 'A B hehehe - this will haunt me right ? PositionerBack PIN 4 'red wire Positioner at back '1 switch-sensor used to Reverse and Stop at Top Dumper DumperSensor PIN 5 ' white wire 'Photo diode light detector CheckLight PIN 6 'its own wire set 'not really coded - just flashing lights GreenLight PIN 7 'yel-white wire 'No error detection AFAIK so just for funsies RedLight PIN 8 'red wire , black of set is ground Siren PIN 9 'on board only- sounds at end of cycle 'IR detector for a hand held TV remote control IAW Three Buttons 'PIN 10 'o what to do with these, i just gotta use it all :) 'Additional Servo Positioner Retract servo- 'but not needed if the Positioner actually Works ... 'used to Stop the incoming train cars at correct location 'PIN 11 '4 Servos on Pins: 12 :Positioner, 13: Arm, 14 : Brake, 15 : Dumper dumperSpeed VAR Word dumperSpeed=20 'Set here to change all places easier dumperStop VAR Word dumperStop=760 'center of dead band positionerSpeed VAR Word positionerSpeed=20 'Set here to change all places easier positionerStop VAR Word positionerStop=758 'center of dead band brakeSet VAR Word brakeSet=570 '582 '583 'Brake holds the axle Tight 'THE PLOT 'A Unit train arrives and the Power de-couples from front ' and runs around dumper to wait for its train to be dumped. ' The train is Pushed to Positioner by Industry Power. 'The Positioner is near dumper, Arm and the Brake are Down. 'the Start Button is Pressed 'Position1Car: Push 1 car forward and Brake it, 'Check if more cars (Light detector) {it is needed here the first time...} 'then go into the lOOP 'lOOP: 'Push 1 car forward and Brake it, the car before is Now in dumper 'Rotate Dumper 'Check if more cars (Light detector ) 'Repeat LOOP until Detector Exits the Loop : no more cars 'Done: Retract brake and raise Positioner a LITTLE bit ' as it has GRABBED the Coupler ' Positioner Near Dumper and the Arm raised a LITTLE 'Thus at end 1 car on ready-track , 1 car On dumper : IS dumped 'Pull Last car through-onto Dumper from other end with Power locomotive. ' Then Dump Last car Using the 3rd Push button to activate Dumper 'global variables Byte : Value can be 0 to 255 counter VAR Word ' Value can be 0 to 65535 debugthis VAR Word carShadow VAR Word ' >1600 is a car <50 is no car , THIS is middle low carShadow=500 time VAR Word 'IF (time < CarShadow) THEN NoMoreCars=1 noMoreCars VAR Bit duration VAR Word 'for Sound frequency VAR Word 'ditto '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// 'THE PROGRAM '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// DEBUG "Program started",CR 'Print to computer screen DO 'Do a MAIN LOOP Responding to the 3 Buttons ... 'Initialize Something 'All pins are input at startup, PULSOUT takes care of Output by itself 'the photo resistor will be High 6 ONLY while running AFAIK 'Check Buttons at Start AND while Looping ... GOSUB Check_Buttons 'Flash some LEDs GreenLight PIN 8 , RedLight PIN 9 PULSOUT 8,50000 'red 'go check buttons rather than pause to 'seem' interactive GOSUB Check_Buttons 'PAUSE 100 PULSOUT 7,65000 '130msec ON Green LED GOSUB Check_Buttons 'PAUSE 200 '200msec OFF GOSUB Check_Buttons PULSOUT 8,50000 'red GOSUB Check_Buttons 'PAUSE 100 PULSOUT 7,65000 '130msec ON GOSUB Check_Buttons 'PAUSE 200 '200msec OFF GOSUB Check_Buttons PULSOUT 8,50000 'red GOSUB Check_Buttons 'PAUSE 100 PULSOUT 7,65000 '130msec ON Green LED GOSUB Check_Buttons 'PAUSE 200 '200msec OFF GOSUB Check_Buttons PULSOUT 8,50000 'red GOSUB Check_Buttons 'PAUSE 100 PULSOUT 7,65000 'four flashes ident this program version GOSUB Check_Buttons 'PAUSE 200 GOSUB Check_Buttons PULSOUT 8,50000 'red GOSUB Check_Buttons 'PAUSE 100 'MAIN LOOP ENDS here LOOP 'YES it will run Forever .. UNTIL Emergency STOP BUTTON is pressed END 'so this end is redundant and never used, wasting program space '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// 'The Program Ends '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// 'Check_Buttons: '///////////////////////////////////////////////////// Check_Buttons: FOR counter = 1 TO 50 'check a lot between the LEDs being ON 'Start and Run the Sequence .. StartDumpRun IF (StartButton=1) THEN GOSUB Start_Dump_Run 'Emergency Stop IF (EmergencyStopBtn=1) THEN END 'Dumper IF (RotateDumper1Btn=1) THEN GOSUB Rotate_Dumper NEXT 'IR TV control would be similar to 3 Buttons ... someday RETURN 'return from a Gosub '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// 'StartDumpRun Starts here '///////////////////////////////////////////////////// Start_Dump_Run : DEBUG "Positioner started",CR 'Put 1 car ahead of Loop GOSUB Position_1Car IF (emergencyStopBtn=1) THEN END 'Check Light detector GOSUB Traffic_Light IF (noMoreCars=1) THEN END 'Something is Really wrong-or just testing DEBUG "Lets dump this Unit Train!",CR DEBUG "till the Light is less than the Shadow",CR DO 'BE SURE TO Watch for the Emergency Stop Button! During the Sequence IF (emergencyStopBtn=1) THEN END DEBUG "Positioner started",CR GOSUB Position_1Car IF (emergencyStopBtn=1) THEN END 'Could maybe use a light detector at Edge of dumper to check for 'correct placement- but setting it up so no false reads seems Difficult- 'It would depend on where the light is from ' as the detector would be at edge of car. DEBUG "Rotating Dumper",CR GOSUB Rotate_Dumper IF (emergencyStopBtn=1) THEN END GOSUB Traffic_Light IF (noMoreCars=1) THEN EXIT 'See Light at end of tunnel LOOP DEBUG "All done! use Locomotive for positioning",CR DEBUG "Dumper Control with the Dumper button",CR 'Raise arm a LITTLE bit to release Coupler so Power can move the cars FOR counter= 932 TO 789 STEP 10 'gradual raise arm a LITTLE bit PULSOUT 13, counter 'hope they dont roll away... PAUSE 20 'o they cant-arm is on this side NEXT 'Power is at the Front of train again GOSUB Lower_Brake GOSUB Hyperspaced 'If i knew music i would play a tune RETURN 'or cared to play a cellphone ringtone '///////////////////////////////////////////////////// 'Start_Dump_Run ENDS here '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// 'Hyperspaced: notification of completion '///////////////////////////////////////////////////// Hyperspaced: PAUSE 100 FOR duration = 15 TO 1 'STEP 1 Step 1 is Normal? change FOR frequency = 2000 TO 2500 STEP 20 FREQOUT 9, duration, frequency NEXT NEXT FREQOUT 9, 2000, 2000, 2010 RETURN '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// 'Traffic_Light: '///////////////////////////////////////////////////// ' HIGH 6 is same as OUT6 = 1 and DIR6 = 1 ' Make the specified pin an output and high. ' The HIGH command sets the specified pin to 1 (a +5 volt level) ' and then sets its mode to output. ' LOW 6 OUT6 = 0 DIR6 = 1 ' The LOW command sets the specified pin to 0 (a 0 volt level) ' and then sets its mode to output. '///////////////////////////////////////////////////// Traffic_Light: HIGH 6 ' CheckLight PIN 6 PAUSE 100 'charge capacitor RCTIME 6, 1, time IF (time < carShadow) THEN noMoreCars=1 'DEBUG HOME, "time = ", DEC5 time," CarShadow = ",DEC5 CarShadow DEBUG "Light ", DEC5 time," < ",DEC5 carShadow, " Shadow?", CR 'carShadow = 500 '>1600 is a car <50 is no car 'Dark is big, Light is small time values LOW 6 ' i dunno if i should, 'but i dont want current charging all the time RETURN '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// 'Position_1Car '///////////////////////////////////////////////////// 'Brake should be Set, Arm Down 'Positioner Arm values ' 900 all UP, 1500 Car top, 1800 above coupler, 1830 grabs coupler ' 1840 ehh, 1850 ehehe, 1855 good little loose, 1860 ! little loose ' 1865 ok, 1870 tight, 1873 too Tight, 1880 Servo grumbling '932=1864 1864=932=466 '///////////////////////////////////////////////////// Position_1Car: 'Check-Set brake just in case, Raise Arm, Move Positioner to Back, PULSOUT 14, brakeSet PAUSE 20 'Raise arm SLOWLY ? to clear cars FOR counter= 932 TO 466 STEP 10 'gradual raise arm PULSOUT 13, counter PAUSE 20 NEXT PULSOUT 13, 466 '13: Arm 'dunno what step does to leftovers PAUSE 20 'DIR13=0 'remove pulse to insure stop IF (emergencyStopBtn=1) THEN END FOR counter = 1 TO 5 'Move it back past the switch PULSOUT 12, positionerStop-positionerSpeed PAUSE 20 NEXT debugthis=0 '12 :Positioner - is CW is Reverse DO debugthis=debugthis+1 PULSOUT 12, positionerStop-positionerSpeed PAUSE 20 LOOP WHILE (PositionerBack=0) 'away from dumper PULSOUT 12, positionerStop PAUSE 20 'DIR12=0 'remove pulse to insure stop DEBUG "Positioner Reverse: ", DEC debugthis, CR IF (EmergencyStopBtn=1) THEN END 'Lower Arm to Grab Coupler and push, Lower Brake so cars can move FOR Counter= 466 TO 888 STEP 5'10 'gradual Lower arm PULSOUT 13, Counter PAUSE 20 NEXT FOR Counter= 888 TO 932 'Very gradually Lower arm to Coupler bar PULSOUT 13, Counter PAUSE 20 NEXT PULSOUT 13, 932 '13: Arm PAUSE 20 ' DIR13=0 'remove pulse to insure stop IF (emergencyStopBtn=1) THEN END GOSUB Lower_Brake 'so cars can move forward IF (emergencyStopBtn=1) THEN END 'Move Positioner forward, Set Brake debugthis=0 '12 :Positioner + is CCW is Forward FOR counter = 1 TO 5 'Move it past the switch PULSOUT 12, positionerStop+positionerSpeed PAUSE 20 NEXT DO debugthis=debugthis+1 PULSOUT 12, positionerStop+positionerSpeed PAUSE 20 LOOP WHILE (PositionerAtEnd=0) 'PositionerAtEnd PULSOUT 12, positionerStop PAUSE 20 ' DIR12=0 'remove pulse to insure stop DEBUG "Positioner Forward: ", DEC debugthis, CR IF (EmergencyStopBtn=1) THEN END GOSUB Set_Brake RETURN '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// 'Set_Brake: '///////////////////////////////////////////////////// 'Brake ups and downs '1000 is Topped OUT : 500 : it hits the track above '1050 is just clear of Top Out : 525 '1130 '1161 it Lifts the wheels from the track 580 or 581 582 '1136 ...1140 is Good and Tight '1140 : 570 '1164 : brakeSet=582 '1145 '1166 BrakeSet is just before : 583 '1150 ...is caught but... '1200 is caught but way loose 600 '1500 is Below track : 750 normal centered '1800 is bottom out:900 '///////////////////////////////////////////////////// Set_Brake: 'debug "Set Brake" FOR Counter= 750 TO brakeSet STEP 4 '10 gradual brake-raise arm to axle PULSOUT 14, Counter '14 : Brake PAUSE 20 NEXT PULSOUT 14, brakeSet 'dunno what step does to leftovers PAUSE 20 ' DIR14=0 'remove pulse to insure stop 'debug "Brake Set" RETURN ' from Sub SetBrake: Lower_Brake: 'debug "Lower Brake" FOR counter=brakeSet TO 750 STEP 10 'gradual release -- going down PULSOUT 14, counter '14 : Brake PAUSE 20 NEXT PULSOUT 14, 750 PAUSE 20 ' DIR14=0 'remove pulse to insure stop 'debug "Brake Lowered" RETURN ' from Sub LowerBrake: '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// 'RotateDumper '///////////////////////////////////////////////////// 'Set Dumper to rotating (its Not a Position, it is the rotation Speed 'Check Switch-Sensor and Reverse when it is hit 'till it is hit again at top and Stopped Rotate_Dumper: '15 : Dumper DEBUG "Dumper started", CR debugthis=5 FOR counter = 1 TO 5 'Move it past the switch - then keep going PULSOUT 15, dumperStop+dumperSpeed ' + is CCW is Forward to Dump PAUSE 20 'DEBUG "Dumper ",DEC DumperSensor ,CR 'used during actual de-bugging once NEXT 'The servo IS turning till Switch hit DO 'DO:LOOP WHILE(?=0) is a trick debugthis=debugthis+1 PULSOUT 15, dumperStop+dumperSpeed ' + is CCW is Forward to Dump PAUSE 20 LOOP WHILE (DumperSensor=0) PULSOUT 15, dumperStop 'Stop turning, so it does not spit gears reversing PAUSE 20 IF (emergencyStopBtn=1) THEN END DEBUG "Dumper Upsidedown: ", DEC debugthis, CR DEBUG "Dumper returning", CR debugthis=5 FOR counter = 1 TO 5 'Move it past the switch PULSOUT 15, dumperStop-dumperSpeed ' - is CW is Reverse to TOP PAUSE 20 NEXT 'The servo IS turning till Switch hit DO debugthis=debugthis+1 PULSOUT 15, dumperStop-dumperSpeed ' - is CW is Reverse to TOP PAUSE 20 LOOP WHILE (DumperSensor=0) PULSOUT 15, dumperStop 'Stop turning, we are at top again PAUSE 20 ' DIR15=0 'remove pulse to insure stop IF (emergencyStopBtn=1) THEN END DEBUG "Dumper Topside: ", DEC debugthis, CR 'to count turnaround loops DEBUG "Dumper Done", CR 'totally useless but interesting RETURN '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// '///////////////////////////////////////////////////// 'NO MORE CODE :) '///////////////////////////////////////////////////// END 'just in double case, yes some more wasted code space :)