Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

Joe Turner

By: a guest on Jan 17th, 2008  |  syntax: Python  |  size: 4.18 KB  |  views: 3,313  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #! /usr/bin/env python
  2.  
  3. """pyduino - A python library to interface with the firmata arduino firmware.
  4. Copyright (C) 2007 Joe Turner <orphansandoligarchs@gmail.com>
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  19. """
  20.  
  21. __version__ = "0.11_dev"
  22.  
  23. import time
  24. import serial
  25.  
  26. # Message command bytes - straight outta Pd_firmware.pde
  27. DIGITAL_MESSAGE = 0x90 # send data for a digital pin
  28. ANALOG_MESSAGE = 0xE0 # send data for an analog pin (or PWM)
  29.  
  30. # PULSE_MESSAGE = 0xA0 # proposed pulseIn/Out message (SysEx)
  31. # SHIFTOUT_MESSAGE = 0xB0 # proposed shiftOut message (SysEx)
  32.  
  33. REPORT_ANALOG_PIN = 0xC0 # enable analog input by pin #
  34. REPORT_DIGITAL_PORTS = 0xD0 # enable digital input by port pair
  35. START_SYSEX = 0xF0 # start a MIDI SysEx message
  36. SET_DIGITAL_PIN_MODE = 0xF4 # set a digital pin to INPUT or OUTPUT
  37. END_SYSEX = 0xF7 # end a MIDI SysEx message
  38. REPORT_VERSION = 0xF9 # report firmware version
  39. SYSTEM_RESET = 0xFF # reset from MIDI
  40.  
  41. # Pin modes
  42. DIGITAL_INPUT = 0
  43. DIGITAL_OUTPUT = 1
  44. DIGITAL_PWM = 2
  45.  
  46. PWM_PINS = (9, 10, 11)
  47.  
  48. class Arduino:
  49.     """Base class for the arduino board"""
  50.  
  51.     def __init__(self, port):
  52.         self.sp = serial.Serial(port, 57600, timeout=0.02)
  53.         # Allow 2 secs for Diecimila auto-reset to happen
  54.         time.sleep(2)
  55.  
  56.         self.digital = []
  57.         for i in range(14):
  58.             self.digital.append(Digital(self.sp, i))
  59.  
  60.         self.analog = []
  61.         for i in range(6):
  62.             self.analog.append(Analog(self.sp, i))
  63.  
  64.         #Obtain firmata version
  65.         self.sp.write(chr(REPORT_VERSION))
  66.         self.iterate()
  67.  
  68.     def __str__(self):
  69.         return "Arduino: %s"% self.sp.port
  70.            
  71.     def iterate(self):
  72.         """Read and handle a command byte from Arduino's serial port"""
  73.         data = self.sp.read()
  74.         if data != "":
  75.             self._process_input(ord(data))
  76.  
  77.     def _process_input(self, data):
  78.         """Process a command byte and any additional information bytes"""
  79.         if data < 0xF0:
  80.             #Multibyte
  81.             message = data & 0xF0
  82.             pin = data & 0x0F
  83.             if message == DIGITAL_MESSAGE:
  84.                 #Digital in
  85.                 lsb = ""
  86.                 msb = ""
  87.                 while lsb == "":
  88.                     lsb = self.sp.read()
  89.                 while msb == "":
  90.                     msb = self.sp.read()
  91.                 lsb = ord(lsb)
  92.                 msb = ord(msb)
  93.                 self._set_digital_mask(lsb + (msb << 7))
  94.             elif message == ANALOG_MESSAGE:
  95.                 #Analog in
  96.                 lsb = ""
  97.                 msb = ""
  98.                 while lsb == "":
  99.                     lsb = self.sp.read()
  100.                 while msb == "":
  101.                     msb = self.sp.read()
  102.                 lsb = ord(lsb)
  103.                 msb = ord(msb)
  104.                 self.analog[pin].value = msb << 7 | lsb
  105.         elif data == REPORT_VERSION:
  106.             major, minor = self.sp.read(2)
  107.             self.firmata_version = (ord(major), ord(minor))
  108.  
  109.     def _set_digital_mask(self, input_mask):
  110.         """ Alter the digital mask to reflect changes in the digital inputs"""
  111.         for pin in self.digital:
  112.             value = (input_mask & 1 << pin.pin) > 0
  113.             if pin.mode == DIGITAL_INPUT and value != pin.read():
  114.                 Digital.mask ^= 1 << pin.pin
  115.  
  116.     def get_firmata_version(self):
  117.         """Return a (major, minor) version tuple for the firmata firmware"""
  118.         return self.firmata_version
  119.  
  120.     def exit(self):
  121.         """Exit the application cleanly"""
  122.         self.sp.close()
clone this paste RAW Paste Data