Stap 6: Uitvoering van de PyMata API commando en verslag methoden
OPDRACHT berichten - pymata.py
Volgende code we de PyMata API methoden voor de drie stepper motor sub opdrachten en een API-methode voor het ophalen van het gerapporteerde versienummer. Alle zijn code voor de API gewijzigd pymata.py. De eerste drie methoden, stepper_config, stepper_step en stepper_request_library_version vertalen de opdracht naar een goed geformatteerde SysEx opdracht die vervolgens wordt verzonden naar de Arduino. De laatste methode, get_stepper_version, resulteert niet in elke SysEx messaging, maar gewoon het resultaat voor een eerdere versie-aanvraag.
def stepper_config(self, steps_per_revolution, stepper_pins): """ Configure stepper motor prior to operation. steps_per_revolution: number of steps per motor revolution stepper_pins: a list of control pin numbers - either 4 or 2 """ data = [self.STEPPER_CONFIGURE, steps_per_revolution & 0x7f, steps_per_revolution >> 7] for pin in range(len(stepper_pins)): data.append(stepper_pins[pin]) self._command_handler.send_sysex(self._command_handler.STEPPER_DATA, data)
def stepper_step(self, motor_speed, number_of_steps): """ Move a stepper motor for the number of steps at the specified speed motor_speed: 21 bits of data to set motor speed number_of_steps: 14 bits for number of steps & direction positive is forward, negative is reverse """ if number_of_steps > 0: direction = 1 else: direction = 0 abs_number_of_steps = abs(number_of_steps) data = [self.STEPPER_STEP, motor_speed & 0x7f, (motor_speed >> 7) & 0x7f, motor_speed >> 14, abs_number_of_steps & 0x7f, abs_number_of_steps >> 7, direction] self._command_handler.send_sysex(self._command_handler.STEPPER_DATA, data)
def stepper_request_library_version(self): """ Request the stepper library version from the Arduino. To retrieve the version after this command is called, call get_stepper_version """ data = [self.STEPPER_LIBRARY_VERSION] self._command_handler.send_sysex(self._command_handler.STEPPER_DATA, data)
Tot slot implementeren we get_stepper_library_version:
def get_stepper_version(self, timeout=20): """ timeout: specify a time to allow arduino to process and return a version the stepper version number if it was set. """ # get current time start_time = time.time()
# wait for version to come from the Arduino
while self._command_handler.stepper_library_version <= 0: if time.time() - start_time > timeout: print "Stepper Library Version Request timed-out. Did you send a stepper_request_library_version command?" return else: pass return self._command_handler.stepper_library_version
Dit voltooit alle wijzigingen aan pymata.py. Sluit en sla pymata.py.
RAPPORTBERICHTEN - pymata_command_handler.py
Nu zullen we het verslag handler-methode toevoegen aan pymata_command_handler.py, zodat het kan ontvangen en verwerken van stepper bibliotheek versie verslagen. Merk op dat deze methode de gegevens van herassembleert de de SysEx bericht en winkels in een interne variabele genaamd stepper_library_version.
def stepper_version_response(self, data): """ This method handles a stepper library version message sent from the Arduino data - two 7 bit bytes that contain the library version number """ self.stepper_library_version = (data[0] & 0x7f) + (data[1] << 7)
Tot slot moeten we de command_dispatch-tabel voor het verwerken van de ontvangst van het antwoord van stepper versie bijwerken. Een nieuwe vermelding toevoegen aan de onderkant van de bestaande tabel voor STEPPER_DATA zoals hieronder getoond. Elke vermelding in de tabel command_dispatch bestaat uit de SysEx opdracht, de naam van de methode van de behandeling, en het aantal 7 bits waarden geretourneerd. De 7-bits waarden zal worden samengevoegd en geïnterpreteerd als opgegeven door de SysEx-berichtindelingen die we eerder gedefinieerd.
def run(self): """ This method starts the thread that continuously runs to receive and interpret messages coming from Firmata. This must be the last method in this file It also checks the deque for messages to be sent to Firmata. """ # To add a command to the command dispatch table, append here. self.command_dispatch.update({self.REPORT_VERSION: [self.report_version, 2]}) self.command_dispatch.update({self.REPORT_FIRMWARE: [self.report_firmware, 1]}) self.command_dispatch.update({self.ANALOG_MESSAGE: [self.analog_message, 2]}) self.command_dispatch.update({self.DIGITAL_MESSAGE: [self.digital_message, 2]}) self.command_dispatch.update({self.ENCODER_DATA: [self.encoder_data, 3]}) self.command_dispatch.update({self.SONAR_DATA: [self.sonar_data, 3]}) self.command_dispatch.update({self.STRING_DATA: [self._string_data, 2]}) self.command_dispatch.update({self.I2C_REPLY: [self.i2c_reply, 2]}) self.command_dispatch.update({self.CAPABILITY_RESPONSE: [self.capability_response, 2]}) self.command_dispatch.update({self.PIN_STATE_RESPONSE: [self.pin_state_response, 2]}) self.command_dispatch.update({self.ANALOG_MAPPING_RESPONSE: [self.analog_mapping_response, 2]}) self.command_dispatch.update({self.STEPPER_DATA: [self.stepper_version_response, 2]})
De opdracht verzending tabel wordt gedefinieerd als een kaart in pymata_command_handler.py. Deze commentaar bij de code uitgelegd het gebruik ervan en hoe nieuwe opdrachten toevoegen aan het.
# This is a map that allows the look up of command handler methods using a command as the key. # This is populated in the run method after the python interpreter "sees" all of the command handler method defines (python does not have forward referencing)
# The "key" is the command, and the value contains is a list containing the method name and the number of # parameter bytes that the method will require to process the message (in some cases the value is unused) command_dispatch = {}
Opslaan en sluiten pymata_command_handler.py. De client wijzigingen zijn nu voltooid.