User Tools

Site Tools


traincontrol

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
traincontrol [2021/10/12 15:56]
dpisuperadmin [Next Steps]
traincontrol [2021/10/15 02:47] (current)
dpisuperadmin [Hardware and Wiring]
Line 12: Line 12:
 open-drain driver. open-drain driver.
  
-{{ wiki:traintrack.jpg?480}}This page is organized as follows:+{{ wiki:traintrack.jpg?480| Train Table}}This page is organized as follows:
   * Hardware and Wiring   * Hardware and Wiring
   * Peripherals   * Peripherals
   * Software   * Software
 +    * Linux
 +    * Python
   * Next Steps   * Next Steps
     * DC filter     * DC filter
Line 23: Line 25:
 {{ trans1.v3.gif?480 }} {{ trans1.v3.gif?480 }}
 ==== Hardware and Wiring ==== ==== Hardware and Wiring ====
-{{ wiki:trainui.jpg?480}}+{{ wiki:trainui.jpg?480| Track and Speed Controls}}
  
 User interface hardware consists of a quad slide switch card and a quad slide potentiometer card.  The leftmost two switches control the track switches.  An on switch puts the track switch into the upward, or inner loop, position.  The rightmost slide switch controls the engine direction with up being the forward direction.  The rightmost slide pot controls the engine speed with up being as fast as possible.  Even with a PWM frequency of 50 Hertz the slide pot must be almost 30 percent up before the engine moves.  The direction slide switch is ignored unless the speed of the engine is set to zero. User interface hardware consists of a quad slide switch card and a quad slide potentiometer card.  The leftmost two switches control the track switches.  An on switch puts the track switch into the upward, or inner loop, position.  The rightmost slide switch controls the engine direction with up being the forward direction.  The rightmost slide pot controls the engine speed with up being as fast as possible.  Even with a PWM frequency of 50 Hertz the slide pot must be almost 30 percent up before the engine moves.  The direction slide switch is ignored unless the speed of the engine is set to zero.
  
-{{ wiki:trainelectronics.jpg?480}}+{{ wiki:trainelectronics.jpg?480| H-Bridge and Open-drain driver}}
  
 Engine and track switch control use a dual H-bridge card and a quad open-drain driver card.  The dual DC motor controller peripheral (DC2) and the dual H-bridge card (D7HB) can easily control the engine speed and direction.  We set the PWM frequency to 50 Hertz to give better low speed control of the engine.  A better solution to low speed control might be the LC filter described in the Next-Steps section below. Engine and track switch control use a dual H-bridge card and a quad open-drain driver card.  The dual DC motor controller peripheral (DC2) and the dual H-bridge card (D7HB) can easily control the engine speed and direction.  We set the PWM frequency to 50 Hertz to give better low speed control of the engine.  A better solution to low speed control might be the LC filter described in the Next-Steps section below.
  
-The track switches are left and right hand three-wire switches from Atlas.  These switches have a common wire and two coil wires.  Energizing a coil causes the switch to change position.  These coils must be energized only long enough to switch.  They will overhead and be damaged if the coils remain energized for an extended time.  Switching only takes 100 ms or so. Since we are using using open-drain drivers we have to tie the common line to a positive voltage.+The track switches are left and right hand three-wire switches from Atlas.  These switches have a common wire and two coil wires.  Energizing a coil causes the switch to change position.  These coils must be energized only long enough to switch.  They will overheat and be damaged if the coils remain energized for an extended time.  Switching only takes 50 ms or so. Since we are using open-drain drivers we have to tie the common line to a positive voltage.
  
 One problem with our chosen hardware is that at power up the open-drain driver outputs are at ground.  This is a problem since the switch coils could overheat if the system does not come up fast enough.  Recall that one of our goals was to build this system quickly and we did not want to add more hardware to the system.  We found a simple solution using the available hardware. The engine control only uses one H-bridge, and the power up state of the H-bridge is ground.  Since the H-bridge can handle seven amps we connected the common (positive voltage) of the track switches to one output of the second H-bridge.  We turn the H-bridge on after system boot and so do not risk overheating the switch coils. One problem with our chosen hardware is that at power up the open-drain driver outputs are at ground.  This is a problem since the switch coils could overheat if the system does not come up fast enough.  Recall that one of our goals was to build this system quickly and we did not want to add more hardware to the system.  We found a simple solution using the available hardware. The engine control only uses one H-bridge, and the power up state of the H-bridge is ground.  Since the H-bridge can handle seven amps we connected the common (positive voltage) of the track switches to one output of the second H-bridge.  We turn the H-bridge on after system boot and so do not risk overheating the switch coils.
