Schritt 6: Umsetzung der PyMata API-Befehl und Bericht-Methoden
BEFEHLSMELDUNGEN - pymata.py
Als nächstes code wir die PyMata API-Methoden für die drei Stepper motor Sub-Befehle und eine API-Methode zum Abrufen der gemeldete Versionsnummer. Pymata.py werden alle Änderungen am Code für die API. Die ersten drei Methoden, Stepper_config, Stepper_step und Stepper_request_library_version übersetzen den Befehl in eine ordnungsgemäß formatierte SysEx-Befehl, der dann an den Arduino gesendet wird. Die letzte Methode, Get_stepper_version, führt keine SysEx-messaging, aber einfach das Ergebnis für eine vorherige Version-Anforderung zurückgegeben.
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)
Schließlich implementieren wir 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
Dies schließt alle Änderungen an pymata.py. Schließen Sie und speichern Sie pymata.py.
Nachrichten melden - pymata_command_handler.py
Wir werden jetzt die Bericht-Handler-Methode pymata_command_handler.py, hinzufügen, damit es kann empfangen und verarbeiten von Schrittmotor-Bibliothek Version Berichte. Beachten Sie, dass diese Methode werden die Daten aus der SysEx-Nachricht und speichert es in eine interne Variable namens 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)
Zu guter Letzt müssen wir die Command_dispatch-Tabelle, um den Erhalt der Stepper Version Antwort verarbeiten zu aktualisieren. Fügen Sie einen neuen Eintrag unten der vorhandenen Tabelle für STEPPER_DATA wie unten gezeigt. Jeder Eintrag in der Command_dispatch-Tabelle besteht aus den SysEx Befehl, den Namen der die Behandlungsmethode und die Anzahl der 7-Bit-Werte zurückgegeben. Die 7-Bit-Werte werden wieder zusammengesetzt und gemäß der SysEx-Message-Formate, die wir zuvor definierten interpretiert werden.
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]})
Der Befehlstabelle Versand ist definiert als eine Karte im pymata_command_handler.py. Diese Codekommentare erklären, seine Verwendung und wie man neue Befehle hinzufügen.
# 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 = {}
Speichern Sie und schließen Sie pymata_command_handler.py. Die Client-Änderungen sind nun abgeschlossen.