4f61e0c70232f23aeb6417bd2b561c1bc26eb976
1 # This code is copyright ...... under the GPL v2.
2 # This code is derived from scratch_gpio_handler by Simon Walters, which
3 # is derived from scratch_handler by Thomas Preston
4 # Version 0.1: It's kind of working.
17 DEFAULT_HOST
= '127.0.0.1'
18 BUFFER_SIZE
= 240 #used to be 100
20 DEVICES
= ['/dev/ttyACM0', '/dev/ttyACM1','/dev/ttyACM3']
21 ARDUINO_BAUD_RATE
= 9600
23 BROADCAST_NAMES
= {'guitar': 'guitar',
31 SENSOR_NAMES
= {'guitar': 'guitar_pitch'}
33 logging
.basicConfig(level
= logging
.INFO
)
34 #logging.basicConfig(level = logging.DEBUG)
36 class MyError(Exception):
37 def __init__(self
, value
):
41 return repr(self
.value
)
43 class ScratchSender(threading
.Thread
):
44 def __init__(self
, socket
):
45 threading
.Thread
.__init
__(self
)
46 self
.scratch_socket
= socket
47 self
._stop
= threading
.Event()
49 def join(self
,timeout
=None):
51 threading
.Thread
.join(self
, timeout
)
54 return self
._stop
.isSet()
57 while not self
.stopped():
58 time
.sleep(0.01) # be kind to cpu - not certain why :)
60 def send_scratch_command(self
, cmd
):
63 a
.append(chr((n
>> 24) & 0xFF))
64 a
.append(chr((n
>> 16) & 0xFF))
65 a
.append(chr((n
>> 8) & 0xFF))
66 a
.append(chr(n
& 0xFF))
67 self
.scratch_socket
.send(a
.tostring() + cmd
)
70 class ArduinoListener(threading
.Thread
):
71 def __init__(self
, device
, speed
, sender
, instruments
, values
):
72 threading
.Thread
.__init
__(self
)
73 self
.arduino_device
= serial
.Serial(device
, speed
, timeout
=0.5)
74 self
._stop
= threading
.Event()
75 self
.scratch_sender
= sender
76 self
.instruments
= instruments
78 logging
.info("Started listener on port %s" % device
)
80 def join(self
,timeout
=None):
82 threading
.Thread
.join(self
, timeout
)
85 return self
._stop
.isSet()
88 self
.arduino_device
.readline() # discard the first (partial) line
89 while not self
.stopped():
90 logging
.debug('Thread waiting for a signal')
92 device_line
= self
.arduino_device
.readline()
94 instrument
, instrument_value_string
= device_line
.rstrip().split(',', 1)
95 instrument_value
= int(instrument_value_string
)
96 logging
.info('Instrument: %s, Value: %d' % (instrument
, instrument_value
))
97 if instrument
in self
.values
:
99 logging
.info("sensor-update %s %d" % (self
.values
[instrument
], (instrument_value
* 100) / 1024))
100 self
.scratch_sender
.send_scratch_command("sensor-update %s %d" % (self
.values
[instrument
], (instrument_value
* 100) / 1024))
104 if instrument
in self
.instruments
:
105 if isinstance(self
.instruments
[instrument
], dict):
106 broadcast
= self
.instruments
[instrument
][instrument_value
]
108 broadcast
= self
.instruments
[instrument
]
110 logging
.info("broadcast %s" % broadcast
)
111 self
.scratch_sender
.send_scratch_command('broadcast %s' % broadcast
)
116 except serial
.SerialException
:
117 logging
.error('Serial exception')
118 logging
.debug('Thread run() exiting')
121 def create_socket(host
, port
):
124 logging
.info('Connecting to Scratch')
125 scratch_sock
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
126 scratch_sock
.connect((host
, port
))
129 logging
.warning("There was an error connecting to Scratch!")
130 logging
.warning("I couldn't find a Mesh session at host: %s, port: %s" % (host
, port
))
134 def cleanup_threads(threads
):
135 logging
.debug("Stopping %d threads" % len(threads
))
136 for thread
in threads
:
138 logging
.debug("Threads joined")
140 if __name__
== '__main__':
141 if len(sys
.argv
) > 1:
146 cycle_trace
= 'start'
148 if (cycle_trace
== 'disconnected'):
149 logging
.info("Scratch disconnected")
150 cleanup_threads(listeners
+ sender
)
152 cycle_trace
= 'start'
154 if (cycle_trace
== 'start'):
156 logging
.info('Connecting to Scratch...')
157 the_socket
= create_socket(host
, PORT
)
158 logging
.info('Connected to Scratch')
159 the_socket
.settimeout(SOCKET_TIMEOUT
)
160 sender
= ScratchSender(the_socket
)
161 listeners
= [ArduinoListener(device
, ARDUINO_BAUD_RATE
, sender
, BROADCAST_NAMES
, SENSOR_NAMES
) for device
in DEVICES
]
162 cycle_trace
= 'running'
163 logging
.info("Listeners running....")
165 for listener
in listeners
:
172 except KeyboardInterrupt:
173 logging
.warning("Interrrupted")
174 cleanup_threads(listeners
+ [sender
])