Esempio n. 1
0
    def input_device_changed(self, index):
        success, index = self.audio_device.select_input_device(index)
        self.ui.DeviceList.setCurrentIndex(index)
        self.fft_plot.must_plot = True
        if not success:
# Note: the error message is a child of the settings dialog, so that
# that dialog remains on top when the error message is closed
            error_message = QErrorMessage(self.settings_dialog)
            error_message.setWindowTitle("Input device error")
            error_message.showMessage("Impossible to use the selected input"
                                      " device, reverting to the previous one")
Esempio n. 2
0
	def second_channel_changed(self, index):
		self.ui.actionStart.setChecked(False)
		
		success, index = self.audiobackend.select_second_channel(index)
		
		self.settings_dialog.comboBox_secondChannel.setCurrentIndex(index)
		
		if not success:
			# Note: the error message is a child of the settings dialog, so that
			# that dialog remains on top when the error message is closed
			error_message = QErrorMessage(self.settings_dialog)
			error_message.setWindowTitle("Input device error")
			error_message.showMessage("Impossible to use the selected channel as the second channel, reverting to the previous one")
		
		self.ui.actionStart.setChecked(True)
 def loadParameterSet(self):
     s = QSettings()
     name = self.configCombo.currentText()
     s.beginGroup('ParameterSets')
     if not name in s.childGroups():
         dlg = QErrorMessage(self)
         dlg.setWindowTitle('Error')
         dlg.showMessage('No saved parameters available for %s' % name)
         return
     s.beginGroup(name)
     for item in self.parameterItems:
         item.setValue(s.value(item.objectName(), item.value(), type=float))
     self.adjustExcitationCb.setChecked(s.value('adjustExcitation', False, type=bool))
     self.sensorNameLe.setText(s.value('sensorName', '', type=QString))
     self.visaCombo.setCurrentIndex(self.visaCombo.findText(s.value('sr830Visa', 'GPIB0::12', type=QString)))
     self.autoRangingCb.setChecked(s.value('autoRanging', True, type=bool))
     self.minSensitivityCombo.setCurrentCodeSilently(s.value('minSensitivity', 0, type=int))
     s.endGroup()
     s.endGroup()
Esempio n. 4
0
class ImagesWidget(QWidget, Ui_Images):
    images = None

    def __init__(self, parent, app):
        super(QWidget, self).__init__()
        self.app = app

        self.setupUi(self)

        self.error_msg = QErrorMessage()
        self.error_msg.setWindowTitle("Starter Kit: Blinkenlights Demo " + config.DEMO_VERSION)

        self.slider_frame_rate.valueChanged.connect(self.slider_frame_rate_changed)
        self.spinbox_frame_rate.valueChanged.connect(self.spinbox_frame_rate_changed)
        self.button_choose.pressed.connect(self.choose_pressed)
        self.button_show.pressed.connect(self.show_pressed)
        self.button_default.pressed.connect(self.default_pressed)

        self.update_frame_rate_timer = QTimer(self)
        self.update_frame_rate_timer.timeout.connect(self.update_frame_rate)

        self.default_pressed()

    def start(self):
        self.images = Images(self.app.ipcon)

        self.update_frame_rate()

        self.images.frame_rendered(0)

    def stop(self):
        if self.images:
            self.images.stop_rendering()
            self.images = None

    def spinbox_frame_rate_changed(self, frame_rate):
        self.slider_frame_rate.setValue(frame_rate)
        self.update_frame_rate_timer.start(100)

    def slider_frame_rate_changed(self, frame_rate):
        self.spinbox_frame_rate.setValue(frame_rate)

    def show_pressed(self):
        if self.images:
            files = unicode(self.text_edit_files.toPlainText()).strip()

            if len(files) > 0:
                new_images = files.split('\n')

                try:
                    self.images.set_new_images(new_images)
                except Exception as e:
                    self.error_msg.showMessage(str(e))

                self.images.frame_prepare_next()
                self.images.frame_rendered(0)

    def choose_pressed(self):
        for filename in QFileDialog.getOpenFileNames(self, 'Choose Images', QDir.homePath()):
            self.text_edit_files.append(filename)

    def default_pressed(self):
        self.spinbox_frame_rate.setValue(1)

    def update_frame_rate(self):
        self.update_frame_rate_timer.stop()

        config.IMAGES_FRAME_RATE = self.spinbox_frame_rate.value()

        if self.images:
            self.images.update_frame_rate()
