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 from Tkinter import Tk
18 from tkSimpleDialog import askstring
24 DEFAULT_HOST
= '127.0.0.1'
25 BUFFER_SIZE
= 240 #used to be 100
27 DRUM_DEVICE
= '/dev/ttyACM0'
28 GUITAR_DEVICE
= '/dev/ttyUSB1'
29 MARACAS_DEVICE
= '/dev/ttyACM1'
30 ARDUINO_BAUD_RATE
= 57600
32 DRUM_INSTRUMENT_NAMES
= {0: 'cymbal',
38 DRUM_VALUE_NAMES
= {0: 'drum-volume',
44 GUITAR_INSTRUMENT_NAMES
= {0: 'guitar'}
45 GUITAR_VALUE_NAMES
= {0: 'guitar_pitch'}
47 GUITAR_INSTRUMENT_NAMES
= {0: 'guitar'}
48 GUITAR_VALUE_NAMES
= {0: 'guitar_pitch'}
50 MARACAS_INSTRUMENT_NAMES
= {0: 'maracas', 2: 'maracas'}
51 MARACAS_VALUE_NAMES
= {0: 'maracas_vigour', 2: 'maracas_vigour'}
54 class MyError(Exception):
55 def __init__(self
, value
):
59 return repr(self
.value
)
61 class ScratchSender(threading
.Thread
):
62 def __init__(self
, socket
):
63 threading
.Thread
.__init
__(self
)
64 self
.scratch_socket
= socket
65 self
._stop
= threading
.Event()
72 return self
._stop
.isSet()
77 while not self
.stopped():
78 time
.sleep(0.01) # be kind to cpu - not certain why :)
80 def send_scratch_command(self
, cmd
):
83 a
.append(chr((n
>> 24) & 0xFF))
84 a
.append(chr((n
>> 16) & 0xFF))
85 a
.append(chr((n
>> 8) & 0xFF))
86 a
.append(chr(n
& 0xFF))
87 self
.scratch_socket
.send(a
.tostring() + cmd
)
90 class ArduinoListener(threading
.Thread
):
91 def __init__(self
, device
, speed
, sender
, instruments
, values
):
92 threading
.Thread
.__init
__(self
)
93 self
.arduino_device
= serial
.Serial(device
, speed
)
94 self
._stop
= threading
.Event()
95 self
.scratch_sender
= sender
96 self
.instruments
= instruments
103 return self
._stop
.isSet()
106 self
.arduino_device
.readline() # discard the first (partial) line
107 while not self
.stopped():
109 pin_string
, pin_value_string
= self
.arduino_device
.readline().rstrip().split(',', 1)
110 pin
= int(pin_string
)
111 pin_value
= int(pin_value_string
)
112 print dt
.datetime
.now(), 'Pin: %d, Value: %d' % (pin
, pin_value
)
114 print "sensor-update %s %d" % (self
.values
[pin
], (pin_value
* 100) / 1024)
115 self
.scratch_sender
.send_scratch_command("sensor-update %s %d" % (self
.values
[pin
], (pin_value
* 100) / 1024))
120 print "broadcast %s" % self
.instruments
[pin
]
121 self
.scratch_sender
.send_scratch_command('broadcast %s' % self
.instruments
[pin
])
126 except serial
.SerialException
:
127 print 'Serial exception'
131 def create_socket(host
, port
):
135 scratch_sock
= socket
.socket(socket
.AF_INET
, socket
.SOCK_STREAM
)
136 scratch_sock
.connect((host
, port
))
139 print "There was an error connecting to Scratch!"
140 print "I couldn't find a Mesh session at host: %s, port: %s" % (host
, port
)
146 def cleanup_threads(threads
):
147 for thread
in threads
:
150 for thread
in threads
:
153 if __name__
== '__main__':
154 if len(sys
.argv
) > 1:
160 cycle_trace
= 'start'
162 if (cycle_trace
== 'disconnected'):
163 print "Scratch disconnected"
164 cleanup_threads((listener
, sender
))
166 cycle_trace
= 'start'
168 if (cycle_trace
== 'start'):
170 print 'Starting to connect...' ,
171 the_socket
= create_socket(host
, PORT
)
173 the_socket
.settimeout(SOCKET_TIMEOUT
)
174 ## data = the_socket.recv(BUFFER_SIZE)
175 ## print "Discard 1st data buffer" , data[4:].lower()
176 sender
= ScratchSender(the_socket
)
177 drum_listener
= ArduinoListener(DRUM_DEVICE
, ARDUINO_BAUD_RATE
, sender
, DRUM_INSTRUMENT_NAMES
, DRUM_VALUE_NAMES
)
178 guitar_listener
= ArduinoListener(GUITAR_DEVICE
, ARDUINO_BAUD_RATE
, sender
, GUITAR_INSTRUMENT_NAMES
, GUITAR_VALUE_NAMES
)
179 maracas_listener
= ArduinoListener(MARACAS_DEVICE
, ARDUINO_BAUD_RATE
, sender
, MARACAS_INSTRUMENT_NAMES
, MARACAS_VALUE_NAMES
)
180 cycle_trace
= 'running'
183 drum_listener
.start()
184 guitar_listener
.start()
185 maracas_listener
.start()
189 #print 'Sending:' "sensor-update %s %d" % (VOLUME_NAMES[pin], (pin_value * 100) / 1024)
190 #sender.send_scratch_command("sensor-update %s %d" % (VOLUME_NAMES[pin], (pin_value * 100) / 1024))
191 #print 'Sending:' 'broadcast %s' % INSTRUMENT_NAMES[pin]
192 #sender.send_scratch_command('broadcast %s' % INSTRUMENT_NAMES[pin])
194 #sender.send_scratch_command("sensor-update guitar-pitch 10")
195 #sender.send_scratch_command("broadcast cymbal")
197 #sender.send_scratch_command("broadcast snare")
199 #sender.send_scratch_command("broadcast hihat")
201 #sender.send_scratch_command("broadcast slowdrum")
203 #sender.send_scratch_command("broadcast tomtom")
212 except KeyboardInterrupt:
213 cleanup_threads((sender
, drum_listener
, guitar_listener
, maracas_listener
))