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/ttyACM3']
21 #DEVICES = ['/dev/ttyACM0', '/dev/ttyACM1','/dev/ttyACM3']
22 ARDUINO_BAUD_RATE
= 9600
24 BROADCAST_NAMES
= {'guitar': 'guitar',
32 SENSOR_NAMES
= {'guitar': 'guitar_pitch'}
34 logging
.basicConfig(level
= logging
.INFO
)
35 #logging.basicConfig(level = logging.DEBUG)
37 class MyError(Exception):
38 def __init__(self
, value
):
42 return repr(self
.value
)
44 class ScratchSender(threading
.Thread
):
45 def __init__(self
, socket
):
46 threading
.Thread
.__init
__(self
)
47 self
.scratch_socket
= socket
48 self
._stop
= threading
.Event()
50 def join(self
,timeout
=None):
52 threading
.Thread
.join(self
, timeout
)
55 return self
._stop
.isSet()
58 while not self
.stopped():
59 time
.sleep(0.01) # be kind to cpu - not certain why :)
61 def send_scratch_command(self
, cmd
):
64 a
.append(chr((n
>> 24) & 0xFF))
65 a
.append(chr((n
>> 16) & 0xFF))
66 a
.append(chr((n
>> 8) & 0xFF))
67 a
.append(chr(n
& 0xFF))
68 self
.scratch_socket
.send(a
.tostring() + cmd
)
71 class ArduinoListener(threading
.Thread
):
72 def __init__(self
, device
, speed
, sender
, instruments
, values
):
73 threading
.Thread
.__init
__(self
)
74 self
.arduino_device
= serial
.Serial(device
, speed
, timeout
=0.5)
75 self
._stop
= threading
.Event()
76 self
.scratch_sender
= sender
77 self
.instruments
= instruments
79 logging
.info("Started listener on port %s" % device
)
81 def join(self
,timeout
=None):
83 threading
.Thread
.join(self
, timeout
)
86 return self
._stop
.isSet()
89 self
.arduino_device
.readline() # discard the first (partial) line
90 while not self
.stopped():
91 logging
.debug('Thread waiting for a signal')
93 device_line
= self
.arduino_device
.readline()
95 instrument
, instrument_value_string
= device_line
.rstrip().split(',', 1)
96 instrument_value
= int(instrument_value_string
)
97 logging
.info('Instrument: %s, Value: %d' % (instrument
, instrument_value
))
98 if instrument
in self
.values
:
100 logging
.info("sensor-update %s %d" % (self
.values
[instrument
], (instrument_value
* 100) / 1024))
101 self
.scratch_sender
.send_scratch_command("sensor-update %s %d" % (self
.values
[instrument
], (instrument_value
* 100) / 1024))
105 if instrument
in self
.instruments
:
106 if isinstance(self
.instruments
[instrument
], dict):
107 broadcast
= self
.instruments
[instrument
][instrument_value
]
109 broadcast
= self
.instruments
[instrument
]
111 logging
.info("broadcast %s" % broadcast
)
112 self
.scratch_sender
.send_scratch_command('broadcast %s' % broadcast
)
117 except serial
.SerialException
:
118 logging
.error('Serial exception')
119 logging
.debug('Thread run() exiting')
122 def create_socket(host
, port
):
125 logging
.info('Connecting to Scratch')
126 scratch_sock
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
127 scratch_sock
.connect((host
, port
))
130 logging
.warning("There was an error connecting to Scratch!")
131 logging
.warning("I couldn't find a Mesh session at host: %s, port: %s" % (host
, port
))
135 def cleanup_threads(threads
):
136 logging
.debug("Stopping %d threads" % len(threads
))
137 for thread
in threads
:
139 logging
.debug("Threads joined")
141 if __name__
== '__main__':
142 if len(sys
.argv
) > 1:
147 cycle_trace
= 'start'
149 if (cycle_trace
== 'disconnected'):
150 logging
.info("Scratch disconnected")
151 cleanup_threads(listeners
+ sender
)
153 cycle_trace
= 'start'
155 if (cycle_trace
== 'start'):
157 logging
.info('Connecting to Scratch...')
158 the_socket
= create_socket(host
, PORT
)
159 logging
.info('Connected to Scratch')
160 the_socket
.settimeout(SOCKET_TIMEOUT
)
161 sender
= ScratchSender(the_socket
)
162 listeners
= [ArduinoListener(device
, ARDUINO_BAUD_RATE
, sender
, BROADCAST_NAMES
, SENSOR_NAMES
) for device
in DEVICES
]
163 cycle_trace
= 'running'
164 logging
.info("Listeners running....")
166 for listener
in listeners
:
173 except KeyboardInterrupt:
174 logging
.warning("Interrrupted")
175 cleanup_threads(listeners
+ [sender
])