Line 41: Line 43:
 A wireviz generated wiring diagram for the system is shown below.   A wireviz generated wiring diagram for the system is shown below.  
 {{ wiki:trainwiring.png }} {{ wiki:trainwiring.png }}
 +/*  Wiringviz source file for the above
 +connectors:
 +  Switch-Left:
 +    type: Soldered wires
 +    pinlabels: [Coil-Left, Common, Coil-Straight]
 +    show_name: false
 +    notes: Track Switch Left
 +  Switch-Right:
 +    type: Soldered wires
 +    pinlabels: [Coil-Right, Common, Coil-Straight]
 +    show_name: false
 +    notes: Track Switch Right
 +  DC-IN:
 +    type: Barrel
 +    subtype: female
 +    pinlabels: [V+, GND]
 +    show_name: false
 +    notes: Power Adapter
 +  SMR-5:
 +    type: screw terminal
 +    pinlabels: [V+, GND, V5.0, GND]
 +    show_name: false
 +    notes: SMR-5 regulator
 +  DRV4:
 +    type: screw terminal
 +    pinlabels: [V+, GND, O1, O2, O3, O4]
 +    show_name: false
 +    notes: DRV4 Open-Drain Driver
 +  D7HB:
 +    type: screw terminal
 +    pinlabels: [V+, GND, A1, A2, B1, B2]
 +    show_name: false
 +    notes: D7HB H-bridge
 +  SBC:
 +    type: Soldered wires
 +    pinlabels: [V5.0, GND]
 +    show_name: false
 +    notes: Single Board Computer
 +  Track:
 +    type: screw terminal
 +    pinlabels: [Rail-1, Rail-2]
 +    show_name: false
 +    notes: Track
 +
 +cables:
 +  W1:
 +    colors: [RD,BK]
 +  W2:
 +    colors: [RD,BK]
 +  W3:
 +    colors: [RD,WH]
 +  W4:
 +    colors: [RD,WH]
 +  W5:
 +    colors: [GN,YE,RD]
 +  W6:
 +    colors: [GN,YE,RD]
 +  W7:
 +    colors: [RD,WH]
 +
 +connections:
 +  -
 +    - DRV4:  [4,1,3]
 +    - W5:    [1,2,3]
 +    - Switch-Left: [1,2,3]
 +  -
 +    - DRV4:  [5,1,6]
 +    - W6:    [1,2,3]
 +    - Switch-Right: [1,2,3]
 +  -
 +    - DRV4:  [1,2]
 +    - W7:    [1,2]
 +    - D7HB:  [5,2]
 +  -
 +    - DC-IN: [1-2]
 +    - W1:    [1-2]
 +    - SMR-5: [1-2]
 +  -
 +    - D7HB:  [1-2]
 +    - W2:    [1-2]
 +    - SMR-5: [1-2]
 +  -
 +    - SMR-5: [3,4]
 +    - W3:    [1-2]
 +    - SBC:   [1-2]
 +  -
 +    - D7HB:  [3,4]
 +    - W4:    [1,2]
 +    - Track: [1,2]
 +*/
  
 ==== Peripherals ==== ==== Peripherals ====
-The four daughter cards in the system are the D7HB dual H-bridge, the DRV4 quad open-drain driver, the SW4 quad slide switch, and the SLIDE4 quad slide pot.  The Linux (and FPGA) drivers for these are the DC2 dual DC motor controller, the OUT4 quad binary output, the IN4 quad binary input, and the SLIDE4 quad slide pot input.+The four  //cards// in the system are the D7HB dual H-bridge, the DRV4 quad open-drain driver, the SW4 quad slide switch, and the SLIDE4 quad slide pot.  The Linux (and FPGA) //peripherals// for these are the DC2 dual DC motor controller, the OUT4 quad binary output, the IN4 quad binary input, and the SLIDE4 quad slide pot input.
  
