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/13 21:47]
dpisuperadmin [Software]
traincontrol [2021/10/15 02:47] (current)
dpisuperadmin [Hardware and Wiring]
Line 33: Line 33:
 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 overheat and be damaged if the coils remain energized for an extended time.  Switching only takes 100 ms or so. Since we are 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 43: 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"  We used the Demand Peripherals support page "Build your FPGA Image" 
Line 74: Line 164:
 <tab10> dpset out4 outval f \\ <tab10> dpset out4 outval f \\
 Test one switch with the commands: \\ Test one switch with the commands: \\
-<tab10> dpset out4 outval e ; sleep 0.;dpset out4 outval f \\+<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 134: Line 224:
 # be set unless the speed is set to zero. # 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: try:
     sock_cmd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)     sock_cmd = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     sock_cmd.connect(('localhost', 8870))     sock_cmd.connect(('localhost', 8870))
 +    
     # Init H-bridge PWM frequency to 50 Hz and mode to brake.     # Init H-bridge PWM frequency to 50 Hz and mode to brake.
     # Set the H-bridge watchdog timer to 300 ms.     # Set the H-bridge watchdog timer to 300 ms.
-    sock_cmd.send(b'dpset dc2 mode0 b \n') # brake is only at init time +    response = send_cmd(sock_cmd, b'dpset dc2 mode0 b \n') # brake is only at init time 
-    sock_cmd.send(b'dpset dc2 power0 0 \n') +    response = send_cmd(sock_cmdb'dpset dc2 power0 0 \n') 
-    sock_cmd.send(b'dpset dc2 pwm_frequency 50 \n') +    response = send_cmd(sock_cmdb'dpset dc2 pwm_frequency 50 \n') 
-    sock_cmd.send(b'dpset dc2 watchdog 300 \n') +    response = send_cmd(sock_cmd, b'dpset dc2 watchdog 400 \n')
-    time.sleep(0.05) +
-    results = sock_cmd.recv(1024)  # for the four \\ character responses+
     # init track swith states to unknown     # init track swith states to unknown
     switch_left = "u"     switch_left = "u"
Line 154: Line 258:
     while True:     while True:
         # Get speed and switch settings         # Get speed and switch settings
-        sock_cmd.send(b'dpget slide4 positions\n'+        positions = send_cmd(sock_cmdb'dpget slide4 positions\n'
-        time.sleep(0.05) +        position1 = int(positions[:4])
-        positions = sock_cmd.recv(1024)  +
-        #print("got : ", positions.decode()+
-        position1 = int(positions.decode()[:4])+
         speed = int(100 * (1024 - position1) / 1024)         speed = int(100 * (1024 - position1) / 1024)
-        sock_cmd.send(b'dpget in4 inputs\n'+        switches = send_cmd(sock_cmdb'dpget in4 inputs\n')
-        time.sleep(0.05) +
-        switches = sock_cmd.recv(1024)  +
-        #print("sw4 : ", int(switches.decode()[0],16))+
  
         # Set track switches if controlling slide switches changed         # Set track switches if controlling slide switches changed
-        if (int(switches.decode()[0],16) & 8 == 8) and (switch_left != "l") :+        if (int(switches[0],16) & 8 == 8) and (switch_left != "l") :
             switch_left = "l"             switch_left = "l"
-            sock_cmd.send(b'dpset out4 outval d \n')+            response = send_cmd(sock_cmd, b'dpset out4 outval d \n')
             time.sleep(0.05)             time.sleep(0.05)
-            sock_cmd.send(b'dpset out4 outval f \n'+            response = send_cmd(sock_cmdb'dpset out4 outval f \n') 
-            time.sleep(0.05) +        elif (int(switches[0],16) & 8 == 0) and (switch_left != "s") :
-            results = sock_cmd.recv(1024+
-        elif (int(switches.decode()[0],16) & 8 == 0) and (switch_left != "s") :+
             switch_left = "s"             switch_left = "s"
-            sock_cmd.send(b'dpset out4 outval e \n')+            response = send_cmd(sock_cmd, b'dpset out4 outval e \n')
             time.sleep(0.05)             time.sleep(0.05)
-            sock_cmd.send(b'dpset out4 outval f \n'+            response = send_cmd(sock_cmdb'dpset out4 outval f \n') 
-            time.sleep(0.05) +        if (int(switches[0],16) & 4 == 4) and (switch_right != "r") :
-            results = sock_cmd.recv(1024+
-        if (int(switches.decode()[0],16) & 4 == 4) and (switch_right != "r") :+
             switch_right = "r"             switch_right = "r"
-            sock_cmd.send(b'dpset out4 outval b \n')+            response = send_cmd(sock_cmd, b'dpset out4 outval b \n')
             time.sleep(0.05)             time.sleep(0.05)
-            sock_cmd.send(b'dpset out4 outval f \n'+            response = send_cmd(sock_cmdb'dpset out4 outval f \n') 
-            time.sleep(0.05) +        elif (int(switches[0],16) & 4 == 0) and (switch_right != "s") :
-            results = sock_cmd.recv(1024+
-        elif (int(switches.decode()[0],16) & 4 == 0) and (switch_right != "s") :+
             switch_right = "s"             switch_right = "s"
-            sock_cmd.send(b'dpset out4 outval 7 \n') +            response = send_cmd(sock_cmdb'dpset out4 outval 7 \n')
-            time.sleep(0.05) +
-            sock_cmd.send(b'dpset out4 outval f \n')+
             time.sleep(0.05)             time.sleep(0.05)
-            results sock_cmd.recv(1024)+            response send_cmd(sock_cmd, b'dpset out4 outval f \n')
         #print("switches : ", switch_left, switch_right)         #print("switches : ", switch_left, switch_right)
  
         # Set engine direction if speed is zero         # Set engine direction if speed is zero
         if speed == 0:         if speed == 0:
-            if int(switches.decode()[0],16) & 1 == 1 : +            if int(switches[0],16) & 1 == 1 : 
-                sock_cmd.send(b'dpset dc2 mode0 f \n')+                response = send_cmd(sock_cmd, b'dpset dc2 mode0 f \n')
             else :             else :
-                sock_cmd.send(b'dpset dc2 mode0 r \n')+                response = send_cmd(sock_cmd, b'dpset dc2 mode0 r \n')
         # Always set engine speed to keep watchdog alive         # Always set engine speed to keep watchdog alive
-        sock_cmd.send(b'dpset dc2 power0 ' b"%d" b'\n' % speed)+        response = send_cmd(sock_cmd, b'dpset dc2 power0 ' b"%d" b'\n' % speed)
         time.sleep(0.05)         time.sleep(0.05)
-        results = sock_cmd.recv(1024) # collect backslash prompt chars 
         #print("speed : ", speed)         #print("speed : ", speed)
  
traincontrol.1634161642.txt.gz · Last modified: 2021/10/13 21:47 by dpisuperadmin