Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #! /usr/bin/env python
- """pyduino - A python library to interface with the firmata arduino firmware.
- Copyright (C) 2007 Joe Turner <orphansandoligarchs@gmail.com>
- This program is free software; you can redistribute it and/or
- modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 2
- of the License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- """
- __version__ = "0.11_dev"
- import time
- import serial
- # Message command bytes - straight outta Pd_firmware.pde
- DIGITAL_MESSAGE = 0x90 # send data for a digital pin
- ANALOG_MESSAGE = 0xE0 # send data for an analog pin (or PWM)
- # PULSE_MESSAGE = 0xA0 # proposed pulseIn/Out message (SysEx)
- # SHIFTOUT_MESSAGE = 0xB0 # proposed shiftOut message (SysEx)
- REPORT_ANALOG_PIN = 0xC0 # enable analog input by pin #
- REPORT_DIGITAL_PORTS = 0xD0 # enable digital input by port pair
- START_SYSEX = 0xF0 # start a MIDI SysEx message
- SET_DIGITAL_PIN_MODE = 0xF4 # set a digital pin to INPUT or OUTPUT
- END_SYSEX = 0xF7 # end a MIDI SysEx message
- REPORT_VERSION = 0xF9 # report firmware version
- SYSTEM_RESET = 0xFF # reset from MIDI
- # Pin modes
- DIGITAL_INPUT = 0
- DIGITAL_OUTPUT = 1
- DIGITAL_PWM = 2
- PWM_PINS = (9, 10, 11)
- class Arduino:
- """Base class for the arduino board"""
- def __init__(self, port):
- self.sp = serial.Serial(port, 57600, timeout=0.02)
- # Allow 2 secs for Diecimila auto-reset to happen
- time.sleep(2)
- self.digital = []
- for i in range(14):
- self.digital.append(Digital(self.sp, i))
- self.analog = []
- for i in range(6):
- self.analog.append(Analog(self.sp, i))
- #Obtain firmata version
- self.sp.write(chr(REPORT_VERSION))
- self.iterate()
- def __str__(self):
- return "Arduino: %s"% self.sp.port
- def iterate(self):
- """Read and handle a command byte from Arduino's serial port"""
- data = self.sp.read()
- if data != "":
- self._process_input(ord(data))
- def _process_input(self, data):
- """Process a command byte and any additional information bytes"""
- if data < 0xF0:
- #Multibyte
- message = data & 0xF0
- pin = data & 0x0F
- if message == DIGITAL_MESSAGE:
- #Digital in
- lsb = ""
- msb = ""
- while lsb == "":
- lsb = self.sp.read()
- while msb == "":
- msb = self.sp.read()
- lsb = ord(lsb)
- msb = ord(msb)
- self._set_digital_mask(lsb + (msb << 7))
- elif message == ANALOG_MESSAGE:
- #Analog in
- lsb = ""
- msb = ""
- while lsb == "":
- lsb = self.sp.read()
- while msb == "":
- msb = self.sp.read()
- lsb = ord(lsb)
- msb = ord(msb)
- self.analog[pin].value = msb << 7 | lsb
- elif data == REPORT_VERSION:
- major, minor = self.sp.read(2)
- self.firmata_version = (ord(major), ord(minor))
- def _set_digital_mask(self, input_mask):
- """ Alter the digital mask to reflect changes in the digital inputs"""
- for pin in self.digital:
- value = (input_mask & 1 << pin.pin) > 0
- if pin.mode == DIGITAL_INPUT and value != pin.read():
- Digital.mask ^= 1 << pin.pin
- def get_firmata_version(self):
- """Return a (major, minor) version tuple for the firmata firmware"""
- return self.firmata_version
- def exit(self):
- """Exit the application cleanly"""
- self.sp.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement