Source code for CncShieldGUI.CncShieldGUI

"""\
CncShieldGUI.py

GUI controller for the CNC_Shield_Server Arduino sketch.

Copyright (c) 2015, Garth Zeglin.  All rights reserved. Licensed under the terms
of the BSD 3-clause license.
"""

from __future__ import print_function
import os, sys, argparse, math

# import the common GUI library over which this built
from ArduinoGUI.ArduinoConsole import ArduinoConsole

################################################################
[docs]class CncShieldGUIController(object): """Application-specific control object to manage the GUI for the CNC_Shield_Server. This class creates a generic ArduinoConsole GUI, adds application-specific GUI controls, and manages basic I/O using a protocol object. :param client: a protocol object to receive commands from the GUI :param port: the name of the serial port device :param kwargs: collect any unused keyword arguments """ def __init__(self, client, port = None, **kwargs ): """Initialize the application-specific GUI.""" # create the generic interface self.window = ArduinoConsole() # reroute printed output to the console window; this works because there is a write method defined sys.stdout = self.window # add custom interface elements. self.window.addSlider("X", self.x_slider_moved) self.window.addSlider("Y", self.y_slider_moved) self.window.addSlider("Z", self.z_slider_moved) self.window.addButton("Enable", self.enable_button_pressed) self.window.addButton("Disable", self.disable_button_pressed) self.window.addButton("Home", self.home_button_pressed) self.window.addButton("Start", self.start_button_pressed) self.window.addButton("Stop", self.stop_button_pressed) # add a plot window self.window.addScope() self.window.addScopeChannel('x', color='red', duration=10) self.window.addScopeChannel('y', color='green', duration=10) self.window.addScopeChannel('z', color='blue', duration=10) # set up the connect/disconnect control self.window.attachConnectCallback( self._connect_disconnect ) # set up the command lin self.window.attachCommandCallback( self._command_input) self.client = client self.input_monitor = None # fill in the default text field for the Arduino port name if provided if port is not None: self.window.setArduinoPortName(port) return #============================================================================= def _connect_disconnect(self, name, flag ): if flag: # connect if self.client.is_connected(): print("Client already connected.") else: if name is not None and name != "": self.client.set_serial_port_name(name) print("Connecting to the Arduino.") self.client.open_serial_port() # set up an event after the Arduino has had time to boot self.window.newSingleShotTimer( 2000, self._startup_delay_complete) # create a monitor for the serial port device connected to the Arduino to indicate when data is ready self.input_monitor = self.window.newInputMonitor( self.client.input.fileno(), self.port_data_ready ) else: # disconnect if self.client.is_connected(): self.input_monitor.setEnabled(False) self.client.close_serial_port() self.input_monitor = None else: print("Client not connected.") return def _command_input(self, command): print( "User entered '%s'." % command) self.client.send_command(command) return def _startup_delay_complete(self): print("Arduino bootup delay complete.") self.client.flush_serial_input() self.window.resetPlotPressed() #=============================================================================
[docs] def enable_button_pressed(self): """Callback function activated to enable the motor drivers when the GUI button is pressed.""" print("User enabling drivers.") self.client.motor_enable(True)
[docs] def disable_button_pressed(self): """Callback function activated to disable the motor drivers when the GUI button is pressed.""" print("User disabling drivers.") self.client.motor_enable(False)
[docs] def home_button_pressed(self): """Callback function activated to move to the origin when the GUI button is pressed.""" print("User commanding move to home.") self.client.issue_move([0,0,0])
[docs] def start_button_pressed(self): """Callback function activated to start a user script.""" print("User pressed Start.") self.client.start_script() return
[docs] def stop_button_pressed(self): """Callback function activated to interrupt a user script.""" print("User pressed Stop.") self.client.stop_script() return
#============================================================================= # Note that the following functions have a hardcoded scaling from slider -> microsteps.
[docs] def x_slider_moved(self, value): """Callback function activated when the X slider is moved.""" # print("User moved X slider to %f." % value) self.client.issue_move( [int(20000*value), self.client.target[1], self.client.target[2] ])
[docs] def y_slider_moved(self, value): """Callback function activated when the Y slider is moved.""" # print("User moved Y slider to %f." % value) self.client.issue_move( [self.client.target[0], int(20000*value), self.client.target[2] ])
[docs] def z_slider_moved(self, value): """Callback function activated when the Z slider is moved.""" # print("User moved Z slider to %f." % value) self.client.issue_move( [self.client.target[0], self.client.target[1], int(20000*value) ])
#=============================================================================
[docs] def port_data_ready(self, fd): """Callback function activated when data is received from the Arduino. This just prints a message, but would usually process status messages as part of a command protocol.""" # process the input last_position_count = self.client.position_message_count self.client.debug = self.window.isShowingRawData() self.client.wait_for_input() # if new position data was received, add it to the plot if self.client.position_message_count > last_position_count: t = [ 1e-6 * self.client.arduino_time] x = [ self.client.position[0] ] y = [ self.client.position[1] ] z = [ self.client.position[2] ] self.window.addScopeSamples('x', x, t) self.window.addScopeSamples('y', y, t) self.window.addScopeSamples('z', z, t) self.window.replotScope() return
################################################################