rbbit 0.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/Gemfile +6 -0
- data/LICENSE +21 -0
- data/README.md +94 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/rbbit +184 -0
- data/lib/rbbit/version.rb +3 -0
- data/lib/rbbit.rb +456 -0
- data/microbit/microbit-rbbit_20201127_js.txt +153 -0
- data/microbit/microbit-rbbit_20201127_v1.5.hex +14625 -0
- data/microbit/microbit-rbbit_20201127_v2.0.hex +34286 -0
- data/rbbit.gemspec +45 -0
- data/sample_console/s1_heart.rb +28 -0
- data/sample_console/s2_myname.rb +16 -0
- data/sample_console/s3_smiley.rb +63 -0
- data/sample_console/s4_dice1.rb +38 -0
- data/sample_console/s4_dice2.rb +82 -0
- data/sample_console/t1_blinker.rb +39 -0
- data/sample_console/t2_rotation.rb +47 -0
- data/sample_console/t3_timer.rb +24 -0
- data/sample_console/t4_alphabet.rb +28 -0
- data/sample_console/t5_switch.rb +33 -0
- data/sample_console/t6_dq.rb +111 -0
- data/sample_console/t7_ball.rb +69 -0
- data/sample_console/t8_light.rb +56 -0
- data/sample_console/t9_progress.rb +154 -0
- data/sample_web/led.html +325 -0
- data/sample_web/monitor.html +253 -0
- data/sample_web/rectangle.html +76 -0
- data/sample_web/sound.html +171 -0
- metadata +146 -0
data/lib/rbbit.rb
ADDED
@@ -0,0 +1,456 @@
|
|
1
|
+
require "rbbit/version"
|
2
|
+
|
3
|
+
require 'serialport'
|
4
|
+
require 'em-websocket'
|
5
|
+
require 'websocket-client-simple'
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
module Rbbit
|
9
|
+
class Error < StandardError; end
|
10
|
+
|
11
|
+
WS_PORT = 50215 # default WebSocket port
|
12
|
+
|
13
|
+
#
|
14
|
+
# WebSocket Server
|
15
|
+
#
|
16
|
+
class Agent
|
17
|
+
def initialize(mb, ws_server)
|
18
|
+
@mb = mb
|
19
|
+
#
|
20
|
+
ws_port = (ws_server == :default ? WS_PORT : ws_server)
|
21
|
+
run_server(ws_port)
|
22
|
+
Kernel.sleep 1
|
23
|
+
@con = WebSocket::Client::Simple.connect "ws://127.0.0.1:#{ws_port}"
|
24
|
+
@con.on :message do |msg|
|
25
|
+
#puts msg.data
|
26
|
+
end
|
27
|
+
@con.on :open do
|
28
|
+
@con.send('Hello')
|
29
|
+
end
|
30
|
+
@con.on :close do |e|
|
31
|
+
#p e
|
32
|
+
#exit 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def send_to_ws(data)
|
37
|
+
@con.send(data)
|
38
|
+
end
|
39
|
+
|
40
|
+
private def send_to_mb(data)
|
41
|
+
#p data (例外処理...)
|
42
|
+
if data["command"] == 'on'
|
43
|
+
x = (data["arg1"] ? data["arg1"] : nil)
|
44
|
+
y = (data["arg2"] ? data["arg2"] : nil)
|
45
|
+
@mb.led_on(x, y)
|
46
|
+
elsif data["command"] == 'off'
|
47
|
+
x = (data["arg1"] ? data["arg1"] : nil)
|
48
|
+
y = (data["arg2"] ? data["arg2"] : nil)
|
49
|
+
@mb.led_off(x, y)
|
50
|
+
elsif data["command"] == 'turn'
|
51
|
+
x = data["arg1"]
|
52
|
+
y = data["arg2"]
|
53
|
+
@mb.led_turn(x, y)
|
54
|
+
elsif data["command"] == 'show'
|
55
|
+
pattern = data["arg1"]
|
56
|
+
@mb.led_show(pattern)
|
57
|
+
elsif data["command"] == 'puts'
|
58
|
+
str = data["arg1"]
|
59
|
+
@mb.led_puts(str)
|
60
|
+
elsif data["command"] == 'play'
|
61
|
+
freq = data["arg1"].to_sym
|
62
|
+
beat = data["arg2"].to_f
|
63
|
+
@mb.sound_play(freq, beat)
|
64
|
+
elsif data["command"] == 'rest'
|
65
|
+
beat = data["arg2"].to_f
|
66
|
+
@mb.sound_rest(beat)
|
67
|
+
elsif data["command"] == 'volume'
|
68
|
+
v = data["arg1"].to_f
|
69
|
+
@mb.sound_volume = v
|
70
|
+
elsif data["command"] == 'tempo'
|
71
|
+
bpm = data["arg1"].to_f
|
72
|
+
@mb.sound_tempo = bpm
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
private def run_server(ws_port)
|
77
|
+
Thread.new do
|
78
|
+
connections = Array.new
|
79
|
+
EventMachine::WebSocket.start(host: "127.0.0.1", port: ws_port) do |ws|
|
80
|
+
ws.onopen {
|
81
|
+
# ws.send "Connected"
|
82
|
+
connections.push(ws) unless connections.index(ws)
|
83
|
+
}
|
84
|
+
ws.onmessage { |msg|
|
85
|
+
data = JSON.parse(msg) rescue nil
|
86
|
+
if data
|
87
|
+
if data.has_key?("command")
|
88
|
+
#p data
|
89
|
+
#p connections.size
|
90
|
+
send_to_mb(data)
|
91
|
+
else
|
92
|
+
connections.each do |con|
|
93
|
+
con.send(msg)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
}
|
98
|
+
ws.onclose {
|
99
|
+
#puts "Close"
|
100
|
+
connections.delete(ws) if connections.index(ws)
|
101
|
+
exit if connections.size == 0
|
102
|
+
}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
#
|
110
|
+
# Class Library
|
111
|
+
#
|
112
|
+
class Microbit
|
113
|
+
TONE = {
|
114
|
+
C3: 131 , # do3
|
115
|
+
Cs3: 139 , # do#3
|
116
|
+
D3: 147 , # re3
|
117
|
+
Ds3: 156 , # re#3
|
118
|
+
E3: 165 , # mi3
|
119
|
+
F3: 175 , # fa3
|
120
|
+
Fs3: 185 , # fa#3
|
121
|
+
G3: 196 , # so3
|
122
|
+
Gs3: 208 , # so#3
|
123
|
+
A3: 220 , # la3
|
124
|
+
As3: 233 , # la#3
|
125
|
+
B3: 247 , # ti3
|
126
|
+
C4: 262 , # do4
|
127
|
+
Cs4: 277 , # do#4
|
128
|
+
D4: 294 , # re4
|
129
|
+
Ds4: 311 , # re#4
|
130
|
+
E4: 330 , # mi4
|
131
|
+
F4: 349 , # fa4
|
132
|
+
Fs4: 370 , # fa#4
|
133
|
+
G4: 392 , # so4
|
134
|
+
Gs4: 415 , # so#4
|
135
|
+
A4: 440 , # la4
|
136
|
+
As4: 466 , # la#4
|
137
|
+
B4: 494 , # ti4
|
138
|
+
C5: 523 , # do5
|
139
|
+
Cs5: 554 , # do#5
|
140
|
+
D5: 587 , # re5
|
141
|
+
Ds5: 622 , # re#5
|
142
|
+
E5: 659 , # mi5
|
143
|
+
F5: 698 , # fa5
|
144
|
+
Fs5: 740 , # fa#5
|
145
|
+
G5: 784 , # so5
|
146
|
+
Gs5: 831 , # so#5
|
147
|
+
A5: 880 , # la5
|
148
|
+
As5: 932 , # la#5
|
149
|
+
B5: 988 , # ti5
|
150
|
+
C6: 1047 , # do6
|
151
|
+
}
|
152
|
+
WAIT = 0.05
|
153
|
+
attr_reader :x, :y, :z, :p, :r, :l, :t
|
154
|
+
|
155
|
+
def initialize(port = nil, ws_server = nil)
|
156
|
+
@agent = Agent.new(self, ws_server) if ws_server
|
157
|
+
@q = Queue.new
|
158
|
+
|
159
|
+
@x = nil
|
160
|
+
@y = nil
|
161
|
+
@z = nil
|
162
|
+
@p = nil
|
163
|
+
@r = nil
|
164
|
+
@l = nil
|
165
|
+
@t = nil
|
166
|
+
@button_down = {}
|
167
|
+
@button_down_last = {}
|
168
|
+
@button_press = {}
|
169
|
+
@button_release = {}
|
170
|
+
@button_down[:a] = nil
|
171
|
+
@button_down[:b] = nil
|
172
|
+
@button_down_last[:a] = nil
|
173
|
+
@button_down_last[:b] = nil
|
174
|
+
@button_press[:a] = nil
|
175
|
+
@button_press[:b] = nil
|
176
|
+
@button_release[:a] = nil
|
177
|
+
@button_release[:b] = nil
|
178
|
+
|
179
|
+
@on_press_a = nil
|
180
|
+
@on_press_b = nil
|
181
|
+
@on_release_a = nil
|
182
|
+
@on_release_b = nil
|
183
|
+
|
184
|
+
@volume = 127
|
185
|
+
@bpm = 120 # ウェイト調整のため、この値で明示的に初期化(initialize末尾)
|
186
|
+
|
187
|
+
@continue_thread = nil
|
188
|
+
@continue_loop = nil
|
189
|
+
|
190
|
+
@port = port || ENV['MB_PORT']
|
191
|
+
baud_rate = 115200
|
192
|
+
data_bits = 8
|
193
|
+
stop_bits = 1
|
194
|
+
parity = 0
|
195
|
+
|
196
|
+
raise Rbbit::Error, "serialport 'nil' is not available" unless @port
|
197
|
+
|
198
|
+
begin
|
199
|
+
@sp = SerialPort.open(@port, baud_rate, data_bits, stop_bits, parity)
|
200
|
+
rescue => e
|
201
|
+
#Kernel.puts e
|
202
|
+
#exit
|
203
|
+
raise Rbbit::Error, "serialport '#{@port}' is not available"
|
204
|
+
end
|
205
|
+
Kernel.sleep 0.5
|
206
|
+
|
207
|
+
# -- for write
|
208
|
+
@thread_w = Thread.new do
|
209
|
+
loop do
|
210
|
+
Thread.pass # for other threads
|
211
|
+
unless @q.empty?
|
212
|
+
cmd = @q.pop
|
213
|
+
if cmd.class == Array
|
214
|
+
@sp.write cmd[0]; Kernel.sleep cmd[1]
|
215
|
+
else
|
216
|
+
@sp.write cmd
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# -- for read
|
223
|
+
@thread_r = Thread.new do
|
224
|
+
# Thread.pass
|
225
|
+
@sp.read_timeout = 200
|
226
|
+
@continue_thread = true
|
227
|
+
loop do
|
228
|
+
break unless @continue_thread
|
229
|
+
Thread.pass # for other threads
|
230
|
+
begin
|
231
|
+
value = @sp.readline.chomp.strip.split(',')
|
232
|
+
# Kernel.p value
|
233
|
+
rescue EOFError
|
234
|
+
Kernel.sleep 0.1
|
235
|
+
retry
|
236
|
+
rescue ArgumentError
|
237
|
+
# 回避:`strip': invalid byte sequence in UTF-8 (ArgumentError)
|
238
|
+
# `split': invalid byte sequence in UTF-8 (ArgumentError)
|
239
|
+
Kernel.sleep 0.1
|
240
|
+
retry
|
241
|
+
end
|
242
|
+
|
243
|
+
@x = value[0].to_i
|
244
|
+
@y = value[1].to_i
|
245
|
+
@z = value[2].to_i
|
246
|
+
@p = value[3].to_i # pitch
|
247
|
+
@r = value[4].to_i # roll
|
248
|
+
@l = value[5].to_i # light
|
249
|
+
@t = value[6].to_i # temp
|
250
|
+
@button_down[:a] = (value[7] == "1" ? true : false)
|
251
|
+
@button_down[:b] = (value[8] == "1" ? true : false)
|
252
|
+
button_status
|
253
|
+
event_proc
|
254
|
+
if @agent
|
255
|
+
senddata = JSON.generate({x: @x,
|
256
|
+
y: @y,
|
257
|
+
z: @z,
|
258
|
+
p: @p,
|
259
|
+
r: @r,
|
260
|
+
l: @l,
|
261
|
+
t: @t,
|
262
|
+
a_down: @button_down[:a],
|
263
|
+
a_press: @button_press[:a],
|
264
|
+
a_release: @button_release[:a],
|
265
|
+
b_down: @button_down[:b],
|
266
|
+
b_press: @button_press[:b],
|
267
|
+
b_release: @button_release[:b]})
|
268
|
+
@agent.send_to_ws senddata
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
# -- init
|
274
|
+
self.sound_volume = @volume
|
275
|
+
self.sound_tempo = @bpm
|
276
|
+
end
|
277
|
+
|
278
|
+
def on_press_a(&block)
|
279
|
+
@on_press_a = block
|
280
|
+
end
|
281
|
+
|
282
|
+
def on_release_a(&block)
|
283
|
+
@on_release_a = block
|
284
|
+
end
|
285
|
+
|
286
|
+
def on_press_b(&block)
|
287
|
+
@on_press_b = block
|
288
|
+
end
|
289
|
+
|
290
|
+
def on_release_b(&block)
|
291
|
+
@on_release_b = block
|
292
|
+
end
|
293
|
+
|
294
|
+
def mainloop(&block)
|
295
|
+
@b = block # ブロックを登録
|
296
|
+
@continue_loop = true
|
297
|
+
loop do
|
298
|
+
break unless @continue_loop
|
299
|
+
@b.call
|
300
|
+
Kernel.sleep WAIT # ブロック1回処理ごとにウェイト
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def break
|
305
|
+
Kernel.sleep 0.5 ###
|
306
|
+
@continue_loop = false
|
307
|
+
end
|
308
|
+
|
309
|
+
def close(delay = 0)
|
310
|
+
@continue_thread = false
|
311
|
+
Kernel.sleep 1
|
312
|
+
until @q.empty? # wait for until command queue has been empty
|
313
|
+
Kernel.sleep 0.5
|
314
|
+
# Kernel.puts "sync #{@q.size}"
|
315
|
+
end
|
316
|
+
Kernel.sleep 0.5 + delay / 1000
|
317
|
+
@thread_w.kill
|
318
|
+
@thread_r.kill
|
319
|
+
@sp.close
|
320
|
+
end
|
321
|
+
|
322
|
+
def wait(ms)
|
323
|
+
@q << ["SLEEP %03d\n" % [ms], WAIT + ms / 1000.0]
|
324
|
+
end
|
325
|
+
|
326
|
+
def reset
|
327
|
+
@q << "RESET \n"
|
328
|
+
end
|
329
|
+
|
330
|
+
def port
|
331
|
+
@port
|
332
|
+
end
|
333
|
+
|
334
|
+
private def button_status
|
335
|
+
@button_down.each_key do |k|
|
336
|
+
change = @button_down[k] ^ @button_down_last[k] # Get change of mouse press status (XOR)
|
337
|
+
press = change & @button_down[k] # Detect change to press from release
|
338
|
+
release = change & !@button_down[k] # Detect change to release from press
|
339
|
+
@button_press[k] = press # Set mouse_press status
|
340
|
+
@button_release[k] = release # Set mouse_release status
|
341
|
+
@button_down_last[k] = @button_down[k]
|
342
|
+
end
|
343
|
+
end
|
344
|
+
|
345
|
+
private def event_proc
|
346
|
+
@on_press_a.call if @on_press_a and @button_press[:a]
|
347
|
+
@on_press_b.call if @on_press_b and @button_press[:b]
|
348
|
+
@on_release_a.call if @on_release_a and @button_release[:a]
|
349
|
+
@on_release_b.call if @on_release_b and @button_release[:b]
|
350
|
+
end
|
351
|
+
|
352
|
+
def button_down?(k)
|
353
|
+
@button_down[k]
|
354
|
+
end
|
355
|
+
|
356
|
+
# Pending...
|
357
|
+
#def button_press?(k)
|
358
|
+
# status = @button_press[k]
|
359
|
+
# @button_press[k] = false if @button_press[k] # avoid continuous judgment
|
360
|
+
# status
|
361
|
+
#end
|
362
|
+
|
363
|
+
# Pending...
|
364
|
+
#def button_release?(k)
|
365
|
+
# status = @button_release[k]
|
366
|
+
# @button_release[k] = false if @button_release[k] # avoid continuous judgment
|
367
|
+
# status
|
368
|
+
#end
|
369
|
+
|
370
|
+
def led_on(x = nil, y = nil)
|
371
|
+
if (x == nil and y == nil)
|
372
|
+
@q << ["LEDfil\n", WAIT]
|
373
|
+
else
|
374
|
+
@q << ["LEDon #{x}#{y}\n", WAIT]
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
def led_off(x = nil, y = nil)
|
379
|
+
if (x == nil and y == nil)
|
380
|
+
@q << ["LEDclr\n", WAIT]
|
381
|
+
else
|
382
|
+
@q << ["LEDoff#{x}#{y}\n", WAIT]
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
def led_turn(x, y)
|
387
|
+
@q << ["LEDtrn#{x}#{y}\n", WAIT]
|
388
|
+
end
|
389
|
+
|
390
|
+
def led_puts(str)
|
391
|
+
@q << ["LEDput#{str}\n", WAIT + str.length * 0.5]
|
392
|
+
end
|
393
|
+
|
394
|
+
def led_show(pattern)
|
395
|
+
ptn = []
|
396
|
+
5.times do |j|
|
397
|
+
ptn[j] = 0
|
398
|
+
5.times do |i|
|
399
|
+
ptn[j] += (2 ** (4 - i)) unless pattern[j][i] == 0 # 5-digits to decimal
|
400
|
+
end
|
401
|
+
end
|
402
|
+
#Kernel.p ptn
|
403
|
+
@q << ["LEDshw%02d%02d%02d%02d%02d\n" % ptn, WAIT]
|
404
|
+
end
|
405
|
+
|
406
|
+
def sound_volume=(v)
|
407
|
+
@q << ["SNDvol#{v}\n", WAIT]
|
408
|
+
@volume = v
|
409
|
+
end
|
410
|
+
|
411
|
+
def sound_tempo=(bpm)
|
412
|
+
@q << ["SNDbpm#{bpm}\n", WAIT]
|
413
|
+
@bpm = bpm
|
414
|
+
end
|
415
|
+
|
416
|
+
def sound_play(freq, beat)
|
417
|
+
@q << ["SNDply%04d%s\n" % [TONE[freq], _beat(beat)], WAIT * 0 + 60.0 / @bpm * beat] ###
|
418
|
+
end
|
419
|
+
|
420
|
+
def sound_rest(beat)
|
421
|
+
@q << ["SNDrst%s\n" % [_beat(beat)], WAIT + 60.0 / @bpm * beat]
|
422
|
+
end
|
423
|
+
|
424
|
+
private def _beat(beat)
|
425
|
+
if beat >= 4.0 # Whole note
|
426
|
+
return "4"
|
427
|
+
elsif beat >= 2.0 # Half note
|
428
|
+
return "2"
|
429
|
+
elsif beat >= 1.0 # Quarter note
|
430
|
+
return "1"
|
431
|
+
elsif beat >= 0.5 # Eighth note
|
432
|
+
return "/2"
|
433
|
+
elsif beat >= 0.25 # Sixteenth note
|
434
|
+
return "/4"
|
435
|
+
elsif beat >= 0.125 # Thirty-second note
|
436
|
+
return "/8"
|
437
|
+
else # Sixty-fourth note
|
438
|
+
return "/16"
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
alias_method :on, :led_on
|
443
|
+
alias_method :off, :led_off
|
444
|
+
alias_method :turn, :led_turn
|
445
|
+
alias_method :show, :led_show
|
446
|
+
alias_method :puts, :led_puts
|
447
|
+
|
448
|
+
alias_method :play, :sound_play
|
449
|
+
alias_method :rest, :sound_rest
|
450
|
+
alias_method :volume=, :sound_volume=
|
451
|
+
alias_method :tempo=, :sound_tempo=
|
452
|
+
|
453
|
+
end
|
454
|
+
|
455
|
+
end
|
456
|
+
|
@@ -0,0 +1,153 @@
|
|
1
|
+
function sound_rest (text: string) {
|
2
|
+
if (text == "1") {
|
3
|
+
music.rest(music.beat(BeatFraction.Whole))
|
4
|
+
} else if (text == "2") {
|
5
|
+
music.rest(music.beat(BeatFraction.Double))
|
6
|
+
} else if (text == "4") {
|
7
|
+
music.rest(music.beat(BeatFraction.Breve))
|
8
|
+
} else if (text == "/2") {
|
9
|
+
music.rest(music.beat(BeatFraction.Half))
|
10
|
+
} else if (text == "/4") {
|
11
|
+
music.rest(music.beat(BeatFraction.Quarter))
|
12
|
+
} else if (text == "/8") {
|
13
|
+
music.rest(music.beat(BeatFraction.Eighth))
|
14
|
+
} else if (text == "/16") {
|
15
|
+
music.rest(music.beat(BeatFraction.Sixteenth))
|
16
|
+
} else {
|
17
|
+
|
18
|
+
}
|
19
|
+
}
|
20
|
+
function sound_play (fq: number, text: string) {
|
21
|
+
if (text == "1") {
|
22
|
+
music.playTone(fq, music.beat(BeatFraction.Whole))
|
23
|
+
} else if (text == "2") {
|
24
|
+
music.playTone(fq, music.beat(BeatFraction.Double))
|
25
|
+
} else if (text == "4") {
|
26
|
+
music.playTone(fq, music.beat(BeatFraction.Breve))
|
27
|
+
} else if (text == "/2") {
|
28
|
+
music.playTone(fq, music.beat(BeatFraction.Half))
|
29
|
+
} else if (text == "/4") {
|
30
|
+
music.playTone(fq, music.beat(BeatFraction.Quarter))
|
31
|
+
} else if (text == "/8") {
|
32
|
+
music.playTone(fq, music.beat(BeatFraction.Eighth))
|
33
|
+
} else if (text == "/16") {
|
34
|
+
music.playTone(fq, music.beat(BeatFraction.Sixteenth))
|
35
|
+
} else {
|
36
|
+
|
37
|
+
}
|
38
|
+
}
|
39
|
+
let button_b = 0
|
40
|
+
let button_a = 0
|
41
|
+
let ms = 0
|
42
|
+
let y = 0
|
43
|
+
let x = 0
|
44
|
+
let bpm = 0
|
45
|
+
let volume = 0
|
46
|
+
let freq = 0
|
47
|
+
let value = 0
|
48
|
+
let param = ""
|
49
|
+
let cmd = ""
|
50
|
+
let recv = ""
|
51
|
+
serial.setRxBufferSize(128)
|
52
|
+
basic.showLeds(`
|
53
|
+
# # . # #
|
54
|
+
# . . . #
|
55
|
+
. . . . .
|
56
|
+
# . . . #
|
57
|
+
# # . # #
|
58
|
+
`)
|
59
|
+
basic.forever(function () {
|
60
|
+
let leng: string;
|
61
|
+
recv = serial.readLine()
|
62
|
+
cmd = recv.substr(0, 6)
|
63
|
+
if (cmd == "LEDshw") {
|
64
|
+
for (let j = 0; j <= 4; j++) {
|
65
|
+
param = recv.substr(6 + j * 2, 2)
|
66
|
+
value = parseFloat(param)
|
67
|
+
for (let i = 0; i <= 4; i++) {
|
68
|
+
if (value % 2 == 1) {
|
69
|
+
led.plot(4 - i, j)
|
70
|
+
value = value - 1
|
71
|
+
} else {
|
72
|
+
led.unplot(4 - i, j)
|
73
|
+
}
|
74
|
+
value = value / 2
|
75
|
+
}
|
76
|
+
}
|
77
|
+
} else if (recv == "LEDclr") {
|
78
|
+
basic.showLeds(`
|
79
|
+
. . . . .
|
80
|
+
. . . . .
|
81
|
+
. . . . .
|
82
|
+
. . . . .
|
83
|
+
. . . . .
|
84
|
+
`)
|
85
|
+
} else if (recv == "LEDfil") {
|
86
|
+
basic.showLeds(`
|
87
|
+
# # # # #
|
88
|
+
# # # # #
|
89
|
+
# # # # #
|
90
|
+
# # # # #
|
91
|
+
# # # # #
|
92
|
+
`)
|
93
|
+
} else if (cmd == "LEDput") {
|
94
|
+
param = recv.substr(6, recv.length - 6)
|
95
|
+
basic.showString(param)
|
96
|
+
} else if (cmd == "SNDply") {
|
97
|
+
param = recv.substr(6, 4)
|
98
|
+
freq = parseFloat(param)
|
99
|
+
leng = recv.substr(10, recv.length - 9)
|
100
|
+
sound_play(freq, leng)
|
101
|
+
} else if (cmd == "SNDrst") {
|
102
|
+
param = recv.substr(6, 3)
|
103
|
+
leng = param
|
104
|
+
sound_rest(leng)
|
105
|
+
} else if (cmd == "SNDvol") {
|
106
|
+
param = recv.substr(6, 3)
|
107
|
+
volume = parseFloat(param)
|
108
|
+
music.setVolume(volume)
|
109
|
+
} else if (cmd == "SNDbpm") {
|
110
|
+
param = recv.substr(6, 3)
|
111
|
+
bpm = parseFloat(param)
|
112
|
+
music.setTempo(bpm)
|
113
|
+
} else if (cmd == "LEDon ") {
|
114
|
+
param = recv.substr(6, 1)
|
115
|
+
x = parseFloat(param)
|
116
|
+
param = recv.substr(7, 1)
|
117
|
+
y = parseFloat(param)
|
118
|
+
led.plot(x, y)
|
119
|
+
} else if (cmd == "LEDoff") {
|
120
|
+
param = recv.substr(6, 1)
|
121
|
+
x = parseFloat(param)
|
122
|
+
param = recv.substr(7, 1)
|
123
|
+
y = parseFloat(param)
|
124
|
+
led.unplot(x, y)
|
125
|
+
} else if (cmd == "LEDtrn") {
|
126
|
+
param = recv.substr(6, 1)
|
127
|
+
x = parseFloat(param)
|
128
|
+
param = recv.substr(7, 1)
|
129
|
+
y = parseFloat(param)
|
130
|
+
led.toggle(x, y)
|
131
|
+
} else if (cmd == "RESET ") {
|
132
|
+
control.reset()
|
133
|
+
} else if (cmd == "SLEEP ") {
|
134
|
+
param = recv.substr(6, 3)
|
135
|
+
ms = parseFloat(param)
|
136
|
+
basic.pause(ms)
|
137
|
+
} else {
|
138
|
+
|
139
|
+
}
|
140
|
+
})
|
141
|
+
basic.forever(function () {
|
142
|
+
if (input.buttonIsPressed(Button.A)) {
|
143
|
+
button_a = 1
|
144
|
+
} else {
|
145
|
+
button_a = 0
|
146
|
+
}
|
147
|
+
if (input.buttonIsPressed(Button.B)) {
|
148
|
+
button_b = 1
|
149
|
+
} else {
|
150
|
+
button_b = 0
|
151
|
+
}
|
152
|
+
serial.writeNumbers([input.acceleration(Dimension.X), input.acceleration(Dimension.Y), input.acceleration(Dimension.Z), input.rotation(Rotation.Pitch), input.rotation(Rotation.Roll), input.lightLevel(), input.temperature(), button_a, button_b])
|
153
|
+
})
|