ocoge/blocks/sensors/ssd1306.js

731 lines
23 KiB
JavaScript
Raw Permalink Normal View History

/*************** */
/** SSD1306 OLED */
/*************** */
Blockly.Blocks['oc_oled_init'] = {
init: function () {
this.appendDummyInput()
.appendField("有機ELディスプレイ")
.appendField(new Blockly.FieldVariable("oled"), "i2c_device")
.appendField("に接続");
this.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("I2Cアドレス")
.appendField(new Blockly.FieldDropdown([["0x3c", "0x3c"], ["0x3d", "0x3d"]]), "i2c_addr");
this.appendDummyInput()
.setAlign(Blockly.ALIGN_RIGHT)
.appendField("画面サイズ(幅x高さ)")
.appendField(new Blockly.FieldDropdown([["128x64", "128x64"], ["128x32", "128x32"], ["96x16", "96x16"]]), "disp_size");
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setStyle('sensor_blocks');
this.setTooltip("I2C 接続の SSD1306 有機ELディスプレイを使えるようにします。");
this.setHelpUrl("");
}
};
javascript.javascriptGenerator.forBlock['oc_oled_init'] = function (block, generator) {
var variable_i2c_device = generator.nameDB_.getName(block.getFieldValue('i2c_device'), Blockly.Names.NameType.VARIABLE);
var dropdown_i2c_addr = block.getFieldValue('i2c_addr');
var dropdown_disp_size = block.getFieldValue('disp_size');
Blockly.JavaScript.provideFunction_(
'require_oled', [`const _oled = require('@ocoge/ssd1306');`]
);
let size_x, size_y;
if (dropdown_disp_size == '128x64') {
size_x = 128;
size_y = 64;
}
var code = `var _opts = {
width: ${size_x},
height: ${size_y},
address: ${dropdown_i2c_addr},
bus: ${apptool.i2c_bus}
};
${variable_i2c_device} = new _oled(_rg, _opts);
${variable_i2c_device}.clearDisplay();
${variable_i2c_device}.turnOnDisplay();
`;
return code;
};
/** Draw Line */
Blockly.Blocks['oc_oled_drawline'] = {
init: function () {
this.appendValueInput("start_x")
.setCheck("Number")
.appendField(new Blockly.FieldVariable("oled"), "oled_hand")
.appendField("に線を描く:始点 (");
this.appendValueInput("start_y")
.setCheck("Number")
.appendField(",");
this.appendValueInput("end_x")
.setCheck("Number")
.appendField(") 終点 (");
this.appendValueInput("end_y")
.setCheck("Number")
.appendField(",");
this.appendDummyInput()
.appendField(") 色")
.appendField(new Blockly.FieldDropdown([["白", "1"], ["黒", "0"]]), "color");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setStyle('sensor_blocks');
this.setTooltip("OLED に線を描きます。");
this.setHelpUrl("");
}
};
javascript.javascriptGenerator.forBlock['oc_oled_drawline'] = function (block, generator) {
var variable_oled_hand = generator.nameDB_.getName(block.getFieldValue('oled_hand'), Blockly.Names.NameType.VARIABLE);
var value_start_x = generator.valueToCode(block, 'start_x', javascript.Order.ATOMIC);
var value_start_y = generator.valueToCode(block, 'start_y', javascript.Order.ATOMIC);
var value_end_x = generator.valueToCode(block, 'end_x', javascript.Order.ATOMIC);
var value_end_y = generator.valueToCode(block, 'end_y', javascript.Order.ATOMIC);
var dropdown_color = block.getFieldValue('color');
var code = `${variable_oled_hand}.drawLine(${value_start_x}, ${value_start_y}, ${value_end_x}, ${value_end_y}, ${dropdown_color});`;
return code;
};
/** 矩形塗りつぶし */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_oled_fillrect",
"message0": "%1 に四角形を描画して塗りつぶす:左上座標 ( %2 , %3 ) 幅 %4 高さ %5 色 %6",
"args0": [
{
"type": "field_variable",
"name": "oled_hand",
"variable": "oled"
},
{
"type": "input_value",
"name": "left",
"check": "Number"
},
{
"type": "input_value",
"name": "top",
"check": "Number"
},
{
"type": "input_value",
"name": "width",
"check": "Number"
},
{
"type": "input_value",
"name": "height",
"check": "Number"
},
{
"type": "field_dropdown",
"name": "color",
"options": [
[
"白",
"1"
],
[
"黒",
"0"
]
]
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"tooltip": "OLED に四角形を描画して塗りつぶします。",
"helpUrl": "",
"style": "sensor_blocks"
}]);
javascript.javascriptGenerator.forBlock['oc_oled_fillrect'] = function (block, generator) {
var variable_oled_hand = generator.nameDB_.getName(block.getFieldValue('oled_hand'), Blockly.Names.NameType.VARIABLE);
var value_left = generator.valueToCode(block, 'left', javascript.Order.ATOMIC);
var value_top = generator.valueToCode(block, 'top', javascript.Order.ATOMIC);
var value_width = generator.valueToCode(block, 'width', javascript.Order.ATOMIC);
var value_height = generator.valueToCode(block, 'height', javascript.Order.ATOMIC);
var dropdown_color = block.getFieldValue('color');
var code = `${variable_oled_hand}.fillRect(${value_left}, ${value_top}, ${value_width}, ${value_height}, ${dropdown_color});\n`;
return code;
};
/** 文字を描画node-canvas */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_oled_canvastext",
"message0": "%1 にテキストを表示 %2 フォント %3 %4 色 %5 %6 始点 x座標 %7 y座標 %8",
"args0": [
{
"type": "field_variable",
"name": "oled_hand",
"variable": "oled"
},
{
"type": "input_value",
"name": "text",
"check": "String"
},
{
"type": "field_dropdown",
"name": "font",
"options": [
[
"美咲ゴシック(8x8)",
"8px MisakiGothic"
],
[
"PixelMplus(10x10)",
"10px PixelMplus10"
],
[
"PixelMplus(12x12)",
"12px PixelMplus12"
]
]
},
{
"type": "input_dummy",
"align": "RIGHT"
},
{
"type": "field_dropdown",
"name": "color",
"options": [
[
"白",
"white"
],
[
"黒",
"black"
]
]
},
{
"type": "input_dummy",
"align": "RIGHT"
},
{
"type": "input_value",
"name": "start_x",
"check": "Number",
"align": "RIGHT"
},
{
"type": "input_value",
"name": "start_y",
"check": "Number",
"align": "RIGHT"
}
],
"inputsInline": false,
"previousStatement": null,
"nextStatement": null,
"style": "sensor_blocks",
"tooltip": "OLEDに指定のフォントで文字を描画しますnode-canvas利用。始点は1文字目の左下の座標です。",
"helpUrl": ""
}]);
javascript.javascriptGenerator.forBlock['oc_oled_canvastext'] = function (block, generator) {
var variable_oled_hand = generator.nameDB_.getName(block.getFieldValue('oled_hand'), Blockly.Names.NameType.VARIABLE);
var value_text = generator.valueToCode(block, 'text', javascript.Order.ATOMIC);
var value_start_x = generator.valueToCode(block, 'start_x', javascript.Order.ATOMIC);
var value_start_y = generator.valueToCode(block, 'start_y', javascript.Order.ATOMIC);
var dropdown_font = block.getFieldValue('font');
var dropdown_color = block.getFieldValue('color');
var code = `${variable_oled_hand}.drawRGBAImage(await apptool.textToRGBA(${value_text}, '${dropdown_font}', '${dropdown_color}', ${value_start_x}, ${value_start_y}), 0, 0);`;
return code;
};
Blockly.defineBlocksWithJsonArray([{
"type": "oc_oled_writestring",
"message0": "%1 に英数字を表示 %2 フォント %3 %4 色 %5 %6 始点 x座標 %7 y座標 %8",
"args0": [
{
"type": "field_variable",
"name": "oled_hand",
"variable": "oled"
},
{
"type": "input_value",
"name": "text",
"check": "String"
},
{
"type": "field_dropdown",
"name": "font",
"options": [
["oled_3x5", "oled_3x5"],
["tiny_4x6", "tiny_4x6"],
["oled_5x7", "oled_5x7"],
["small_6x8", "small_6x8"],
["sinclair_8x8", "sinclair_8x8"],
["sinclair_inverted_8x8", "sinclair_inverted_8x8"],
["tiny_8x8", "tiny_8x8"],
["cp437_8x8", "cp437_8x8"],
["myke2_8x9", "myke2_8x9"],
["small_8x12", "small_8x12"],
["tron_8x12", "tron_8x12"],
["retro_8x16", "retro_8x16"],
["medium_numbers_12x16", "medium_numbers_12x16"],
["big_numbers_14x24", "big_numbers_14x24"],
["arial_bold_16x16", "arial_bold_16x16"],
["arial_italic_16x16", "arial_italic_16x16"],
["arial_normal_16x16", "arial_normal_16x16"],
["big_16x16", "big_16x16"],
["franklin_gothic_normal_16x16", "franklin_gothic_normal_16x16"],
["hallfetica_normal_16x16", "hallfetica_normal_16x16"],
["nadianne_16x16", "nadianne_16x16"],
["sinclair_medium_16x16", "sinclair_medium_16x16"],
["sinclair_medium_inverted_16x16", "sinclair_medium_inverted_16x16"],
["swiss_721_outline_16x16", "swiss_721_outline_16x16"],
["various_symbols_16x16", "various_symbols_16x16"],
["dot_matrix_medium_16x22", "dot_matrix_medium_16x22"],
["dot_matrix_medium_zero_slash_16x22", "dot_matrix_medium_zero_slash_16x22"],
["dot_matrix_medium_numbers_only_16x22", "dot_matrix_medium_numbers_only_16x22"],
["arial_round_16x24", "arial_round_16x24"],
["ocr_a_extended_medium_16x24", "ocr_a_extended_medium_16x24"],
["sixteen_segment_16x24", "sixteen_segment_16x24"],
["grotesk_16x32", "grotesk_16x32"],
["grotesk_bold_16x32", "grotesk_bold_16x32"],
["retro_16x32", "retro_16x32"],
["various_symbols_16x32", "various_symbols_16x32"],
["various_symbols_v2_16x32", "various_symbols_v2_16x32"],
["dot_matrix_large_numbers_only_24x29", "dot_matrix_large_numbers_only_24x29"],
["inconsola_24x32", "inconsola_24x32"],
["ubuntu_24x32", "ubuntu_24x32"],
["ubuntu_bold_24x32", "ubuntu_bold_24x32"],
["dingbats1_extra_large_32x24", "dingbats1_extra_large_32x24"],
["various_symbols_32x32", "various_symbols_32x32"]
]
},
{
"type": "input_dummy",
"align": "RIGHT"
},
{
"type": "field_dropdown",
"name": "color",
"options": [
[
"白",
"1"
],
[
"黒",
"0"
]
]
},
{
"type": "input_dummy",
"align": "RIGHT"
},
{
"type": "input_value",
"name": "start_x",
"check": "Number",
"align": "RIGHT"
},
{
"type": "input_value",
"name": "start_y",
"check": "Number",
"align": "RIGHT"
}
],
"inputsInline": false,
"previousStatement": null,
"nextStatement": null,
"tooltip": "OLEDに指定の英字(数字)フォントで文字を描画します。始点は1文字目の左上の座標です。",
"helpUrl": "",
"style": "sensor_blocks"
}]);
javascript.javascriptGenerator.forBlock['oc_oled_writestring'] = function (block, generator) {
var variable_oled_hand = generator.nameDB_.getName(block.getFieldValue('oled_hand'), Blockly.Names.NameType.VARIABLE);
var value_text = generator.valueToCode(block, 'text', javascript.Order.ATOMIC);
var dropdown_font = block.getFieldValue('font');
var dropdown_color = block.getFieldValue('color');
var value_start_x = generator.valueToCode(block, 'start_x', javascript.Order.ATOMIC);
var value_start_y = generator.valueToCode(block, 'start_y', javascript.Order.ATOMIC);
Blockly.JavaScript.provideFunction_(
'require_fontpack', [`const _fontpack = require('oled-font-pack');`]
);
var code = `${variable_oled_hand}.setCursor(${value_start_x}, ${value_start_y});
${variable_oled_hand}.writeString(_fontpack.${dropdown_font}, 1, ${value_text}, ${dropdown_color}, false);
`;
return code;
};
/** 点を描画 */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_oled_drawpixel",
"message0": "%1 に点を描画:座標 ( %2 , %3 ) 色 %4",
"args0": [
{
"type": "field_variable",
"name": "oled_hand",
"variable": "oled"
},
{
"type": "input_value",
"name": "x",
"check": "Number"
},
{
"type": "input_value",
"name": "y",
"check": "Number"
},
{
"type": "field_dropdown",
"name": "color",
"options": [
[
"白",
"1"
],
[
"黒",
"0"
]
]
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"tooltip": "OLED に点を描きます。",
"helpUrl": "",
"style": "sensor_blocks"
}]);
javascript.javascriptGenerator.forBlock['oc_oled_drawpixel'] = function (block, generator) {
var variable_oled_hand = generator.nameDB_.getName(block.getFieldValue('oled_hand'), Blockly.Names.NameType.VARIABLE);
var value_x = generator.valueToCode(block, 'x', javascript.Order.ATOMIC);
var value_y = generator.valueToCode(block, 'y', javascript.Order.ATOMIC);
var dropdown_color = block.getFieldValue('color');
var code = `${variable_oled_hand}.drawPixel([[${value_x}, ${value_y}, ${dropdown_color}]]);\n`;
return code;
};
/** PNG 画像をファイルから読み込んで描画 */
Blockly.defineBlocksWithJsonArray([{
"type": "oc_oled_readpngfile",
"message0": "%1 に PNG ファイル %2 を表示:始点 ( %3 , %4 )",
"args0": [
{
"type": "field_variable",
"name": "oled_hand",
"variable": "oled"
},
{
"type": "input_value",
"name": "fname",
"check": "String"
},
{
"type": "input_value",
"name": "x",
"check": "Number"
},
{
"type": "input_value",
"name": "y",
"check": "Number"
}
],
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"style": "sensor_blocks",
"tooltip": "PNG ファイルを読み込んで OLED に表示します。「始点」は左上の座標です。",
"helpUrl": ""
}]);
javascript.javascriptGenerator.forBlock['oc_oled_readpngfile'] = function (block, generator) {
var variable_oled_hand = generator.nameDB_.getName(block.getFieldValue('oled_hand'), Blockly.Names.NameType.VARIABLE);
var value_fname = generator.valueToCode(block, 'fname', javascript.Order.ATOMIC);
var value_x = generator.valueToCode(block, 'x', javascript.Order.ATOMIC);
var value_y = generator.valueToCode(block, 'y', javascript.Order.ATOMIC);
var code = `${variable_oled_hand}.drawRGBAImage(await apptool.readPngFile(${value_fname}),${value_x},${value_y});\n`;
return code;
};
/********* */
/** Flyout */
/********* */
flyout_contents = flyout_contents.concat([
{
"kind": "label",
"text": "有機ELディスプレイ(SSD1306)",
"web-line": "4.0",
"web-line-width": "200"
},
{
"kind": "block",
"type": "oc_oled_init",
"fields": {
"type": "field_variable",
"name": "i2c_device",
"variable": "oled"
},
"fields": {
"i2c_addr": "0x3c",
"disp_size": "128x64"
}
},
{
"kind": "block",
"type": "oc_oled_drawpixel",
"fields": {
"type": "field_variable",
"name": "oled_hand",
"variable": "oled"
},
"inputs": {
"x": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": "0"
}
}
},
"y": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": "0"
}
}
},
},
"fields": {
"color": "1",
}
},
{
"kind": "block",
"type": "oc_oled_drawline",
"fields": {
"type": "field_variable",
"name": "oled_hand",
"variable": "oled"
},
"inputs": {
"start_x": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": "0"
}
}
},
"start_y": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": "0"
}
}
},
"end_x": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": "128"
}
}
},
"end_y": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": "64"
}
}
},
},
"fields": {
"color": "1",
}
},
{
"kind": "block",
"type": "oc_oled_fillrect",
"fields": {
"type": "field_variable",
"name": "oled_hand",
"variable": "oled"
},
"inputs": {
"left": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": "24"
}
}
},
"top": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": "12"
}
}
},
"width": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": "80"
}
}
},
"height": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": "40"
}
}
},
},
"fields": {
"color": "1",
}
},
{
"kind": "block",
"type": "oc_oled_canvastext",
"fields": {
"type": "field_variable",
"name": "oled_hand",
"variable": "oled"
},
"inputs": {
"text": {
"shadow": {
"type": "text",
"fields": {
"TEXT": "我輩は猫である。"
}
}
},
"start_x": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": "0"
}
}
},
"start_y": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": "0"
}
}
},
},
"fields": {
"font": '8px MisakiGothic',
"color": "white"
}
},
{
"kind": "block",
"type": "oc_oled_writestring",
"fields": {
"type": "field_variable",
"name": "oled_hand",
"variable": "oled"
},
"inputs": {
"text": {
"shadow": {
"type": "text",
"fields": {
"TEXT": "I am a cat."
}
}
},
"start_x": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": "0"
}
}
},
"start_y": {
"shadow": {
"type": "math_number",
"fields": {
"NUM": "0"
}
}
},
},
"fields": {
"font": 'oled_5x7',
"color": "1"
}
},
{
"inputs": {
"type": "field_variable",
"name": "oled_hand",
"variable": "oled"
},
"inputs": {
"fname": {
"shadow": {
"fields": {
"TEXT": "/home/pi/1.png"
},
"type": "text"
}
},
"x": {
"shadow": {
"fields": {
"NUM": "0"
},
"type": "math_number"
}
},
"y": {
"shadow": {
"fields": {
"NUM": "0"
},
"type": "math_number"
}
}
},
"kind": "block",
"type": "oc_oled_readpngfile"
}
// {
// "inputs": {
// "type": "field_variable",
// "name": "oled_hand",
// "variable": "oled"
// },
// "inputs": {
// "fname": {
// "shadow": {
// "fields": {
// "TEXT": null
// },
// "type": "text"
// }
// }
// },
// "kind": "block",
// "type": "oc_oled_readpngfile"
// }
]);