Advertisement
Guest User

skunkworks

a guest
Dec 5th, 2011
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.32 KB | None | 0 0
  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.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement