Python Stepper Scripting¶
The stepper_motion_script.py
Python script demonstrates sending motion
commands from a laptop to the CNCShieldServer Arduino Sketch running on an
Arduino.
The script file can be found in the cncclient folder, and are also available in a single zip file.
CncShieldClient Class Documentation¶
-
class
cncclient.stepper_motion_script.
CncShieldClient
(port=None, verbose=False, debug=False, **kwargs)[source]¶ Class to manage a connection to a CNC_Shield_Server running on a serial-connected Arduino.
Parameters: - port – the name of the serial port device
- verbose – flag to increase console output
- debug – flag to print raw inputs on sconsole
- kwargs – collect any unused keyword arguments
-
close
()[source]¶ Shut down the serial connection to the Arduino, after which this object may no longer be used.
Full Script Code¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | #!/usr/bin/env python
"""\
test_client.py : sample code in Python to communicate with an Arduino running CNC_Shield_Server
Copyright (c) 2015, Garth Zeglin. All rights reserved. Licensed under the terms
of the BSD 3-clause license.
"""
#================================================================
from __future__ import print_function
import argparse
import time
# This requires a pySerial installation.
# Package details: https://pypi.python.org/pypi/pyserial,
# Documentation: http://pythonhosted.org/pyserial/
import serial
#================================================================
class CncShieldClient(object):
"""Class to manage a connection to a CNC_Shield_Server running on a
serial-connected Arduino.
:param port: the name of the serial port device
:param verbose: flag to increase console output
:param debug: flag to print raw inputs on sconsole
:param kwargs: collect any unused keyword arguments
"""
def __init__(self, port=None, verbose=False, debug=False, **kwargs ):
# initialize the client state
self.arduino_time = 0
self.position = [0, 0, 0]
self.target = [0, 0, 0]
self.verbose = verbose
self.debug = debug
self.awake = False
# open the serial port, which should also reset the Arduino
self.port = serial.Serial( port, 115200, timeout=5 )
if self.verbose:
print("Opened serial port named", self.port.name)
print("Sleeping briefly while Arduino boots...")
# wait briefly for the Arduino to finish booting
time.sleep(2) # units are seconds
# throw away any extraneous input
self.port.flushInput()
return
def close(self):
"""Shut down the serial connection to the Arduino, after which this object may no longer be used."""
self.port.close()
self.port = None
return
def _wait_for_input(self):
line = self.port.readline().rstrip()
if line:
elements = line.split()
if self.debug:
print("Received: '%s'" % line)
if elements[0] == 'txyz':
self.arduino_time = int(elements[1])
self.position = [int(s) for s in elements[2:]]
elif elements[0] == 'awake':
self.awake = True
elif elements[0] == 'dbg':
print("Received debugging message:", line)
else:
print("Unknown status message: ", line)
return
def _send_command(self, string):
if self.verbose:
print("Sending: ", string)
self.port.write( string+'\n')
return
def motor_enable( self, value=True):
"""Issue a command to enable or disable the stepper motor drivers."""
self._send_command( "enable 1" if value is True else "enable 0" )
return
def wait_for_wakeup(self):
"""Issue a status query and wait until an 'awake' status has been received."""
while self.awake is False:
self._send_command( "ping" )
self._wait_for_input()
def move_to(self, position):
"""Issue a command to move to a [x, y, z] absolute position (specified in microsteps) and wait until completion.
:param position: a list or tuple with at least three elements
"""
self._send_command( "goto %d %d %d" % tuple(position))
self.target = position
while self.position[0] != position[0] or self.position[1] != position[1] or self.position[2] != position[2]:
self._wait_for_input()
if self.verbose:
print ("Position:", self.position)
return
#================================================================
# The following section is run when this is loaded as a script.
if __name__ == "__main__":
# Initialize the command parser.
parser = argparse.ArgumentParser( description = """Simple test client to send data to the CNC_Shield_Server on an Arduino.""")
parser.add_argument( '-v', '--verbose', action='store_true', help='Enable more detailed output.' )
parser.add_argument( '--debug', action='store_true', help='Enable debugging output.' )
parser.add_argument( '--extra', action='store_true', help='Unused.')
parser.add_argument( '-p', '--port', default='/dev/tty.usbmodem1411', help='Specify the name of the Arduino serial port device (default is /dev/tty.usbmodem1411).')
# Parse the command line, returning a Namespace.
args = parser.parse_args()
# Convert the Namespace to a set of keyword arguments and initialize the
# client object. Note that it will ignore extraneous values, e.g., from
# additional command argument inputs unneeded by this object.
client = CncShieldClient(**vars(args))
# Begin the motion sequence. This may be safely interrupted by the user pressing Control-C.
try:
print("Waiting for wakeup.")
client.wait_for_wakeup()
print("Beginning movement sequence.")
client.motor_enable()
client.move_to([1000, 2000, 3000])
client.move_to([0, 0, 0])
client.move_to([1000, 2000, 3000])
client.move_to([0, 0, 0])
client.move_to([3000, 2000, 1000])
client.move_to([0, 0, 0])
client.move_to([3000, 2000, 1000])
client.move_to([0, 0, 0])
except KeyboardInterrupt:
print("User interrupted motion.")
# Issue a command to turn off the drivers, then shut down the connection.
client.motor_enable(False)
client.close()
|