def retrieveVariables(self): self.systemControllerProfilometerRoutineStart = profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineStart) profilometerParameters.updateDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineStart,False) self.systemControllerProfilometerRoutineRunning = profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineRunning) self.systemControllerProfilometerRoutineDirection = profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineDirection) self.systemControllerProfilometerRoutineStepSize = profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineStepSize) self.systemControllerProfilometerRoutineTravelDirection = profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineTravelDistance)
def run(self): # Initializes the data and equipment self.initializeData() self.initializeEquipment() self.retrieveVariables() while (True): # if self.systemControllerProfilometerRoutineStart: # True - start profilometer routine # Commented out to see if we can skip getVaraibles if profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineStart): # True - start profilometer routine # self.profilometerRoutine(self.systemControllerProfilometerRoutineDirection,self.systemControllerProfilometerRoutineTravelDirection,self.systemControllerProfilometerRoutineStepSize) self.profilometerRoutine(profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineDirection), profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineTravelDistance), profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineStepSize))
def buttonClickedStartStop(self): ## If statement that cycles through the start/stop functionality of the button # First if statement that checks for routine running = True and then stops the run if profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineRunning) == True: # Update the profilometer routine running to False when start/stop button clicked profilometerParameters.updateDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineRunning,False) self.updateMovementButtonsState(True) # Updates the start/stop button to green and start self.buttonStartStop.setText('Start') self.buttonStartStop.setStyleSheet('background-color: green;border:0px;border-radius:10') print('Profilometer Routine Stopped') # Else if statement that checks for routine running = False and then starts the run elif profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineRunning) == False: # Updates the profilometer routine running to True when start/stop button clicked profilometerParameters.updateDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineRunning,True) # Updates the profilometer start flag to True when start/stop button clicked profilometerParameters.updateDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineStart,True) # Updates the profilometer routine direction based on the radio button selected profilometerParameters.updateDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineDirection,self.retrieveProfilometerRoutineDirection()) # Updates the profilometer routine step size based on the value entered into the entry box profilometerParameters.updateDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineStepSize,self.entryBoxStepSize.text()) # Updates the profilometer routine travel distance based on the value entered into the entry box profilometerParameters.updateDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineTravelDistance,self.entryBoxTravelDistance.text()) self.updateMovementButtonsState(False) # Updates the start/stop button to red and stop self.buttonStartStop.setText('STOP') self.buttonStartStop.setStyleSheet('background-color: red;border:0px;border-radius:10') print('Profilometer Routine Started') ## Routine to test realtime plotting # Runs a while loop that checks to see if the routine is running while profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineRunning): # Asks the GUI to process any events manually QtGui.QApplication.processEvents() try: # If statement that checks to see if a new data point has been added if profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_newDataPoint): # Calls the plot data routine self.buttonClickedPlotData() # print('plot') # Acquires the data thread lock profilometerParameters.dataThreadLock.acquire() # print('dataThreadLock acquired (UI)') # Sets the new data point to false profilometerParameters.updateDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_newDataPoint,False) # Releases the data thread lock profilometerParameters.dataThreadLock.release() # print('dataThreadLock released (UI)') except: pass
def retrieveData(self): # Creates lists that will be appended to with the desired data _dataDirection_X = [] _dataDirection_Y = [] _dataDirection_Z = [] _dataVolts = [] _dataHeight = [] # # Generates fake data for testing # profilometerParameters.clearDataStorageInstances() # for i in range(75): # profilometerDataClass.profilometerData(i*1.0,i*1.0,i*1.0,math.sin(i/math.pi*180/100)*math.exp(i/100)) # Loops through each data class instance and appends the data to the lists # Also pulls out the data to return for _dataSet in profilometerParameters.retrieveDataStorageInstances(): _dataDirection_X.append(_dataSet.x) _dataDirection_Y.append(_dataSet.y) _dataDirection_Z.append(_dataSet.z) _dataVolts.append(_dataSet.volts) #Calculates the height of the sample by multiplying it by the correction factor _dataHeight.append(_dataSet.volts * profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_calibrationRatio)) # Returns the direction and volts data return _dataDirection_X, _dataDirection_Y, _dataDirection_Z, _dataVolts, _dataHeight
def retrieveVoltage(self): # profilometerParameters.agilent34461a.query("DIAG:REMOTE") # Sets a sample size multimeterReadingsSampleSize = 1 # Sets a varaible that will hold the total value of all multimeter readings for finding the average multimeterReadingsTotals = 0.0 for i in range(multimeterReadingsSampleSize): # Checks to see if the profilometer routine has been manually stopped by the user if not profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineRunning): # Returns the multimeter back to local so that the display updates # profilometerParameters.agilent34461a.query("DIAG:LOCAL") break # Takes the running total and adds the current reading multimeterReadingsTotals = multimeterReadingsTotals + float(profilometerParameters.agilent34461a.query("MEASure:VOLTage:DC?")) # Finds the average multimeter reading multimeterReadingsAverage = multimeterReadingsTotals/multimeterReadingsSampleSize # Returns the multimeter back to local so that the display updates # profilometerParameters.agilent34461a.query("DIAG:LOCAL") # Command does not work for this device (no known command) return multimeterReadingsAverage
def profilometerRoutine(self, direction, travelDistance, stepSize): # Converts the travel distance and step size to a float travelDistance = float(travelDistance) stepSize = float(stepSize) # Changes profilometer start to false so that the routine only runs once profilometerParameters.updateDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineStart,False) # Clears the data from any previous runs profilometerParameters.clearDataStorageInstances() # Creates an instance of the stages _stagesInstance = profilometerXYZStages.XYZStages() _stagesInstance.XYZStagesInitialize() # If statement that checks to make sure a valid direction has been entered and changes direction to # a value recognized by the stages class if direction == 'X': _movementDirection = _stagesInstance.positioner_X elif direction == 'Y': _movementDirection = _stagesInstance.positioner_Y else: print('Please select a direction') return # If statement that checks the sign of the travel distance if travelDistance < 0: stepSize = -stepSize i = 0 # While loop that starts at 0 and moves the stage by step size until travel distance has been reached # Flow is: Scan > Move > Iterate - This allows us to scan the first and last points while i <= abs(float(travelDistance)): # Checks to see if the user clicked the stop button mid print and stops the print if so if not profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineRunning): _stagesInstance.moveStageAbort() print('MID PRINTING STOP') break # Gets a data reading from the multimeter multimeterData = self.Agilent34461a.retrieveVoltage() # Gets the current x,y,z stage locations [x,y,z] = _stagesInstance.retrieveStagePostion() # Creates an instance of the data class with the current data profilometerDataClass.profilometerData(x,y,z,multimeterData) # Acquires the data thread lock profilometerParameters.dataThreadLock.acquire() # print('dataThreadLock acquired (SC)') # Updates the new data point to true profilometerParameters.updateDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_newDataPoint,True) # Releases the data thread lock profilometerParameters.dataThreadLock.release() # print('dataThreadLock released (SC)') # Moves the stages by creating a stage thread and then running that thread for the movement amount and direction _stagesInstanceThread = threading.Thread(target=_stagesInstance.moveStageRelative,args=(_movementDirection,[stepSize/1000])) _stagesInstanceThread.start() # For loop that runs during the stage movement and aborts the movement if the user clicks the stop button motionStatus = _stagesInstance.checkMotionStatus() while (motionStatus != 0): motionStatus = _stagesInstance.checkMotionStatus() # Checks to see if the user has clicked the stop button and aborts the stage movement if they have if not profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_routineRunning): _stagesInstance.moveStageAbort() print('MID PRINTING STOP') break # Increases i by the step size for the next iteration i = i + abs(stepSize)/1000 print('Profilometer Routine Complete')
def buttonClickedSaveData(self): # While loop that checks for widgets within the plot layout and then deletes them # This is used to clear the plot each time a new plot is added to the plot layout while self.layoutPlot.count() > 0: item = self.layoutPlot.takeAt(0) if not item: continue w = item.widget() if w: w.deleteLater() # Retrieves the direction and millivolts data from the system controller [data_X, data_Y, data_Z, data_volts, data_height] = self.systemController.retrieveData() # Checks to see if the desired default path doesn't exists on the machine if not os.path.exists(profilometerParameters.profilometerDefaultSavePath): # Tries to create the desired default path if it doesn't exist try: os.makedirs(profilometerParameters.profilometerDefaultSavePath) except: pass # Opens a save as dialog directed towards the users' Documents/Data/Profilometer folder _saveFileName, saveButtonClicked = QtGui.QFileDialog.getSaveFileNameAndFilter(self, "Save Profilometer Data", os.path.expanduser('~/Documents/Data/Profilometer')) # If the user clicks the save button the data is saved as a csv if saveButtonClicked: # Opens the CSV file to save the data too _dataFile = open(str(_saveFileName) + '.csv','wt') # Creates a writer that will write the data to the csv file _dataWriter = csv.writer(_dataFile) # Finds the number of blocks that the user has entered (new block when user hits enter) numberOfBlocks = self.entryBoxHeader.blockCount() # Runs through each block and saves it as a new row in the CSV file for block in range(numberOfBlocks): _dataWriter.writerow(('# ' + str(self.entryBoxHeader.document().findBlockByNumber(block).text()),'')) # '' is needed to keep each line together # Includes the calibration ratio used below the header data _dataWriter.writerow(('# Calibration ratio used: ' + str(profilometerParameters.retrieveDictionaryParameter(profilometerParameters.kHNSystemControllerProfilometer_calibrationRatio)),'')) # Includes the direction of the scan _dataWriter.writerow(('# Scan direction: ' + str(self.retrieveProfilometerRoutineDirection()))) # Includes the date and time of the save _dataWriter.writerow(('Date and time: ' + str(datetime.datetime.now()),'')) # Writes the column headers into the file _dataWriter.writerow(('X','Y','Z','Volts','Height (mm)')) # Loops through each element of the data lists and writes them to a row in the csv for i in range(len(data_X)): _dataWriter.writerow((data_X[i],data_Y[i],data_Z[i],data_volts[i],data_height[i])) # Closes the data file _dataFile.close() # If the cancel button is clicked nothing happens for now else: pass # Displays the plot of the data that was also saved graphicsLayoutWidget = pg.GraphicsLayoutWidget() graphicsLayout = pg.GraphicsLayout(border=(100,100,100)) graphicsLayoutWidget.addItem(graphicsLayout) plot1 = graphicsLayout.addPlot(title='Profile') plot1.plot(x = data_X, y = data_height) plot1.setLabel('bottom','Distance (mm)') plot1.setLabel('left','Height (mm)') # plot1.setXRange(0,(float(self.entryBoxTravelDistance.text()) + 2.0)) # plot1.setYRange(-1.0,1.0) plot1.showGrid(True, True, 0.75) self.layoutPlot.addWidget(graphicsLayoutWidget)