ValveControl Scripting in Python¶
The Arduino driving the valves can run the supplied ValveControl Arduino Sketch. This example control program can apply either closed-loop or open-loop valve control. It be configured for the specific actuator, valve, and optional feedback sensor arrangement.
The sketch acts upon command messages received over the USB serial port. The simplest means of testing is to use a terminal program to directly issue commands to the controller. This could simply be the console within the Arduino IDE, or a separate terminal program such as minicom or CoolTerm.
The more flexible way to drive the system is to use a Python script on a separate computer to send commands to the embedded controller. A self-contained Python sample appears below. It does require a pySerial installation to communicate with the Arduino.
This example uses only open-loop ‘speed’ commands to set the fill and empty rate on the two pairs of valves. The primary building block function for the sequence is set_flow().
- pneumatics_exercise.valve_sequence.set_flow(port, flow, extend=1, retract=2, pause=None, verbose=False)[source]¶
Issue an open-loop set of flow commands for a valve pair attached to an actuator. Returns immediately or after an optional delay. No return value.
- Parameters:
port – serial port stream handle
flow – net flow from -100 full retraction rate to 100 full extension rate
extend – channel number for extension valve pair
retract – channel number for retract valve pair
pause – time in seconds to delay after issuing command
verbose – flag to enable printed debugging output
- Returns:
None
The full script is below. It can also be directly downloaded from the Python source tree on the course site.
1#!/usr/bin/env python
2"""\
3valve_sequence.py
4
5Play back a sequence of pneumatic valve activations using a serial port
6connection to an Arduino running ValveControl.
7
8Copyright (c) 2015-2017, Garth Zeglin. All rights reserved. Licensed under the
9terms of the BSD 3-clause license.
10
11"""
12################################################################
13# Import standard Python 2.7 modules.
14from __future__ import print_function
15import os, sys, time, argparse
16
17# This module requires a pySerial installation.
18# Package details: https://pypi.python.org/pypi/pyserial,
19# Documentation: http://pythonhosted.org/pyserial/
20import serial
21
22################################################################
23def set_flow( port, flow, extend=1, retract=2, pause=None, verbose=False):
24 """Issue an open-loop set of flow commands for a valve pair attached to an actuator.
25 Returns immediately or after an optional delay. No return value.
26
27 :param port: serial port stream handle
28 :param flow: net flow from -100 full retraction rate to 100 full extension rate
29 :param extend: channel number for extension valve pair
30 :param retract: channel number for retract valve pair
31 :param pause: time in seconds to delay after issuing command
32 :param verbose: flag to enable printed debugging output
33 :return: None
34 """
35
36
37 if flow > 0:
38 ext_command = "speed %d %d" % (extend, flow)
39 ret_command = "speed %d %d" % (retract, -100)
40 elif flow == 0:
41 ext_command = "speed %d %d" % (extend, 0)
42 ret_command = "speed %d %d" % (retract, 0)
43 else:
44 ext_command = "speed %d %d" % (extend, -100)
45 ret_command = "speed %d %d" % (retract, -flow)
46
47 if verbose:
48 print ("Issuing %s, %s" % (ext_command, ret_command))
49
50 port.write("%s\n%s\n" % (ext_command, ret_command))
51
52 if pause is not None:
53 time.sleep(pause)
54
55 # ignore any sensor feedback
56 port.flushInput()
57
58 return
59
60################################################################
61# The following section is run when this is loaded as a script.
62if __name__ == "__main__":
63
64 # Initialize the command parser.
65 parser = argparse.ArgumentParser( description = """Scripted sequence of pneumatic valve activations using the ValveControl controller on an Arduino.""")
66 parser.add_argument( '-v', '--verbose', action='store_true', help='Enable more detailed output.' )
67 parser.add_argument( '--debug', action='store_true', help='Enable debugging output.' )
68 parser.add_argument( '-p', '--port', default='/dev/tty.usbmodem1411', help='Specify the name of the Arduino serial port device (default is /dev/tty.usbmodem1411).')
69
70 # Parse the command line, returning a Namespace.
71 args = parser.parse_args()
72
73 # Open the serial port, which should also reset the Arduino
74 print("Connecting to Arduino.")
75 port = serial.Serial( args.port, 115200, timeout=5 )
76 if args.verbose:
77 print("Opened serial port named", port.name)
78
79 print("Sleeping briefly while Arduino boots...")
80 time.sleep(2.0)
81
82 # throw away any extraneous input
83 print("Flushing Arduino input...")
84 port.flushInput()
85
86 # Begin the motion sequence. This may be safely interrupted by the user pressing Control-C.
87 try:
88 print("Beginning movement sequence.")
89 set_flow(port, 50, pause=2.0, verbose=args.verbose)
90 set_flow(port, 0, pause=2.0, verbose=args.verbose)
91 set_flow(port, -50, pause=2.0, verbose=args.verbose)
92 set_flow(port, 0, pause=2.0, verbose=args.verbose)
93 set_flow(port, 100, pause=2.0, verbose=args.verbose)
94 set_flow(port, 0, pause=2.0, verbose=args.verbose)
95 set_flow(port, -100, pause=2.0, verbose=args.verbose)
96 print("Movement complete.")
97
98 except KeyboardInterrupt:
99 print("User interrupted motion.")
100
101 # Close the serial port connection.
102 port.write("stop\n")
103 port.close()