Esempio n. 5
0
class Stepper(PluginBase, Ui_Stepper):
    qtcb_position_reached = pyqtSignal(int)
    qtcb_under_voltage = pyqtSignal(int)
    
    def __init__(self, *args):
        PluginBase.__init__(self, BrickStepper, *args)

        self.setupUi(self)
     
        self.stepper = self.device
     
        self.endis_all(False)
        
        self.update_timer = QTimer()
        self.update_timer.timeout.connect(self.update_data)
        
        self.new_value = 0
        self.update_counter = 0
        
        self.full_brake_time = 0

        self.qem = QErrorMessage(self)
        self.qem.setWindowTitle("Under Voltage")

        self.decay_widget.hide()

        self.setting_sync_rect_checkbox = False

        self.velocity_syncer = SliderSpinSyncer(self.velocity_slider,
                                                self.velocity_spin,
                                                self.velocity_changed)

        self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider,
                                                    self.acceleration_spin,
                                                    self.acceleration_changed)

        self.deceleration_syncer = SliderSpinSyncer(self.deceleration_slider,
                                                    self.deceleration_spin,
                                                    self.deceleration_changed)

        self.decay_syncer = SliderSpinSyncer(self.decay_slider,
                                             self.decay_spin,
                                             self.decay_changed)

        self.enable_checkbox.toggled.connect(self.enable_toggled)
        self.forward_button.clicked.connect(self.forward_clicked)
        self.stop_button.clicked.connect(self.stop_clicked)
        self.full_brake_button.clicked.connect(self.full_brake_clicked)
        self.backward_button.clicked.connect(self.backward_clicked)
        self.to_button.clicked.connect(self.to_button_clicked)
        self.steps_button.clicked.connect(self.steps_button_clicked)
        self.motor_current_button.clicked.connect(self.motor_current_button_clicked)
        self.minimum_motor_voltage_button.clicked.connect(self.minimum_motor_voltage_button_clicked)
        self.sync_rect_checkbox.toggled.connect(self.sync_rect_toggled)
        
        self.mode_dropbox.currentIndexChanged.connect(self.mode_changed)
        
        self.qtcb_position_reached.connect(self.cb_position_reached)
        self.stepper.register_callback(self.stepper.CALLBACK_POSITION_REACHED, 
                                       self.qtcb_position_reached.emit)
        
        self.qtcb_under_voltage.connect(self.cb_under_voltage)
        self.stepper.register_callback(self.stepper.CALLBACK_UNDER_VOLTAGE, 
                                       self.qtcb_under_voltage.emit)

        self.ste = 0
        self.pos = 0
        self.current_velocity = 0
        self.cur = 0
        self.sv  = 0
        self.ev  = 0
        self.mv  = 0
        self.mod = 0

        if self.firmware_version >= (1, 1, 4):
            reset = QAction('Reset', self)
            reset.triggered.connect(lambda: self.stepper.reset())
            self.set_actions(reset)
        
    def start(self):
        self.update_timer.start(100)
        self.update_start()
        
    def stop(self):
        self.update_timer.stop()

    def destroy(self):
        pass

    def get_url_part(self):
        return 'stepper'

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickStepper.DEVICE_IDENTIFIER
    
    def cb_position_reached(self, position):
        self.position_update(position)
        self.endis_all(True)
            
    def disable_list(self, button_list):
        for button in button_list:
            button.setEnabled(False)
        
    def endis_all(self, value):
        self.forward_button.setEnabled(value)
        self.stop_button.setEnabled(value)
        self.backward_button.setEnabled(value)
        self.to_button.setEnabled(value)
        self.steps_button.setEnabled(value)
        self.full_brake_button.setEnabled(value)
        
    def mode_changed(self, index):
        try:
            self.stepper.set_step_mode(1 << index)
            self.mod = 1 << index
        except ip_connection.Error:
            return
        
    def forward_clicked(self):
        try:
            self.stepper.drive_forward()
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, self.steps_button])
        
    def backward_clicked(self):
        try:
            self.stepper.drive_backward()
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, self.steps_button])
        
    def stop_clicked(self):
        try:
            self.stepper.stop()
        except ip_connection.Error:
            return
        self.endis_all(True)
        
    def full_brake_clicked(self):
        try:
            self.stepper.full_brake()
        except ip_connection.Error:
            return
        self.endis_all(True)
        
    def to_button_clicked(self):
        drive_to = self.to_spin.value()
        try:
            self.stepper.set_target_position(drive_to)
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, 
                           self.steps_button, 
                           self.forward_button,
                           self.backward_button])
        
    def steps_button_clicked(self):
        drive_steps = self.steps_spin.value()
        try:
            self.stepper.set_steps(drive_steps)
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, 
                           self.steps_button, 
                           self.forward_button,
                           self.backward_button])
        
    def motor_current_button_clicked(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(0)
        qid.setIntMaximum(2500)
        qid.setIntStep(100)
        async_call(self.stepper.get_motor_current, None, qid.setIntValue, self.increase_error_count)
        qid.intValueSelected.connect(self.motor_current_selected)
        qid.setLabelText("Choose motor current in mA.")
#                         "<font color=red>Setting this too high can destroy your Motor.</font>")
        qid.open()
        
    def minimum_motor_voltage_button_clicked(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(0)
        qid.setIntMaximum(40000)
        qid.setIntStep(100)
        async_call(self.stepper.get_minimum_voltage, None, qid.setIntValue, self.increase_error_count)
        qid.intValueSelected.connect(self.minimum_motor_voltage_selected)
        qid.setLabelText("Choose minimum motor voltage in mV.")
        qid.open()
        
    def motor_current_selected(self, value):
        try:
            self.stepper.set_motor_current(value)
        except ip_connection.Error:
            return
        
    def minimum_motor_voltage_selected(self, value):
        try:
            self.stepper.set_minimum_voltage(value)
        except ip_connection.Error:
            return
        
    def cb_under_voltage(self, ov):
        mv_str = self.minimum_voltage_label.text()
        ov_str = "%gV" % round(ov/1000.0, 1)
        if not self.qem.isVisible():
            self.qem.showMessage("Under Voltage: Output Voltage of " + ov_str +
                                 " is below minimum voltage of " + mv_str,
                                 "Stepper_UnderVoltage")

    def enable_toggled(self, checked):
        try:
            if checked:
                if not self.stepper.is_enabled():
                    self.endis_all(True)
                    self.stepper.enable()
            else:
                if self.stepper.is_enabled():
                    self.endis_all(False)
                    self.stepper.disable()
        except ip_connection.Error:
            return

    def sync_rect_toggled(self, checked):
        if not self.setting_sync_rect_checkbox and checked:
            rc = QMessageBox.warning(get_main_window(), 'Synchronous Rectification',
                                     'If you want to use high speeds (> 10000 steps/s) for a large stepper motor with a ' +
                                     'large inductivity we strongly suggest that you do not enable synchronous rectification. ' +
                                     'Otherwise the Brick may not be able to cope with the load and overheat.',
                                     QMessageBox.Ok | QMessageBox.Cancel)

            if rc != QMessageBox.Ok:
                self.sync_rect_checkbox.setChecked(False)
                return

        try:
            self.stepper.set_sync_rect(checked)
        except ip_connection.Error:
            return

        self.decay_widget.setVisible(checked)

    def stack_input_voltage_update(self, sv):
        sv_str = "%gV"  % round(sv/1000.0, 1)
        self.stack_voltage_label.setText(sv_str)
        
    def external_input_voltage_update(self, ev):
        ev_str = "%gV"  % round(ev/1000.0, 1)
        self.external_voltage_label.setText(ev_str)
        
    def minimum_voltage_update(self, mv):
        mv_str = "%gV"  % round(mv/1000.0, 1)
        self.minimum_voltage_label.setText(mv_str)
        
    def maximum_current_update(self, cur):
        cur_str = "%gA"  % round(cur/1000.0, 1)
        self.maximum_current_label.setText(cur_str)
        
    def position_update(self, pos):
        pos_str = "%d" % pos
        self.position_label.setText(pos_str)
        
    def remaining_steps_update(self, ste):
        ste_str = "%d" % ste
        self.remaining_steps_label.setText(ste_str)
        
    def current_velocity_update(self, velocity):
        velocity_str = "%d" % velocity
        self.current_velocity_label.setText(velocity_str)
        self.speedometer.set_velocity(velocity)

    def mode_update(self, mod):
        if mod == 8:
            index = 3
        elif mod == 4:
            index = 2
        elif mod == 2:
            index = 1
        else:
            index = 0
            
        self.mode_dropbox.setCurrentIndex(index)
        
    def get_max_velocity_async(self, velocity):
        if not self.velocity_slider.isSliderDown():
            if velocity != self.velocity_slider.sliderPosition():
                self.velocity_slider.setSliderPosition(velocity)
                self.velocity_spin.setValue(velocity)
        
    def get_speed_ramping_async(self, ramp):
        acc, dec = ramp
        if not self.acceleration_slider.isSliderDown() and \
           not self.deceleration_slider.isSliderDown():
            if acc != self.acceleration_slider.sliderPosition():
                self.acceleration_slider.setSliderPosition(acc)
                self.acceleration_spin.setValue(acc)
            if dec != self.deceleration_slider.sliderPosition():
                self.deceleration_slider.setSliderPosition(dec)
                self.deceleration_spin.setValue(dec)

    def get_decay_async(self, decay):
        if not self.decay_slider.isSliderDown():
            if decay != self.decay_slider.sliderPosition():
                self.decay_slider.setSliderPosition(decay)
                self.decay_spin.setValue(decay)
        
    def is_enabled_async(self, enabled):
        if enabled:
            if not self.enable_checkbox.isChecked():
                self.endis_all(True)
                self.enable_checkbox.setChecked(True)
        else:
            if self.enable_checkbox.isChecked():
                self.endis_all(False)
                self.enable_checkbox.setChecked(False)

    def is_sync_rect_async(self, sync_rect):
        self.setting_sync_rect_checkbox = True
        self.sync_rect_checkbox.setChecked(sync_rect)
        self.setting_sync_rect_checkbox = False

    def update_start(self):
        async_call(self.stepper.get_max_velocity, None, self.get_max_velocity_async, self.increase_error_count)
        async_call(self.stepper.get_speed_ramping, None, self.get_speed_ramping_async, self.increase_error_count)
        async_call(self.stepper.get_decay, None, self.get_decay_async, self.increase_error_count)
        async_call(self.stepper.is_enabled, None, self.is_enabled_async, self.increase_error_count)
        async_call(self.stepper.is_sync_rect, None, self.is_sync_rect_async, self.increase_error_count)

    def update_data(self):
        async_call(self.stepper.get_remaining_steps, None, self.remaining_steps_update, self.increase_error_count)
        async_call(self.stepper.get_current_position, None, self.position_update, self.increase_error_count)
        async_call(self.stepper.get_current_velocity, None, self.current_velocity_update, self.increase_error_count)

        self.update_counter += 1
        if self.update_counter % 10 == 0:
            async_call(self.stepper.get_motor_current, None, self.maximum_current_update, self.increase_error_count)
            async_call(self.stepper.get_stack_input_voltage, None, self.stack_input_voltage_update, self.increase_error_count)
            async_call(self.stepper.get_external_input_voltage, None, self.external_input_voltage_update, self.increase_error_count)
            async_call(self.stepper.get_minimum_voltage, None, self.minimum_voltage_update, self.increase_error_count)
            async_call(self.stepper.get_step_mode, None, self.mode_update, self.increase_error_count)

    def velocity_changed(self, value):
        try:
            self.stepper.set_max_velocity(value)
        except ip_connection.Error:
            return

    def acceleration_changed(self, value):
        dec = self.deceleration_spin.value()
        try:
            self.stepper.set_speed_ramping(value, dec)
        except ip_connection.Error:
            return
            
    def deceleration_changed(self, value):
        acc = self.acceleration_slider.value()
        try:
            self.stepper.set_speed_ramping(acc, value)
        except ip_connection.Error:
            return

    def decay_changed(self, value):
        try:
            self.stepper.set_decay(value)
        except ip_connection.Error:
            return
Esempio n. 6
0
class SilentStepper(PluginBase, Ui_SilentStepper):
    qtcb_position_reached = pyqtSignal(int)
    qtcb_under_voltage = pyqtSignal(int)
    
    def __init__(self, *args):
        PluginBase.__init__(self, BrickSilentStepper, *args)

        self.setupUi(self)
     
        self.silent_stepper = self.device
     
        self.endis_all(False)
        
        self.update_timer = QTimer()
        self.update_timer.timeout.connect(self.update_data)

        self.speedometer = SpeedoMeter()
        self.vertical_layout_right.insertWidget(5, self.speedometer)
        
        self.new_value = 0
        self.update_counter = 0
        
        self.full_brake_time = 0

        self.qem = QErrorMessage(self)
        self.qem.setWindowTitle("Under Voltage")

        self.velocity_syncer = SliderSpinSyncer(self.velocity_slider,
                                                self.velocity_spin,
                                                self.velocity_changed)

        self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider,
                                                    self.acceleration_spin,
                                                    self.acceleration_changed)

        self.deceleration_syncer = SliderSpinSyncer(self.deceleration_slider,
                                                    self.deceleration_spin,
                                                    self.deceleration_changed)

        self.enable_checkbox.stateChanged.connect(self.enable_state_changed)
        self.forward_button.clicked.connect(self.forward_clicked)
        self.stop_button.clicked.connect(self.stop_clicked)
        self.full_brake_button.clicked.connect(self.full_brake_clicked)
        self.backward_button.clicked.connect(self.backward_clicked)
        self.to_button.clicked.connect(self.to_button_clicked)
        self.steps_button.clicked.connect(self.steps_button_clicked)
        self.motor_current_button.clicked.connect(self.motor_current_button_clicked)
        self.minimum_motor_voltage_button.clicked.connect(self.minimum_motor_voltage_button_clicked)

        self.qtcb_position_reached.connect(self.cb_position_reached)
        self.silent_stepper.register_callback(self.silent_stepper.CALLBACK_POSITION_REACHED, 
                                              self.qtcb_position_reached.emit)
        
        self.qtcb_under_voltage.connect(self.cb_under_voltage)
        self.silent_stepper.register_callback(self.silent_stepper.CALLBACK_UNDER_VOLTAGE, 
                                              self.qtcb_under_voltage.emit)
        
        # Step Configuration
        self.step_resolution_dropbox.currentIndexChanged.connect(self.step_configuration_changed)
        self.interpolate_checkbox.stateChanged.connect(self.step_configuration_changed)
        
        # Basic Configuration
        self.standstill_current_spin.valueChanged.connect(self.basic_configuration_changed)
        self.motor_run_current_spin.valueChanged.connect(self.basic_configuration_changed)
        self.standstill_delay_time_spin.valueChanged.connect(self.basic_configuration_changed)
        self.power_down_time_spin.valueChanged.connect(self.basic_configuration_changed)
        self.stealth_threshold_spin.valueChanged.connect(self.basic_configuration_changed)
        self.coolstep_threashold_spin.valueChanged.connect(self.basic_configuration_changed)
        self.classic_threshold_spin.valueChanged.connect(self.basic_configuration_changed)
        self.high_velocity_chopper_mode_checkbox.stateChanged.connect(self.basic_configuration_changed)
        
        # Spreadcycle Configuration
        self.slow_decay_duration_spin.valueChanged.connect(self.spreadcycle_configuration_changed)
        self.enable_random_slow_decay_checkbox.stateChanged.connect(self.spreadcycle_configuration_changed)
        self.fast_decay_duration_spin.valueChanged.connect(self.spreadcycle_configuration_changed)
        self.hysteresis_start_value_spin.valueChanged.connect(self.spreadcycle_configuration_changed)
        self.hysteresis_end_value_spin.valueChanged.connect(self.spreadcycle_configuration_changed)
        self.sinewave_offset_spin.valueChanged.connect(self.spreadcycle_configuration_changed)
        self.chopper_mode_combo.currentIndexChanged.connect(self.spreadcycle_configuration_changed)
        self.comperator_blank_time_combo.currentIndexChanged.connect(self.spreadcycle_configuration_changed)
        self.fast_decay_without_comperator_checkbox.stateChanged.connect(self.spreadcycle_configuration_changed)
        
        # Stealth Configuration
        self.enable_stealth_checkbox.stateChanged.connect(self.stealth_configuration_changed)
        self.amplitude_spin.valueChanged.connect(self.stealth_configuration_changed)
        self.gradient_spin.valueChanged.connect(self.stealth_configuration_changed)
        self.enable_autoscale_checkbox.stateChanged.connect(self.stealth_configuration_changed)
        self.force_symmetric_checkbox.stateChanged.connect(self.stealth_configuration_changed)
        self.freewheel_mode_combo.currentIndexChanged.connect(self.stealth_configuration_changed)
        
        # Coolstep Configuration
        self.minimum_stallguard_value_spin.valueChanged.connect(self.coolstep_configuration_changed)
        self.maximum_stallguard_value_spin.valueChanged.connect(self.coolstep_configuration_changed)
        self.current_up_step_width_combo.currentIndexChanged.connect(self.coolstep_configuration_changed)
        self.current_down_step_width_combo.currentIndexChanged.connect(self.coolstep_configuration_changed)
        self.minimum_current_combo.currentIndexChanged.connect(self.coolstep_configuration_changed)
        self.stallguard_threshold_value_spin.valueChanged.connect(self.coolstep_configuration_changed)
        self.stallguard_mode_combo.currentIndexChanged.connect(self.coolstep_configuration_changed)
        
        # Misc Configuration
        self.disable_short_to_ground_protection_checkbox.stateChanged.connect(self.misc_configuration_changed)
        self.synchronize_phase_frequency_spin.valueChanged.connect(self.misc_configuration_changed)
        
        self.ste = 0
        self.pos = 0
        self.current_velocity = 0
        self.cur = 0
        self.sv  = 0
        self.ev  = 0
        self.mv  = 0
        self.mod = 0

        reset = QAction('Reset', self)
        reset.triggered.connect(lambda: self.silent_stepper.reset())
        self.set_actions(reset)
        
    def start(self):
        self.update_timer.start(100)
        self.update_start()
        
    def stop(self):
        self.update_timer.stop()

    def destroy(self):
        pass

    def get_url_part(self):
        return 'silent_stepper'

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickSilentStepper.DEVICE_IDENTIFIER
    
    def cb_position_reached(self, position):
        self.position_update(position)
        self.endis_all(True)
            
    def disable_list(self, button_list):
        for button in button_list:
            button.setEnabled(False)
        
    def endis_all(self, value):
        self.forward_button.setEnabled(value)
        self.stop_button.setEnabled(value)
        self.backward_button.setEnabled(value)
        self.to_button.setEnabled(value)
        self.steps_button.setEnabled(value)
        self.full_brake_button.setEnabled(value)
        
    def step_configuration_changed(self, _):
        step_resolution = self.step_resolution_dropbox.currentIndex()
        interpolation = self.interpolate_checkbox.isChecked()
        try:
            self.silent_stepper.set_step_configuration(step_resolution, interpolation)
        except ip_connection.Error:
            return
        
    def basic_configuration_changed(self, _):
        standstill_current = self.standstill_current_spin.value()
        motor_run_current = self.motor_run_current_spin.value()
        standstill_delay_time = self.standstill_delay_time_spin.value()
        power_down_time = self.power_down_time_spin.value()
        stealth_threshold = self.stealth_threshold_spin.value()
        coolstep_threshold = self.coolstep_threashold_spin.value()
        classic_threshold = self.classic_threshold_spin.value()
        high_velocity_chopper_mode = self.high_velocity_chopper_mode_checkbox.isChecked()
        
        try:
            self.silent_stepper.set_basic_configuration(standstill_current, motor_run_current, standstill_delay_time, power_down_time, stealth_threshold, coolstep_threshold, classic_threshold, high_velocity_chopper_mode)
        except ip_connection.Error:
            return

    def spreadcycle_configuration_changed(self, _):
        slow_decay_duration = self.slow_decay_duration_spin.value()
        enable_random_slow_decay = self.enable_random_slow_decay_checkbox.isChecked()
        fast_decay_duration = self.fast_decay_duration_spin.value()
        hysteresis_start_value = self.hysteresis_start_value_spin.value()
        hysteresis_end_value = self.hysteresis_end_value_spin.value()
        sinewave_offset = self.sinewave_offset_spin.value()
        chopper_mode = self.chopper_mode_combo.currentIndex()
        comperator_blank_time = self.comperator_blank_time_combo.currentIndex()
        fast_decay_without_comperator = self.fast_decay_without_comperator_checkbox.isChecked()
        
        try:
            self.silent_stepper.set_spreadcycle_configuration(slow_decay_duration, enable_random_slow_decay, fast_decay_duration, hysteresis_start_value, hysteresis_end_value, sinewave_offset, chopper_mode, comperator_blank_time, fast_decay_without_comperator)
        except ip_connection.Error:
            return
        
    def stealth_configuration_changed(self, _):
        enable_stealth = self.enable_stealth_checkbox.isChecked()
        amplitude = self.amplitude_spin.value()
        gradient = self.gradient_spin.value()
        enable_autoscale = self.enable_autoscale_checkbox.isChecked()
        force_symmetric = self.force_symmetric_checkbox.isChecked()
        freewheel_mode = self.freewheel_mode_combo.currentIndex()
        
        try:
            self.silent_stepper.set_stealth_configuration(enable_stealth, amplitude, gradient, enable_autoscale, force_symmetric, freewheel_mode)
        except ip_connection.Error:
            return
        
    def coolstep_configuration_changed(self, _):
        minimum_stallguard_value = self.minimum_stallguard_value_spin.value()
        maximum_stallguard_value = self.maximum_stallguard_value_spin.value()
        current_up_step_width = self.current_up_step_width_combo.currentIndex()
        current_down_step_width = self.current_down_step_width_combo.currentIndex()
        minimum_current = self.minimum_current_combo.currentIndex()
        stallguard_threshold_value = self.stallguard_threshold_value_spin.value()
        stallguard_mode = self.stallguard_mode_combo.currentIndex()
        
        try:
            self.silent_stepper.set_coolstep_configuration(minimum_stallguard_value, maximum_stallguard_value, current_up_step_width, current_down_step_width, minimum_current, stallguard_threshold_value, stallguard_mode)
        except ip_connection.Error:
            return
        
    def misc_configuration_changed(self, _):
        disable_short_to_ground_protection = self.disable_short_to_ground_protection_checkbox.isChecked()
        synchronize_phase_frequency = self.synchronize_phase_frequency_spin.value()
        
        try:
            self.silent_stepper.set_misc_configuration(disable_short_to_ground_protection, synchronize_phase_frequency)
        except ip_connection.Error:
            return
        
    def forward_clicked(self):
        try:
            self.silent_stepper.drive_forward()
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, self.steps_button])
        
    def backward_clicked(self):
        try:
            self.silent_stepper.drive_backward()
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, self.steps_button])
        
    def stop_clicked(self):
        try:
            self.silent_stepper.stop()
        except ip_connection.Error:
            return
        self.endis_all(True)
        
    def full_brake_clicked(self):
        try:
            self.silent_stepper.full_brake()
        except ip_connection.Error:
            return
        self.endis_all(True)
        
    def to_button_clicked(self):
        drive_to = self.to_spin.value()
        try:
            self.silent_stepper.set_target_position(drive_to)
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, 
                           self.steps_button, 
                           self.forward_button,
                           self.backward_button])
        
    def steps_button_clicked(self):
        drive_steps = self.steps_spin.value()
        try:
            self.silent_stepper.set_steps(drive_steps)
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, 
                           self.steps_button, 
                           self.forward_button,
                           self.backward_button])
        
    def motor_current_button_clicked(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(0)
        qid.setIntMaximum(2500)
        qid.setIntStep(100)
        async_call(self.silent_stepper.get_motor_current, None, qid.setIntValue, self.increase_error_count)
        qid.intValueSelected.connect(self.motor_current_selected)
        qid.setLabelText("Choose motor current in mA.")
        qid.open()
        
    def minimum_motor_voltage_button_clicked(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(0)
        qid.setIntMaximum(40000)
        qid.setIntStep(100)
        async_call(self.silent_stepper.get_minimum_voltage, None, qid.setIntValue, self.increase_error_count)
        qid.intValueSelected.connect(self.minimum_motor_voltage_selected)
        qid.setLabelText("Choose minimum motor voltage in mV.")
        qid.open()
        
    def motor_current_selected(self, value):
        try:
            self.silent_stepper.set_motor_current(value)
        except ip_connection.Error:
            return
        
    def minimum_motor_voltage_selected(self, value):
        try:
            self.silent_stepper.set_minimum_voltage(value)
        except ip_connection.Error:
            return
        
    def cb_under_voltage(self, ov):
        mv_str = self.minimum_voltage_label.text()
        ov_str = "%gV"  % round(ov/1000.0, 1)
        if not self.qem.isVisible():
            self.qem.showMessage("Under Voltage: Output Voltage of " + ov_str +
                                 " is below minimum voltage of " + mv_str,
                                 "SilentStepper_UnderVoltage")
        
    def enable_state_changed(self, state):
        try:
            if state == Qt.Checked:
                self.endis_all(True)
                self.silent_stepper.enable()
            elif state == Qt.Unchecked:
                self.endis_all(False)
                self.silent_stepper.disable()
        except ip_connection.Error:
            return
        
    def stack_input_voltage_update(self, sv):
        sv_str = "%gV"  % round(sv/1000.0, 1)
        self.stack_voltage_label.setText(sv_str)
        
    def external_input_voltage_update(self, ev):
        ev_str = "%gV"  % round(ev/1000.0, 1)
        self.external_voltage_label.setText(ev_str)
        
    def minimum_voltage_update(self, mv):
        mv_str = "%gV"  % round(mv/1000.0, 1)
        self.minimum_voltage_label.setText(mv_str)
        
    def maximum_current_update(self, cur):
        cur_str = "%gA"  % round(cur/1000.0, 1)
        self.maximum_current_label.setText(cur_str)
        
    def position_update(self, pos):
        pos_str = "%d" % pos
        self.position_label.setText(pos_str)
        
    def remaining_steps_update(self, ste):
        ste_str = "%d" % ste
        self.remaining_steps_label.setText(ste_str)
        
    def driver_status_update(self, update):
        if update.open_load == 0:
            self.status_open_load.setText('No')
        elif update.open_load == 1:
            self.status_open_load.setText('Phase A')
        elif update.open_load == 2:
            self.status_open_load.setText('Phase B')
        elif update.open_load == 3:
            self.status_open_load.setText('Phase A and B')
        else:
            self.status_open_load.setText('Unkown')
            
        if update.short_to_ground == 0:
            self.status_short_to_ground.setText('No')
        elif update.short_to_ground == 1:
            self.status_short_to_ground.setText('Phase A')
        elif update.short_to_ground == 2:
            self.status_short_to_ground.setText('Phase B')
        elif update.short_to_ground == 3:
            self.status_short_to_ground.setText('Phase A and B')
        else:
            self.status_short_to_ground.setText('Unkown')
            
        if update.over_temperature == 0:
            self.status_over_temperature.setText('No')
        elif update.over_temperature == 1:
            self.status_over_temperature.setText('<font color=yellow>Warning</font>')
        elif update.over_temperature == 2:
            self.status_over_temperature.setText('<font color=red>Limit</font>')
        
        if update.motor_stalled:
            self.status_motor_stalled.setText('Yes')
        else:
            self.status_motor_stalled.setText('No')
            
        self.status_actual_motor_current.setText(str(update.actual_motor_current))
        
        if update.full_step_active:
            self.status_full_step_active.setText('Yes')
        else:
            self.status_full_step_active.setText('No')
            
        self.status_stallguard_result.setText(str(update.stallguard_result))
        self.status_stealth_voltage_amplitude.setText(str(update.stealth_voltage_amplitude))
            
    def get_max_velocity_async(self, velocity):
        if not self.velocity_slider.isSliderDown():
            if velocity != self.velocity_slider.sliderPosition():
                self.velocity_slider.setSliderPosition(velocity)
                self.velocity_spin.setValue(velocity)
        
    def get_speed_ramping_async(self, ramp):
        acc, dec = ramp
        if not self.acceleration_slider.isSliderDown() and \
           not self.deceleration_slider.isSliderDown():
            if acc != self.acceleration_slider.sliderPosition():
                self.acceleration_slider.setSliderPosition(acc)
                self.acceleration_spin.setValue(acc)
            if dec != self.deceleration_slider.sliderPosition():
                self.deceleration_slider.setSliderPosition(dec)
                self.deceleration_spin.setValue(dec)
        
    def is_enabled_async(self, enabled):
        if enabled:
            if not self.enable_checkbox.isChecked():
                self.endis_all(True)
                self.enable_checkbox.blockSignals(True)
                self.enable_checkbox.setChecked(True)
                self.enable_checkbox.blockSignals(False)
        else:
            if self.enable_checkbox.isChecked():
                self.endis_all(False)
                self.enable_checkbox.blockSignals(True)
                self.enable_checkbox.setChecked(False)
                self.enable_checkbox.blockSignals(False)
                        
    def get_step_configuration_async(self, conf):
        self.step_resolution_dropbox.blockSignals(True)
        self.step_resolution_dropbox.setCurrentIndex(conf.step_resolution)
        self.step_resolution_dropbox.blockSignals(False)
        
        self.interpolate_checkbox.blockSignals(True)
        self.interpolate_checkbox.setChecked(conf.interpolation)
        self.interpolate_checkbox.blockSignals(False)
        
    def get_basic_configuration_async(self, conf):
        self.standstill_current_spin.blockSignals(True)
        self.standstill_current_spin.setValue(conf.standstill_current)
        self.standstill_current_spin.blockSignals(False)

        self.motor_run_current_spin.blockSignals(True)
        self.motor_run_current_spin.setValue(conf.motor_run_current)
        self.motor_run_current_spin.blockSignals(False)
        
        self.standstill_delay_time_spin.blockSignals(True)
        self.standstill_delay_time_spin.setValue(conf.standstill_delay_time)
        self.standstill_delay_time_spin.blockSignals(False)
        
        self.power_down_time_spin.blockSignals(True)
        self.power_down_time_spin.setValue(conf.power_down_time)
        self.power_down_time_spin.blockSignals(False)
        
        self.stealth_threshold_spin.blockSignals(True)
        self.stealth_threshold_spin.setValue(conf.stealth_threshold)
        self.stealth_threshold_spin.blockSignals(False)
        
        self.coolstep_threashold_spin.blockSignals(True)
        self.coolstep_threashold_spin.setValue(conf.coolstep_threshold)
        self.coolstep_threashold_spin.blockSignals(False)
        
        self.classic_threshold_spin.blockSignals(True)
        self.classic_threshold_spin.setValue(conf.classic_threshold)
        self.classic_threshold_spin.blockSignals(False)
        
        self.high_velocity_chopper_mode_checkbox.blockSignals(True)
        self.high_velocity_chopper_mode_checkbox.setChecked(conf.high_velocity_chopper_mode)
        self.high_velocity_chopper_mode_checkbox.blockSignals(False)
    
    def get_spreadcycle_configuration_async(self, conf):
        self.slow_decay_duration_spin.blockSignals(True)
        self.slow_decay_duration_spin.setValue(conf.slow_decay_duration)
        self.slow_decay_duration_spin.blockSignals(False)
        
        self.enable_random_slow_decay_checkbox.blockSignals(True)
        self.enable_random_slow_decay_checkbox.setChecked(conf.enable_random_slow_decay)
        self.enable_random_slow_decay_checkbox.blockSignals(False)
        
        self.fast_decay_duration_spin.blockSignals(True)
        self.fast_decay_duration_spin.setValue(conf.fast_decay_duration)
        self.fast_decay_duration_spin.blockSignals(False)
        
        self.hysteresis_start_value_spin.blockSignals(True)
        self.hysteresis_start_value_spin.setValue(conf.hysteresis_start_value)
        self.hysteresis_start_value_spin.blockSignals(False)
        
        self.hysteresis_end_value_spin.blockSignals(True)
        self.hysteresis_end_value_spin.setValue(conf.hysteresis_end_value)
        self.hysteresis_end_value_spin.blockSignals(False)
        
        self.sinewave_offset_spin.blockSignals(True)
        self.sinewave_offset_spin.setValue(conf.sinewave_offset)
        self.sinewave_offset_spin.blockSignals(False)
        
        self.chopper_mode_combo.blockSignals(True)
        self.chopper_mode_combo.setCurrentIndex(conf.chopper_mode)
        self.chopper_mode_combo.blockSignals(False)
        
        self.standstill_current_spin.blockSignals(True)
        self.comperator_blank_time_combo.setCurrentIndex(conf.comperator_blank_time)
        self.standstill_current_spin.blockSignals(False)
        
        self.fast_decay_without_comperator_checkbox.blockSignals(True)
        self.fast_decay_without_comperator_checkbox.setChecked(conf.fast_decay_without_comperator)
        self.fast_decay_without_comperator_checkbox.blockSignals(False)
        
    
    def get_stealth_configuration_async(self, conf):
        self.enable_stealth_checkbox.blockSignals(True)
        self.enable_stealth_checkbox.setChecked(conf.enable_stealth)
        self.enable_stealth_checkbox.blockSignals(False)
        
        self.amplitude_spin.blockSignals(True)
        self.amplitude_spin.setValue(conf.amplitude)
        self.amplitude_spin.blockSignals(False)
        
        self.gradient_spin.blockSignals(True)
        self.gradient_spin.setValue(conf.gradient)
        self.gradient_spin.blockSignals(False)
        
        self.enable_autoscale_checkbox.blockSignals(True)
        self.enable_autoscale_checkbox.setChecked(conf.enable_autoscale)
        self.enable_autoscale_checkbox.blockSignals(False)
        
        self.force_symmetric_checkbox.blockSignals(True)
        self.force_symmetric_checkbox.setChecked(conf.force_symmetric)
        self.force_symmetric_checkbox.blockSignals(False)
        
        self.freewheel_mode_combo.blockSignals(True)
        self.freewheel_mode_combo.setCurrentIndex(conf.freewheel_mode)
        self.freewheel_mode_combo.blockSignals(False)
    
    def get_coolstep_configuration_async(self, conf):
        self.minimum_stallguard_value_spin.blockSignals(True)
        self.minimum_stallguard_value_spin.setValue(conf.minimum_stallguard_value)
        self.minimum_stallguard_value_spin.blockSignals(False)
    
        self.maximum_stallguard_value_spin.blockSignals(True)
        self.maximum_stallguard_value_spin.setValue(conf.maximum_stallguard_value)
        self.maximum_stallguard_value_spin.blockSignals(False)
    
        self.current_up_step_width_combo.blockSignals(True)
        self.current_up_step_width_combo.setCurrentIndex(conf.current_up_step_width)
        self.current_up_step_width_combo.blockSignals(False)
    
        self.current_down_step_width_combo.blockSignals(True)
        self.current_down_step_width_combo.setCurrentIndex(conf.current_down_step_width)
        self.current_down_step_width_combo.blockSignals(False)
    
        self.minimum_current_combo.blockSignals(True)
        self.minimum_current_combo.setCurrentIndex(conf.minimum_current)
        self.minimum_current_combo.blockSignals(False)
    
        self.stallguard_threshold_value_spin.blockSignals(True)
        self.stallguard_threshold_value_spin.setValue(conf.stallguard_threshold_value)
        self.stallguard_threshold_value_spin.blockSignals(False)
    
        self.stallguard_mode_combo.blockSignals(True)
        self.stallguard_mode_combo.setCurrentIndex(conf.stallguard_mode)
        self.stallguard_mode_combo.blockSignals(False)
        
    def get_misc_configuration_async(self, conf):
        self.disable_short_to_ground_protection_checkbox.blockSignals(True)
        self.disable_short_to_ground_protection_checkbox.setChecked(conf.disable_short_to_ground_protection)
        self.disable_short_to_ground_protection_checkbox.blockSignals(False)
        
        self.synchronize_phase_frequency_spin.blockSignals(True)
        self.synchronize_phase_frequency_spin.setValue(conf.synchronize_phase_frequency)
        self.synchronize_phase_frequency_spin.blockSignals(False)
        
    def update_start(self):
        async_call(self.silent_stepper.get_max_velocity, None, self.get_max_velocity_async, self.increase_error_count)
        async_call(self.silent_stepper.get_speed_ramping, None, self.get_speed_ramping_async, self.increase_error_count)
        async_call(self.silent_stepper.is_enabled, None, self.is_enabled_async, self.increase_error_count)
        async_call(self.silent_stepper.get_step_configuration, None, self.get_step_configuration_async, self.increase_error_count)
        async_call(self.silent_stepper.get_basic_configuration, None, self.get_basic_configuration_async, self.increase_error_count)
        async_call(self.silent_stepper.get_spreadcycle_configuration, None, self.get_spreadcycle_configuration_async, self.increase_error_count)
        async_call(self.silent_stepper.get_stealth_configuration, None, self.get_stealth_configuration_async, self.increase_error_count)
        async_call(self.silent_stepper.get_coolstep_configuration, None, self.get_coolstep_configuration_async, self.increase_error_count)
        async_call(self.silent_stepper.get_misc_configuration, None, self.get_misc_configuration_async, self.increase_error_count)

    def update_data(self):
        async_call(self.silent_stepper.get_remaining_steps, None, self.remaining_steps_update, self.increase_error_count)
        async_call(self.silent_stepper.get_current_position, None, self.position_update, self.increase_error_count)
        async_call(self.silent_stepper.get_current_velocity, None, self.speedometer.set_velocity, self.increase_error_count)

        self.update_counter += 1
        if self.update_counter % 10 == 0:
            async_call(self.silent_stepper.get_motor_current, None, self.maximum_current_update, self.increase_error_count)
            async_call(self.silent_stepper.get_stack_input_voltage, None, self.stack_input_voltage_update, self.increase_error_count)
            async_call(self.silent_stepper.get_external_input_voltage, None, self.external_input_voltage_update, self.increase_error_count)
            async_call(self.silent_stepper.get_minimum_voltage, None, self.minimum_voltage_update, self.increase_error_count)
            async_call(self.silent_stepper.get_driver_status, None, self.driver_status_update, self.increase_error_count)

    def velocity_changed(self, value):
        try:
            self.silent_stepper.set_max_velocity(value)
        except ip_connection.Error:
            return

    def acceleration_changed(self, value):
        dec = self.deceleration_spin.value()
        try:
            self.silent_stepper.set_speed_ramping(value, dec)
        except ip_connection.Error:
            return
            
    def deceleration_changed(self, value):
        acc = self.acceleration_slider.value()
        try:
            self.silent_stepper.set_speed_ramping(acc, value)
        except ip_connection.Error:
            return
Esempio n. 7
0
class Stepper(PluginBase, Ui_Stepper):
    qtcb_position_reached = pyqtSignal(int)
    qtcb_under_voltage = pyqtSignal(int)

    def __init__(self, *args):
        PluginBase.__init__(self, BrickStepper, *args)

        self.setupUi(self)

        self.stepper = self.device

        self.endis_all(False)

        self.update_timer = QTimer()
        self.update_timer.timeout.connect(self.update_data)

        self.new_value = 0
        self.update_counter = 0

        self.full_brake_time = 0

        self.qem = QErrorMessage(self)
        self.qem.setWindowTitle("Under Voltage")

        self.decay_widget.hide()

        self.setting_sync_rect_checkbox = False

        self.velocity_syncer = SliderSpinSyncer(self.velocity_slider,
                                                self.velocity_spin,
                                                self.velocity_changed)

        self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider,
                                                    self.acceleration_spin,
                                                    self.acceleration_changed)

        self.deceleration_syncer = SliderSpinSyncer(self.deceleration_slider,
                                                    self.deceleration_spin,
                                                    self.deceleration_changed)

        self.decay_syncer = SliderSpinSyncer(self.decay_slider,
                                             self.decay_spin,
                                             self.decay_changed)

        self.enable_checkbox.toggled.connect(self.enable_toggled)
        self.forward_button.clicked.connect(self.forward_clicked)
        self.stop_button.clicked.connect(self.stop_clicked)
        self.full_brake_button.clicked.connect(self.full_brake_clicked)
        self.backward_button.clicked.connect(self.backward_clicked)
        self.to_button.clicked.connect(self.to_button_clicked)
        self.steps_button.clicked.connect(self.steps_button_clicked)
        self.motor_current_button.clicked.connect(
            self.motor_current_button_clicked)
        self.minimum_motor_voltage_button.clicked.connect(
            self.minimum_motor_voltage_button_clicked)
        self.sync_rect_checkbox.toggled.connect(self.sync_rect_toggled)

        self.mode_dropbox.currentIndexChanged.connect(self.mode_changed)

        self.qtcb_position_reached.connect(self.cb_position_reached)
        self.stepper.register_callback(self.stepper.CALLBACK_POSITION_REACHED,
                                       self.qtcb_position_reached.emit)

        self.qtcb_under_voltage.connect(self.cb_under_voltage)
        self.stepper.register_callback(self.stepper.CALLBACK_UNDER_VOLTAGE,
                                       self.qtcb_under_voltage.emit)

        self.ste = 0
        self.pos = 0
        self.current_velocity = 0
        self.cur = 0
        self.sv = 0
        self.ev = 0
        self.mv = 0
        self.mod = 0

        if self.firmware_version >= (2, 3, 1):
            self.status_led_action = QAction('Status LED', self)
            self.status_led_action.setCheckable(True)
            self.status_led_action.toggled.connect(
                lambda checked: self.stepper.enable_status_led()
                if checked else self.stepper.disable_status_led())
            self.set_configs([(0, None, [self.status_led_action])])
        else:
            self.status_led_action = None

        if self.firmware_version >= (1, 1, 4):
            reset = QAction('Reset', self)
            reset.triggered.connect(lambda: self.stepper.reset())
            self.set_actions([(0, None, [reset])])

    def start(self):
        if self.firmware_version >= (2, 3, 1):
            async_call(self.stepper.is_status_led_enabled, None,
                       self.status_led_action.setChecked,
                       self.increase_error_count)

        self.update_timer.start(100)
        self.update_start()

    def stop(self):
        self.update_timer.stop()

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickStepper.DEVICE_IDENTIFIER

    def cb_position_reached(self, position):
        self.position_update(position)
        self.endis_all(True)

    def disable_list(self, button_list):
        for button in button_list:
            button.setEnabled(False)

    def endis_all(self, value):
        self.forward_button.setEnabled(value)
        self.stop_button.setEnabled(value)
        self.backward_button.setEnabled(value)
        self.to_button.setEnabled(value)
        self.steps_button.setEnabled(value)
        self.full_brake_button.setEnabled(value)

    def mode_changed(self, index):
        try:
            self.stepper.set_step_mode(1 << index)
            self.mod = 1 << index
        except ip_connection.Error:
            return

    def forward_clicked(self):
        try:
            self.stepper.drive_forward()
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, self.steps_button])

    def backward_clicked(self):
        try:
            self.stepper.drive_backward()
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, self.steps_button])

    def stop_clicked(self):
        try:
            self.stepper.stop()
        except ip_connection.Error:
            return
        self.endis_all(True)

    def full_brake_clicked(self):
        try:
            self.stepper.full_brake()
        except ip_connection.Error:
            return
        self.endis_all(True)

    def to_button_clicked(self):
        drive_to = self.to_spin.value()
        try:
            self.stepper.set_target_position(drive_to)
        except ip_connection.Error:
            return
        self.disable_list([
            self.to_button, self.steps_button, self.forward_button,
            self.backward_button
        ])

    def steps_button_clicked(self):
        drive_steps = self.steps_spin.value()
        try:
            self.stepper.set_steps(drive_steps)
        except ip_connection.Error:
            return
        self.disable_list([
            self.to_button, self.steps_button, self.forward_button,
            self.backward_button
        ])

    def motor_current_button_clicked(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(0)
        qid.setIntMaximum(2500)
        qid.setIntStep(100)
        async_call(self.stepper.get_motor_current, None, qid.setIntValue,
                   self.increase_error_count)
        qid.intValueSelected.connect(self.motor_current_selected)
        qid.setLabelText("Choose motor current in mA.")
        #                         "<font color=red>Setting this too high can destroy your Motor.</font>")
        qid.open()

    def minimum_motor_voltage_button_clicked(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(0)
        qid.setIntMaximum(40000)
        qid.setIntStep(100)
        async_call(self.stepper.get_minimum_voltage, None, qid.setIntValue,
                   self.increase_error_count)
        qid.intValueSelected.connect(self.minimum_motor_voltage_selected)
        qid.setLabelText("Choose minimum motor voltage in mV.")
        qid.open()

    def motor_current_selected(self, value):
        try:
            self.stepper.set_motor_current(value)
        except ip_connection.Error:
            return

    def minimum_motor_voltage_selected(self, value):
        try:
            self.stepper.set_minimum_voltage(value)
        except ip_connection.Error:
            return

    def cb_under_voltage(self, ov):
        mv_str = self.minimum_voltage_label.text()
        ov_str = "%gV" % round(ov / 1000.0, 1)
        if not self.qem.isVisible():
            self.qem.showMessage(
                "Under Voltage: Output Voltage of " + ov_str +
                " is below minimum voltage of " + mv_str,
                "Stepper_UnderVoltage")

    def enable_toggled(self, checked):
        try:
            if checked:
                if not self.stepper.is_enabled():
                    self.endis_all(True)
                    self.stepper.enable()
            else:
                if self.stepper.is_enabled():
                    self.endis_all(False)
                    self.stepper.disable()
        except ip_connection.Error:
            return

    def sync_rect_toggled(self, checked):
        if not self.setting_sync_rect_checkbox and checked:
            rc = QMessageBox.warning(
                get_main_window(), 'Synchronous Rectification',
                'If you want to use high speeds (> 10000 steps/s) for a large stepper motor with a '
                +
                'large inductivity we strongly suggest that you do not enable synchronous rectification. '
                +
                'Otherwise the Brick may not be able to cope with the load and overheat.',
                QMessageBox.Ok | QMessageBox.Cancel)

            if rc != QMessageBox.Ok:
                self.sync_rect_checkbox.setChecked(False)
                return

        try:
            self.stepper.set_sync_rect(checked)
        except ip_connection.Error:
            return

        self.decay_widget.setVisible(checked)

    def stack_input_voltage_update(self, sv):
        sv_str = "%gV" % round(sv / 1000.0, 1)
        self.stack_voltage_label.setText(sv_str)

    def external_input_voltage_update(self, ev):
        ev_str = "%gV" % round(ev / 1000.0, 1)
        self.external_voltage_label.setText(ev_str)

    def minimum_voltage_update(self, mv):
        mv_str = "%gV" % round(mv / 1000.0, 1)
        self.minimum_voltage_label.setText(mv_str)

    def maximum_current_update(self, cur):
        cur_str = "%gA" % round(cur / 1000.0, 1)
        self.maximum_current_label.setText(cur_str)

    def position_update(self, pos):
        pos_str = "%d" % pos
        self.position_label.setText(pos_str)

    def remaining_steps_update(self, ste):
        ste_str = "%d" % ste
        self.remaining_steps_label.setText(ste_str)

    def current_velocity_update(self, velocity):
        velocity_str = "%d" % velocity
        self.current_velocity_label.setText(velocity_str)
        self.speedometer.set_velocity(velocity)

    def mode_update(self, mod):
        if mod == 8:
            index = 3
        elif mod == 4:
            index = 2
        elif mod == 2:
            index = 1
        else:
            index = 0

        self.mode_dropbox.setCurrentIndex(index)

    def get_max_velocity_async(self, velocity):
        if not self.velocity_slider.isSliderDown():
            if velocity != self.velocity_slider.sliderPosition():
                self.velocity_slider.setSliderPosition(velocity)
                self.velocity_spin.setValue(velocity)

    def get_speed_ramping_async(self, ramp):
        acc, dec = ramp
        if not self.acceleration_slider.isSliderDown() and \
           not self.deceleration_slider.isSliderDown():
            if acc != self.acceleration_slider.sliderPosition():
                self.acceleration_slider.setSliderPosition(acc)
                self.acceleration_spin.setValue(acc)
            if dec != self.deceleration_slider.sliderPosition():
                self.deceleration_slider.setSliderPosition(dec)
                self.deceleration_spin.setValue(dec)

    def get_decay_async(self, decay):
        if not self.decay_slider.isSliderDown():
            if decay != self.decay_slider.sliderPosition():
                self.decay_slider.setSliderPosition(decay)
                self.decay_spin.setValue(decay)

    def is_enabled_async(self, enabled):
        if enabled:
            if not self.enable_checkbox.isChecked():
                self.endis_all(True)
                self.enable_checkbox.setChecked(True)
        else:
            if self.enable_checkbox.isChecked():
                self.endis_all(False)
                self.enable_checkbox.setChecked(False)

    def is_sync_rect_async(self, sync_rect):
        self.setting_sync_rect_checkbox = True
        self.sync_rect_checkbox.setChecked(sync_rect)
        self.setting_sync_rect_checkbox = False

    def update_start(self):
        async_call(self.stepper.get_max_velocity, None,
                   self.get_max_velocity_async, self.increase_error_count)
        async_call(self.stepper.get_speed_ramping, None,
                   self.get_speed_ramping_async, self.increase_error_count)
        async_call(self.stepper.get_decay, None, self.get_decay_async,
                   self.increase_error_count)
        async_call(self.stepper.is_enabled, None, self.is_enabled_async,
                   self.increase_error_count)
        async_call(self.stepper.is_sync_rect, None, self.is_sync_rect_async,
                   self.increase_error_count)

    def update_data(self):
        async_call(self.stepper.get_remaining_steps, None,
                   self.remaining_steps_update, self.increase_error_count)
        async_call(self.stepper.get_current_position, None,
                   self.position_update, self.increase_error_count)
        async_call(self.stepper.get_current_velocity, None,
                   self.current_velocity_update, self.increase_error_count)

        self.update_counter += 1
        if self.update_counter % 10 == 0:
            async_call(self.stepper.get_motor_current, None,
                       self.maximum_current_update, self.increase_error_count)
            async_call(self.stepper.get_stack_input_voltage, None,
                       self.stack_input_voltage_update,
                       self.increase_error_count)
            async_call(self.stepper.get_external_input_voltage, None,
                       self.external_input_voltage_update,
                       self.increase_error_count)
            async_call(self.stepper.get_minimum_voltage, None,
                       self.minimum_voltage_update, self.increase_error_count)
            async_call(self.stepper.get_step_mode, None, self.mode_update,
                       self.increase_error_count)

    def velocity_changed(self, value):
        try:
            self.stepper.set_max_velocity(value)
        except ip_connection.Error:
            return

    def acceleration_changed(self, value):
        dec = self.deceleration_spin.value()
        try:
            self.stepper.set_speed_ramping(value, dec)
        except ip_connection.Error:
            return

    def deceleration_changed(self, value):
        acc = self.acceleration_slider.value()
        try:
            self.stepper.set_speed_ramping(acc, value)
        except ip_connection.Error:
            return

    def decay_changed(self, value):
        try:
            self.stepper.set_decay(value)
        except ip_connection.Error:
            return
Esempio n. 8
0
class DC(PluginBase, Ui_DC):
    qtcb_position_reached = pyqtSignal(int)
    qtcb_under_voltage = pyqtSignal(int)
    qtcb_emergency_shutdown = pyqtSignal()
    
    def __init__ (self, ipcon, uid):
        PluginBase.__init__(self, ipcon, uid)
     
        self.setupUi(self)
        
        self.dc = brick_dc.DC(self.uid)
        self.device = self.dc
        self.ipcon.add_device(self.dc)
        self.version = '.'.join(map(str, self.dc.get_version()[1]))
        
        self.update_timer = QTimer()
        self.update_timer.timeout.connect(self.update_data)
        

        self.speedometer = SpeedoMeter()
        self.vertical_layout_right.insertWidget(4, self.speedometer)
        
        self.new_value = 0
        self.update_counter = 0
        
        self.full_brake_time = 0
        
        self.velocity_slider.sliderReleased.connect(self.velocity_slider_released)
        self.velocity_slider.valueChanged.connect(self.velocity_spin.setValue)
        self.velocity_spin.editingFinished.connect(self.velocity_spin_finished)
        
        self.acceleration_slider.sliderReleased.connect(self.acceleration_slider_released)
        self.acceleration_slider.valueChanged.connect(self.acceleration_spin.setValue)
        self.acceleration_spin.editingFinished.connect(self.acceleration_spin_finished)
        
        self.frequency_slider.sliderReleased.connect(self.frequency_slider_released)
        self.frequency_slider.valueChanged.connect(self.frequency_spin.setValue)
        self.frequency_spin.editingFinished.connect(self.frequency_spin_finished)
        
        self.radio_mode_brake.toggled.connect(self.brake_value_changed)
        self.radio_mode_coast.toggled.connect(self.coast_value_changed)
        
        self.minimum_voltage_button.pressed.connect(self.minimum_voltage_button_pressed)
        self.full_brake_button.pressed.connect(self.full_brake_pressed)
        self.enable_checkbox.stateChanged.connect(self.enable_state_changed)
        
        self.emergency_signal = None
        self.under_signal = None
        self.current_velocity_signal = None
        self.velocity_reached_signal = None
        
        self.qem = QErrorMessage(self)
        
        self.qtcb_under_voltage.connect(self.cb_under_voltage)
        self.dc.register_callback(self.dc.CALLBACK_UNDER_VOLTAGE,
                                  self.qtcb_under_voltage.emit) 
        
        self.qtcb_emergency_shutdown.connect(self.cb_emergency_shutdown)
        self.dc.register_callback(self.dc.CALLBACK_EMERGENCY_SHUTDOWN,
                                  self.qtcb_emergency_shutdown.emit) 
        
        self.qtcb_position_reached.connect(self.update_velocity)
        self.dc.register_callback(self.dc.CALLBACK_VELOCITY_REACHED,
                                  self.qtcb_position_reached.emit) 
        self.dc.register_callback(self.dc.CALLBACK_CURRENT_VELOCITY,
                                  self.qtcb_position_reached.emit) 
    
    def start(self):
        self.update_timer.start(1000)
        try:
            self.dc.set_current_velocity_period(100)
            self.update_start()
            self.update_data()
        except ip_connection.Error:
            return
        
    def stop(self):
        self.update_timer.stop()
        try:
            self.dc.set_current_velocity_period(0)
        except ip_connection.Error:
            return
        
    @staticmethod
    def has_name(name):
        return 'DC Brick' in name 
        
    def cb_emergency_shutdown(self):
        if not self.qem.isVisible():
            self.qem.setWindowTitle("Emergency Shutdown")
            self.qem.showMessage("Emergency Shutdown: Short-Circuit or Over-Temperature")
        
    def cb_under_voltage(self, ov):
        mv_str = self.minimum_voltage_label.text()
        ov_str = "%gV"  % round(ov/1000.0, 1)
        if not self.qem.isVisible():
            self.qem.setWindowTitle("Under Voltage")
            self.qem.showMessage("Under Voltage: Output Voltage of " + ov_str +
                                 " is below minimum voltage of " + mv_str)
        
    def enable_state_changed(self, state):
        try:
            if state == Qt.Checked:
                self.dc.enable()
            elif state == Qt.Unchecked:
                self.dc.disable()
        except ip_connection.Error:
            return
            
    def brake_value_changed(self, checked):
        if checked:
            try:
                self.dc.set_drive_mode(0)
            except ip_connection.Error:
                return
        
    def coast_value_changed(self, checked):
        if checked:
            try:
                self.dc.set_drive_mode(1)
            except ip_connection.Error:
                return
        
    def full_brake_pressed(self):
        try:
            self.dc.full_brake()
        except ip_connection.Error:
            return
        
    def minimum_voltage_selected(self, value):
        try:
            self.dc.set_minimum_voltage(value)
        except ip_connection.Error:
            return
        
    def minimum_voltage_button_pressed(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(5000)
        qid.setIntMaximum(0xFFFF)
        qid.setIntStep(100)
        try:
            qid.setIntValue(self.dc.get_minimum_voltage())
        except ip_connection.Error:
            return
        qid.intValueSelected.connect(self.minimum_voltage_selected)
        qid.setLabelText("Choose minimum motor voltage in mV.")
        qid.open()
        
    def stack_input_voltage_update(self, sv):
        sv_str = "%gV"  % round(sv/1000.0, 1)
        self.stack_voltage_label.setText(sv_str)
        
    def external_input_voltage_update(self, ev):
        ev_str = "%gV"  % round(ev/1000.0, 1)
        self.external_voltage_label.setText(ev_str)
        
    def minimum_voltage_update(self, mv):
        mv_str = "%gV"  % round(mv/1000.0, 1)
        self.minimum_voltage_label.setText(mv_str)
        
    def drive_mode_update(self, dm):
        if dm == 0:
            self.radio_mode_brake.setChecked(True)
            self.radio_mode_coast.setChecked(False)
        else:
            self.radio_mode_brake.setChecked(False)
            self.radio_mode_coast.setChecked(True)
            
    def current_consumption_update(self, cc):
        if cc >= 1000:
            cc_str = "%gA"  % round(cc/1000.0, 1)
        else:
            cc_str = "%gmA" % cc
            
        self.current_label.setText(cc_str)

    
    def update_velocity(self, value):
        if value != self.speedometer.value():
            self.speedometer.set_velocity(value)
        
    def update_start(self):
        try:
            dm = self.dc.get_drive_mode()
            self.drive_mode_update(dm)
            
            if not self.velocity_slider.isSliderDown():
                velocity = self.dc.get_velocity()
                if velocity != self.velocity_slider.sliderPosition():
                    self.velocity_slider.setSliderPosition(velocity)
                    self.velocity_spin.setValue(velocity)
                 
            if not self.acceleration_slider.isSliderDown():
                acceleration = self.dc.get_acceleration()
                if acceleration != self.acceleration_slider.sliderPosition():
                    self.acceleration_slider.setSliderPosition(acceleration)
                    self.acceleration_spin.setValue(acceleration)
                    
            if not self.frequency_slider.isSliderDown():
                frequency = self.dc.get_pwm_frequency()
                if frequency != self.frequency_slider.sliderPosition():
                    self.frequency_slider.setSliderPosition(frequency)
                    self.frequency_spin.setValue(frequency)
    
            enabled = self.dc.is_enabled()
            if enabled:
                self.enable_checkbox.setCheckState(Qt.Checked)
            else:
                self.enable_checkbox.setCheckState(Qt.Unchecked)
        except ip_connection.Error:
            return
        
    def update_data(self):
        try:
            sv = self.dc.get_stack_input_voltage()
            ev = self.dc.get_external_input_voltage()
            mv = self.dc.get_minimum_voltage()
            cc = self.dc.get_current_consumption()
        except ip_connection.Error:
            return
        
        self.stack_input_voltage_update(sv)
        self.external_input_voltage_update(ev)
        self.minimum_voltage_update(mv)
        self.current_consumption_update(cc)
        
    def acceleration_slider_released(self):
        value = self.acceleration_slider.value()
        self.acceleration_spin.setValue(value)
        try:
            self.dc.set_acceleration(value)
        except ip_connection.Error:
            return
        
    def acceleration_spin_finished(self):
        value = self.acceleration_spin.value()
        self.acceleration_slider.setValue(value)
        try:
            self.dc.set_acceleration(value)
        except ip_connection.Error:
            return
        
    def velocity_slider_released(self):
        value = self.velocity_slider.value()
        self.velocity_spin.setValue(value)
        try:
            self.dc.set_velocity(value)
        except ip_connection.Error:
            return
        
    def velocity_spin_finished(self):
        value = self.velocity_spin.value()
        self.velocity_slider.setValue(value)
        try:
            self.dc.set_velocity(value)
        except ip_connection.Error:
            return
        
    def frequency_slider_released(self):
        value = self.frequency_slider.value()
        self.frequency_spin.setValue(value)
        try:
            self.dc.set_pwm_frequency(value)
        except ip_connection.Error:
            return
        
    def frequency_spin_finished(self):
        value = self.frequency_spin.value()
        self.frequency_slider.setValue(value)
        try:
            self.dc.set_pwm_frequency(value)
        except ip_connection.Error:
            return
Esempio n. 9
0
class Stepper(PluginBase, Ui_Stepper):
    qtcb_position_reached = pyqtSignal(int)
    qtcb_under_voltage = pyqtSignal(int)

    def __init__(self, ipcon, uid):
        PluginBase.__init__(self, ipcon, uid)
        self.setupUi(self)

        self.stepper = brick_stepper.Stepper(self.uid)
        self.device = self.stepper
        self.ipcon.add_device(self.stepper)
        self.version = '.'.join(map(str, self.stepper.get_version()[1]))

        self.endis_all(False)

        self.update_timer = QTimer()
        self.update_timer.timeout.connect(self.update_data)

        self.speedometer = SpeedoMeter()
        self.vertical_layout_right.insertWidget(5, self.speedometer)

        self.new_value = 0
        self.update_counter = 0

        self.full_brake_time = 0

        self.qem = QErrorMessage(self)
        self.qem.setWindowTitle("Under Voltage")

        self.velocity_slider.sliderReleased.connect(
            self.velocity_slider_released)
        self.velocity_slider.valueChanged.connect(self.velocity_spin.setValue)
        self.velocity_spin.editingFinished.connect(self.velocity_spin_finished)

        self.acceleration_slider.sliderReleased.connect(
            self.acceleration_slider_released)
        self.acceleration_slider.valueChanged.connect(
            self.acceleration_spin.setValue)
        self.acceleration_spin.editingFinished.connect(
            self.acceleration_spin_finished)

        self.deceleration_slider.sliderReleased.connect(
            self.deceleration_slider_released)
        self.deceleration_slider.valueChanged.connect(
            self.deceleration_spin.setValue)
        self.deceleration_spin.editingFinished.connect(
            self.deceleration_spin_finished)

        self.decay_slider.sliderReleased.connect(self.decay_slider_released)
        self.decay_slider.valueChanged.connect(self.decay_spin.setValue)
        self.decay_spin.editingFinished.connect(self.decay_spin_finished)

        self.enable_checkbox.stateChanged.connect(self.enable_state_changed)
        self.forward_button.pressed.connect(self.forward_pressed)
        self.stop_button.pressed.connect(self.stop_pressed)
        self.full_brake_button.pressed.connect(self.full_brake_pressed)
        self.backward_button.pressed.connect(self.backward_pressed)
        self.to_button.pressed.connect(self.to_button_pressed)
        self.steps_button.pressed.connect(self.steps_button_pressed)
        self.motor_current_button.pressed.connect(
            self.motor_current_button_pressed)
        self.minimum_motor_voltage_button.pressed.connect(
            self.minimum_motor_voltage_button_pressed)

        self.mode_dropbox.currentIndexChanged.connect(self.mode_changed)

        self.qtcb_position_reached.connect(self.cb_position_reached)
        self.stepper.register_callback(self.stepper.CALLBACK_POSITION_REACHED,
                                       self.qtcb_position_reached.emit)

        self.qtcb_under_voltage.connect(self.cb_under_voltage)
        self.stepper.register_callback(self.stepper.CALLBACK_UNDER_VOLTAGE,
                                       self.qtcb_under_voltage.emit)

    def start(self):
        self.update_timer.start(100)
        self.update_start()

    def stop(self):
        self.update_timer.stop()

    @staticmethod
    def has_name(name):
        return 'Stepper Brick' in name

    def cb_position_reached(self, position):
        self.position_update(position)
        self.endis_all(True)

    def disable_list(self, button_list):
        for button in button_list:
            button.setEnabled(False)

    def endis_all(self, value):
        self.forward_button.setEnabled(value)
        self.stop_button.setEnabled(value)
        self.backward_button.setEnabled(value)
        self.to_button.setEnabled(value)
        self.steps_button.setEnabled(value)
        self.full_brake_button.setEnabled(value)

    def mode_changed(self, index):
        try:
            self.stepper.set_step_mode(1 << index)
        except ip_connection.Error:
            return

    def forward_pressed(self):
        try:
            self.stepper.drive_forward()
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, self.steps_button])

    def backward_pressed(self):
        try:
            self.stepper.drive_backward()
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, self.steps_button])

    def stop_pressed(self):
        try:
            self.stepper.stop()
        except ip_connection.Error:
            return
        self.endis_all(True)

    def full_brake_pressed(self):
        try:
            self.stepper.full_brake()
        except ip_connection.Error:
            return
        self.endis_all(True)

    def to_button_pressed(self):
        drive_to = self.to_spin.value()
        try:
            self.stepper.set_target_position(drive_to)
        except ip_connection.Error:
            return
        self.disable_list([
            self.to_button, self.steps_button, self.forward_button,
            self.backward_button
        ])

    def steps_button_pressed(self):
        drive_steps = self.steps_spin.value()
        try:
            self.stepper.set_steps(drive_steps)
        except ip_connection.Error:
            return
        self.disable_list([
            self.to_button, self.steps_button, self.forward_button,
            self.backward_button
        ])

    def motor_current_button_pressed(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(0)
        qid.setIntMaximum(2500)
        qid.setIntStep(100)
        try:
            qid.setIntValue(self.stepper.get_motor_current())
        except ip_connection.Error:
            return
        qid.intValueSelected.connect(self.motor_current_selected)
        qid.setLabelText("Choose motor current in mA.")
        #                         "<font color=red>Setting this too high can destroy your Motor.</font>")
        qid.open()

    def minimum_motor_voltage_button_pressed(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(0)
        qid.setIntMaximum(40000)
        qid.setIntStep(100)
        try:
            qid.setIntValue(self.stepper.get_minimum_voltage())
        except ip_connection.Error:
            return
        qid.intValueSelected.connect(self.minimum_motor_voltage_selected)
        qid.setLabelText("Choose minimum motor voltage in mV.")
        qid.open()

    def motor_current_selected(self, value):
        try:
            self.stepper.set_motor_current(value)
        except ip_connection.Error:
            return

    def minimum_motor_voltage_selected(self, value):
        try:
            self.stepper.set_minimum_voltage(value)
        except ip_connection.Error:
            return

    def cb_under_voltage(self, ov):
        mv_str = self.minimum_voltage_label.text()
        ov_str = "%gV" % round(ov / 1000.0, 1)
        if not self.qem.isVisible():
            self.qem.showMessage("Under Voltage: Output Voltage of " + ov_str +
                                 " is below minimum voltage of " + mv_str)

    def enable_state_changed(self, state):
        try:
            if state == Qt.Checked:
                self.endis_all(True)
                self.stepper.enable()
            elif state == Qt.Unchecked:
                self.endis_all(False)
                self.stepper.disable()
        except ip_connection.Error:
            return

    def stack_input_voltage_update(self, sv):
        sv_str = "%gV" % round(sv / 1000.0, 1)
        self.stack_voltage_label.setText(sv_str)

    def external_input_voltage_update(self, ev):
        ev_str = "%gV" % round(ev / 1000.0, 1)
        self.external_voltage_label.setText(ev_str)

    def minimum_voltage_update(self, mv):
        mv_str = "%gV" % round(mv / 1000.0, 1)
        self.minimum_voltage_label.setText(mv_str)

    def maximum_current_update(self, cur):
        cur_str = "%gA" % round(cur / 1000.0, 1)
        self.maximum_current_label.setText(cur_str)

    def position_update(self, pos):
        pos_str = "%g" % pos
        self.position_label.setText(pos_str)

    def remaining_steps_update(self, ste):
        ste_str = "%g" % ste
        self.remaining_steps_label.setText(ste_str)

    def mode_update(self, mod):
        if mod == 8:
            index = 3
        elif mod == 4:
            index = 2
        elif mod == 2:
            index = 1
        else:
            index = 0

        self.mode_dropbox.setCurrentIndex(index)

    def update_start(self):
        try:
            if not self.velocity_slider.isSliderDown():
                velocity = self.stepper.get_max_velocity()
                if velocity != self.velocity_slider.sliderPosition():
                    self.velocity_slider.setSliderPosition(velocity)
                    self.velocity_spin.setValue(velocity)

            if not self.acceleration_slider.isSliderDown() and \
               not self.deceleration_slider.isSliderDown():
                acc, dec = self.stepper.get_speed_ramping()
                if acc != self.acceleration_slider.sliderPosition():
                    self.acceleration_slider.setSliderPosition(acc)
                    self.acceleration_spin.setValue(acc)
                if dec != self.deceleration_slider.sliderPosition():
                    self.deceleration_slider.setSliderPosition(dec)
                    self.deceleration_spin.setValue(dec)

            if not self.decay_slider.isSliderDown():
                dec = self.stepper.get_decay()
                if dec != self.decay_slider.sliderPosition():
                    self.decay_slider.setSliderPosition(dec)
                    self.decay_spin.setValue(dec)

            enabled = self.stepper.is_enabled()
            if enabled:
                if self.enable_checkbox.checkState() != Qt.Checked:
                    self.endis_all(True)
                    self.enable_checkbox.setCheckState(Qt.Checked)
            else:
                if self.enable_checkbox.checkState() != Qt.Unchecked:
                    self.endis_all(False)
                    self.enable_checkbox.setCheckState(Qt.Unchecked)
        except ip_connection.Error:
            return

    def update_infos(self):
        try:
            cur = self.stepper.get_motor_current()
            sv = self.stepper.get_stack_input_voltage()
            ev = self.stepper.get_external_input_voltage()
            mv = self.stepper.get_minimum_voltage()
            mod = self.stepper.get_step_mode()
        except ip_connection.Error:
            return

        self.maximum_current_update(cur)
        self.stack_input_voltage_update(sv)
        self.external_input_voltage_update(ev)
        self.minimum_voltage_update(mv)
        self.mode_update(mod)

    def update_values(self):
        try:
            ste = self.stepper.get_remaining_steps()
            pos = self.stepper.get_current_position()
            self.remaining_steps_update(ste)
            self.position_update(pos)

            current_velocity = self.stepper.get_current_velocity()
            if current_velocity != self.speedometer.value():
                self.speedometer.set_velocity(current_velocity)
        except ip_connection.Error:
            return

    def update_data(self):
        try:
            ste = self.stepper.get_remaining_steps()
            pos = self.stepper.get_current_position()
            self.remaining_steps_update(ste)
            self.position_update(pos)

            current_velocity = self.stepper.get_current_velocity()
            if current_velocity != self.speedometer.value():
                self.speedometer.set_velocity(current_velocity)
        except ip_connection.Error:
            return
        self.update_counter += 1
        if self.update_counter % 10 == 0:
            self.update_infos()

        self.update_values()

    def velocity_slider_released(self):
        value = self.velocity_slider.value()
        self.velocity_spin.setValue(value)
        try:
            self.stepper.set_max_velocity(value)
        except ip_connection.Error:
            return

    def velocity_spin_finished(self):
        value = self.velocity_spin.value()
        self.velocity_slider.setValue(value)
        try:
            self.stepper.set_max_velocity(value)
        except ip_connection.Error:
            return

    def acceleration_slider_released(self):
        acc = self.acceleration_slider.value()
        dec = self.deceleration_slider.value()
        self.acceleration_spin.setValue(acc)
        try:
            self.stepper.set_speed_ramping(acc, dec)
        except ip_connection.Error:
            return

    def acceleration_spin_finished(self):
        acc = self.acceleration_spin.value()
        dec = self.deceleration_spin.value()
        self.acceleration_slider.setValue(acc)
        try:
            self.stepper.set_speed_ramping(acc, dec)
        except ip_connection.Error:
            return

    def deceleration_slider_released(self):
        acc = self.acceleration_slider.value()
        dec = self.deceleration_slider.value()
        self.deceleration_spin.setValue(dec)
        try:
            self.stepper.set_speed_ramping(acc, dec)
        except ip_connection.Error:
            return

    def deceleration_spin_finished(self):
        acc = self.acceleration_spin.value()
        dec = self.deceleration_spin.value()
        self.deceleration_slider.setValue(dec)
        try:
            self.stepper.set_speed_ramping(acc, dec)
        except ip_connection.Error:
            return

    def decay_slider_released(self):
        value = self.decay_slider.value()
        self.decay_spin.setValue(value)
        try:
            self.stepper.set_decay(value)
        except ip_connection.Error:
            return

    def decay_spin_finished(self):
        value = self.decay_spin.value()
        self.decay_slider.setValue(value)
        try:
            self.stepper.set_decay(value)
        except ip_connection.Error:
            return
Esempio n. 10
0
class ImagesWidget(QWidget, Ui_Images):
    images = None

    def __init__(self, parent, app):
        super(QWidget, self).__init__()
        self.app = app

        self.setupUi(self)

        self.error_msg = QErrorMessage()
        self.error_msg.setWindowTitle("Starter Kit: Blinkenlights Demo " +
                                      config.DEMO_VERSION)

        self.slider_frame_rate.valueChanged.connect(
            self.slider_frame_rate_changed)
        self.spinbox_frame_rate.valueChanged.connect(
            self.spinbox_frame_rate_changed)
        self.button_choose.pressed.connect(self.choose_pressed)
        self.button_show.pressed.connect(self.show_pressed)
        self.button_default.pressed.connect(self.default_pressed)

        self.update_frame_rate_timer = QTimer(self)
        self.update_frame_rate_timer.timeout.connect(self.update_frame_rate)

        self.default_pressed()

    def start(self):
        self.images = Images(self.app.ipcon)

        self.update_frame_rate()

        self.images.frame_rendered(0)

    def stop(self):
        if self.images:
            self.images.stop_rendering()
            self.images = None

    def spinbox_frame_rate_changed(self, frame_rate):
        self.slider_frame_rate.setValue(frame_rate)
        self.update_frame_rate_timer.start(100)

    def slider_frame_rate_changed(self, frame_rate):
        self.spinbox_frame_rate.setValue(frame_rate)

    def show_pressed(self):
        if self.images:
            files = unicode(self.text_edit_files.toPlainText()).strip()

            if len(files) > 0:
                new_images = files.split('\n')

                try:
                    self.images.set_new_images(new_images)
                except Exception as e:
                    self.error_msg.showMessage(str(e))

                self.images.frame_prepare_next()
                self.images.frame_rendered(0)

    def choose_pressed(self):
        dialog = QFileDialog()
        dialog.setDirectory(QDir.homePath())
        dialog.setFileMode(QFileDialog.ExistingFiles)

        if dialog.exec_():
            filenames = dialog.selectedFiles()
            for filename in filenames:
                self.text_edit_files.append(filename)

    def default_pressed(self):
        self.spinbox_frame_rate.setValue(1)

    def update_frame_rate(self):
        self.update_frame_rate_timer.stop()

        config.IMAGES_FRAME_RATE = self.spinbox_frame_rate.value()

        if self.images:
            self.images.update_frame_rate()
Esempio n. 11
0
class DC(PluginBase, Ui_DC):
    qtcb_position_reached = pyqtSignal(int)
    qtcb_under_voltage = pyqtSignal(int)
    qtcb_emergency_shutdown = pyqtSignal()
    
    def __init__(self, ipcon, uid, version):
        PluginBase.__init__(self, ipcon, uid, 'DC Brick', version)
        
        self.setupUi(self)
        self.encoder_hide_all()
        
        self.dc = BrickDC(uid, ipcon)
        self.device = self.dc
        
        self.update_timer = QTimer()
        self.update_timer.timeout.connect(self.update_data)
        
        self.speedometer = SpeedoMeter()
        self.vertical_layout_right.insertWidget(4, self.speedometer)
        
        self.new_value = 0
        self.update_counter = 0
        
        self.full_brake_time = 0
        
        self.velocity_slider.sliderReleased.connect(self.velocity_slider_released)
        self.velocity_slider.valueChanged.connect(self.velocity_spin.setValue)
        self.velocity_spin.editingFinished.connect(self.velocity_spin_finished)
        
        self.acceleration_slider.sliderReleased.connect(self.acceleration_slider_released)
        self.acceleration_slider.valueChanged.connect(self.acceleration_spin.setValue)
        self.acceleration_spin.editingFinished.connect(self.acceleration_spin_finished)
        
        self.frequency_slider.sliderReleased.connect(self.frequency_slider_released)
        self.frequency_slider.valueChanged.connect(self.frequency_spin.setValue)
        self.frequency_spin.editingFinished.connect(self.frequency_spin_finished)
        
        self.radio_mode_brake.toggled.connect(self.brake_value_changed)
        self.radio_mode_coast.toggled.connect(self.coast_value_changed)
        
        self.minimum_voltage_button.pressed.connect(self.minimum_voltage_button_pressed)
        self.full_brake_button.pressed.connect(self.full_brake_pressed)
        self.enable_checkbox.stateChanged.connect(self.enable_state_changed)
        
        self.emergency_signal = None
        self.under_signal = None
        self.current_velocity_signal = None
        self.velocity_reached_signal = None
        
        self.qem = QErrorMessage(self)
        
        self.qtcb_under_voltage.connect(self.cb_under_voltage)
        self.dc.register_callback(self.dc.CALLBACK_UNDER_VOLTAGE,
                                  self.qtcb_under_voltage.emit) 
        
        self.qtcb_emergency_shutdown.connect(self.cb_emergency_shutdown)
        self.dc.register_callback(self.dc.CALLBACK_EMERGENCY_SHUTDOWN,
                                  self.qtcb_emergency_shutdown.emit) 
        
        self.qtcb_position_reached.connect(self.update_velocity)
        self.dc.register_callback(self.dc.CALLBACK_VELOCITY_REACHED,
                                  self.qtcb_position_reached.emit) 
        self.dc.register_callback(self.dc.CALLBACK_CURRENT_VELOCITY,
                                  self.qtcb_position_reached.emit)
        
#        if self.version >= (2, 0, 1):
#            self.enable_encoder_checkbox.stateChanged.connect(self.enable_encoder_state_changed)
#            self.encoder_show()
#        else:
#            self.enable_encoder_checkbox.setText('Enable Encoder (Firmware >= 2.01 required)')
#            self.enable_encoder_checkbox.setEnabled(False)
    
    def start(self):
        self.update_timer.start(1000)
        async_call(self.dc.set_current_velocity_period, 100, None, self.increase_error_count)
        self.update_start()
        self.update_data()
        
    def stop(self):
        self.update_timer.stop()
        async_call(self.dc.set_current_velocity_period, 0, None, self.increase_error_count)

    def has_reset_device(self):
        return self.version >= (1, 1, 3)

    def reset_device(self):
        if self.has_reset_device():
            self.dc.reset()

    def is_brick(self):
        return True

    def get_url_part(self):
        return 'dc'

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickDC.DEVICE_IDENTIFIER
        
    def cb_emergency_shutdown(self):
        if not self.qem.isVisible():
            self.qem.setWindowTitle("Emergency Shutdown")
            self.qem.showMessage("Emergency Shutdown: Short-Circuit or Over-Temperature")
        
    def cb_under_voltage(self, ov):
        mv_str = self.minimum_voltage_label.text()
        ov_str = "%gV"  % round(ov/1000.0, 1)
        if not self.qem.isVisible():
            self.qem.setWindowTitle("Under Voltage")
            self.qem.showMessage("Under Voltage: Output Voltage of " + ov_str +
                                 " is below minimum voltage of " + mv_str,
                                 "DC_UnderVoltage")
            
    def encoder_hide_all(self):
        self.enable_encoder_checkbox.hide()
        self.encoder_hide()
            
    def encoder_hide(self):
        self.p_label.hide()
        self.p_spinbox.hide()
        self.i_label.hide()
        self.i_spinbox.hide()
        self.d_label.hide()
        self.d_spinbox.hide()
        self.st_label.hide()
        self.st_spinbox.hide()
        self.cpr_label.hide()
        self.cpr_spinbox.hide()
        self.encoder_spacer.hide()
        
    def encoder_show(self):
        self.p_label.show()
        self.p_spinbox.show()
        self.i_label.show()
        self.i_spinbox.show()
        self.d_label.show()
        self.d_spinbox.show()
        self.st_label.show()
        self.st_spinbox.show()
        self.cpr_label.show()
        self.cpr_spinbox.show()
        self.encoder_spacer.show()          
         
    def enable_encoder_state_changed(self, state):
        try:
            if state == Qt.Checked:
                self.dc.enable_encoder()
                self.update_encoder()
            elif state == Qt.Unchecked:
                self.dc.disable_encoder()

        except ip_connection.Error:
            return
        
    def enable_state_changed(self, state):
        try:
            if state == Qt.Checked:
                self.dc.enable()
            elif state == Qt.Unchecked:
                self.dc.disable()
        except ip_connection.Error:
            return
            
    def brake_value_changed(self, checked):
        if checked:
            try:
                self.dc.set_drive_mode(0)
            except ip_connection.Error:
                return
        
    def coast_value_changed(self, checked):
        if checked:
            try:
                self.dc.set_drive_mode(1)
            except ip_connection.Error:
                return
        
    def full_brake_pressed(self):
        try:
            self.dc.full_brake()
        except ip_connection.Error:
            return
        
    def minimum_voltage_selected(self, value):
        try:
            self.dc.set_minimum_voltage(value)
        except ip_connection.Error:
            return
        
    def minimum_voltage_button_pressed(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(5000)
        qid.setIntMaximum(0xFFFF)
        qid.setIntStep(100)
        async_call(self.dc.get_minimum_voltage, None, qid.setIntValue, self.increase_error_count)
        qid.intValueSelected.connect(self.minimum_voltage_selected)
        qid.setLabelText("Choose minimum motor voltage in mV.")
        qid.open()
        
    def stack_input_voltage_update(self, sv):
        sv_str = "%gV"  % round(sv/1000.0, 1)
        self.stack_voltage_label.setText(sv_str)
        
    def external_input_voltage_update(self, ev):
        ev_str = "%gV"  % round(ev/1000.0, 1)
        self.external_voltage_label.setText(ev_str)
        
    def minimum_voltage_update(self, mv):
        mv_str = "%gV"  % round(mv/1000.0, 1)
        self.minimum_voltage_label.setText(mv_str)
        
    def drive_mode_update(self, dm):
        if dm == 0:
            self.radio_mode_brake.setChecked(True)
            self.radio_mode_coast.setChecked(False)
        else:
            self.radio_mode_brake.setChecked(False)
            self.radio_mode_coast.setChecked(True)
            
    def current_consumption_update(self, cc):
        if cc >= 1000:
            cc_str = "%gA"  % round(cc/1000.0, 1)
        else:
            cc_str = "%gmA" % cc
            
        self.current_label.setText(cc_str)

    
    def update_velocity(self, value):
        if value != self.speedometer.value():
            self.speedometer.set_velocity(value)
        
    def get_velocity_async(self, velocity):
        if not self.velocity_slider.isSliderDown():
            if velocity != self.velocity_slider.sliderPosition():
                self.velocity_slider.setSliderPosition(velocity)
                self.velocity_spin.setValue(velocity)
        
    def get_acceleration_async(self, acceleration):
        if not self.acceleration_slider.isSliderDown():
            if acceleration != self.acceleration_slider.sliderPosition():
                self.acceleration_slider.setSliderPosition(acceleration)
                self.acceleration_spin.setValue(acceleration)
        
    def get_pwm_frequency_async(self, frequency):
        if not self.frequency_slider.isSliderDown():
            if frequency != self.frequency_slider.sliderPosition():
                self.frequency_slider.setSliderPosition(frequency)
                self.frequency_spin.setValue(frequency)
        
    def is_enabled_async(self, enabled):
        if enabled:
            self.enable_checkbox.setCheckState(Qt.Checked)
        else:
            self.enable_checkbox.setCheckState(Qt.Unchecked)
            
    def is_encoder_enabled_async(self, enabled):
        if enabled:
            self.enable_encoder_checkbox.setCheckState(Qt.Checked)
        else:
            self.enable_encoder_checkbox.setCheckState(Qt.Unchecked)
            
    def get_encoder_config_async(self, cpr):
        self.cpr_spinbox.setValue(cpr)
    
    def get_encoder_pid_config_async(self, pid_config):
        self.p_spinbox.setValue(pid_config.p)
        self.i_spinbox.setValue(pid_config.i)
        self.d_spinbox.setValue(pid_config.d)
        self.st_spinbox.setValue(pid_config.sample_time)
        
    def update_encoder(self):
        async_call(self.dc.get_encoder_config, None, self.get_encoder_config_async, self.increase_error_count)
        async_call(self.dc.get_encoder_pid_config, None, self.get_encoder_pid_config_async, self.increase_error_count)
        async_call(self.dc.is_encoder_enabled, None, self.is_encoder_enabled_async, self.increase_error_count)
        
        
    def update_start(self):
        async_call(self.dc.get_drive_mode, None, self.drive_mode_update, self.increase_error_count)
        async_call(self.dc.get_velocity, None, self.get_velocity_async, self.increase_error_count)
        async_call(self.dc.get_acceleration, None, self.get_acceleration_async, self.increase_error_count)
        async_call(self.dc.get_pwm_frequency, None, self.get_pwm_frequency_async, self.increase_error_count)
        async_call(self.dc.is_enabled, None, self.is_enabled_async, self.increase_error_count)
#        if self.version >= (2, 0, 1):
#            self.update_encoder()
            

    def update_data(self):
        async_call(self.dc.get_stack_input_voltage, None, self.stack_input_voltage_update, self.increase_error_count)
        async_call(self.dc.get_external_input_voltage, None, self.external_input_voltage_update, self.increase_error_count)
        async_call(self.dc.get_minimum_voltage, None, self.minimum_voltage_update, self.increase_error_count)
        async_call(self.dc.get_current_consumption, None, self.current_consumption_update, self.increase_error_count)
        
    def acceleration_slider_released(self):
        value = self.acceleration_slider.value()
        self.acceleration_spin.setValue(value)
        try:
            self.dc.set_acceleration(value)
        except ip_connection.Error:
            return
        
    def acceleration_spin_finished(self):
        value = self.acceleration_spin.value()
        self.acceleration_slider.setValue(value)
        try:
            self.dc.set_acceleration(value)
        except ip_connection.Error:
            return
        
    def velocity_slider_released(self):
        value = self.velocity_slider.value()
        self.velocity_spin.setValue(value)
        try:
            self.dc.set_velocity(value)
        except ip_connection.Error:
            return
        
    def velocity_spin_finished(self):
        value = self.velocity_spin.value()
        self.velocity_slider.setValue(value)
        try:
            self.dc.set_velocity(value)
        except ip_connection.Error:
            return
        
    def frequency_slider_released(self):
        value = self.frequency_slider.value()
        self.frequency_spin.setValue(value)
        try:
            self.dc.set_pwm_frequency(value)
        except ip_connection.Error:
            return
        
    def frequency_spin_finished(self):
        value = self.frequency_spin.value()
        self.frequency_slider.setValue(value)
        try:
            self.dc.set_pwm_frequency(value)
        except ip_connection.Error:
            return
Esempio n. 12
0
class Stepper(PluginBase, Ui_Stepper):
    qtcb_position_reached = pyqtSignal(int)
    qtcb_under_voltage = pyqtSignal(int)
    
    def __init__(self, ipcon, uid, version):
        PluginBase.__init__(self, ipcon, uid, 'Stepper Brick', version)
        
        self.setupUi(self)
     
        self.stepper = BrickStepper(uid, ipcon)
        self.device = self.stepper
     
        self.endis_all(False)
        
        self.update_timer = QTimer()
        self.update_timer.timeout.connect(self.update_data)

        self.speedometer = SpeedoMeter()
        self.vertical_layout_right.insertWidget(5, self.speedometer)
        
        self.new_value = 0
        self.update_counter = 0
        
        self.full_brake_time = 0

        self.qem = QErrorMessage(self)
        self.qem.setWindowTitle("Under Voltage")
        
        self.velocity_slider.sliderReleased.connect(self.velocity_slider_released)
        self.velocity_slider.valueChanged.connect(self.velocity_spin.setValue)
        self.velocity_spin.editingFinished.connect(self.velocity_spin_finished)
        
        self.acceleration_slider.sliderReleased.connect(self.acceleration_slider_released)
        self.acceleration_slider.valueChanged.connect(self.acceleration_spin.setValue)
        self.acceleration_spin.editingFinished.connect(self.acceleration_spin_finished)
        
        self.deceleration_slider.sliderReleased.connect(self.deceleration_slider_released)
        self.deceleration_slider.valueChanged.connect(self.deceleration_spin.setValue)
        self.deceleration_spin.editingFinished.connect(self.deceleration_spin_finished)
        
#        self.decay_slider.sliderReleased.connect(self.decay_slider_released)
#        self.decay_slider.valueChanged.connect(self.decay_spin.setValue)
#        self.decay_spin.editingFinished.connect(self.decay_spin_finished)
        
        self.enable_checkbox.stateChanged.connect(self.enable_state_changed)
        self.forward_button.pressed.connect(self.forward_pressed)
        self.stop_button.pressed.connect(self.stop_pressed)
        self.full_brake_button.pressed.connect(self.full_brake_pressed)
        self.backward_button.pressed.connect(self.backward_pressed)
        self.to_button.pressed.connect(self.to_button_pressed)
        self.steps_button.pressed.connect(self.steps_button_pressed)
        self.motor_current_button.pressed.connect(self.motor_current_button_pressed)
        self.minimum_motor_voltage_button.pressed.connect(self.minimum_motor_voltage_button_pressed)
        
        self.mode_dropbox.currentIndexChanged.connect(self.mode_changed)
        
        self.qtcb_position_reached.connect(self.cb_position_reached)
        self.stepper.register_callback(self.stepper.CALLBACK_POSITION_REACHED, 
                                       self.qtcb_position_reached.emit)
        
        self.qtcb_under_voltage.connect(self.cb_under_voltage)
        self.stepper.register_callback(self.stepper.CALLBACK_UNDER_VOLTAGE, 
                                       self.qtcb_under_voltage.emit)
        
        self.update_data_async_thread = None
        
        self.ste = 0
        self.pos = 0
        self.current_velocity = 0
        self.cur = 0
        self.sv  = 0
        self.ev  = 0
        self.mv  = 0
        self.mod = 0
        
    def start(self):
        self.update_timer.start(100)
        self.update_start()
        
    def stop(self):
        self.update_timer.stop()

    def has_reset_device(self):
        return self.version >= (1, 1, 4)

    def reset_device(self):
        if self.has_reset_device():
            self.stepper.reset()

    def is_brick(self):
        return True

    def get_url_part(self):
        return 'stepper'

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickStepper.DEVICE_IDENTIFIER
    
    def cb_position_reached(self, position):
        self.position_update(position)
        self.endis_all(True)
            
    def disable_list(self, button_list):
        for button in button_list:
            button.setEnabled(False)
        
    def endis_all(self, value):
        self.forward_button.setEnabled(value)
        self.stop_button.setEnabled(value)
        self.backward_button.setEnabled(value)
        self.to_button.setEnabled(value)
        self.steps_button.setEnabled(value)
        self.full_brake_button.setEnabled(value)
        
    def mode_changed(self, index):
        try:
            self.stepper.set_step_mode(1 << index)
            self.mod = 1 << index
        except ip_connection.Error:
            return
        
    def forward_pressed(self):
        try:
            self.stepper.drive_forward()
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, self.steps_button])
        
    def backward_pressed(self):
        try:
            self.stepper.drive_backward()
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, self.steps_button])
        
    def stop_pressed(self):
        try:
            self.stepper.stop()
        except ip_connection.Error:
            return
        self.endis_all(True)
        
    def full_brake_pressed(self):
        try:
            self.stepper.full_brake()
        except ip_connection.Error:
            return
        self.endis_all(True)
        
    def to_button_pressed(self):
        drive_to = self.to_spin.value()
        try:
            self.stepper.set_target_position(drive_to)
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, 
                           self.steps_button, 
                           self.forward_button,
                           self.backward_button])
        
    def steps_button_pressed(self):
        drive_steps = self.steps_spin.value()
        try:
            self.stepper.set_steps(drive_steps)
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, 
                           self.steps_button, 
                           self.forward_button,
                           self.backward_button])
        
    def motor_current_button_pressed(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(0)
        qid.setIntMaximum(2500)
        qid.setIntStep(100)
        async_call(self.stepper.get_motor_current, None, qid.setIntValue, self.increase_error_count)
        qid.intValueSelected.connect(self.motor_current_selected)
        qid.setLabelText("Choose motor current in mA.")
#                         "<font color=red>Setting this too high can destroy your Motor.</font>")
        qid.open()
        
    def minimum_motor_voltage_button_pressed(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(0)
        qid.setIntMaximum(40000)
        qid.setIntStep(100)
        async_call(self.stepper.get_minimum_voltage, None, qid.setIntValue, self.increase_error_count)
        qid.intValueSelected.connect(self.minimum_motor_voltage_selected)
        qid.setLabelText("Choose minimum motor voltage in mV.")
        qid.open()
        
    def motor_current_selected(self, value):
        try:
            self.stepper.set_motor_current(value)
        except ip_connection.Error:
            return
        
    def minimum_motor_voltage_selected(self, value):
        try:
            self.stepper.set_minimum_voltage(value)
        except ip_connection.Error:
            return
        
    def cb_under_voltage(self, ov):
        mv_str = self.minimum_voltage_label.text()
        ov_str = "%gV"  % round(ov/1000.0, 1)
        if not self.qem.isVisible():
            self.qem.showMessage("Under Voltage: Output Voltage of " + ov_str +
                                 " is below minimum voltage of " + mv_str,
                                 "Stepper_UnderVoltage")
        
    def enable_state_changed(self, state):
        try:
            if state == Qt.Checked:
                self.endis_all(True)
                self.stepper.enable()
            elif state == Qt.Unchecked:
                self.endis_all(False)
                self.stepper.disable()
        except ip_connection.Error:
            return
        
    def stack_input_voltage_update(self, sv):
        sv_str = "%gV"  % round(sv/1000.0, 1)
        self.stack_voltage_label.setText(sv_str)
        
    def external_input_voltage_update(self, ev):
        ev_str = "%gV"  % round(ev/1000.0, 1)
        self.external_voltage_label.setText(ev_str)
        
    def minimum_voltage_update(self, mv):
        mv_str = "%gV"  % round(mv/1000.0, 1)
        self.minimum_voltage_label.setText(mv_str)
        
    def maximum_current_update(self, cur):
        cur_str = "%gA"  % round(cur/1000.0, 1)
        self.maximum_current_label.setText(cur_str)
        
    def position_update(self, pos):
        pos_str = "%d" % pos
        self.position_label.setText(pos_str)
        
    def remaining_steps_update(self, ste):
        ste_str = "%d" % ste
        self.remaining_steps_label.setText(ste_str)
        
    def mode_update(self, mod):
        if mod == 8:
            index = 3
        elif mod == 4:
            index = 2
        elif mod == 2:
            index = 1
        else:
            index = 0
            
        self.mode_dropbox.setCurrentIndex(index)
        
    def get_max_velocity_async(self, velocity):
        if not self.velocity_slider.isSliderDown():
            if velocity != self.velocity_slider.sliderPosition():
                self.velocity_slider.setSliderPosition(velocity)
                self.velocity_spin.setValue(velocity)
        
    def get_speed_ramping_async(self, ramp):
        acc, dec = ramp
        if not self.acceleration_slider.isSliderDown() and \
           not self.deceleration_slider.isSliderDown():
            if acc != self.acceleration_slider.sliderPosition():
                self.acceleration_slider.setSliderPosition(acc)
                self.acceleration_spin.setValue(acc)
            if dec != self.deceleration_slider.sliderPosition():
                self.deceleration_slider.setSliderPosition(dec)
                self.deceleration_spin.setValue(dec)
        
    def is_enabled_async(self, enabled):
        if enabled:
            if self.enable_checkbox.checkState() != Qt.Checked:
                self.endis_all(True)
                self.enable_checkbox.setCheckState(Qt.Checked)
        else:
            if self.enable_checkbox.checkState() != Qt.Unchecked:
                self.endis_all(False)
                self.enable_checkbox.setCheckState(Qt.Unchecked)
        
    def update_start(self):
        async_call(self.stepper.get_max_velocity, None, self.get_max_velocity_async, self.increase_error_count)
        async_call(self.stepper.get_speed_ramping, None, self.get_speed_ramping_async, self.increase_error_count)
        async_call(self.stepper.is_enabled, None, self.is_enabled_async, self.increase_error_count)

    def update_data(self):
        async_call(self.stepper.get_remaining_steps, None, self.remaining_steps_update, self.increase_error_count)
        async_call(self.stepper.get_current_position, None, self.position_update, self.increase_error_count)
        async_call(self.stepper.get_current_velocity, None, self.speedometer.set_velocity, self.increase_error_count)

        self.update_counter += 1
        if self.update_counter % 10 == 0:
            async_call(self.stepper.get_motor_current, None, self.maximum_current_update, self.increase_error_count)
            async_call(self.stepper.get_stack_input_voltage, None, self.stack_input_voltage_update, self.increase_error_count)
            async_call(self.stepper.get_external_input_voltage, None, self.external_input_voltage_update, self.increase_error_count)
            async_call(self.stepper.get_minimum_voltage, None, self.minimum_voltage_update, self.increase_error_count)
            async_call(self.stepper.get_step_mode, None, self.mode_update, self.increase_error_count)
        
    def velocity_slider_released(self):
        value = self.velocity_slider.value()
        self.velocity_spin.setValue(value)
        try:
            self.stepper.set_max_velocity(value)
        except ip_connection.Error:
            return
 
    def velocity_spin_finished(self):
        value = self.velocity_spin.value()
        self.velocity_slider.setValue(value)
        try:
            self.stepper.set_max_velocity(value)
        except ip_connection.Error:
            return
    
    def acceleration_slider_released(self):
        acc = self.acceleration_slider.value()
        dec = self.deceleration_slider.value()
        self.acceleration_spin.setValue(acc)
        try:
            self.stepper.set_speed_ramping(acc, dec)
        except ip_connection.Error:
            return
 
    def acceleration_spin_finished(self):
        acc = self.acceleration_spin.value()
        dec = self.deceleration_spin.value()
        self.acceleration_slider.setValue(acc)
        try:
            self.stepper.set_speed_ramping(acc, dec)
        except ip_connection.Error:
            return
            
    def deceleration_slider_released(self):
        acc = self.acceleration_slider.value()
        dec = self.deceleration_slider.value()
        self.deceleration_spin.setValue(dec)
        try:
            self.stepper.set_speed_ramping(acc, dec)
        except ip_connection.Error:
            return
 
    def deceleration_spin_finished(self):
        acc = self.acceleration_spin.value()
        dec = self.deceleration_spin.value()
        self.deceleration_slider.setValue(dec)
        try:
            self.stepper.set_speed_ramping(acc, dec)
        except ip_connection.Error:
            return
Esempio n. 13
0
class SilentStepper(PluginBase, Ui_SilentStepper):
    qtcb_position_reached = pyqtSignal(int)
    qtcb_under_voltage = pyqtSignal(int)

    def __init__(self, *args):
        PluginBase.__init__(self, BrickSilentStepper, *args)

        self.setupUi(self)

        self.silent_stepper = self.device

        self.endis_all(False)

        self.update_timer = QTimer()
        self.update_timer.timeout.connect(self.update_data)

        self.speedometer = SpeedoMeter()
        self.vertical_layout_right.insertWidget(5, self.speedometer)

        self.new_value = 0
        self.update_counter = 0

        self.full_brake_time = 0

        self.qem = QErrorMessage(self)
        self.qem.setWindowTitle("Under Voltage")

        self.velocity_syncer = SliderSpinSyncer(self.velocity_slider,
                                                self.velocity_spin,
                                                self.velocity_changed)

        self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider,
                                                    self.acceleration_spin,
                                                    self.acceleration_changed)

        self.deceleration_syncer = SliderSpinSyncer(self.deceleration_slider,
                                                    self.deceleration_spin,
                                                    self.deceleration_changed)

        self.enable_checkbox.stateChanged.connect(self.enable_state_changed)
        self.forward_button.clicked.connect(self.forward_clicked)
        self.stop_button.clicked.connect(self.stop_clicked)
        self.full_brake_button.clicked.connect(self.full_brake_clicked)
        self.backward_button.clicked.connect(self.backward_clicked)
        self.to_button.clicked.connect(self.to_button_clicked)
        self.steps_button.clicked.connect(self.steps_button_clicked)
        self.motor_current_button.clicked.connect(self.motor_current_button_clicked)
        self.minimum_motor_voltage_button.clicked.connect(self.minimum_motor_voltage_button_clicked)

        self.qtcb_position_reached.connect(self.cb_position_reached)
        self.silent_stepper.register_callback(self.silent_stepper.CALLBACK_POSITION_REACHED,
                                              self.qtcb_position_reached.emit)

        self.qtcb_under_voltage.connect(self.cb_under_voltage)
        self.silent_stepper.register_callback(self.silent_stepper.CALLBACK_UNDER_VOLTAGE,
                                              self.qtcb_under_voltage.emit)

        # Step Configuration
        self.step_resolution_dropbox.currentIndexChanged.connect(self.step_configuration_changed)
        self.interpolate_checkbox.stateChanged.connect(self.step_configuration_changed)

        # Basic Configuration
        self.standstill_current_spin.valueChanged.connect(self.basic_configuration_changed)
        self.motor_run_current_spin.valueChanged.connect(self.basic_configuration_changed)
        self.standstill_delay_time_spin.valueChanged.connect(self.basic_configuration_changed)
        self.power_down_time_spin.valueChanged.connect(self.basic_configuration_changed)
        self.stealth_threshold_spin.valueChanged.connect(self.basic_configuration_changed)
        self.coolstep_threashold_spin.valueChanged.connect(self.basic_configuration_changed)
        self.classic_threshold_spin.valueChanged.connect(self.basic_configuration_changed)
        self.high_velocity_chopper_mode_checkbox.stateChanged.connect(self.basic_configuration_changed)

        # Spreadcycle Configuration
        self.slow_decay_duration_spin.valueChanged.connect(self.spreadcycle_configuration_changed)
        self.enable_random_slow_decay_checkbox.stateChanged.connect(self.spreadcycle_configuration_changed)
        self.fast_decay_duration_spin.valueChanged.connect(self.spreadcycle_configuration_changed)
        self.hysteresis_start_value_spin.valueChanged.connect(self.spreadcycle_configuration_changed)
        self.hysteresis_end_value_spin.valueChanged.connect(self.spreadcycle_configuration_changed)
        self.sine_wave_offset_spin.valueChanged.connect(self.spreadcycle_configuration_changed)
        self.chopper_mode_combo.currentIndexChanged.connect(self.spreadcycle_configuration_changed)
        self.comparator_blank_time_combo.currentIndexChanged.connect(self.spreadcycle_configuration_changed)
        self.fast_decay_without_comparator_checkbox.stateChanged.connect(self.spreadcycle_configuration_changed)

        # Stealth Configuration
        self.enable_stealth_checkbox.stateChanged.connect(self.stealth_configuration_changed)
        self.amplitude_spin.valueChanged.connect(self.stealth_configuration_changed)
        self.gradient_spin.valueChanged.connect(self.stealth_configuration_changed)
        self.enable_autoscale_checkbox.stateChanged.connect(self.stealth_configuration_changed)
        self.force_symmetric_checkbox.stateChanged.connect(self.stealth_configuration_changed)
        self.freewheel_mode_combo.currentIndexChanged.connect(self.stealth_configuration_changed)

        # Coolstep Configuration
        self.minimum_stallguard_value_spin.valueChanged.connect(self.coolstep_configuration_changed)
        self.maximum_stallguard_value_spin.valueChanged.connect(self.coolstep_configuration_changed)
        self.current_up_step_width_combo.currentIndexChanged.connect(self.coolstep_configuration_changed)
        self.current_down_step_width_combo.currentIndexChanged.connect(self.coolstep_configuration_changed)
        self.minimum_current_combo.currentIndexChanged.connect(self.coolstep_configuration_changed)
        self.stallguard_threshold_value_spin.valueChanged.connect(self.coolstep_configuration_changed)
        self.stallguard_mode_combo.currentIndexChanged.connect(self.coolstep_configuration_changed)

        # Misc Configuration
        self.disable_short_to_ground_protection_checkbox.stateChanged.connect(self.misc_configuration_changed)
        self.synchronize_phase_frequency_spin.valueChanged.connect(self.misc_configuration_changed)

        self.ste = 0
        self.pos = 0
        self.current_velocity = 0
        self.cur = 0
        self.sv  = 0
        self.ev  = 0
        self.mv  = 0
        self.mod = 0

        self.status_led_action = QAction('Status LED', self)
        self.status_led_action.setCheckable(True)
        self.status_led_action.toggled.connect(lambda checked: self.silent_stepper.enable_status_led() if checked else self.silent_stepper.disable_status_led())
        self.set_configs([(0, None, [self.status_led_action])])

        reset = QAction('Reset', self)
        reset.triggered.connect(lambda: self.silent_stepper.reset())
        self.set_actions([(0, None, [reset])])

    def start(self):
        async_call(self.silent_stepper.is_status_led_enabled, None, self.status_led_action.setChecked, self.increase_error_count)

        self.update_timer.start(100)
        self.update_start()

    def stop(self):
        self.update_timer.stop()

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickSilentStepper.DEVICE_IDENTIFIER

    def cb_position_reached(self, position):
        self.position_update(position)
        self.endis_all(True)

    def disable_list(self, button_list):
        for button in button_list:
            button.setEnabled(False)

    def endis_all(self, value):
        self.forward_button.setEnabled(value)
        self.stop_button.setEnabled(value)
        self.backward_button.setEnabled(value)
        self.to_button.setEnabled(value)
        self.steps_button.setEnabled(value)
        self.full_brake_button.setEnabled(value)

    def step_configuration_changed(self, _):
        step_resolution = self.step_resolution_dropbox.currentIndex()
        interpolation = self.interpolate_checkbox.isChecked()
        try:
            self.silent_stepper.set_step_configuration(step_resolution, interpolation)
        except ip_connection.Error:
            return

    def basic_configuration_changed(self, _):
        standstill_current = self.standstill_current_spin.value()
        motor_run_current = self.motor_run_current_spin.value()
        standstill_delay_time = self.standstill_delay_time_spin.value()
        power_down_time = self.power_down_time_spin.value()
        stealth_threshold = self.stealth_threshold_spin.value()
        coolstep_threshold = self.coolstep_threashold_spin.value()
        classic_threshold = self.classic_threshold_spin.value()
        high_velocity_chopper_mode = self.high_velocity_chopper_mode_checkbox.isChecked()

        try:
            self.silent_stepper.set_basic_configuration(standstill_current, motor_run_current, standstill_delay_time, power_down_time, stealth_threshold, coolstep_threshold, classic_threshold, high_velocity_chopper_mode)
        except ip_connection.Error:
            return

    def spreadcycle_configuration_changed(self, _):
        slow_decay_duration = self.slow_decay_duration_spin.value()
        enable_random_slow_decay = self.enable_random_slow_decay_checkbox.isChecked()
        fast_decay_duration = self.fast_decay_duration_spin.value()
        hysteresis_start_value = self.hysteresis_start_value_spin.value()
        hysteresis_end_value = self.hysteresis_end_value_spin.value()
        sine_wave_offset = self.sine_wave_offset_spin.value()
        chopper_mode = self.chopper_mode_combo.currentIndex()
        comparator_blank_time = self.comparator_blank_time_combo.currentIndex()
        fast_decay_without_comparator = self.fast_decay_without_comparator_checkbox.isChecked()

        try:
            self.silent_stepper.set_spreadcycle_configuration(slow_decay_duration, enable_random_slow_decay, fast_decay_duration, hysteresis_start_value, hysteresis_end_value, sine_wave_offset, chopper_mode, comparator_blank_time, fast_decay_without_comparator)
        except ip_connection.Error:
            return

    def stealth_configuration_changed(self, _):
        enable_stealth = self.enable_stealth_checkbox.isChecked()
        amplitude = self.amplitude_spin.value()
        gradient = self.gradient_spin.value()
        enable_autoscale = self.enable_autoscale_checkbox.isChecked()
        force_symmetric = self.force_symmetric_checkbox.isChecked()
        freewheel_mode = self.freewheel_mode_combo.currentIndex()

        try:
            self.silent_stepper.set_stealth_configuration(enable_stealth, amplitude, gradient, enable_autoscale, force_symmetric, freewheel_mode)
        except ip_connection.Error:
            return

    def coolstep_configuration_changed(self, _):
        minimum_stallguard_value = self.minimum_stallguard_value_spin.value()
        maximum_stallguard_value = self.maximum_stallguard_value_spin.value()
        current_up_step_width = self.current_up_step_width_combo.currentIndex()
        current_down_step_width = self.current_down_step_width_combo.currentIndex()
        minimum_current = self.minimum_current_combo.currentIndex()
        stallguard_threshold_value = self.stallguard_threshold_value_spin.value()
        stallguard_mode = self.stallguard_mode_combo.currentIndex()

        try:
            self.silent_stepper.set_coolstep_configuration(minimum_stallguard_value, maximum_stallguard_value, current_up_step_width, current_down_step_width, minimum_current, stallguard_threshold_value, stallguard_mode)
        except ip_connection.Error:
            return

    def misc_configuration_changed(self, _):
        disable_short_to_ground_protection = self.disable_short_to_ground_protection_checkbox.isChecked()
        synchronize_phase_frequency = self.synchronize_phase_frequency_spin.value()

        try:
            self.silent_stepper.set_misc_configuration(disable_short_to_ground_protection, synchronize_phase_frequency)
        except ip_connection.Error:
            return

    def forward_clicked(self):
        try:
            self.silent_stepper.drive_forward()
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, self.steps_button])

    def backward_clicked(self):
        try:
            self.silent_stepper.drive_backward()
        except ip_connection.Error:
            return
        self.disable_list([self.to_button, self.steps_button])

    def stop_clicked(self):
        try:
            self.silent_stepper.stop()
        except ip_connection.Error:
            return
        self.endis_all(True)

    def full_brake_clicked(self):
        try:
            self.silent_stepper.full_brake()
        except ip_connection.Error:
            return
        self.endis_all(True)

    def to_button_clicked(self):
        drive_to = self.to_spin.value()
        try:
            self.silent_stepper.set_target_position(drive_to)
        except ip_connection.Error:
            return
        self.disable_list([self.to_button,
                           self.steps_button,
                           self.forward_button,
                           self.backward_button])

    def steps_button_clicked(self):
        drive_steps = self.steps_spin.value()
        try:
            self.silent_stepper.set_steps(drive_steps)
        except ip_connection.Error:
            return
        self.disable_list([self.to_button,
                           self.steps_button,
                           self.forward_button,
                           self.backward_button])

    def motor_current_button_clicked(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(360)
        qid.setIntMaximum(1640)
        qid.setIntStep(100)
        async_call(self.silent_stepper.get_motor_current, None, qid.setIntValue, self.increase_error_count)
        qid.intValueSelected.connect(self.motor_current_selected)
        qid.setLabelText("Choose motor current in mA.")
        qid.open()

    def minimum_motor_voltage_button_clicked(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(0)
        qid.setIntMaximum(40000)
        qid.setIntStep(100)
        async_call(self.silent_stepper.get_minimum_voltage, None, qid.setIntValue, self.increase_error_count)
        qid.intValueSelected.connect(self.minimum_motor_voltage_selected)
        qid.setLabelText("Choose minimum motor voltage in mV.")
        qid.open()

    def motor_current_selected(self, value):
        try:
            self.silent_stepper.set_motor_current(value)
        except ip_connection.Error:
            return

    def minimum_motor_voltage_selected(self, value):
        try:
            self.silent_stepper.set_minimum_voltage(value)
        except ip_connection.Error:
            return

    def cb_under_voltage(self, ov):
        mv_str = self.minimum_voltage_label.text()
        ov_str = "%gV"  % round(ov/1000.0, 1)
        if not self.qem.isVisible():
            self.qem.showMessage("Under Voltage: Output Voltage of " + ov_str +
                                 " is below minimum voltage of " + mv_str,
                                 "SilentStepper_UnderVoltage")

    def enable_state_changed(self, state):
        try:
            if state == Qt.Checked:
                self.endis_all(True)
                self.silent_stepper.enable()
            elif state == Qt.Unchecked:
                self.endis_all(False)
                self.silent_stepper.disable()
        except ip_connection.Error:
            return

    def stack_input_voltage_update(self, sv):
        sv_str = "%gV"  % round(sv/1000.0, 1)
        self.stack_voltage_label.setText(sv_str)

    def external_input_voltage_update(self, ev):
        ev_str = "%gV"  % round(ev/1000.0, 1)
        self.external_voltage_label.setText(ev_str)

    def minimum_voltage_update(self, mv):
        mv_str = "%gV"  % round(mv/1000.0, 1)
        self.minimum_voltage_label.setText(mv_str)

    def maximum_current_update(self, cur):
        cur_str = "%gA"  % round(cur/1000.0, 1)
        self.maximum_current_label.setText(cur_str)

    def position_update(self, pos):
        pos_str = "%d" % pos
        self.position_label.setText(pos_str)

    def remaining_steps_update(self, ste):
        ste_str = "%d" % ste
        self.remaining_steps_label.setText(ste_str)

    def driver_status_update(self, update):
        if update.open_load == 0:
            self.status_open_load.setText('No')
        elif update.open_load == 1:
            self.status_open_load.setText('Phase A')
        elif update.open_load == 2:
            self.status_open_load.setText('Phase B')
        elif update.open_load == 3:
            self.status_open_load.setText('Phase A and B')
        else:
            self.status_open_load.setText('Unknown')

        if update.short_to_ground == 0:
            self.status_short_to_ground.setText('No')
        elif update.short_to_ground == 1:
            self.status_short_to_ground.setText('Phase A')
        elif update.short_to_ground == 2:
            self.status_short_to_ground.setText('Phase B')
        elif update.short_to_ground == 3:
            self.status_short_to_ground.setText('Phase A and B')
        else:
            self.status_short_to_ground.setText('Unknown')

        if update.over_temperature == 0:
            self.status_over_temperature.setText('No')
        elif update.over_temperature == 1:
            self.status_over_temperature.setText('<font color=yellow>Warning</font>')
        elif update.over_temperature == 2:
            self.status_over_temperature.setText('<font color=red>Limit</font>')

        if update.motor_stalled:
            self.status_motor_stalled.setText('Yes')
        else:
            self.status_motor_stalled.setText('No')

        self.status_actual_motor_current.setText(str(update.actual_motor_current))

        if update.full_step_active:
            self.status_full_step_active.setText('Yes')
        else:
            self.status_full_step_active.setText('No')

        self.status_stallguard_result.setText(str(update.stallguard_result))
        self.status_stealth_voltage_amplitude.setText(str(update.stealth_voltage_amplitude))

    def get_max_velocity_async(self, velocity):
        if not self.velocity_slider.isSliderDown():
            if velocity != self.velocity_slider.sliderPosition():
                self.velocity_slider.setSliderPosition(velocity)
                self.velocity_spin.setValue(velocity)

    def get_speed_ramping_async(self, ramp):
        acc, dec = ramp
        if not self.acceleration_slider.isSliderDown() and \
           not self.deceleration_slider.isSliderDown():
            if acc != self.acceleration_slider.sliderPosition():
                self.acceleration_slider.setSliderPosition(acc)
                self.acceleration_spin.setValue(acc)
            if dec != self.deceleration_slider.sliderPosition():
                self.deceleration_slider.setSliderPosition(dec)
                self.deceleration_spin.setValue(dec)

    def is_enabled_async(self, enabled):
        if enabled:
            if not self.enable_checkbox.isChecked():
                self.endis_all(True)
                self.enable_checkbox.blockSignals(True)
                self.enable_checkbox.setChecked(True)
                self.enable_checkbox.blockSignals(False)
        else:
            if self.enable_checkbox.isChecked():
                self.endis_all(False)
                self.enable_checkbox.blockSignals(True)
                self.enable_checkbox.setChecked(False)
                self.enable_checkbox.blockSignals(False)

    def get_step_configuration_async(self, conf):
        self.step_resolution_dropbox.blockSignals(True)
        self.step_resolution_dropbox.setCurrentIndex(conf.step_resolution)
        self.step_resolution_dropbox.blockSignals(False)

        self.interpolate_checkbox.blockSignals(True)
        self.interpolate_checkbox.setChecked(conf.interpolation)
        self.interpolate_checkbox.blockSignals(False)

    def get_basic_configuration_async(self, conf):
        self.standstill_current_spin.blockSignals(True)
        self.standstill_current_spin.setValue(conf.standstill_current)
        self.standstill_current_spin.blockSignals(False)

        self.motor_run_current_spin.blockSignals(True)
        self.motor_run_current_spin.setValue(conf.motor_run_current)
        self.motor_run_current_spin.blockSignals(False)

        self.standstill_delay_time_spin.blockSignals(True)
        self.standstill_delay_time_spin.setValue(conf.standstill_delay_time)
        self.standstill_delay_time_spin.blockSignals(False)

        self.power_down_time_spin.blockSignals(True)
        self.power_down_time_spin.setValue(conf.power_down_time)
        self.power_down_time_spin.blockSignals(False)

        self.stealth_threshold_spin.blockSignals(True)
        self.stealth_threshold_spin.setValue(conf.stealth_threshold)
        self.stealth_threshold_spin.blockSignals(False)

        self.coolstep_threashold_spin.blockSignals(True)
        self.coolstep_threashold_spin.setValue(conf.coolstep_threshold)
        self.coolstep_threashold_spin.blockSignals(False)

        self.classic_threshold_spin.blockSignals(True)
        self.classic_threshold_spin.setValue(conf.classic_threshold)
        self.classic_threshold_spin.blockSignals(False)

        self.high_velocity_chopper_mode_checkbox.blockSignals(True)
        self.high_velocity_chopper_mode_checkbox.setChecked(conf.high_velocity_chopper_mode)
        self.high_velocity_chopper_mode_checkbox.blockSignals(False)

    def get_spreadcycle_configuration_async(self, conf):
        self.slow_decay_duration_spin.blockSignals(True)
        self.slow_decay_duration_spin.setValue(conf.slow_decay_duration)
        self.slow_decay_duration_spin.blockSignals(False)

        self.enable_random_slow_decay_checkbox.blockSignals(True)
        self.enable_random_slow_decay_checkbox.setChecked(conf.enable_random_slow_decay)
        self.enable_random_slow_decay_checkbox.blockSignals(False)

        self.fast_decay_duration_spin.blockSignals(True)
        self.fast_decay_duration_spin.setValue(conf.fast_decay_duration)
        self.fast_decay_duration_spin.blockSignals(False)

        self.hysteresis_start_value_spin.blockSignals(True)
        self.hysteresis_start_value_spin.setValue(conf.hysteresis_start_value)
        self.hysteresis_start_value_spin.blockSignals(False)

        self.hysteresis_end_value_spin.blockSignals(True)
        self.hysteresis_end_value_spin.setValue(conf.hysteresis_end_value)
        self.hysteresis_end_value_spin.blockSignals(False)

        self.sine_wave_offset_spin.blockSignals(True)
        self.sine_wave_offset_spin.setValue(conf.sine_wave_offset)
        self.sine_wave_offset_spin.blockSignals(False)

        self.chopper_mode_combo.blockSignals(True)
        self.chopper_mode_combo.setCurrentIndex(conf.chopper_mode)
        self.chopper_mode_combo.blockSignals(False)

        self.standstill_current_spin.blockSignals(True)
        self.comparator_blank_time_combo.setCurrentIndex(conf.comparator_blank_time)
        self.standstill_current_spin.blockSignals(False)

        self.fast_decay_without_comparator_checkbox.blockSignals(True)
        self.fast_decay_without_comparator_checkbox.setChecked(conf.fast_decay_without_comparator)
        self.fast_decay_without_comparator_checkbox.blockSignals(False)


    def get_stealth_configuration_async(self, conf):
        self.enable_stealth_checkbox.blockSignals(True)
        self.enable_stealth_checkbox.setChecked(conf.enable_stealth)
        self.enable_stealth_checkbox.blockSignals(False)

        self.amplitude_spin.blockSignals(True)
        self.amplitude_spin.setValue(conf.amplitude)
        self.amplitude_spin.blockSignals(False)

        self.gradient_spin.blockSignals(True)
        self.gradient_spin.setValue(conf.gradient)
        self.gradient_spin.blockSignals(False)

        self.enable_autoscale_checkbox.blockSignals(True)
        self.enable_autoscale_checkbox.setChecked(conf.enable_autoscale)
        self.enable_autoscale_checkbox.blockSignals(False)

        self.force_symmetric_checkbox.blockSignals(True)
        self.force_symmetric_checkbox.setChecked(conf.force_symmetric)
        self.force_symmetric_checkbox.blockSignals(False)

        self.freewheel_mode_combo.blockSignals(True)
        self.freewheel_mode_combo.setCurrentIndex(conf.freewheel_mode)
        self.freewheel_mode_combo.blockSignals(False)

    def get_coolstep_configuration_async(self, conf):
        self.minimum_stallguard_value_spin.blockSignals(True)
        self.minimum_stallguard_value_spin.setValue(conf.minimum_stallguard_value)
        self.minimum_stallguard_value_spin.blockSignals(False)

        self.maximum_stallguard_value_spin.blockSignals(True)
        self.maximum_stallguard_value_spin.setValue(conf.maximum_stallguard_value)
        self.maximum_stallguard_value_spin.blockSignals(False)

        self.current_up_step_width_combo.blockSignals(True)
        self.current_up_step_width_combo.setCurrentIndex(conf.current_up_step_width)
        self.current_up_step_width_combo.blockSignals(False)

        self.current_down_step_width_combo.blockSignals(True)
        self.current_down_step_width_combo.setCurrentIndex(conf.current_down_step_width)
        self.current_down_step_width_combo.blockSignals(False)

        self.minimum_current_combo.blockSignals(True)
        self.minimum_current_combo.setCurrentIndex(conf.minimum_current)
        self.minimum_current_combo.blockSignals(False)

        self.stallguard_threshold_value_spin.blockSignals(True)
        self.stallguard_threshold_value_spin.setValue(conf.stallguard_threshold_value)
        self.stallguard_threshold_value_spin.blockSignals(False)

        self.stallguard_mode_combo.blockSignals(True)
        self.stallguard_mode_combo.setCurrentIndex(conf.stallguard_mode)
        self.stallguard_mode_combo.blockSignals(False)

    def get_misc_configuration_async(self, conf):
        self.disable_short_to_ground_protection_checkbox.blockSignals(True)
        self.disable_short_to_ground_protection_checkbox.setChecked(conf.disable_short_to_ground_protection)
        self.disable_short_to_ground_protection_checkbox.blockSignals(False)

        self.synchronize_phase_frequency_spin.blockSignals(True)
        self.synchronize_phase_frequency_spin.setValue(conf.synchronize_phase_frequency)
        self.synchronize_phase_frequency_spin.blockSignals(False)

    def update_start(self):
        async_call(self.silent_stepper.get_max_velocity, None, self.get_max_velocity_async, self.increase_error_count)
        async_call(self.silent_stepper.get_speed_ramping, None, self.get_speed_ramping_async, self.increase_error_count)
        async_call(self.silent_stepper.is_enabled, None, self.is_enabled_async, self.increase_error_count)
        async_call(self.silent_stepper.get_step_configuration, None, self.get_step_configuration_async, self.increase_error_count)
        async_call(self.silent_stepper.get_basic_configuration, None, self.get_basic_configuration_async, self.increase_error_count)
        async_call(self.silent_stepper.get_spreadcycle_configuration, None, self.get_spreadcycle_configuration_async, self.increase_error_count)
        async_call(self.silent_stepper.get_stealth_configuration, None, self.get_stealth_configuration_async, self.increase_error_count)
        async_call(self.silent_stepper.get_coolstep_configuration, None, self.get_coolstep_configuration_async, self.increase_error_count)
        async_call(self.silent_stepper.get_misc_configuration, None, self.get_misc_configuration_async, self.increase_error_count)

    def update_data(self):
        async_call(self.silent_stepper.get_remaining_steps, None, self.remaining_steps_update, self.increase_error_count)
        async_call(self.silent_stepper.get_current_position, None, self.position_update, self.increase_error_count)
        async_call(self.silent_stepper.get_current_velocity, None, self.speedometer.set_velocity, self.increase_error_count)

        self.update_counter += 1
        if self.update_counter % 10 == 0:
            async_call(self.silent_stepper.get_motor_current, None, self.maximum_current_update, self.increase_error_count)
            async_call(self.silent_stepper.get_stack_input_voltage, None, self.stack_input_voltage_update, self.increase_error_count)
            async_call(self.silent_stepper.get_external_input_voltage, None, self.external_input_voltage_update, self.increase_error_count)
            async_call(self.silent_stepper.get_minimum_voltage, None, self.minimum_voltage_update, self.increase_error_count)
            async_call(self.silent_stepper.get_driver_status, None, self.driver_status_update, self.increase_error_count)

    def velocity_changed(self, value):
        try:
            self.silent_stepper.set_max_velocity(value)
        except ip_connection.Error:
            return

    def acceleration_changed(self, value):
        dec = self.deceleration_spin.value()
        try:
            self.silent_stepper.set_speed_ramping(value, dec)
        except ip_connection.Error:
            return

    def deceleration_changed(self, value):
        acc = self.acceleration_slider.value()
        try:
            self.silent_stepper.set_speed_ramping(acc, value)
        except ip_connection.Error:
            return
Esempio n. 14
0
class Blinkenlights(QApplication):
    HOST = "localhost"
    PORT = 4223

    ipcon = None

    projects = []
    active_project = None

    error_msg = None

    def __init__(self, args):
        super(QApplication, self).__init__(args)

        self.error_msg = QErrorMessage()
        self.error_msg.setWindowTitle("Starter Kit: Blinkenlights Demo " + config.DEMO_VERSION)

        signal.signal(signal.SIGINT, self.exit_demo)
        signal.signal(signal.SIGTERM, self.exit_demo)

        self.make_gui()
        self.connect()

    def exit_demo(self, signl=None, frme=None):
        try:
            self.ipcon.disconnect()
            self.timer.stop()
            self.tabs.destroy()
        except:
            pass

        sys.exit()

    def make_gui(self):
        self.main = MainWindow(self)
        self.main.setWindowIcon(QIcon(os.path.join(ProgramPath.program_path(), "demo-icon.png")))

        self.tabs = QTabWidget()

        widget = QWidget()
        layout = QVBoxLayout()
        layout.addWidget(self.tabs)
        widget.setLayout(layout)

        self.main.setCentralWidget(widget)

        self.setup = SetupWidget(self.tabs, self)
        self.tetris = TetrisWidget(self.tabs, self)
        self.pong = PongWidget(self.tabs, self)
        self.fire = FireWidget(self.tabs, self)
        self.text = TextWidget(self.tabs, self)
        self.images = ImagesWidget(self.tabs, self)
        self.rainbow = RainbowWidget(self.tabs, self)

        self.projects.append(self.setup)
        self.projects.append(self.tetris)
        self.projects.append(self.pong)
        self.projects.append(self.fire)
        self.projects.append(self.text)
        self.projects.append(self.images)
        self.projects.append(self.rainbow)

        self.tabs.addTab(self.setup, "Setup")
        self.tabs.addTab(self.tetris, "Tetris")
        self.tabs.addTab(self.pong, "Pong")
        self.tabs.addTab(self.fire, "Fire")
        self.tabs.addTab(self.text, "Text")
        self.tabs.addTab(self.images, "Images")
        self.tabs.addTab(self.rainbow, "Rainbow")

        self.active_project = self.projects[0]

        self.tabs.currentChanged.connect(self.tab_changed_slot)

        self.main.setWindowTitle("Starter Kit: Blinkenlights Demo " + config.DEMO_VERSION)
        self.main.show()

    def connect(self):
        config.UID_LED_STRIP_BRICKLET = None
        self.setup.label_led_strip_found.setText('No')
        self.setup.label_led_strip_uid.setText('None')

        config.UID_MULTI_TOUCH_BRICKLET = None
        self.setup.label_multi_touch_found.setText('No')
        self.setup.label_multi_touch_uid.setText('None')

        config.UID_DUAL_BUTTON_BRICKLET = (None, None)
        self.setup.label_dual_button1_found.setText('No')
        self.setup.label_dual_button1_uid.setText('None')
        self.setup.label_dual_button2_found.setText('No')
        self.setup.label_dual_button2_uid.setText('None')

        config.UID_PIEZO_SPEAKER_BRICKLET = None
        self.setup.label_piezo_speaker_found.setText('No')
        self.setup.label_piezo_speaker_uid.setText('None')

        config.UID_SEGMENT_DISPLAY_4X7_BRICKLET = None
        self.setup.label_segment_display_found.setText('No')
        self.setup.label_segment_display_uid.setText('None')

        if self.ipcon != None:
            try:
                self.ipcon.disconnect()
            except:
                pass

        self.ipcon = IPConnection()

        host = self.setup.edit_host.text()
        port = self.setup.spinbox_port.value()
        try:
            self.ipcon.connect(host, port)
        except Error as e:
            self.error_msg.showMessage('Connection Error: ' + str(e.description) + "<br><br>Brickd installed and running?")
            return
        except socket.error as e:
            self.error_msg.showMessage('Socket error: ' + str(e) + "<br><br>Brickd installed and running?")
            return

        self.ipcon.register_callback(IPConnection.CALLBACK_ENUMERATE,
                                     self.cb_enumerate)
        self.ipcon.register_callback(IPConnection.CALLBACK_CONNECTED,
                                     self.cb_connected)

        # Wait for a second to give user visual feedback
        timer = QTimer(self)
        timer.setSingleShot(True)
        timer.timeout.connect(self.ipcon.enumerate)
        timer.start(250)

    def tab_changed_slot(self, tabIndex):
        self.active_project.stop()
        self.active_project = self.projects[tabIndex]
        self.active_project.start()

    def cb_enumerate(self, uid, connected_uid, position, hardware_version,
                     firmware_version, device_identifier, enumeration_type):
        if enumeration_type == IPConnection.ENUMERATION_TYPE_CONNECTED or \
           enumeration_type == IPConnection.ENUMERATION_TYPE_AVAILABLE:
            if device_identifier == LEDStrip.DEVICE_IDENTIFIER:
                config.UID_LED_STRIP_BRICKLET = uid
                self.setup.label_led_strip_found.setText('Yes')
                self.setup.label_led_strip_uid.setText(uid)
            elif device_identifier == MultiTouch.DEVICE_IDENTIFIER:
                config.UID_MULTI_TOUCH_BRICKLET = uid
                self.setup.label_multi_touch_found.setText('Yes')
                self.setup.label_multi_touch_uid.setText(uid)
            elif device_identifier == DualButton.DEVICE_IDENTIFIER:
                if config.UID_DUAL_BUTTON_BRICKLET[0] == None:
                    config.UID_DUAL_BUTTON_BRICKLET = (uid, None)
                    self.setup.label_dual_button1_found.setText('Yes')
                    self.setup.label_dual_button1_uid.setText(uid)
                else:
                    config.UID_DUAL_BUTTON_BRICKLET = (config.UID_DUAL_BUTTON_BRICKLET[0], uid)
                    self.setup.label_dual_button2_found.setText('Yes')
                    self.setup.label_dual_button2_uid.setText(uid)
            elif device_identifier == PiezoSpeaker.DEVICE_IDENTIFIER:
                config.UID_PIEZO_SPEAKER_BRICKLET = uid
                self.setup.label_piezo_speaker_found.setText('Yes')
                self.setup.label_piezo_speaker_uid.setText(uid)
            elif device_identifier == SegmentDisplay4x7.DEVICE_IDENTIFIER:
                config.UID_SEGMENT_DISPLAY_4X7_BRICKLET = uid
                self.setup.label_segment_display_found.setText('Yes')
                self.setup.label_segment_display_uid.setText(uid)

    def cb_connected(self, connected_reason):
        if connected_reason == IPConnection.CONNECT_REASON_AUTO_RECONNECT:
            while True:
                try:
                    self.ipcon.enumerate()
                    break
                except Error as e:
                    self.error_msg.showMessage('Enumerate Error: ' + str(e.description))
                    time.sleep(1)
Esempio n. 15
0
class Servo(PluginBase, Ui_Servo):
    qtcb_under_voltage = pyqtSignal(int)

    def __init__(self, *args):
        PluginBase.__init__(self, BrickServo, *args)

        self.setupUi(self)

        self.servo = self.device

        self.position_list = []
        self.velocity_list = []
        self.acceleration_list = []
        self.enable_list = []

        self.up_cur = 0
        self.up_siv = 0
        self.up_eiv = 0
        self.up_opv = 0
        self.up_mv = 0

        self.up_ena = [0] * 7
        self.up_pos = [0] * 7
        self.up_vel = [0] * 7
        self.up_acc = [0] * 7

        self.update_timer = QTimer()
        self.update_timer.timeout.connect(self.update_apply)
        self.update_timer.setInterval(50)

        self.alive = True

        for i in range(1, 8):
            label = QLabel()
            label.setText('Off')
            self.enable_list.append(label)
            self.status_grid.addWidget(label, i, 1)

        for i in range(1, 8):
            pk = PositionKnob()
            self.position_list.append(pk)
            self.status_grid.addWidget(pk, i, 2)

        for i in range(1, 8):
            cb = ColorBar(Qt.Vertical)
            self.velocity_list.append(cb)
            self.status_grid.addWidget(cb, i, 3)

        for i in range(1, 8):
            cb = ColorBar(Qt.Vertical)
            self.acceleration_list.append(cb)
            self.status_grid.addWidget(cb, i, 4)

        self.qem = QErrorMessage(self)
        self.qem.setWindowTitle("Under Voltage")

        self.test_button.clicked.connect(self.test_button_clicked)
        self.output_voltage_button.clicked.connect(
            self.output_voltage_button_clicked)

        self.servo_dropbox.currentIndexChanged.connect(
            lambda x: self.update_servo_specific())
        self.enable_checkbox.stateChanged.connect(self.enable_state_changed)

        self.position_syncer = SliderSpinSyncer(self.position_slider,
                                                self.position_spin,
                                                self.position_changed)

        self.velocity_syncer = SliderSpinSyncer(self.velocity_slider,
                                                self.velocity_spin,
                                                self.velocity_changed)

        self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider,
                                                    self.acceleration_spin,
                                                    self.acceleration_changed)

        self.period_syncer = SliderSpinSyncer(self.period_slider,
                                              self.period_spin,
                                              self.period_changed)

        self.pulse_width_min_spin.editingFinished.connect(
            self.pulse_width_spin_finished)
        self.pulse_width_max_spin.editingFinished.connect(
            self.pulse_width_spin_finished)
        self.degree_min_spin.editingFinished.connect(self.degree_spin_finished)
        self.degree_max_spin.editingFinished.connect(self.degree_spin_finished)

        self.minimum_voltage_button.clicked.connect(
            self.minimum_voltage_button_clicked)

        self.qtcb_under_voltage.connect(self.cb_under_voltage)
        self.servo.register_callback(self.servo.CALLBACK_UNDER_VOLTAGE,
                                     self.qtcb_under_voltage.emit)

        class WorkerThread(QThread):
            def __init__(self, parent=None, func=None):
                QThread.__init__(self, parent)
                self.func = func

            def run(self):
                self.func()

        self.test_event = Event()
        self.test_thread_object = WorkerThread(self, self.test_thread)
        self.update_event = Event()
        self.update_thread_object = WorkerThread(self, self.update_thread)

        self.update_thread_first_time = False

        self.update_done_event = Event()
        self.update_done_event.set()

        if self.firmware_version >= (2, 3, 1):
            self.status_led_action = QAction('Status LED', self)
            self.status_led_action.setCheckable(True)
            self.status_led_action.toggled.connect(
                lambda checked: self.servo.enable_status_led()
                if checked else self.servo.disable_status_led())
            self.set_configs([(0, None, [self.status_led_action])])
        else:
            self.status_led_action = None

        if self.firmware_version >= (1, 1, 3):
            reset = QAction('Reset', self)
            reset.triggered.connect(lambda: self.servo.reset())
            self.set_actions([(0, None, [reset])])

    def start(self):
        if self.firmware_version >= (2, 3, 1):
            async_call(self.servo.is_status_led_enabled, None,
                       self.status_led_action.setChecked,
                       self.increase_error_count)

        self.alive = True
        self.test_event.clear()
        self.update_done_event.set()
        self.update_event.set()

        if not self.test_thread_object.isRunning():
            self.test_thread_object.start()

        if not self.update_thread_object.isRunning():
            self.update_thread_object.start()

        self.update_servo_specific()

        self.update_timer.start()

    def stop(self):
        if self.test_button.text() == "Stop Test":
            self.test_button_clicked()

        self.update_timer.stop()

        self.update_event.clear()
        self.alive = False
        self.update_done_event.wait()

    def destroy(self):
        self.test_event.set()
        self.update_event.set()

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickServo.DEVICE_IDENTIFIER

    def get_period_async(self, per):
        self.period_spin.setValue(per)
        self.period_slider.setValue(per)

    def is_enabled_async(self, ena):
        self.enable_checkbox.setChecked(ena)

    def get_position_async(self, pos):
        self.position_spin.setValue(pos)
        self.position_slider.setValue(pos)

    def get_velocity_async(self, vel):
        self.velocity_spin.setValue(vel)
        self.velocity_slider.setValue(vel)

    def get_acceleration_async(self, acc):
        self.acceleration_spin.setValue(acc)
        self.acceleration_slider.setValue(acc)

    def get_degree_async(self, deg, i):
        deg_min, deg_max = deg

        self.degree_min_spin.setValue(deg_min)
        self.degree_max_spin.setValue(deg_max)

        self.position_slider.setMinimum(deg_min)
        self.position_slider.setMaximum(deg_max)
        self.position_spin.setMinimum(deg_min)
        self.position_spin.setMaximum(deg_max)

        self.position_list[i].set_total_angle((deg_max - deg_min) / 100)
        self.position_list[i].set_range(deg_min / 100, deg_max / 100)

    def get_pulse_width_async(self, pulse):
        pulse_min, pulse_max = pulse
        self.pulse_width_min_spin.setValue(pulse_min)
        self.pulse_width_max_spin.setValue(pulse_max)

    def update_servo_specific(self):
        i = self.selected_servo()
        if i == 255:
            self.enable_checkbox.setChecked(False)
            return

        async_call(self.servo.get_position, i, self.get_position_async,
                   self.increase_error_count)
        async_call(self.servo.get_velocity, i, self.get_velocity_async,
                   self.increase_error_count)
        async_call(self.servo.get_acceleration, i, self.get_acceleration_async,
                   self.increase_error_count)
        async_call(self.servo.get_period, i, self.get_period_async,
                   self.increase_error_count)
        async_call(self.servo.is_enabled, i, self.is_enabled_async,
                   self.increase_error_count)

        def get_lambda_deg(i):
            return lambda x: self.get_degree_async(x, i)

        async_call(self.servo.get_degree, i, get_lambda_deg(i),
                   self.increase_error_count)
        async_call(self.servo.get_pulse_width, i, self.get_pulse_width_async,
                   self.increase_error_count)

    def error_handler(self, error):
        pass

    def servo_current_update(self, value):
        self.current_label.setText(str(value) + "mA")

    def stack_input_voltage_update(self, sv):
        sv_str = "%gV" % round(sv / 1000.0, 1)
        self.stack_voltage_label.setText(sv_str)

    def external_input_voltage_update(self, ev):
        ev_str = "%gV" % round(ev / 1000.0, 1)
        self.external_voltage_label.setText(ev_str)

    def output_voltage_update(self, ov):
        ov_str = "%gV" % round(ov / 1000.0, 1)
        self.output_voltage_label.setText(ov_str)

    def minimum_voltage_update(self, mv):
        mv_str = "%gV" % round(mv / 1000.0, 1)
        self.minimum_voltage_label.setText(mv_str)

    def position_update(self, i, pos):
        self.position_list[i].set_value(pos / 100)

    def velocity_update(self, i, vel):
        self.velocity_list[i].set_height(vel * 100 / 0xFFFF)

    def acceleration_update(self, i, acc):
        self.acceleration_list[i].set_height(acc * 100 / 0xFFFF)

    def deactivate_servo(self, i):
        if self.enable_list[i].text() != 'Off':
            self.velocity_list[i].grey()
            self.acceleration_list[i].grey()

    def activate_servo(self, i):
        if self.enable_list[i].text() != 'On':
            self.velocity_list[i].color()
            self.acceleration_list[i].color()

    def selected_servo(self):
        try:
            return int(self.servo_dropbox.currentText()[-1:])
        except:
            return 255

    def enable_state_changed(self, state):
        s = self.selected_servo()
        try:
            if state == Qt.Checked:
                self.servo.enable(s)
            elif state == Qt.Unchecked:
                self.servo.disable(s)
        except ip_connection.Error:
            return

    def update_apply(self):
        if not self.update_thread_first_time:
            return

        self.servo_current_update(self.up_cur)
        self.stack_input_voltage_update(self.up_siv)
        self.external_input_voltage_update(self.up_eiv)
        self.output_voltage_update(self.up_opv)
        self.minimum_voltage_update(self.up_mv)
        for i in range(7):
            if self.up_ena[i]:
                self.activate_servo(i)

                self.position_update(i, self.up_pos[i])
                self.velocity_update(i, self.up_vel[i])
                self.acceleration_update(i, self.up_acc[i])

                self.enable_list[i].setText('On')
            else:
                self.deactivate_servo(i)
                self.enable_list[i].setText('Off')

    def update_thread(self):
        while self.alive:
            time.sleep(0.1)

            try:
                servo = self.selected_servo()
                if servo == 255:
                    self.up_cur = self.servo.get_overall_current()
                else:
                    self.up_cur = self.servo.get_servo_current(servo)

                self.up_siv = self.servo.get_stack_input_voltage()
                self.up_eiv = self.servo.get_external_input_voltage()
                self.up_opv = self.servo.get_output_voltage()
                self.up_mv = self.servo.get_minimum_voltage()

                for i in range(7):
                    self.up_ena[i] = self.servo.is_enabled(i)
                    if self.up_ena[i]:
                        self.activate_servo(i)
                        self.up_pos[i] = self.servo.get_current_position(i)
                        self.up_vel[i] = self.servo.get_current_velocity(i)
                        self.up_acc[i] = self.servo.get_acceleration(i)

                #self.update_apply()

                self.update_done_event.set()
                self.update_event.wait()
                self.update_done_event.clear()
            except ip_connection.Error:
                pass

            self.update_thread_first_time = True

        self.update_done_event.set()

    def test_thread(self):
        def test(num, ena, acc, vel, pos):
            if not self.alive:
                return

            try:
                if ena:
                    self.servo.enable(num)
                else:
                    self.servo.disable(num)
                self.servo.set_acceleration(num, acc)
                self.servo.set_velocity(num, vel)
                self.servo.set_position(num, pos)
            except ip_connection.Error:
                return

        def random_test():
            for i in range(7):
                test(i, random.randrange(0, 2), random.randrange(0, 65536),
                     random.randrange(0, 65536), random.randrange(-9000, 9001))

        while self.alive:
            self.test_event.wait()
            if not self.alive:
                return

            # Full Speed left for 2 seconds
            for i in range(7):
                test(i, True, 65535, 65535, 9000)
            time.sleep(2)
            self.test_event.wait()
            if not self.alive:
                return

            # Full Speed right for 2 seconds
            for i in range(7):
                test(i, True, 65535, 65535, -9000)
            time.sleep(2)
            self.test_event.wait()
            if not self.alive:
                return

            # Test different speeds
            for i in range(19):
                for j in range(7):
                    test(j, True, 65535, 65535 * i / 18, -9000 + i * 1000)
                time.sleep(0.1)
                self.test_event.wait()
                if not self.alive:
                    return
            time.sleep(1)
            self.test_event.wait()
            if not self.alive:
                return

            # Test acceleration
            for i in range(7):
                test(i, True, 100, 65535, -9000)

            time.sleep(3)
            self.test_event.wait()
            if not self.alive:
                return

            # Random for 3 seconds
            random_test()
            time.sleep(3)

    def test_button_clicked(self):
        if self.test_button.text() == "Start Test":
            self.test_button.setText("Stop Test")
            self.test_event.set()
        else:
            self.test_button.setText("Start Test")
            self.test_event.clear()

    def output_voltage_button_clicked(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(2000)
        qid.setIntMaximum(9000)
        qid.setIntStep(100)
        async_call(self.servo.get_output_voltage, None, qid.setIntValue,
                   self.increase_error_count)
        qid.intValueSelected.connect(self.output_voltage_selected)
        qid.setLabelText("Choose Output Voltage in mV.")
        #                         "<font color=red>Setting this too high can destroy your servo.</font>")
        qid.open()

    def output_voltage_selected(self, value):
        try:
            self.servo.set_output_voltage(value)
        except ip_connection.Error:
            return

    def position_changed(self, value):
        try:
            self.servo.set_position(self.selected_servo(), value)
        except ip_connection.Error:
            return

    def velocity_changed(self, value):
        try:
            self.servo.set_velocity(self.selected_servo(), value)
        except ip_connection.Error:
            return

    def acceleration_changed(self, value):
        try:
            self.servo.set_acceleration(self.selected_servo(), value)
        except ip_connection.Error:
            return

    def period_changed(self, value):
        try:
            self.servo.set_period(self.selected_servo(), value)
        except ip_connection.Error:
            return

    def pulse_width_spin_finished(self):
        try:
            self.servo.set_pulse_width(self.selected_servo(),
                                       self.pulse_width_min_spin.value(),
                                       self.pulse_width_max_spin.value())
        except ip_connection.Error:
            return

    def degree_spin_finished(self):
        min = self.degree_min_spin.value()
        max = self.degree_max_spin.value()
        servo = self.selected_servo()

        self.position_slider.setMinimum(min)
        self.position_slider.setMaximum(max)
        self.position_spin.setMinimum(min)
        self.position_spin.setMaximum(max)
        if servo == 255:
            for i in range(7):
                self.position_list[i].set_total_angle((max - min) / 100)
                self.position_list[i].set_range(min / 100, max / 100)
        else:
            self.position_list[servo].set_total_angle((max - min) / 100)
            self.position_list[servo].set_range(min / 100, max / 100)

        try:
            self.servo.set_degree(servo, min, max)
        except ip_connection.Error:
            return

    def cb_under_voltage(self, ov):
        mv_str = self.minimum_voltage_label.text()
        ov_str = "%gV" % round(ov / 1000.0, 1)
        if not self.qem.isVisible():
            self.qem.showMessage(
                "Under Voltage: Output Voltage of " + ov_str +
                " is below minimum voltage of " + mv_str, "Servo_UnterVoltage")

    def minimum_voltage_selected(self, value):
        try:
            self.servo.set_minimum_voltage(value)
        except ip_connection.Error:
            return

    def minimum_voltage_button_clicked(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(5000)
        qid.setIntMaximum(0xFFFF)
        qid.setIntStep(100)
        async_call(self.servo.get_minimum_voltage, None, qid.setIntValue,
                   self.increase_error_count)
        qid.intValueSelected.connect(self.minimum_voltage_selected)
        qid.setLabelText("Choose minimum servo voltage in mV.")
        qid.open()
Esempio n. 16
0
class DC(PluginBase, Ui_DC):
    qtcb_velocity_reached = pyqtSignal(int)
    qtcb_under_voltage = pyqtSignal(int)
    qtcb_emergency_shutdown = pyqtSignal()

    def __init__(self, *args):
        PluginBase.__init__(self, BrickDC, *args)

        self.setupUi(self)

        self.dc = self.device

        self.encoder_hide_all()

        self.update_timer = QTimer()
        self.update_timer.timeout.connect(self.update_data)

        self.speedometer = SpeedoMeter()
        self.vertical_layout_right.insertWidget(4, self.speedometer)

        self.new_value = 0
        self.update_counter = 0

        self.full_brake_time = 0

        self.velocity_syncer = SliderSpinSyncer(self.velocity_slider,
                                                self.velocity_spin,
                                                self.velocity_changed)

        self.acceleration_syncer = SliderSpinSyncer(self.acceleration_slider,
                                                    self.acceleration_spin,
                                                    self.acceleration_changed)

        self.frequency_syncer = SliderSpinSyncer(self.frequency_slider,
                                                 self.frequency_spin,
                                                 self.frequency_changed)

        self.radio_mode_brake.toggled.connect(self.brake_value_changed)
        self.radio_mode_coast.toggled.connect(self.coast_value_changed)

        self.minimum_voltage_button.clicked.connect(
            self.minimum_voltage_button_clicked)
        self.full_brake_button.clicked.connect(self.full_brake_clicked)
        self.enable_checkbox.stateChanged.connect(self.enable_state_changed)

        self.emergency_signal = None
        self.under_signal = None
        self.current_velocity_signal = None
        self.velocity_reached_signal = None

        self.qem = QErrorMessage(self)

        self.qtcb_under_voltage.connect(self.cb_under_voltage)
        self.dc.register_callback(self.dc.CALLBACK_UNDER_VOLTAGE,
                                  self.qtcb_under_voltage.emit)

        self.qtcb_emergency_shutdown.connect(self.cb_emergency_shutdown)
        self.dc.register_callback(self.dc.CALLBACK_EMERGENCY_SHUTDOWN,
                                  self.qtcb_emergency_shutdown.emit)

        self.qtcb_velocity_reached.connect(self.update_velocity)
        self.dc.register_callback(self.dc.CALLBACK_VELOCITY_REACHED,
                                  self.qtcb_velocity_reached.emit)

        self.cbe_current_velocity = CallbackEmulator(
            self.dc.get_current_velocity, self.update_velocity,
            self.increase_error_count)

        if self.firmware_version >= (1, 1, 3):
            reset = QAction('Reset', self)
            reset.triggered.connect(lambda: self.dc.reset())
            self.set_actions(reset)

#        if self.firmware_version >= (2, 0, 1):
#            self.enable_encoder_checkbox.stateChanged.connect(self.enable_encoder_state_changed)
#            self.encoder_show()
#        else:
#            self.enable_encoder_checkbox.setText('Enable Encoder (FW Version >= 2.0.1 required)')
#            self.enable_encoder_checkbox.setEnabled(False)

    def start(self):
        self.update_timer.start(1000)
        self.cbe_current_velocity.set_period(100)
        self.update_start()
        self.update_data()

    def stop(self):
        self.update_timer.stop()
        self.cbe_current_velocity.set_period(0)

    def destroy(self):
        pass

    def get_url_part(self):
        return 'dc'

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickDC.DEVICE_IDENTIFIER

    def cb_emergency_shutdown(self):
        if not self.qem.isVisible():
            self.qem.setWindowTitle("Emergency Shutdown")
            self.qem.showMessage(
                "Emergency Shutdown: Short-Circuit or Over-Temperature")

    def cb_under_voltage(self, ov):
        mv_str = self.minimum_voltage_label.text()
        ov_str = "%gV" % round(ov / 1000.0, 1)
        if not self.qem.isVisible():
            self.qem.setWindowTitle("Under Voltage")
            self.qem.showMessage(
                "Under Voltage: Output Voltage of " + ov_str +
                " is below minimum voltage of " + mv_str, "DC_UnderVoltage")

    def encoder_hide_all(self):
        self.enable_encoder_checkbox.hide()
        self.encoder_hide()

    def encoder_hide(self):
        self.p_label.hide()
        self.p_spinbox.hide()
        self.i_label.hide()
        self.i_spinbox.hide()
        self.d_label.hide()
        self.d_spinbox.hide()
        self.st_label.hide()
        self.st_spinbox.hide()
        self.cpr_label.hide()
        self.cpr_spinbox.hide()
        self.encoder_spacer.hide()

    def encoder_show(self):
        self.p_label.show()
        self.p_spinbox.show()
        self.i_label.show()
        self.i_spinbox.show()
        self.d_label.show()
        self.d_spinbox.show()
        self.st_label.show()
        self.st_spinbox.show()
        self.cpr_label.show()
        self.cpr_spinbox.show()
        self.encoder_spacer.show()

    def enable_encoder_state_changed(self, state):
        try:
            if state == Qt.Checked:
                self.dc.enable_encoder()
                self.update_encoder()
            elif state == Qt.Unchecked:
                self.dc.disable_encoder()

        except ip_connection.Error:
            return

    def enable_state_changed(self, state):
        try:
            if state == Qt.Checked:
                self.dc.enable()
            elif state == Qt.Unchecked:
                self.dc.disable()
        except ip_connection.Error:
            return

    def brake_value_changed(self, checked):
        if checked:
            try:
                self.dc.set_drive_mode(0)
            except ip_connection.Error:
                return

    def coast_value_changed(self, checked):
        if checked:
            try:
                self.dc.set_drive_mode(1)
            except ip_connection.Error:
                return

    def full_brake_clicked(self):
        try:
            self.dc.full_brake()
        except ip_connection.Error:
            return

    def minimum_voltage_selected(self, value):
        try:
            self.dc.set_minimum_voltage(value)
        except ip_connection.Error:
            return

    def minimum_voltage_button_clicked(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(5000)
        qid.setIntMaximum(0xFFFF)
        qid.setIntStep(100)
        async_call(self.dc.get_minimum_voltage, None, qid.setIntValue,
                   self.increase_error_count)
        qid.intValueSelected.connect(self.minimum_voltage_selected)
        qid.setLabelText("Choose minimum motor voltage in mV.")
        qid.open()

    def stack_input_voltage_update(self, sv):
        sv_str = "%gV" % round(sv / 1000.0, 1)
        self.stack_voltage_label.setText(sv_str)

    def external_input_voltage_update(self, ev):
        ev_str = "%gV" % round(ev / 1000.0, 1)
        self.external_voltage_label.setText(ev_str)

    def minimum_voltage_update(self, mv):
        mv_str = "%gV" % round(mv / 1000.0, 1)
        self.minimum_voltage_label.setText(mv_str)

    def drive_mode_update(self, dm):
        if dm == 0:
            self.radio_mode_brake.setChecked(True)
            self.radio_mode_coast.setChecked(False)
        else:
            self.radio_mode_brake.setChecked(False)
            self.radio_mode_coast.setChecked(True)

    def current_consumption_update(self, cc):
        if cc >= 1000:
            cc_str = "%gA" % round(cc / 1000.0, 1)
        else:
            cc_str = "%gmA" % cc

        self.current_label.setText(cc_str)

    def update_velocity(self, value):
        self.speedometer.set_velocity(value)

    def get_velocity_async(self, velocity):
        if not self.velocity_slider.isSliderDown():
            if velocity != self.velocity_slider.sliderPosition():
                self.velocity_slider.setSliderPosition(velocity)
                self.velocity_spin.setValue(velocity)

        self.speedometer.set_velocity(velocity)

    def get_acceleration_async(self, acceleration):
        if not self.acceleration_slider.isSliderDown():
            if acceleration != self.acceleration_slider.sliderPosition():
                self.acceleration_slider.setSliderPosition(acceleration)
                self.acceleration_spin.setValue(acceleration)

    def get_pwm_frequency_async(self, frequency):
        if not self.frequency_slider.isSliderDown():
            if frequency != self.frequency_slider.sliderPosition():
                self.frequency_slider.setSliderPosition(frequency)
                self.frequency_spin.setValue(frequency)

    def is_enabled_async(self, enabled):
        self.enable_checkbox.setChecked(enabled)

    def is_encoder_enabled_async(self, enabled):
        self.enable_encoder_checkbox.setChecked(enabled)

    def get_encoder_config_async(self, cpr):
        self.cpr_spinbox.setValue(cpr)

    def get_encoder_pid_config_async(self, pid_config):
        self.p_spinbox.setValue(pid_config.p)
        self.i_spinbox.setValue(pid_config.i)
        self.d_spinbox.setValue(pid_config.d)
        self.st_spinbox.setValue(pid_config.sample_time)

    def update_encoder(self):
        async_call(self.dc.get_encoder_config, None,
                   self.get_encoder_config_async, self.increase_error_count)
        async_call(self.dc.get_encoder_pid_config, None,
                   self.get_encoder_pid_config_async,
                   self.increase_error_count)
        async_call(self.dc.is_encoder_enabled, None,
                   self.is_encoder_enabled_async, self.increase_error_count)

    def update_start(self):
        async_call(self.dc.get_drive_mode, None, self.drive_mode_update,
                   self.increase_error_count)
        async_call(self.dc.get_velocity, None, self.get_velocity_async,
                   self.increase_error_count)
        async_call(self.dc.get_acceleration, None, self.get_acceleration_async,
                   self.increase_error_count)
        async_call(self.dc.get_pwm_frequency, None,
                   self.get_pwm_frequency_async, self.increase_error_count)
        async_call(self.dc.is_enabled, None, self.is_enabled_async,
                   self.increase_error_count)
#        if self.firmware_version >= (2, 0, 1):
#            self.update_encoder()

    def update_data(self):
        async_call(self.dc.get_stack_input_voltage, None,
                   self.stack_input_voltage_update, self.increase_error_count)
        async_call(self.dc.get_external_input_voltage, None,
                   self.external_input_voltage_update,
                   self.increase_error_count)
        async_call(self.dc.get_minimum_voltage, None,
                   self.minimum_voltage_update, self.increase_error_count)
        async_call(self.dc.get_current_consumption, None,
                   self.current_consumption_update, self.increase_error_count)

    def acceleration_changed(self, value):
        try:
            self.dc.set_acceleration(value)
        except ip_connection.Error:
            return

    def velocity_changed(self, value):
        try:
            self.dc.set_velocity(value)
        except ip_connection.Error:
            return

    def frequency_changed(self, value):
        try:
            self.dc.set_pwm_frequency(value)
        except ip_connection.Error:
            return
Esempio n. 17
0
class Servo(PluginBase, Ui_Servo):
    qtcb_under_voltage = pyqtSignal(int)
    
    def __init__ (self, ipcon, uid):
        PluginBase.__init__(self, ipcon, uid)
        self.setupUi(self)
        
        self.servo = brick_servo.Servo(self.uid)
        self.device = self.servo
        self.ipcon.add_device(self.servo)
        self.version = '.'.join(map(str, self.servo.get_version()[1]))
        
        self.update_timer = QTimer()
        self.update_timer.timeout.connect(self.update_apply)
        self.update_timer.setInterval(0)
        self.update_timer.setSingleShot(True)
        
        layout = QVBoxLayout(self)
        layout.addWidget(QLabel('Servo'))
        self.position_list = []
        self.velocity_list = []
        self.acceleration_list = []
        self.enable_list = []
        
        self.up_ena = [0]*7
        self.up_pos = [0]*7
        self.up_vel = [0]*7
        self.up_acc = [0]*7
        
        self.alive = True
        
        for i in range(1, 8):
            label = QLabel()
            label.setText('Off')
            self.enable_list.append(label)
            self.status_grid.addWidget(label, i, 1)
            
        for i in range(1, 8):
            pk = PositionKnob()
            self.position_list.append(pk)
            self.status_grid.addWidget(pk, i, 2)
            
        for i in range(1, 8):
            cb = ColorBar(Qt.Vertical)
            self.velocity_list.append(cb)
            self.status_grid.addWidget(cb, i, 3)
            
        for i in range(1, 8):
            cb = ColorBar(Qt.Vertical)
            self.acceleration_list.append(cb)
            self.status_grid.addWidget(cb, i, 4)
            
        self.qem = QErrorMessage(self)
        self.qem.setWindowTitle("Under Voltage")
            
        self.test_button.clicked.connect(self.test_button_clicked)
        self.output_voltage_button.clicked.connect(self.output_voltage_button_clicked)
            
        self.servo_dropbox.currentIndexChanged.connect(lambda x: self.update_servo_specific())
        self.enable_checkbox.stateChanged.connect(self.enable_state_changed)
        
        self.position_slider.sliderReleased.connect(self.position_slider_released)
        self.position_slider.valueChanged.connect(self.position_spin.setValue)
        self.position_spin.editingFinished.connect(self.position_spin_finished)
        
        self.velocity_slider.sliderReleased.connect(self.velocity_slider_released)
        self.velocity_slider.valueChanged.connect(self.velocity_spin.setValue)
        self.velocity_spin.editingFinished.connect(self.velocity_spin_finished)
        
        self.acceleration_slider.sliderReleased.connect(self.acceleration_slider_released)
        self.acceleration_slider.valueChanged.connect(self.acceleration_spin.setValue)
        self.acceleration_spin.editingFinished.connect(self.acceleration_spin_finished)
        
        self.period_slider.sliderReleased.connect(self.period_slider_released)
        self.period_slider.valueChanged.connect(self.period_spin.setValue)
        self.period_spin.editingFinished.connect(self.period_spin_finished)
        
        self.pulse_width_min_spin.editingFinished.connect(self.pulse_width_spin_finished)
        self.pulse_width_max_spin.editingFinished.connect(self.pulse_width_spin_finished)
        self.degree_min_spin.editingFinished.connect(self.degree_spin_finished)
        self.degree_max_spin.editingFinished.connect(self.degree_spin_finished)
        
        self.minimum_voltage_button.pressed.connect(self.minimum_voltage_button_pressed)
        
        self.qtcb_under_voltage.connect(self.cb_under_voltage)
        self.servo.register_callback(self.servo.CALLBACK_UNDER_VOLTAGE,
                                     self.qtcb_under_voltage.emit) 
        
        class WorkerThread(QThread):
            def __init__(self, parent = None, func = None):
                QThread.__init__(self, parent)
                self.func = func
                
            def run(self):
                self.func()
        
        
        self.test_event = Event()
        self.test_thread_object = WorkerThread(self, self.test_thread)
        self.update_event = Event()
        self.update_thread_object = WorkerThread(self, self.update_thread)
        
        self.update_done_event = Event()
        self.update_done_event.set()

    def stop(self):
        if self.test_button.text() == "Stop Test":
            self.test_button_clicked()
        self.update_event.clear()
        self.alive = False
        self.update_done_event.wait()
        
    def start(self):
        self.alive = True
        self.test_event.clear()
        self.update_done_event.set()
        self.update_event.set()
        
        if not self.test_thread_object.isRunning():
            self.test_thread_object.start()
            
        if not self.update_thread_object.isRunning():
            self.update_thread_object.start() 
            
        self.update_servo_specific()
        
    def destroy(self):
        self.test_event.set()
        self.update_event.set()
    
    @staticmethod
    def has_name(name):
        return 'Servo Brick' in name 
    
    def update_servo_specific(self):
        i = self.selected_servo()
        if i == 255:
            self.enable_checkbox.setCheckState(Qt.Unchecked)
            return
        
        try:
            pos = self.servo.get_position(i);
            vel = self.servo.get_velocity(i);
            acc = self.servo.get_acceleration(i);
            per = self.servo.get_period(i)
            ena = self.servo.is_enabled(i)
            deg_min, deg_max = self.servo.get_degree(i)
            pulse_min, pulse_max = self.servo.get_pulse_width(i)
        except ip_connection.Error:
            return
        
        self.position_spin.setValue(pos)
        self.velocity_spin.setValue(vel)
        self.acceleration_spin.setValue(acc)
        self.period_spin.setValue(per)
        self.position_slider.setValue(pos)
        self.velocity_slider.setValue(vel)
        self.acceleration_slider.setValue(acc)
        self.period_slider.setValue(per)
        if ena:
            self.enable_checkbox.setCheckState(Qt.Checked)
        else:
            self.enable_checkbox.setCheckState(Qt.Unchecked)
    
        self.pulse_width_min_spin.setValue(pulse_min)
        self.pulse_width_max_spin.setValue(pulse_max)
        self.degree_min_spin.setValue(deg_min)
        self.degree_max_spin.setValue(deg_max)
        
        self.position_slider.setMinimum(deg_min)
        self.position_slider.setMaximum(deg_max)
        self.position_spin.setMinimum(deg_min)
        self.position_spin.setMaximum(deg_max)
        self.position_list[i].setTotalAngle((deg_max - deg_min)/100)
        self.position_list[i].setRange(deg_min/100, deg_max/100)
        
    def error_handler(self, error):
        pass
        
    def servo_current_update(self, value):
        self.current_label.setText(str(value) + "mA")
    
    def stack_input_voltage_update(self, sv):
        sv_str = "%gV"  % round(sv/1000.0, 1)
        self.stack_voltage_label.setText(sv_str)
        
    def external_input_voltage_update(self, ev):
        ev_str = "%gV"  % round(ev/1000.0, 1)
        self.external_voltage_label.setText(ev_str)
        
    def output_voltage_update(self, ov):
        ov_str = "%gV"  % round(ov/1000.0, 1)
        self.output_voltage_label.setText(ov_str)
        
    def minimum_voltage_update(self, mv):
        mv_str = "%gV"  % round(mv/1000.0, 1)
        self.minimum_voltage_label.setText(mv_str)
        
    def position_update(self, i, pos):
        self.position_list[i].setValue(pos/100)
    
    def velocity_update(self, i, vel):
        self.velocity_list[i].set_height(vel*100/0xFFFF)

    def acceleration_update(self, i, acc):
        self.acceleration_list[i].set_height(acc*100/0xFFFF)
    
    def deactivate_servo(self, i):
        if self.enable_list[i].text() != 'Off':
            self.velocity_list[i].grey()
            self.acceleration_list[i].grey()
            
    def activate_servo(self, i):
        if self.enable_list[i].text() != 'On':
            self.velocity_list[i].color()
            self.acceleration_list[i].color()
        
    def selected_servo(self):
        try:
            return int(self.servo_dropbox.currentText()[-1:])
        except:
            return 255

    def enable_state_changed(self, state):
        s = self.selected_servo()
        try:
            if state == Qt.Checked:
                self.servo.enable(s)
            elif state == Qt.Unchecked:
                self.servo.disable(s)
        except ip_connection.Error:
            return
            
    def update_apply(self):
        self.servo_current_update(self.up_cur)
        self.stack_input_voltage_update(self.up_siv)
        self.external_input_voltage_update(self.up_eiv)
        self.output_voltage_update(self.up_opv)
        self.minimum_voltage_update(self.up_mv)
        for i in range(7):
            if self.up_ena[i]:
                self.activate_servo(i)
                
                self.position_update(i, self.up_pos[i])
                self.velocity_update(i, self.up_vel[i])
                self.acceleration_update(i, self.up_acc[i])
                
                self.enable_list[i].setText('On')
            else:
                self.deactivate_servo(i)
                self.enable_list[i].setText('Off')
                
    def update_thread(self):
        while self.alive:
            time.sleep(0.1)
            
            try:
                servo = self.selected_servo()
                if servo == 255:
                    self.up_cur = self.servo.get_overall_current()
                else:
                    self.up_cur = self.servo.get_servo_current(servo)
                    
                self.up_siv = self.servo.get_stack_input_voltage()
                self.up_eiv = self.servo.get_external_input_voltage()
                self.up_opv = self.servo.get_output_voltage()
                self.up_mv = self.servo.get_minimum_voltage()
                
                for i in range(7):
                    self.up_ena[i] = self.servo.is_enabled(i)
                    if self.up_ena[i]:
                        self.activate_servo(i)
                        self.up_pos[i] = self.servo.get_current_position(i)
                        self.up_vel[i] = self.servo.get_current_velocity(i)
                        self.up_acc[i] = self.servo.get_acceleration(i)
    
                self.update_timer.start()
                #self.update_apply()
                
                self.update_done_event.set()
                self.update_event.wait()
                self.update_done_event.clear()
            except ip_connection.Error:
                pass
        self.update_done_event.set()
            
    def test_thread(self):
        def test(num, ena, acc, vel, pos):
            if not self.alive:
                return

            try:
                if ena:
                    self.servo.enable(num)
                else:
                    self.servo.disable(num)
                self.servo.set_acceleration(num, acc)
                self.servo.set_velocity(num, vel)
                self.servo.set_position(num, pos)
            except ip_connection.Error:
                return
        
        def random_test():
            for i in range(7):
                test(i,
                     random.randrange(0, 2),
                     random.randrange(0, 65536),
                     random.randrange(0, 65536),
                     random.randrange(-9000, 9001))
            
        while self.alive:
            self.test_event.wait()
            if not self.alive:
                return
            
            # Full Speed left for 2 seconds
            for i in range(7):
                test(i, True, 65535, 65535, 9000)
            time.sleep(2)
            self.test_event.wait()
            if not self.alive:
                return
            
            # Full Speed right for 2 seconds
            for i in range(7):
                test(i, True, 65535, 65535, -9000)
            time.sleep(2)
            self.test_event.wait()
            if not self.alive:
                return
            
            # Test different speeds
            for i in range(19):
                for j in range(7):
                    test(j, True, 65535, 65535*i/18, -9000+i*1000)
                time.sleep(0.1)
                self.test_event.wait()  
                if not self.alive:
                    return
            time.sleep(1)
            self.test_event.wait()
            if not self.alive:
                return
            
            # Test acceleration
            for i in range(7):
                test(i, True, 100, 65535, -9000)
                
            time.sleep(3)
            self.test_event.wait()
            if not self.alive:
                return
            
            # Random for 3 seconds
            random_test()
            time.sleep(3)
    
    def test_button_clicked(self):
        if self.test_button.text() == "Start Test":
            self.test_button.setText("Stop Test")
            self.test_event.set()
        else:
            self.test_button.setText("Start Test")        
            self.test_event.clear()
    
    def output_voltage_button_clicked(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(5000)
        qid.setIntMaximum(27000)
        qid.setIntStep(100)
        try:
            qid.setIntValue(self.servo.get_output_voltage())
        except ip_connection.Error:
            return
        qid.intValueSelected.connect(self.output_voltage_selected)
        qid.setLabelText("Choose Output Voltage in mV.")
#                         "<font color=red>Setting this too high can destroy your servo.</font>")
        qid.open()
        
    def output_voltage_selected(self, value):
        try:
            self.servo.set_output_voltage(value)
        except ip_connection.Error:
            return
        
    def position_slider_released(self):
        value = self.position_slider.value()
        self.position_spin.setValue(value)
        try:
            self.servo.set_position(self.selected_servo(), value)
        except ip_connection.Error:
            return
 
    def position_spin_finished(self):
        value = self.position_spin.value()
        self.position_slider.setValue(value)
        try:
            self.servo.set_position(self.selected_servo(), value)
        except ip_connection.Error:
            return
        
    def velocity_slider_released(self):
        value = self.velocity_slider.value()
        self.velocity_spin.setValue(value)
        try:
            self.servo.set_velocity(self.selected_servo(), value)
        except ip_connection.Error:
            return
        
    def velocity_spin_finished(self):
        value = self.velocity_spin.value()
        self.velocity_slider.setValue(value)
        try:
            self.servo.set_velocity(self.selected_servo(), value)
        except ip_connection.Error:
            return
        
    def acceleration_slider_released(self):
        value = self.acceleration_slider.value()
        self.acceleration_spin.setValue(value)
        try:
            self.servo.set_acceleration(self.selected_servo(), value)
        except ip_connection.Error:
            return
        
    def acceleration_spin_finished(self):
        value = self.acceleration_spin.value()
        self.acceleration_slider.setValue(value)
        try:
            self.servo.set_acceleration(self.selected_servo(), value)
        except ip_connection.Error:
            return
        
    def period_slider_released(self):
        value = self.period_slider.value()
        self.period_spin.setValue(value)
        try:
            self.servo.set_period(self.selected_servo(), value)
        except ip_connection.Error:
            return
        
    def period_spin_finished(self):
        value = self.period_spin.value()
        self.period_slider.setValue(value)
        try:
            self.servo.set_period(self.selected_servo(), value)
        except ip_connection.Error:
            return
        
    def pulse_width_spin_finished(self):
        try:
            self.servo.set_pulse_width(self.selected_servo(), 
                                       self.pulse_width_min_spin.value(), 
                                       self.pulse_width_max_spin.value())
        except ip_connection.Error:
            return
    
    def degree_spin_finished(self):
        min = self.degree_min_spin.value()
        max = self.degree_max_spin.value()
        servo = self.selected_servo()
        
        self.position_slider.setMinimum(min)
        self.position_slider.setMaximum(max)
        self.position_spin.setMinimum(min)
        self.position_spin.setMaximum(max)
        self.position_list[servo].setTotalAngle((max - min)/100)
        self.position_list[servo].setRange(min/100, max/100)
        
        try:
            self.servo.set_degree(servo, min, max)
        except ip_connection.Error:
            return
        
    def cb_under_voltage(self, ov):
        mv_str = self.minimum_voltage_label.text()
        ov_str = "%gV"  % round(ov/1000.0, 1)
        if not self.qem.isVisible():
            self.qem.showMessage("Under Voltage: Output Voltage of " + ov_str +
                                 " is below minimum voltage of " + mv_str)
            
    def minimum_voltage_selected(self, value):
        try:
            self.servo.set_minimum_voltage(value)
        except ip_connection.Error:
            return

    def minimum_voltage_button_pressed(self):
        qid = QInputDialog(self)
        qid.setInputMode(QInputDialog.IntInput)
        qid.setIntMinimum(5000)
        qid.setIntMaximum(0xFFFF)
        qid.setIntStep(100)
        try:
            qid.setIntValue(self.servo.get_minimum_voltage())
        except ip_connection.Error:
            return
        qid.intValueSelected.connect(self.minimum_voltage_selected)
        qid.setLabelText("Choose minimum servo voltage in mV.")
        qid.open()
Esempio n. 18
-1
    def input_device_changed(self, index):
        self.ui.actionStart.setChecked(False)

        success, index = self.audiobackend.select_input_device(index)

        self.settings_dialog.comboBox_inputDevice.setCurrentIndex(index)

        if not success:
            # Note: the error message is a child of the settings dialog, so that
            # that dialog remains on top when the error message is closed
            error_message = QErrorMessage(self.settings_dialog)
            error_message.setWindowTitle("Input device error")
            error_message.showMessage(
                "Impossible to use the selected input device, reverting to the previous one"
            )

        # reset the channels
        first_channel = self.audiobackend.get_current_first_channel()
        self.settings_dialog.comboBox_firstChannel.setCurrentIndex(
            first_channel)
        second_channel = self.audiobackend.get_current_second_channel()
        self.settings_dialog.comboBox_secondChannel.setCurrentIndex(
            second_channel)

        self.ui.actionStart.setChecked(True)