2012年6月2日土曜日

'google-blockly'+'serialport-server'

  1. I used 'Serialport-server' ( http://shokai.github.com/serial­­port-server/ ).
  2. I got the google-blockly code from google code by svn.
  3. I added the 'language_device.js' in demos/maze folder. The 'language_device.js' code is in my blog.
  4. I added one line which request the 'language_device.js' to the 'frame.html' in demos/maze folder.
  5. I added some lines to the 'maze.js' in demos/maze folder. The lines code is in my blog.
    Scratch has the function about 'create a program using blocks'. Scratch has the function about 'serial port communication'. The following page describes the serial port communication between Scratch and Ardino in Japanese and English.
    Scratch+Arduino | Yengawa Systems http://www.yengawa.com/scratch_arduino

動機
コード language_device.js
if (!Blockly.Language) {
  Blockly.Language = {};
}

Blockly.JavaScript = Blockly.Generator.get('JavaScript');

Blockly.Language.device_sendValue = {
  category: 'Device',
  helpUrl: '',
  init: function() {
    this.setColour(210);
    this.addTitle('Send Value');
    var dropdown = new Blockly.FieldDropdown(function() {
      return Blockly.Language.device_sendValue.Symbol;
    });
    this.addTitle(dropdown);
    this.setTitleText(Blockly.Language.device_sendValue.Symbol[0], 1);
    this.addTitle('To Server (Addr \u201C');
    this.addTitle(new Blockly.FieldTextInput('http://localhost:8783'));
    this.addTitle('\u201D \)');
    this.setPreviousStatement(true);
    this.setNextStatement(true);
    this.setTooltip('Send Value to the serialport-server');
  }
};

Blockly.Language.device_sendValue.Symbol = ['o', 'x'];

Blockly.JavaScript.device_sendValue = function() {
  var _addr= Blockly.JavaScript.quote_(this.getTitleText(3));
  var _symbol = Blockly.Language.device_sendValue.Symbol.indexOf(this.getTitleText(1));
  
  if (false) {
    var cmd= "var xhr = new XMLHttpRequest();";
    cmd+= "xhr.open('post', "+_addr+", false);";
    cmd+= "xhr.onreadystatechange = function(){";
    cmd+= "if (xhr.readyState === 4 && xhr.status === 200){";
    cmd+= "}";
    cmd+= "};";
    cmd+= "xhr.send('"+_symbol+"');\n";
    return cmd;
  }
  else {
    return (_symbol===0?"Maze.ledon();":"Maze.ledoff();")+"\n";
  }
};
  • 'Blockly.JavaScript.device_sendValue'においてMazeのアニメに合わせて動作させるために内部用のコマンドを返すようにしてあるが, 単に対応するJavascriptを返すだけならif文のthen側,cmdの値を使えばよい.(serialport-serverに'o'か'x'を送るというJavascript)
  • これをframe.htmlで定義している他のjsファイルと共に読み込ませるだけでエディタの項目に出てくる
  • 編集結果のjavascript codeを取得するには
      var code = Blockly.Generator.workspaceToCode('JavaScript');
    
    で取得できる.(引数文字列'JavaScript'とBlockly.'JavaScript'が対応付いて'Language'の関数(Blocklyの編集用オブジェクト)に対応する'JavaScript'の同名関数の返り値(文字列)の集まりが得られる)
結果
maze.jsの差分(赤色部分)
 …
Maze.animate = function() {
 …
  } else if (action == 'finish') {
    Maze.scheduleFinish();
  }
  else if (action == 'send_o') {
      var xhr = new XMLHttpRequest();
      xhr.open('post', 'http://localhost:8783', true);
      xhr.onreadystatechange = function(){
        if (xhr.readyState === 4 && xhr.status === 200){
        }
      };
      xhr.send('o');
  }
  else if (action == 'send_x') {
      var xhr = new XMLHttpRequest();
      xhr.open('post', 'http://localhost:8783', true);
      xhr.onreadystatechange = function(){
        if (xhr.readyState === 4 && xhr.status === 200){
        }
      };
      xhr.send('x');
  }
  
  Maze.pidList.push(window.setTimeout(Maze.animate, Maze.STEP_SPEED * 5));
};
 …
Maze.ledoff = function() {
  Maze.checkTimeout();
  Maze.path.push(['send_x', null]);
}
Maze.ledon = function() {
  Maze.checkTimeout();
  Maze.path.push(['send_o', null]);
}

0 件のコメント: