# 「ハードウェア」ジャンル <% category = 'hardware' require 'smalruby_editor' colors = SmalrubyEditor::COLORS %> # ハードウェアの環境設定 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'] ] lorPinDropdown = [ ['左', 'left'], ['右', 'right'], ] twoWDPinDropdown = (["D#{n}", "D#{n}"] for n in [2..10]) # ハードウェアを準備する <% n = "#{category}_init_hardware" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= colors[:etc] %>) @appendDummyInput().appendField('ハードウェアを準備する') @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> Blockly.Ruby.definitions_['init_hardware'] = 'init_hardware' '' # 「LED」サブジャンル # LED[▼PIN]をオンにする # LED[▼PIN]をオフにする <% [ ['on', 'オン'], ['off', 'オフ'], ].each do |method, label| n = "#{category}_led_#{method}" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= colors[:looks] %>) @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[▼アノード]コモン[▼PIN]を[カラー]にする <% n = "#{category}_rgb_led_on" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= colors[:looks] %>) @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[▼アノード]コモン[▼PIN]をオフにする <% n = "#{category}_rgb_led_off" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= colors[:looks] %>) @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(<%= colors[:looks] %>) @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(<%= colors[:looks] %>) @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(<%= colors[:looks] %>) @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(<%= colors[:looks] %>) @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(<%= colors[:looks] %>) @appendDummyInput() .appendField('7セグディスプレイをオフにする') @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> "seven_segment_display.off\n" # 「サーボ」サブジャンル # 「サーボ[▼PIN]を( )度(5~180)にする」ブロック <% n = "#{category}_servo_set_position" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= colors[:motion] %>) @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}") # 「2WD車」サブジャンル <% subcategory = 'two_wheel_drive_car' %> # 2WD車[▼PIN]を進める # 2WD車[▼PIN]をバックさせる # 2WD車[▼PIN]を左に曲げる # 2WD車[▼PIN]を右に曲げる # 2WD車[▼PIN]を止める <% [ ['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(<%= colors[:motion] %>) @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車[▼PIN]を( )秒[▼コマンド] <% n = "#{category}_#{subcategory}_run" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= colors[:motion] %>) @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(<%= colors[:motion] %>) @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] # 2WD車[▼PIN]の[▼LOR]の速度を<速度の割合>%にする <% n = "#{category}_#{subcategory}_set_speed" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= colors[:motion] %>) @appendDummyInput() .appendField('2WD車') .appendField(new Blockly.FieldDropdown(pwmPinDropdown), 'PIN') .appendField('の') .appendField(new Blockly.FieldDropdown(lorPinDropdown), 'LOR') .appendField('の速度を') @interpolateMsg('%1%にする', ['SPEED', ['Number'], Blockly.ALIGN_RIGHT], Blockly.ALIGN_RIGHT) @setInputsInline(true) @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> pin = @getFieldValue('PIN') lor = @getFieldValue('LOR') speed = Blockly.Ruby.valueToCode(@, 'SPEED', Blockly.Ruby.ORDER_NONE) || '100' Blockly.Ruby.characterMethodCall_("two_wheel_drive_car(#{Blockly.Ruby.quote_(pin)}).#{lor}_speed = #{speed}") # 2WD車[▼PIN]の[▼LOR]の速度(%) <% n = "#{category}_#{subcategory}_speed" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= colors[:sensing] %>) @appendDummyInput() .appendField('2WD車') .appendField(new Blockly.FieldDropdown(pwmPinDropdown), 'PIN') .appendField('の') .appendField(new Blockly.FieldDropdown(lorPinDropdown), 'LOR') .appendField('の速度(%)') @setOutput(true, 'Number') @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> pin = @getFieldValue('PIN') lor = @getFieldValue('LOR') Blockly.Ruby.characterMethodCallInput_("two_wheel_drive_car(#{Blockly.Ruby.quote_(pin)}).#{lor}_speed") # 「(モータードライバ{で,の})モータ」サブジャンル <% subcategory = 'motor_driver' %> # (モータードライバ[▼PIN]で)モーターを[▼正転させる] <% n = "#{category}_#{subcategory}" %> Blockly.Blocks['<%= n %>'] = init: ()-> methodDropdown = [ ['正転させる', 'forward'], ['逆転させる', 'backward'], ['止める', 'stop'], ] @setHelpUrl('') @setColour(<%= colors[:motion] %>) @appendDummyInput() .appendField('(モータードライバ') .appendField(new Blockly.FieldDropdown(pwmPinDropdown), 'PIN') .appendField('で)モーターを') .appendField(new Blockly.FieldDropdown(methodDropdown), 'METHOD') @setInputsInline(true) @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> pin = @getFieldValue('PIN') method = @getFieldValue('METHOD') Blockly.Ruby.characterMethodCall_("motor_driver(#{Blockly.Ruby.quote_(pin)}).#{method}") # (モータードライバ[▼PIN]の)モーターの速度を%にする <% n = "#{category}_#{subcategory}_set_speed" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= colors[:motion] %>) @appendDummyInput() .appendField('(モータードライバ') .appendField(new Blockly.FieldDropdown(pwmPinDropdown), 'PIN') .appendField('の)モーターの速度を') @interpolateMsg('%1%にする', ['SPEED', ['Number'], Blockly.ALIGN_RIGHT], Blockly.ALIGN_RIGHT) @setInputsInline(true) @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> pin = @getFieldValue('PIN') speed = Blockly.Ruby.valueToCode(@, 'SPEED', Blockly.Ruby.ORDER_NONE) || '100' Blockly.Ruby.characterMethodCall_("motor_driver(#{Blockly.Ruby.quote_(pin)}).speed = #{speed}") # (モータードライバ[▼PIN]の)モーターの速度(%) <% n = "#{category}_#{subcategory}_speed" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= colors[:sensing] %>) @appendDummyInput() .appendField('(モータードライバ') .appendField(new Blockly.FieldDropdown(pwmPinDropdown), 'PIN') .appendField('の)モーターの速度(%)') @setOutput(true, 'Number') @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> pin = @getFieldValue('PIN') Blockly.Ruby.characterMethodCallInput_("motor_driver(#{Blockly.Ruby.quote_(pin)}).speed") # 「ボタン」サブジャンル # 条件:ボタン[▼PIN]が[▼押された] <% n = "#{category}_button_down_or_up" %> Blockly.Blocks['<%= n %>'] = init: ()-> douDropdown = window.SmalrubyEditor.Sensing.DownOrUpDropdown @setHelpUrl('') @setColour(<%= colors[:sensing] %>) @appendDummyInput() .appendField('ボタン') .appendField(new Blockly.FieldDropdown(dioPinDropdown), 'PIN') .appendField('が') .appendField(new Blockly.FieldDropdown(douDropdown), 'DOU') @setOutput(true, 'Boolean') @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> pin = @getFieldValue('PIN') dou = @getFieldValue('DOU') Blockly.Ruby.characterMethodCallInput_("button(#{Blockly.Ruby.quote_(pin)}).#{dou}?") # ボタン[▼PIN]が[▼押された]とき <% n = "#{category}_on_button_down_or_up" %> Blockly.Blocks['<%= n %>'] = init: ()-> douDropdown = window.SmalrubyEditor.Sensing.DownOrUpDropdown @setHelpUrl('') @setColour(<%= colors[:events] %>) @appendDummyInput() .appendField('ボタン') .appendField(new Blockly.FieldDropdown(dioPinDropdown), 'PIN') .appendField('が') .appendField(new Blockly.FieldDropdown(douDropdown), 'DOU') .appendField('とき') @appendStatementInput('DO') @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> pin = @getFieldValue('PIN') dou = @getFieldValue('DOU') Blockly.Ruby.characterEvent_(block, 'DO', "button_#{dou}", Blockly.Ruby.quote_(pin)) # ボタン[▼PIN]のプルアップ抵抗を使わない <% n = "#{category}_button_not_use_pullup" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= colors[:etc] %>) @appendDummyInput() .appendField('ボタン') .appendField(new Blockly.FieldDropdown(dioPinDropdown), 'PIN') .appendField('のプルアップ抵抗を使わない') @setPreviousStatement(true) @setNextStatement(true) @setTooltip('') Blockly.Ruby['<%= n %>'] = (block) -> pin = @getFieldValue('PIN') Blockly.Ruby.characterMethodCall_("button(#{Blockly.Ruby.quote_(pin)}).not_use_pullup") # 「センサー」サブジャンル # センサー[▼PIN] <% n = "#{category}_sensor_value" %> Blockly.Blocks['<%= n %>'] = init: ()-> @setHelpUrl('') @setColour(<%= colors[:sensing] %>) @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(<%= colors[:events] %>) @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))