-We used the Demand Peripherals support page "Build your FPGA Image" to request the four peripherals we needed.  Unused peripheral slots were set to GPIO4.  Our FPGA image has the following slot assignments:+We used the Demand Peripherals support page "Build your FPGA Image"  
 +([[http://demandperipherals.com/support/build_fpga.html|Link]]) 
 +to request the four peripherals we needed.  Unused peripheral slots were set to GPIO4.  Our FPGA image has the following slot assignments:
  
 |  Slot |  Name |  Description | |  Slot |  Name |  Description |
Line 69: Line 163:
 \\ \\
 <tab10> dpset out4 outval f \\ <tab10> dpset out4 outval f \\
 +Test one switch with the commands: \\
 +<tab10> dpset out4 outval e ; sleep 0.05 ;dpset out4 outval f \\
  
 Once the program starts we can read the state of the switches and the position of the slide pots using dpget commands. Once the program starts we can read the state of the switches and the position of the slide pots using dpget commands.
Line 91: Line 187:
 \\ \\
 <tab10> /usr/local/bin/dpdaemon -l /root/DPCore.bin \\ <tab10> /usr/local/bin/dpdaemon -l /root/DPCore.bin \\
 +<tab10> screen -dm -S traincontrol /usr/bin/python3 /root/traincontrol.py \\
 === Python === === Python ===
  
Line 99: Line 195:
  
 At program start time we want to force the speed of the engine to be zero until the slide pot is actually set to zero, at which time the pot can start to control the engine speed. At program start time we want to force the speed of the engine to be zero until the slide pot is actually set to zero, at which time the pot can start to control the engine speed.
 +
 +<code>
 +#!/usr/bin/env python
 +import socket
 +import sys
 +import time
 +
 +# The purpose of this program is to control the speed
 +# and direction of model railroad.  The underlying 
 +# hardware is a Demand Peripherals Baseboard4 FPGA card
 +# along with a quad slide switch card, a quad slide pot,
 +# and dual H-bridge.
 +#   FPGA based peripherals control this hardware through
 +# a daemon supplied by Demand Peripherals.  The Linux
 +# visible peripherals are a in4 peripheral in slot 2,
 +# a slide4 peripheral in slot 3, and a dc2 peripheral 
 +# in slot 4.  Please see their respective pages at :
 +# http://demandperipherals.com/peripherals.html
 +#
 +# This program opens one socket to dpserver for commands
 +# to the FPGA card.  Normally there is one socket per
 +# sensor and one for commands.  In this simple program
 +# we use polling to read the slide pot and direction
 +# switch.
 +#
 +# Switch 0x1 sets the direction. Slide pot 1 sets the
 +# speed.  As a safety measure, the direction can not
 +# be set unless the speed is set to zero.
 +
 +def send_cmd(socket , str ) :
 +    "Send Command to FPGA deamon"
 +    socket.send(str)
 +    response = ''
 +    while True :
 +        c = sock_cmd.recv(1).decode()  # for the four \\ character responses
 +        if c =='\\' :
 +            break
 +        response += c
 +    if ((len(response) > 0) and (response[0] == 'E')) :
 +        # Error if first character of response is an E
 +        print("Command : ", str)
 +        print("Response : ", response)
 +    #print("Command : ", str)
 +    #print("Response : ", response)
 +    return response
 +
 +try:
 +    sock_cmd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 +    sock_cmd.connect(('localhost', 8870))
 +    
 +    # Init H-bridge PWM frequency to 50 Hz and mode to brake.
 +    # Set the H-bridge watchdog timer to 300 ms.
 +    response = send_cmd(sock_cmd, b'dpset dc2 mode0 b \n') # brake is only at init time
 +    response = send_cmd(sock_cmd, b'dpset dc2 power0 0 \n')
 +    response = send_cmd(sock_cmd, b'dpset dc2 pwm_frequency 50 \n')
 +    response = send_cmd(sock_cmd, b'dpset dc2 watchdog 400 \n')
 +    # init track swith states to unknown
 +    switch_left = "u"
 +    switch_right = "u"
 +
 +    # loop forever getting speed and direction
 +    while True:
 +        # Get speed and switch settings
 +        positions = send_cmd(sock_cmd, b'dpget slide4 positions\n')
 +        position1 = int(positions[:4])
 +        speed = int(100 * (1024 - position1) / 1024)
 +        switches = send_cmd(sock_cmd, b'dpget in4 inputs\n')
 +
 +        # Set track switches if controlling slide switches changed
 +        if (int(switches[0],16) & 8 == 8) and (switch_left != "l") :
 +            switch_left = "l"
 +            response = send_cmd(sock_cmd, b'dpset out4 outval d \n')
 +            time.sleep(0.05)
 +            response = send_cmd(sock_cmd, b'dpset out4 outval f \n')
 +        elif (int(switches[0],16) & 8 == 0) and (switch_left != "s") :
 +            switch_left = "s"
 +            response = send_cmd(sock_cmd, b'dpset out4 outval e \n')
 +            time.sleep(0.05)
 +            response = send_cmd(sock_cmd, b'dpset out4 outval f \n')
 +        if (int(switches[0],16) & 4 == 4) and (switch_right != "r") :
 +            switch_right = "r"
 +            response = send_cmd(sock_cmd, b'dpset out4 outval b \n')
 +            time.sleep(0.05)
 +            response = send_cmd(sock_cmd, b'dpset out4 outval f \n')
 +        elif (int(switches[0],16) & 4 == 0) and (switch_right != "s") :
 +            switch_right = "s"
 +            response = send_cmd(sock_cmd, b'dpset out4 outval 7 \n')
 +            time.sleep(0.05)
 +            response = send_cmd(sock_cmd, b'dpset out4 outval f \n')
 +        #print("switches : ", switch_left, switch_right)
 +
 +        # Set engine direction if speed is zero
 +        if speed == 0:
 +            if int(switches[0],16) & 1 == 1 :
 +                response = send_cmd(sock_cmd, b'dpset dc2 mode0 f \n')
 +            else :
 +                response = send_cmd(sock_cmd, b'dpset dc2 mode0 r \n')
 +        # Always set engine speed to keep watchdog alive
 +        response = send_cmd(sock_cmd, b'dpset dc2 power0 ' b"%d" b'\n' % speed)
 +        time.sleep(0.05)
 +        #print("speed : ", speed)
 +
 +except KeyboardInterrupt:
 +    # exit on Ctrl^C
 +    sock_cmd.close()
 +    sys.exit()
 +
 +except socket.error:
 +    print("Couldn't connect to dpdaemon")
 +    sys.exit()
 +
 +</code>
  
  
Line 112: Line 320:
  
 === DCC === === DCC ===
-Model train Digital Command and Control (DCC) is well explained at the DCC Wikipedia article: \\ +Model train Digital Command and Control (DCC) is well explained at the DCC Wikipedia article: 
-<tab10> https://en.wikipedia.org/wiki/Digital_Command_Control \\+https://en.wikipedia.org/wiki/Digital_Command_Control
 The system described in the this article is well positioned to move to DCC.  Right now there are two peripherals that use the D7HB dual H-bridge, the DC2 dual DC motor controller, and the STEPB bipolar stepper motor controller.  With a little Verilog it should be relatively easy to add a third peripheral that uses the D7HB.  Let's call it DCC2 for a dual DCC interface.  One advantage of an FPGA in this situation is that you can go from older DC control to DCC with just a software change -- you do not need to change any wiring to make the track DCC controlled. The system described in the this article is well positioned to move to DCC.  Right now there are two peripherals that use the D7HB dual H-bridge, the DC2 dual DC motor controller, and the STEPB bipolar stepper motor controller.  With a little Verilog it should be relatively easy to add a third peripheral that uses the D7HB.  Let's call it DCC2 for a dual DCC interface.  One advantage of an FPGA in this situation is that you can go from older DC control to DCC with just a software change -- you do not need to change any wiring to make the track DCC controlled.
  
 === Low Cost Track Switch Control === === Low Cost Track Switch Control ===
 {{ http://www.tophobbytrains.com/images/products/display/TOR6012.gif?150}} {{ http://www.tophobbytrains.com/images/products/display/TOR6012.gif?150}}
-Larger layouts tend to use servo motors mounted under the train table to control track switches.  The Tortoise Slow Motion Switch Machine is a popular example.  This picture from tophobbytrains.com shows how the servo movement switches the track.  The servo operates with two 12 volt wires in a type of H-bridge arrangement.  With the two wire at (+12, 0) the switch is in one position and with the wires at (0, 12) it is in the other position.  At stall the current is only 15 or so milliamps so something like the D7BH would be overkill for such low currents. +Larger layouts tend to use servo motors mounted under the train table to control track switches.  The Tortoise Slow Motion Switch Machine is a popular example.  This picture from tophobbytrains 
-We are considering how to solve this problem now.  Please let us know if you have any ideas for a low cost, low current H-bridge.+([[http://www.tophobbytrains.com|Link]]) 
 + shows how the servo movement switches the track.  The servo operates with two 12 volt wires in a type of H-bridge arrangement.  With the two wire at (+12, 0) the switch is in one position and with the wires at (0, +12) it is in the other position.  The stall current is only 15 or so milliamps.  The D7BH and DC2 could control two switches but might be overkill for such low currents.  We are considering how to solve this problem now.  Please let us know if you have any ideas for a low cost, low current H-bridge.
  
  
traincontrol.1634054217.txt.gz · Last modified: 2021/10/12 15:56 by dpisuperadmin