Source code for actuation_tutorial.stepper_sequence_demo
#!/usr/bin/env python3
# Enable basic compatibility features to work with either Python 2 or 3.
from __future__ import print_function, absolute_import, unicode_literals
# Standard library modules.
import os, sys, time, argparse, select, logging
# This requires a pySerial installation.
from serial.serialutil import SerialException
# Configure load path to include the parent folder so the course library can be found in a parallel folder.
sys.path.insert(0, os.path.dirname(os.path.abspath(os.path.dirname(__file__))))
# Import modules from the course library.
from ase.DFMocoProtocol import DFMocoClientProtocol
import ase.SerialTransport
import ase.logging
import ase.events
#================================================================
[docs]def animation_sequence(steppers, nummotors, logger):
"""Produce an animation motion sequence on a set of stepper motor by issuing
motion commands to the stepper interface and performing delays using
ase.events.sleep(). This is a good starting point for customizing the
script.
:param steppers: handle to the DFMocoCNC interface object
:param nummotors: number of motors to assume are connected
:param logger: logging object for debugging and status output
"""
# Extract the DFMocoClientProtocol object from the transport for convenience.
protocol = steppers.protocol
# Configure the maximum pulse rate for our typical stepper hardware.
for m in range(nummotors):
protocol.send_pulse_rate(m, 1500)
# Endless loop to run the sequence in a loop.
while True:
# Send some motion commands.
protocol.send_multiple_targets(0, [3200]*nummotors)
ase.events.sleep(3, [steppers])
# Send some motion commands.
protocol.send_multiple_targets(0, [0]*nummotors)
ase.events.sleep(3, [steppers])
logger.info("Waiting for motions to finish.")
ase.events.wait_for_motion_completion([steppers])
# With more than one motor, try starting the movements at different times.
if nummotors > 1:
protocol.send_target(0, 1000)
ase.events.sleep(2, [steppers])
protocol.send_target(1, 1000)
ase.events.sleep(2, [steppers])
#================================================================
[docs]def main(argv):
"""Main program entry point.
:param argv: list of command line arguments as individual strings
"""
# Initialize the command parser.2
parser = argparse.ArgumentParser( description = """Test animation using an Arduino with stepper driver board running DFMocoCNC.""")
ase.logging.add_logging_arguments(parser)
parser.add_argument('--list', action='store_true', help='Print list of available serial ports.')
parser.add_argument('--motors', type=int, default=3, help='Specify the number of stepper channels. Default: 3.')
default_serial_port = '/dev/tty.usbmodem00146911'
parser.add_argument( '--arduino', default=default_serial_port,
help='Specify the name of the Arduino CNC serial device. Default: %s.' % default_serial_port)
args = parser.parse_args()
# Configure a typical logging setup.
logger, handlers = ase.logging.create_script_logger('animation', args)
if args.list:
ase.SerialTransport.print_serial_port_list()
# Create objects to manage the Arduino and serial port.
steppers = ase.SerialTransport.SerialTransport(DFMocoClientProtocol(), args.arduino)
# Connect to the board.
logger.info("Connecting to DFMoco sketch on %s.", args.arduino)
try:
steppers.open()
except SerialException as exp:
logger.error("Unable to open port: %r", exp)
logger.info("You might try the --list argument to see the available serial ports.\nExiting.")
sys.exit(1);
logger.info("Waiting for steppers to wake up...")
while not steppers.protocol.is_protocol_ready():
steppers.protocol.send_hello()
steppers.wait_for_data()
# Now run the event loop until it exits or control-C is pressed.
try:
logger.info("Beginning animation event loop.")
animation_sequence(steppers, args.motors, logger)
except KeyboardInterrupt:
logger.info("User interrupted operation.")
# Shut down the connection.
steppers.close()
#================================================================
# The following section is run when this is loaded as a script.
if __name__ == "__main__":
# Call the main function with most of the command line arguments.
# This could be customized by pre-defining particular arguments:
constant_args = []
# constant_args = ['--arduino', '/dev/tty.usbmodem00146911']
main(constant_args + sys.argv[1:])