# 「ハードウェア」ジャンル <% category = 'hardware' color = 208 %> # ハードウェアの環境設定 window.SmalrubyEditor.Hardware = Type: 'Arduino' # 種別 DioPins: [2..13] # デジタルIOピン PwmPins: [3, 5, 6, 9, 10, 11] # デジタルIOピンのうちPWMに対応しているピン AiPins: [0..5] # アナログ入力ピン dioPinDropdown = (["D#{n}", "D#{n}"] for n in window.SmalrubyEditor.Hardware.DioPins) pwmPinDropdown = (["D#{n}", "D#{n}"] for n in window.SmalrubyEditor.Hardware.PwmPins) rgbLedPinDropdown = (["D#{n}", "D#{n}"] for n in [3, 9]) aiPinDropdown = (["A#{n}", "A#{n}"] for n in window.SmalrubyEditor.Hardware.AiPins) acDropdown = [ ['アノード', 'anode'] ['カソード', 'cathode'] ] twoWDPinDropdown = (["D#{n}", "D#{n}"] for n in [2..10]) # ハードウェアを準備する <% n = "#{category}_init_hardware" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput().appendField('ハードウェアを準備する') @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> Blockly.Ruby.definitions_['init_hardware'] = 'init_hardware' '' # 「LED」サブジャンル # LED[▼ピン]をオンにする # LED[▼ピン]をオフにする <% [ ['on', 'オン'], ['off', 'オフ'], ].each do |method, label| n = "#{category}_led_#{method}" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput() .appendField('LED') .appendField(new Blockly.FieldDropdown(dioPinDropdown), 'PIN') .appendField('を<%= label %>にする') @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') @setFieldValue('D2', 'PIN') Blockly.Ruby['<%= n %>'] = (block) -> pin = @getFieldValue('PIN') Blockly.Ruby.characterMethodCall_("led(#{Blockly.Ruby.quote_(pin)}).<%= method %>") <% end %> # 「RGB LED」サブジャンル # RGB LED[▼アノード]コモン[▼ピン]を[カラー]にする <% n = "#{category}_rgb_led_on" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput() .appendField('RGB LED') .appendField(new Blockly.FieldDropdown(acDropdown), 'AC') .appendField('コモン') .appendField(new Blockly.FieldDropdown(rgbLedPinDropdown), 'PIN') .appendField('を') .appendField(new Blockly.FieldColour('#ff0000'), 'COLOUR') .appendField('にする') @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> ac = @getFieldValue('AC') pin = @getFieldValue('PIN') c = block.getFieldValue('COLOUR') red = parseInt(c[1..2], 16) green = parseInt(c[3..4], 16) blue = parseInt(c[5..6], 16) Blockly.Ruby.characterMethodCall_("rgb_led_#{ac}(#{Blockly.Ruby.quote_(pin)}).on", "color: [#{red}, #{green}, #{blue}]") # RGB LED[▼アノード]コモン[▼ピン]をオフにする <% n = "#{category}_rgb_led_off" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput() .appendField('RGB LED') .appendField(new Blockly.FieldDropdown(acDropdown), 'AC') .appendField('コモン') .appendField(new Blockly.FieldDropdown(rgbLedPinDropdown), 'PIN') .appendField('をオフにする') @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> ac = @getFieldValue('AC') pin = @getFieldValue('PIN') Blockly.Ruby.characterMethodCall_("rgb_led_#{ac}(#{Blockly.Ruby.quote_(pin)}).off") # 「7セグディスプレイ」サブジャンル # 7セグディスプレイに[▼0-9]を表示する <% n = "#{category}_seven_segment_display_show" %> Blockly.Blocks['<%= n %>'] = init: ()-> dropdown = ([String(n), String(n)] for n in [0..9]) @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput() .appendField('7セグディスプレイに') .appendField(new Blockly.FieldDropdown(dropdown), 'NUM') .appendField('を表示する') @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> num = parseInt(@getFieldValue('NUM')) "seven_segment_display.show(#{num})\n" # 7セグディスプレイをオフにする <% n = "#{category}_seven_segment_display_off" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput() .appendField('7セグディスプレイをオフにする') @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> "seven_segment_display.off\n" # 「LCD」サブジャンル # LCDに( )を表示する <% n = "#{category}_lcd_puts" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= color %>) @appendValueInput('TEXT') .appendField('LCDに') .setCheck('String') @appendDummyInput() .appendField('を表示する') @setInputsInline(true) @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> text = Blockly.Ruby.valueToCode(@, 'TEXT', Blockly.Ruby.ORDER_NONE) || '' "lcd.puts(#{text})\n" # LCDをクリアする <% n = "#{category}_lcd_clear" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput() .appendField('LCDをクリアする') @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> "lcd.clear\n" # 7セグディスプレイをオフにする <% n = "#{category}_seven_segment_display_off" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput() .appendField('7セグディスプレイをオフにする') @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> "seven_segment_display.off\n" # 「サーボ」サブジャンル # 「サーボ[▼ピン]を( )度(5~180)にする」ブロック <% n = "#{category}_servo_set_position" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput() .appendField('サーボ') .appendField(new Blockly.FieldDropdown(pwmPinDropdown), 'PIN') .appendField('を') @appendValueInput('POS') .setCheck('Number') @appendDummyInput() .appendField('度(5~180)にする') @setInputsInline(true) @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> pin = @getFieldValue('PIN') pos = Blockly.Ruby.valueToCode(@, 'POS', Blockly.Ruby.ORDER_FUNCTION_CALL) || '5' Blockly.Ruby.characterMethodCall_("servo(#{Blockly.Ruby.quote_(pin)}).position = #{pos}") # 「車」サブジャンル <% subcategory = 'two_wheel_drive_car' %> # 2WD車[▼ピン]を進める # 2WD車[▼ピン]をバックさせる # 2WD車[▼ピン]を左に曲げる # 2WD車[▼ピン]を右に曲げる # 2WD車[▼ピン]を止める <% [ ['forward', '進める'], ['backward', 'バックさせる'], ['turn_left', '左に曲げる'], ['turn_right', '右に曲げる'], ['stop', '止める'], ].each do |method, label| n = "#{category}_#{subcategory}_#{method}" %> Blockly.Blocks['<%= n %>'] = init: ()-> dropdown = (["D#{n}", "D#{n}"] for n in [2..10]) @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput() .appendField('2WD車') .appendField(new Blockly.FieldDropdown(twoWDPinDropdown), 'PIN') .appendField('を<%= label %>') @setInputsInline(true) @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> pin = @getFieldValue('PIN') Blockly.Ruby.characterMethodCall_("two_wheel_drive_car(#{Blockly.Ruby.quote_(pin)}).<%= method %>") <% end %> # 2WD車[▼ピン]を( )秒[▼コマンド] <% n = "#{category}_#{subcategory}_run" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput() .appendField('2WD車') .appendField(new Blockly.FieldDropdown(twoWDPinDropdown), 'PIN') .appendField('を') @appendValueInput('SEC') .setCheck('Number') @appendDummyInput() .appendField('秒') @appendValueInput('COMMAND').setCheck('String') @setInputsInline(true) @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> pin = @getFieldValue('PIN') sec = Blockly.Ruby.valueToCode(@, 'SEC', Blockly.Ruby.ORDER_NONE) || 0 command = Blockly.Ruby.valueToCode(@, 'COMMAND', Blockly.Ruby.ORDER_NONE) || Blockly.Ruby.quote_('stop') Blockly.Ruby.characterMethodCall_("two_wheel_drive_car(#{Blockly.Ruby.quote_(pin)}).run(command: #{command}, sec: #{sec})") # [▼コマンド] <% n = "#{category}_#{subcategory}_commands" %> Blockly.Blocks['<%= n %>'] = init: ()-> commands = [ ['進める', 'forward'], ['バックさせる', 'backward'], ['左に曲げる', 'turn_left'], ['右に曲げる', 'turn_right'], ['止める', 'stop'], ] @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput() .appendField(new Blockly.FieldDropdown(commands), 'COMMAND') @setOutput(true, 'String') @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> code = Blockly.Ruby.quote_(@getFieldValue('COMMAND')) [code, Blockly.Ruby.ORDER_ATOMIC] # 「ボタン」サブジャンル # 条件:ボタン[▼]を押している # 条件:ボタン[▼]を離している <% [ ['down', '押している'], ['up', '離している'], ].each do |method, label| n = "#{category}_button_#{method}" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput() .appendField('ボタン') .appendField(new Blockly.FieldDropdown(dioPinDropdown), 'PIN') .appendField('を<%= label %>') @setOutput(true, 'Boolean') @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> pin = @getFieldValue('PIN') ["button(#{pin}).<%= method %>?", Blockly.Ruby.ORDER_ATOMIC] <% end %> # ボタン[▼]を押したとき # ボタン[▼]を離したとき <% [ ['down', '押した'], ['up', '離した'], ].each do |name, label| n = "#{category}_on_button_#{name}" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput() .appendField('ボタン') .appendField(new Blockly.FieldDropdown(dioPinDropdown), 'PIN') .appendField('を<%= label %>とき') @appendStatementInput('DO') @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> if (var0 = Blockly.Ruby.receiverName()) pin = @getFieldValue('PIN') branch = Blockly.Ruby.statementToCode(block, 'DO') || '\n' """ #{var0}.on(:button_<%= name %>, #{pin}) do #{branch}end """ else '' <% end %> # 「センサー」サブジャンル # センサー[▼PIN] <% n = "#{category}_sensor_value" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput() .appendField('センサー') .appendField(new Blockly.FieldDropdown(aiPinDropdown), 'PIN') @setOutput(true, 'Number') @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> pin = @getFieldValue('PIN') Blockly.Ruby.characterMethodCallInput_("sensor(#{Blockly.Ruby.quote_(pin)}).value") # センサー[▼PIN]が変化したとき <% n = "#{category}_on_sensor_change" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= color %>) @appendDummyInput() .appendField('センサー') .appendField(new Blockly.FieldDropdown(aiPinDropdown), 'PIN') .appendField('が変化したとき') @appendStatementInput('DO') @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> pin = @getFieldValue('PIN') Blockly.Ruby.characterEvent_(block, 'DO', 'sensor_change', Blockly.Ruby.quote_(pin))