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

skunkworks

By: a guest on Dec 5th, 2011  |  syntax: None  |  size: 4.32 KB  |  views: 48  |  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/python
  2. #    HAL userspace component to interface with Arduino board
  3. #    Copyright (C) 2007 Jeff Epler <jepler@unpythonic.net>
  4. #
  5. #    This program is free software; you can redistribute it and/or modify
  6. #    it under the terms of the GNU General Public License as published by
  7. #    the Free Software Foundation; either version 2 of the License, or
  8. #    (at your option) any later version.
  9. #
  10. #    This program is distributed in the hope that it will be useful,
  11. #    but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. #    GNU General Public License for more details.
  14. #
  15. #    You should have received a copy of the GNU General Public License
  16. #    along with this program; if not, write to the Free Software
  17. #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18. import serial
  19. import hal
  20. import sys
  21. import time
  22.  
  23. def encode(addr, data):
  24.     if data < 0 or data > 2048: raise ValueError, "data %02d out of range" % data
  25.     if addr < 0 or addr > 8: raise ValueError, "address %02d out of range" % addr
  26.     b1 = 0x80 | (addr << 4) | (data >> 7)
  27.     b2 = data & 0x7f
  28.     return chr(b1) + chr(b2)
  29.  
  30. PORT = "/dev/ttyUSB0"
  31.  
  32. if len(sys.argv) > 1:
  33.     PORT = sys.argv[1]
  34.  
  35. if len(sys.argv) > 2:
  36.     nout = int(sys.argv[2])
  37. else:
  38.     nout = 6
  39.  
  40. if nout > 6 or nout < 0:
  41.     raise SystemExit, "Number of digital outputs must be from 0 to 6"
  42.  
  43. pinmap = [2,4,7,8,12,13]
  44. dacpinmap = [3,5,6,9,10,11]
  45.  
  46. ser = serial.Serial(PORT, 9600, timeout=2)
  47.  
  48. c = hal.component("arduino")
  49. for port in range(6):
  50.     c.newpin("analog-in-%02d" % port, hal.HAL_FLOAT, hal.HAL_OUT)
  51.     c.newparam("analog-in-%02d-offset" % port, hal.HAL_FLOAT, hal.HAL_RW)
  52.     c.newparam("analog-in-%02d-gain" % port, hal.HAL_FLOAT, hal.HAL_RW)
  53.     c.newpin("analog-out-%02d" % dacpinmap[port], hal.HAL_FLOAT, hal.HAL_IN)
  54.     c.newparam("analog-out-%02d-offset" % dacpinmap[port], hal.HAL_FLOAT, hal.HAL_RW)
  55.     c.newparam("analog-out-%02d-scale" % dacpinmap[port], hal.HAL_FLOAT, hal.HAL_RW)
  56.     c['analog-in-%02d-gain' % port] = 1.0
  57.     c['analog-out-%02d-scale' % dacpinmap[port]] = 1.0
  58. for port in range(nout):
  59.     c.newpin("digital-out-%02d" % pinmap[port], hal.HAL_BIT, hal.HAL_IN)
  60.     c.newparam("digital-out-%02d-invert" % pinmap[port], hal.HAL_BIT, hal.HAL_RW)
  61. for port in range(nout, 6):
  62.     c.newpin("digital-in-%02d" % pinmap[port], hal.HAL_BIT, hal.HAL_OUT)
  63.     c.newpin("digital-in-%02d-not" % pinmap[port], hal.HAL_BIT, hal.HAL_OUT)
  64.     c.newparam("digital-in-%02d-pullup" % pinmap[port], hal.HAL_BIT, hal.HAL_RW)
  65. c.ready()
  66.  
  67. firstbyte = 0
  68. state = 0
  69. try:
  70.     while 1:
  71.         while ser.inWaiting():
  72.             byte = ord(ser.read())
  73.             if firstbyte & 0x80 == 0x80 and byte & 0x80 == 0:
  74.                 v = (firstbyte << 7) | byte
  75.                 port = (v >> 11) & 7
  76.                
  77.                 if port < 6:
  78.                     if port >= nout:
  79.                         b = v & 1024
  80.                         c['digital-in-%02d' % pinmap[port]] = b != 0
  81.                         c['digital-in-%02d-not' % pinmap[port]] = b == 0
  82.  
  83.                     gain = c['analog-in-%02d-gain' % port] or 1.
  84.                     offset = c['analog-in-%02d-offset' % port]
  85.                     value = (v & 1023) / 1023. * 5.0 * gain + offset
  86.                     c['analog-in-%02d' % port] = value
  87.  
  88.             firstbyte = byte
  89.        
  90.         scale = c['analog-out-%02d-scale' % dacpinmap[state]] or 1.
  91.         offset = c['analog-out-%02d-offset' % dacpinmap[state]]
  92.         data = (c['analog-out-%02d' % dacpinmap[state]] - offset) / scale / 5
  93.         data = int(data * 255 + 0.5)
  94.         if data < 0: data = 0
  95.         if data > 255: data = 255
  96.         if state < nout:
  97.             out = not c['digital-out-%02d' % pinmap[state]]
  98.             invert = not c['digital-out-%02d-invert' % pinmap[state]]
  99.             if out != invert:
  100.                 data |= 0x200
  101.             data = data | 0x100
  102.         else:
  103.             pullup = c['digital-in-%02d-pullup' % pinmap[state]]
  104.             if pullup:
  105.                 data |= 0x200
  106.         data = data | (state << 11)
  107.         ser.write(chr(0x80 | (data >> 7)))
  108.         ser.write(chr(data & 0x7f))
  109.         state = (state+1) % 6
  110.         time.sleep(.001)
  111. except (KeyboardInterrupt,):
  112.     raise SystemExit, 0
  113.  
  114.