mirror of
https://github.com/ocogeclub/ocoge.git
synced 2024-11-24 00:19:48 +00:00
[update] センサーモジュールを内部的に分離、他
This commit is contained in:
parent
559cf7eafa
commit
0571402c5e
55
blocks/sensors/amg8833/AMG8833x.js
Normal file
55
blocks/sensors/amg8833/AMG8833x.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const err_msg = 'AMG8833 is already opened. Please close old connection to use new one.';
|
||||||
|
const pig = require('@ocogeclub/pigpio');
|
||||||
|
|
||||||
|
let pi = -1;
|
||||||
|
let i2c_hand = -1;
|
||||||
|
exports.init = async (i2c_bus, i2c_addr, win = null) => {
|
||||||
|
if (win !== null) {
|
||||||
|
win.addEventListener('beforeunload', async () => {
|
||||||
|
await exports.stop();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (pi >= 0) { throw new Error(err_msg); return; }
|
||||||
|
pi = await pig._pigpio_start('', '');
|
||||||
|
console.log('pi=' + pi);
|
||||||
|
if (i2c_hand >= 0) { throw new Error(err_msg); return; }
|
||||||
|
i2c_hand = await pig._i2c_open(pi, i2c_bus, i2c_addr);
|
||||||
|
console.log('i2c_hand=' + i2c_hand);
|
||||||
|
await pig._i2c_write_byte_data(pi, i2c_hand, 0x00, 0x00); //Normal mode
|
||||||
|
await pig._i2c_write_byte_data(pi, i2c_hand, 0x02, 0x00); //10FPS
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.read_thermistor = async () => {
|
||||||
|
let temp = await pig._i2c_read_word_data(pi, i2c_hand, 0x0e);
|
||||||
|
return temp * 0.0625;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.read_temp_array = async () => {
|
||||||
|
let linedata = [];
|
||||||
|
for (let i = 0; i < 8; i++) {
|
||||||
|
let data = await pig._i2c_read_i2c_block_data(pi, i2c_hand, 0x80 + 0x10 * i, 16);
|
||||||
|
let oneline = [];
|
||||||
|
for (let j = 0; j < 8; j++) {
|
||||||
|
oneline.push(((data[2 * j + 1] & 0x07) * 256 + data[2 * j]) * 0.25);
|
||||||
|
}
|
||||||
|
linedata.push(oneline);
|
||||||
|
}
|
||||||
|
return linedata;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.stop = async () => {
|
||||||
|
if (i2c_hand >= 0) {
|
||||||
|
await pig._i2c_close(pi, i2c_hand);
|
||||||
|
i2c_hand = -1;
|
||||||
|
}
|
||||||
|
if (pi >= 0) {
|
||||||
|
await pig._pigpio_stop(pi);
|
||||||
|
pi = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code was ported from https://www.denshi.club/pc/raspi/5raspberry-pi-zeroiot381i2c-amg8833.html
|
||||||
|
*/
|
425
blocks/sensors/amg8833/index.js
Normal file
425
blocks/sensors/amg8833/index.js
Normal file
@ -0,0 +1,425 @@
|
|||||||
|
Blockly.Msg["UGJ_DRAW_GRIDEYEDATA_TITLE"] = "赤外線アレイセンサ画像表示 %1 温度データ %2 温度範囲上限 %3 %4 温度範囲下限 %5 %6";
|
||||||
|
Blockly.Msg["UGJ_DRAW_GRIDEYEDATA_TOOLTIP"] = "AMG8833の温度データを、画像としてキャンバスに描画します。「着色」をチェックすると、温度範囲で設定されている色をつけて表示します。";
|
||||||
|
|
||||||
|
Blockly.Msg["UGJ_GRIDEYE_INIT_TITLE"] = "赤外線アレイセンサ(アドレス: %1 )を初期化";
|
||||||
|
Blockly.Msg["UGJ_GRIDEYE_INIT_TOOLTIP"] = "赤外線アレイセンサ AMG8833 の使用準備をします。";
|
||||||
|
Blockly.Msg["UGJ_GRIDEYE_THERMISTOR_TITLE"] = "赤外線アレイセンサ本体温度";
|
||||||
|
Blockly.Msg["UGJ_GRIDEYE_THERMISTOR_TOOLTIP"] = "AMG8833に内蔵されたサーミスタ(温度センサ)の値を取得します。";
|
||||||
|
Blockly.Msg["UGJ_GRIDEYE_READ_TITLE"] = "赤外線アレイセンサの値";
|
||||||
|
Blockly.Msg["UGJ_GRIDEYE_READ_TOOLTIP"] = "AMG8833から読み取った温度データを、8x8の配列で取得します。";
|
||||||
|
Blockly.Msg["UGJ_GRIDEYE_STOP_TITLE"] = "赤外線アレイセンサから切断";
|
||||||
|
Blockly.Msg["UGJ_GRIDEYE_STOP_TOOLTIP"] = "センサーとの接続を停止します。";
|
||||||
|
Blockly.Msg["UGJ_GRIDEYE_CANVAS_CREATE_TITLE"] = "赤外線アレイセンサデータ表示キャンバスを作成";
|
||||||
|
Blockly.Msg["UGJ_GRIDEYE_CANVAS_CREATE_TOOLTIP"] = "ディスプレイエリアにAMG8833データ表示用キャンバスを作成します。";
|
||||||
|
Blockly.Msg["UGJ_TEACHABLE_MACHINE_TITLE"] = "TensorFlow.jsによる画像分類器の準備";
|
||||||
|
Blockly.Msg["UGJ_TEACHABLE_MACHINE_TOOLTIP"] = "TensorFlow.jsにMobileNet, KNN Classifierを読み込んで、画像認識(分類)を行う準備をします。";
|
||||||
|
Blockly.Msg["UGJ_GRIDEYE_PREDICT_CLASS_TITLE"] = "赤外線アレイセンサの画像で推論を行う";
|
||||||
|
Blockly.Msg["UGJ_GRIDEYE_PREDICT_CLASS_TOOLTIP"] = "キャンバスに表示されたAMG8833の画像を元に画像分類の推論を行います。推論の結果として定義済みのラベルを返します。";
|
||||||
|
Blockly.Msg["UGJ_GRIDEYE_ADD_EXAMPLE_TITLE"] = "赤外線アレイセンサの画像にラベル %1 をつけてデータセットへ追加";
|
||||||
|
Blockly.Msg["UGJ_GRIDEYE_ADD_EXAMPLE_TOOLTIP"] = "キャンバスに表示されているAMG8833の画像にラベル(クラス名)をつけてデータセットへ追加します。";
|
||||||
|
Blockly.Msg["UGJ_TENSORSET_STRINGIFY_TITLE"] = "学習したクラスデータセットを文字列に変換";
|
||||||
|
Blockly.Msg["UGJ_TENSORSET_STRINGIFY_TOOLTIP"] = "学習したクラスデータセットを文字列に変換して保存します。";
|
||||||
|
Blockly.Msg["UGJ_TENSORSET_PARSE_TITLE"] = "クラスデータ文字列 %1 を画像分類器にセット";
|
||||||
|
Blockly.Msg["UGJ_TENSORSET_PARSE_TOOLTIP"] = "JSONテキストをパースして画像分類器に戻します。";
|
||||||
|
|
||||||
|
/******************* */
|
||||||
|
/** Init Grid-Eye ** */
|
||||||
|
/******************* */
|
||||||
|
var ugjGridEyeInitDefinition = {
|
||||||
|
"type": "ugj_grideye_init",
|
||||||
|
"message0": "%{BKY_UGJ_GRIDEYE_INIT_TITLE}",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "field_dropdown",
|
||||||
|
"name": "addr",
|
||||||
|
"options": [
|
||||||
|
[
|
||||||
|
"0x68",
|
||||||
|
"0x68"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"0x69",
|
||||||
|
"0x69"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputsInline": true,
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"tooltip": "%{BKY_UGJ_GRIDEYE_INIT_TOOLTIP}",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "sensor_blocks"
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_grideye_init'] = {
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit(ugjGridEyeInitDefinition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_grideye_init'] = function (block) {
|
||||||
|
var dropdown_addr = block.getFieldValue('addr');
|
||||||
|
Blockly.JavaScript.provideFunction_(
|
||||||
|
'require_gpio', [`const _pi = require('@ocogeclub/` + elutil.gpio_backend + `');`]
|
||||||
|
);
|
||||||
|
let modpath = elutil.path.join(elutil.blocks_sensors_dir, 'amg8833', 'AMG8833x.js');
|
||||||
|
Blockly.JavaScript.provideFunction_(
|
||||||
|
'require_amg8833', [`const _amg8833 = require('${modpath}');`]
|
||||||
|
);
|
||||||
|
var code = `await _amg8833.init(${elutil.i2c_bus}, ${dropdown_addr}, window);\n`;
|
||||||
|
return code;//
|
||||||
|
};
|
||||||
|
/********************** */
|
||||||
|
/** Grid-Eye 本体温度 ** */
|
||||||
|
/********************** */
|
||||||
|
var ugjGridEyeThermistorDefinition = {
|
||||||
|
"type": "ugj_grideye_thermistor",
|
||||||
|
"message0": "%{BKY_UGJ_GRIDEYE_THERMISTOR_TITLE}",
|
||||||
|
"output": "Number",
|
||||||
|
"tooltip": "%{BKY_UGJ_GRIDEYE_THERMISTOR_TOOLTIP}",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "sensor_blocks"
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_grideye_thermistor'] = {
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit(ugjGridEyeThermistorDefinition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_grideye_thermistor'] = function (block) {
|
||||||
|
var code = `await _amg8833.read_thermistor()`;
|
||||||
|
return [code, Blockly.JavaScript.ORDER_NONE];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**************************** */
|
||||||
|
/** Read Temperature Array ** */
|
||||||
|
/**************************** */
|
||||||
|
var ugjGridEyeReadDefinition = {
|
||||||
|
"type": "ugj_grideye_read",
|
||||||
|
"message0": "%{BKY_UGJ_GRIDEYE_READ_TITLE}",
|
||||||
|
"inputsInline": true,
|
||||||
|
"output": "Array",
|
||||||
|
"tooltip": "%{BKY_UGJ_GRIDEYE_READ_TOOLTIP}",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "sensor_blocks"
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_grideye_read'] = {
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit(ugjGridEyeReadDefinition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_grideye_read'] = function (block) {
|
||||||
|
var code = 'await _amg8833.read_temp_array()';
|
||||||
|
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||||||
|
};
|
||||||
|
/******************* */
|
||||||
|
/** Stop Grid-Eye ** */
|
||||||
|
/******************* */
|
||||||
|
var ugjGridEyeStopDefinition = {
|
||||||
|
"type": "ugj_grideye_stop",
|
||||||
|
"message0": "%{BKY_UGJ_GRIDEYE_STOP_TITLE}",
|
||||||
|
"inputsInline": true,
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"tooltip": "%{BKY_UGJ_GRIDEYE_STOP_TOOLTIP}",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "sensor_blocks"
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_grideye_stop'] = {
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit(ugjGridEyeStopDefinition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_grideye_stop'] = function (block) {
|
||||||
|
var code = 'await _amg8833.stop();\n';
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/***************************** */
|
||||||
|
/** GridEye 表示キャンバス作成 ** */
|
||||||
|
/***************************** */
|
||||||
|
var ugjGridEyeCanvasCreateDefinition = {
|
||||||
|
"type": "ugj_grideye_canvas_create",
|
||||||
|
"message0": "%{BKY_UGJ_GRIDEYE_CANVAS_CREATE_TITLE}",
|
||||||
|
"inputsInline": true,
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"tooltip": "%{BKY_UGJ_GRIDEYE_CANVAS_CREATE_TOOLTIP}",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "multimedia_blocks"
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_grideye_canvas_create'] = {
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit(ugjGridEyeCanvasCreateDefinition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_grideye_canvas_create'] = function (block) {
|
||||||
|
var code = `let _grideye_canvas = document.createElement('canvas');
|
||||||
|
_grideye_canvas.setAttribute('width', 8);
|
||||||
|
_grideye_canvas.setAttribute('height', 8);
|
||||||
|
_grideye_canvas.className = 'subdisplay';
|
||||||
|
_grideye_canvas.style.width = '160px';
|
||||||
|
_grideye_canvas.style.height = '160px';
|
||||||
|
_grideye_canvas.id = 'subcanvas';
|
||||||
|
document.getElementById('display_area').appendChild(_grideye_canvas);
|
||||||
|
_grideye_ctx = _grideye_canvas.getContext('2d');
|
||||||
|
_grideye_imgData = _grideye_ctx.createImageData(8, 8);
|
||||||
|
`;
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
/********************************************** */
|
||||||
|
/** Draw IR Array Data to Image Data ** */
|
||||||
|
/********************************************** */
|
||||||
|
var ugjDrawGrideyedataDefinition = {
|
||||||
|
"type": "ugj_draw_grideyedata",
|
||||||
|
"message0": "%{BKY_UGJ_DRAW_GRIDEYEDATA_TITLE}",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_dummy"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "amg8833data",
|
||||||
|
"check": "Array",
|
||||||
|
"align": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "field_colour",
|
||||||
|
"name": "color_high",
|
||||||
|
"colour": "#ff0000"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "temp_high",
|
||||||
|
"check": "Number",
|
||||||
|
"align": "RIGHT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "field_colour",
|
||||||
|
"name": "color_low",
|
||||||
|
"colour": "#3333ff"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "temp_low",
|
||||||
|
"check": "Number",
|
||||||
|
"align": "RIGHT"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputsInline": false,
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"tooltip": "%{BKY_UGJ_DRAW_GRIDEYEDATA_TOOLTIP}",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "multimedia_blocks"
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_draw_grideyedata'] = {
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit(ugjDrawGrideyedataDefinition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_draw_grideyedata'] = function (block) {
|
||||||
|
var value_amg8833data = Blockly.JavaScript.valueToCode(block, 'amg8833data', Blockly.JavaScript.ORDER_ATOMIC);
|
||||||
|
var colour_color_high = block.getFieldValue('color_high');
|
||||||
|
var value_temp_high = Blockly.JavaScript.valueToCode(block, 'temp_high', Blockly.JavaScript.ORDER_ATOMIC);
|
||||||
|
var colour_color_low = block.getFieldValue('color_low');
|
||||||
|
var value_temp_low = Blockly.JavaScript.valueToCode(block, 'temp_low', Blockly.JavaScript.ORDER_ATOMIC);
|
||||||
|
var functionName = Blockly.JavaScript.provideFunction_(
|
||||||
|
'_mapVal',
|
||||||
|
['const ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = (val, inMin, inMax, outMin, outMax) => {',
|
||||||
|
`return (val - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;`,
|
||||||
|
'}'
|
||||||
|
]
|
||||||
|
);
|
||||||
|
// 温度カラー
|
||||||
|
let hr, hg, hb, lr, lg, lb;
|
||||||
|
hr = '0x' + colour_color_high.slice(1, 3);
|
||||||
|
hg = '0x' + colour_color_high.slice(3, 5);
|
||||||
|
hb = '0x' + colour_color_high.slice(5, 7);
|
||||||
|
lr = '0x' + colour_color_low.slice(1, 3);
|
||||||
|
lg = '0x' + colour_color_low.slice(3, 5);
|
||||||
|
lb = '0x' + colour_color_low.slice(5, 7);
|
||||||
|
var code = ` const _color_range = [[${lr}, ${hr}], [${lg}, ${hg}], [${lb}, ${hb}]];
|
||||||
|
let _grideye_data = ${value_amg8833data};//読み取りブロックを入力に直接接続できるようにする
|
||||||
|
for (let raw = 0; raw < _grideye_canvas.height; raw++) {
|
||||||
|
for (let col = 0; col < _grideye_canvas.width; col++) {
|
||||||
|
for (let rgb = 0; rgb < 3; rgb++) {
|
||||||
|
let pixel = ${functionName}(_grideye_data[raw][col], ${value_temp_low}, ${value_temp_high}, _color_range[rgb][0], _color_range[rgb][1]);
|
||||||
|
_grideye_imgData.data[((raw * _grideye_canvas.width * 4) + col * 4) + rgb] = pixel;
|
||||||
|
}
|
||||||
|
_grideye_imgData.data[((raw * _grideye_canvas.width * 4) + col * 4) + 3] = 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_grideye_ctx.putImageData(_grideye_imgData, 0, 0);
|
||||||
|
|
||||||
|
`;
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**************************** */
|
||||||
|
/** Teachable Machine を開始** */
|
||||||
|
/**************************** */
|
||||||
|
var ugjTeachableMachineDefinition = {
|
||||||
|
"type": "ugj_teachable_machine",
|
||||||
|
"message0": "%{BKY_UGJ_TEACHABLE_MACHINE_TITLE}",
|
||||||
|
"inputsInline": true,
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"tooltip": "%{BKY_UGJ_TEACHABLE_MACHINE_TOOLTIP}",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "multimedia_blocks"
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_teachable_machine'] = {
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit(ugjTeachableMachineDefinition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_teachable_machine'] = function (block) {
|
||||||
|
Blockly.JavaScript.provideFunction_(
|
||||||
|
'require_ts', [`const _tf = require('@tensorflow/tfjs');`]
|
||||||
|
// 'require_ts', [`const _tf = require('@tensorflow/tfjs-node');`]
|
||||||
|
);
|
||||||
|
Blockly.JavaScript.provideFunction_(
|
||||||
|
'require_wasm', [`const _wasm = require('@tensorflow/tfjs-backend-wasm');`]
|
||||||
|
);
|
||||||
|
Blockly.JavaScript.provideFunction_(
|
||||||
|
'require_mobilenet', [`const _mobilenet = require('@tensorflow-models/mobilenet');`]
|
||||||
|
);
|
||||||
|
Blockly.JavaScript.provideFunction_(
|
||||||
|
'require_knn', [`const _knnClassifier = require('@tensorflow-models/knn-classifier');`]
|
||||||
|
);
|
||||||
|
|
||||||
|
var code = `await _tf.setBackend('wasm');
|
||||||
|
const _net = await _mobilenet.load({ version: 1, alpha: 0.25 }); // 高速・低精度
|
||||||
|
const _classifier = _knnClassifier.create();
|
||||||
|
`;
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
/************************* */
|
||||||
|
/** GridEye で推論を行う ** */
|
||||||
|
/************************* */
|
||||||
|
var ugjGridEyePredictClassDefinition = {
|
||||||
|
"type": "ugj_grideye_predict_class",
|
||||||
|
"message0": "%{BKY_UGJ_GRIDEYE_PREDICT_CLASS_TITLE}",
|
||||||
|
"inputsInline": true,
|
||||||
|
"output": "Number",
|
||||||
|
"tooltip": "%{BKY_UGJ_GRIDEYE_PREDICT_CLASS_TOOLTIP}",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "multimedia_blocks"
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_grideye_predict_class'] = {
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit(ugjGridEyePredictClassDefinition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_grideye_predict_class'] = function (block) {
|
||||||
|
var functionName = Blockly.JavaScript.provideFunction_( // left output にするための関数化
|
||||||
|
'_predictClass',
|
||||||
|
[
|
||||||
|
`if (_confidence === undefined) var _confidence;`,
|
||||||
|
`const ${Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_} = async (img, clsfr, mblnet) => {`,
|
||||||
|
`if (clsfr.getNumClasses() > 0) {`,
|
||||||
|
`const result = await clsfr.predictClass(mblnet.infer(img, 'conv_preds'));`,
|
||||||
|
`_confidence = result.confidences[result.label];`,
|
||||||
|
`return result.label;`,
|
||||||
|
`}`,
|
||||||
|
`else return 0;`,
|
||||||
|
`}`
|
||||||
|
]
|
||||||
|
);
|
||||||
|
var code = `await ${functionName}(_grideye_canvas, _classifier, _net)`;
|
||||||
|
return [code, Blockly.JavaScript.ORDER_NONE];
|
||||||
|
};
|
||||||
|
/******************************************** */
|
||||||
|
/** ラベルをつけて Example をデータセットに追加 ** */
|
||||||
|
/******************************************** */
|
||||||
|
var ugjGridEyeAddExampleDefinition = {
|
||||||
|
"type": "ugj_grideye_add_example",
|
||||||
|
"message0": "%{BKY_UGJ_GRIDEYE_ADD_EXAMPLE_TITLE}",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "class_id",
|
||||||
|
"check": "Number"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputsInline": true,
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"tooltip": "%{BKY_UGJ_GRIDEYE_ADD_EXAMPLE_TOOLTIP}",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "multimedia_blocks"
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_grideye_add_example'] = {
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit(ugjGridEyeAddExampleDefinition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_grideye_add_example'] = function (block) {
|
||||||
|
var value_class_id = Blockly.JavaScript.valueToCode(block, 'class_id', Blockly.JavaScript.ORDER_ATOMIC);
|
||||||
|
var code = `_classifier.addExample (_net.infer(_grideye_canvas, true), ${value_class_id});`;
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
/*************************** */
|
||||||
|
/** 学習したクラスを文字列化 ** */
|
||||||
|
/*************************** */
|
||||||
|
var ugjTensorsetStringifyDefinition = {
|
||||||
|
"type": "ugj_tensorset_stringify",
|
||||||
|
"message0": "%{BKY_UGJ_TENSORSET_STRINGIFY_TITLE}",
|
||||||
|
"output": null,
|
||||||
|
"tooltip": "%{BKY_UGJ_TENSORSET_STRINGIFY_TOOLTIP}",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "multimedia_blocks"
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_tensorset_stringify'] = {
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit(ugjTensorsetStringifyDefinition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_tensorset_stringify'] = function (block) {
|
||||||
|
Blockly.JavaScript.provideFunction_(
|
||||||
|
'require_tensorset', [`const _Tensorset = require('tensorset');`]
|
||||||
|
);
|
||||||
|
var code = `await _Tensorset.stringify(_classifier.getClassifierDataset())`;
|
||||||
|
return [code, Blockly.JavaScript.ORDER_NONE];
|
||||||
|
};
|
||||||
|
/***************************************** */
|
||||||
|
/** jsonをデータセットに戻して分類器にセット ** */
|
||||||
|
/***************************************** */
|
||||||
|
var ugjTensorsetParseDefinition = {
|
||||||
|
"type": "ugj_tensorset_parse",
|
||||||
|
"message0": "%{BKY_UGJ_TENSORSET_PARSE_TITLE}",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "class_data_json",
|
||||||
|
"check": "String"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"tooltip": "%{BKY_UGJ_TENSORSET_PARSE_TOOLTIP}",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "multimedia_blocks"
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_tensorset_parse'] = {
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit(ugjTensorsetParseDefinition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_tensorset_parse'] = function (block) {
|
||||||
|
Blockly.JavaScript.provideFunction_(
|
||||||
|
'require_tensorset', [`const _Tensorset = require('tensorset');`]
|
||||||
|
);
|
||||||
|
var value_class_data_json = Blockly.JavaScript.valueToCode(block, 'class_data_json', Blockly.JavaScript.ORDER_ATOMIC);
|
||||||
|
var code = `try {
|
||||||
|
let _class_dataset = _Tensorset.parse(${value_class_data_json});
|
||||||
|
_classifier.setClassifierDataset(_class_dataset);
|
||||||
|
} catch (error) {
|
||||||
|
alert('Could not load class dataset.');
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
87
blocks/sensors/amg8833/index.json
Normal file
87
blocks/sensors/amg8833/index.json
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"kind": "label",
|
||||||
|
"text": "赤外線アレイセンサー(サーマルカメラ)AMG8833",
|
||||||
|
"web-line": "4.0",
|
||||||
|
"web-line-width": "200"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_grideye_init",
|
||||||
|
"fields": {
|
||||||
|
"addr": "0x69"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_grideye_thermistor"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_grideye_read"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_grideye_stop"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_grideye_canvas_create"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_draw_grideyedata",
|
||||||
|
"fields": {
|
||||||
|
"color_high": "#ff0000",
|
||||||
|
"color_low": "#3333ff"
|
||||||
|
},
|
||||||
|
"inputs": {
|
||||||
|
"temp_high": {
|
||||||
|
"shadow": {
|
||||||
|
"type": "math_number",
|
||||||
|
"fields": {
|
||||||
|
"NUM": "28"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"temp_low": {
|
||||||
|
"shadow": {
|
||||||
|
"type": "math_number",
|
||||||
|
"fields": {
|
||||||
|
"NUM": "15"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_teachable_machine"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_grideye_predict_class"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_grideye_add_example",
|
||||||
|
"inputs": {
|
||||||
|
"class_id": {
|
||||||
|
"shadow": {
|
||||||
|
"type": "math_number",
|
||||||
|
"fields": {
|
||||||
|
"NUM": "0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_tensorset_stringify"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_tensorset_parse"
|
||||||
|
}
|
||||||
|
]
|
270
blocks/sensors/bme280/BME280x.js
Normal file
270
blocks/sensors/bme280/BME280x.js
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
this.pig = null;
|
||||||
|
this.pi = null;
|
||||||
|
|
||||||
|
this.i2cBusNo = null;
|
||||||
|
this.i2cAddress = null;
|
||||||
|
this.i2cHand = null;
|
||||||
|
|
||||||
|
this.I2C_ADDRESS_B = 0x76;
|
||||||
|
this.I2C_ADDRESS_A = 0x77;
|
||||||
|
this.CHIP_ID = 0x58;
|
||||||
|
|
||||||
|
this.REGISTER_DIG_T1 = 0x88;
|
||||||
|
this.REGISTER_DIG_T2 = 0x8A;
|
||||||
|
this.REGISTER_DIG_T3 = 0x8C;
|
||||||
|
|
||||||
|
this.REGISTER_DIG_P1 = 0x8E;
|
||||||
|
this.REGISTER_DIG_P2 = 0x90;
|
||||||
|
this.REGISTER_DIG_P3 = 0x92;
|
||||||
|
this.REGISTER_DIG_P4 = 0x94;
|
||||||
|
this.REGISTER_DIG_P5 = 0x96;
|
||||||
|
this.REGISTER_DIG_P6 = 0x98;
|
||||||
|
this.REGISTER_DIG_P7 = 0x9A;
|
||||||
|
this.REGISTER_DIG_P8 = 0x9C;
|
||||||
|
this.REGISTER_DIG_P9 = 0x9E;
|
||||||
|
|
||||||
|
this.REGISTER_DIG_H1 = 0xA1;
|
||||||
|
this.REGISTER_DIG_H2 = 0xE1;
|
||||||
|
this.REGISTER_DIG_H3 = 0xE3;
|
||||||
|
this.REGISTER_DIG_H4 = 0xE4;
|
||||||
|
this.REGISTER_DIG_H5 = 0xE5;
|
||||||
|
this.REGISTER_DIG_H6 = 0xE7;
|
||||||
|
|
||||||
|
this.REGISTER_CHIPID = 0xD0;
|
||||||
|
this.REGISTER_RESET = 0xE0;
|
||||||
|
|
||||||
|
this.REGISTER_CONTROL_HUM = 0xF2;
|
||||||
|
this.REGISTER_CONTROL = 0xF4;
|
||||||
|
this.REGISTER_PRESSURE_DATA = 0xF7;
|
||||||
|
this.REGISTER_TEMP_DATA = 0xFA;
|
||||||
|
this.REGISTER_HUMIDITY_DATA = 0xFD;
|
||||||
|
|
||||||
|
exports.init = async (options) => {
|
||||||
|
this.pig = require('@ocogeclub/pigpio');
|
||||||
|
this.pi = await this.pig._pigpio_start('', '');
|
||||||
|
|
||||||
|
this.i2cBusNo = (options && options.hasOwnProperty('i2cBusNo')) ? options.i2cBusNo : 1;
|
||||||
|
this.i2cAddress = (options && options.hasOwnProperty('i2cAddress')) ? options.i2cAddress : this.BME280_DEFAULT_I2C_ADDRESS();
|
||||||
|
this.i2cHand = await this.pig._i2c_open(this.pi, this.i2cBusNo, this.i2cAddress);
|
||||||
|
|
||||||
|
let r;
|
||||||
|
r = await this.pig._i2c_write_byte_data(this.pi, this.i2cHand, this.REGISTER_CHIPID, 0);
|
||||||
|
if (r < 0) return r;
|
||||||
|
let chipId = await this.pig._i2c_read_byte_data(this.pi, this.i2cHand, this.REGISTER_CHIPID);
|
||||||
|
if (chipId !== this.CHIP_ID_BME280() &&
|
||||||
|
chipId !== this.CHIP_ID1_BMP280() &&
|
||||||
|
chipId !== this.CHIP_ID2_BMP280() &&
|
||||||
|
chipId !== this.CHIP_ID3_BMP280()) {
|
||||||
|
return `Unexpected BMx280 chip ID: 0x${chipId.toString(16).toUpperCase()}`;
|
||||||
|
}
|
||||||
|
// console.log(`Found BMx280 chip ID 0x${chipId.toString(16).toUpperCase()} on bus i2c-${this.i2cBusNo}, address 0x${this.i2cAddress.toString(16).toUpperCase()}`);
|
||||||
|
await this.loadCalibration(async (err) => {
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
// Humidity 16x oversampling
|
||||||
|
//
|
||||||
|
let r = await this.pig._i2c_write_byte_data(this.pi, this.i2cHand, this.REGISTER_CONTROL_HUM, 0b00000101);
|
||||||
|
if (r < 0) return `Humidity 16x oversampling error: ${r}`;
|
||||||
|
// Temperture/pressure 16x oversampling, normal mode
|
||||||
|
//
|
||||||
|
r = await this.pig._i2c_write_byte_data(this.pi, this.i2cHand, this.REGISTER_CONTROL, 0b10110111);
|
||||||
|
if (r < 0) return `Temperture/pressure 16x oversampling error: ${r}`;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset()
|
||||||
|
//
|
||||||
|
// Perform a power-on reset procedure. You will need to call init() following a reset()
|
||||||
|
//
|
||||||
|
exports.reset = async () => {
|
||||||
|
const POWER_ON_RESET_CMD = 0xB6;
|
||||||
|
let r = await this.pig._i2c_write_byte_data(this.pi, this.i2cHand, this.REGISTER_RESET, POWER_ON_RESET_CMD);
|
||||||
|
if (r < 0) return `cannot power-on reset: ${r}`;
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cancel()
|
||||||
|
//
|
||||||
|
// Cancels the sensor and releases resources.
|
||||||
|
//
|
||||||
|
exports.cancel = async () => {
|
||||||
|
if (this.i2cHand >= 0) {
|
||||||
|
await this.pig._i2c_close(this.pi, this.i2cHand);
|
||||||
|
this.i2cHand = null;
|
||||||
|
await this.pig._pigpio_stop(this.pi);
|
||||||
|
this.pi = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.readSensorData = async () => {
|
||||||
|
if (!this.cal) {
|
||||||
|
return 'You must first call bme280.init()';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Grab temperature, humidity, and pressure in a single read
|
||||||
|
//
|
||||||
|
let buffer = await this.pig._i2c_read_i2c_block_data(this.pi, this.i2cHand, this.REGISTER_PRESSURE_DATA, 8);
|
||||||
|
if (!buffer) return `couldn't grab data`;
|
||||||
|
// Temperature (temperature first since we need t_fine for pressure and humidity)
|
||||||
|
//
|
||||||
|
let adc_T = this.uint20(buffer[3], buffer[4], buffer[5]);
|
||||||
|
let tvar1 = ((((adc_T >> 3) - (this.cal.dig_T1 << 1))) * this.cal.dig_T2) >> 11;
|
||||||
|
let tvar2 = (((((adc_T >> 4) - this.cal.dig_T1) * ((adc_T >> 4) - this.cal.dig_T1)) >> 12) * this.cal.dig_T3) >> 14;
|
||||||
|
let t_fine = tvar1 + tvar2;
|
||||||
|
|
||||||
|
let temperature_C = ((t_fine * 5 + 128) >> 8) / 100;
|
||||||
|
|
||||||
|
// Pressure
|
||||||
|
//
|
||||||
|
let adc_P = this.uint20(buffer[0], buffer[1], buffer[2]);
|
||||||
|
let pvar1 = t_fine / 2 - 64000;
|
||||||
|
let pvar2 = pvar1 * pvar1 * this.cal.dig_P6 / 32768;
|
||||||
|
pvar2 = pvar2 + pvar1 * this.cal.dig_P5 * 2;
|
||||||
|
pvar2 = pvar2 / 4 + this.cal.dig_P4 * 65536;
|
||||||
|
pvar1 = (this.cal.dig_P3 * pvar1 * pvar1 / 524288 + this.cal.dig_P2 * pvar1) / 524288;
|
||||||
|
pvar1 = (1 + pvar1 / 32768) * this.cal.dig_P1;
|
||||||
|
|
||||||
|
let pressure_hPa = 0;
|
||||||
|
|
||||||
|
if (pvar1 !== 0) {
|
||||||
|
let p = 1048576 - adc_P;
|
||||||
|
p = ((p - pvar2 / 4096) * 6250) / pvar1;
|
||||||
|
pvar1 = this.cal.dig_P9 * p * p / 2147483648;
|
||||||
|
pvar2 = p * this.cal.dig_P8 / 32768;
|
||||||
|
p = p + (pvar1 + pvar2 + this.cal.dig_P7) / 16;
|
||||||
|
|
||||||
|
pressure_hPa = p / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Humidity (available on the BME280, will be zero on the BMP280 since it has no humidity sensor)
|
||||||
|
//
|
||||||
|
let adc_H = this.uint16(buffer[6], buffer[7]);
|
||||||
|
|
||||||
|
let h = t_fine - 76800;
|
||||||
|
h = (adc_H - (this.cal.dig_H4 * 64 + this.cal.dig_H5 / 16384 * h)) *
|
||||||
|
(this.cal.dig_H2 / 65536 * (1 + this.cal.dig_H6 / 67108864 * h * (1 + this.cal.dig_H3 / 67108864 * h)));
|
||||||
|
h = h * (1 - this.cal.dig_H1 * h / 524288);
|
||||||
|
|
||||||
|
let humidity = (h > 100) ? 100 : (h < 0 ? 0 : h);
|
||||||
|
|
||||||
|
return {
|
||||||
|
temperature_C: temperature_C,
|
||||||
|
humidity: humidity,
|
||||||
|
pressure_hPa: pressure_hPa
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.loadCalibration = async (callback) => {
|
||||||
|
let buffer = await this.pig._i2c_read_i2c_block_data(this.pi, this.i2cHand, this.REGISTER_DIG_T1, 24);
|
||||||
|
if (buffer) {
|
||||||
|
let h1 = await this.pig._i2c_read_byte_data(this.pi, this.i2cHand, this.REGISTER_DIG_H1);
|
||||||
|
let h2 = await this.pig._i2c_read_word_data(this.pi, this.i2cHand, this.REGISTER_DIG_H2);
|
||||||
|
let h3 = await this.pig._i2c_read_byte_data(this.pi, this.i2cHand, this.REGISTER_DIG_H3);
|
||||||
|
let h4 = await this.pig._i2c_read_byte_data(this.pi, this.i2cHand, this.REGISTER_DIG_H4);
|
||||||
|
let h5 = await this.pig._i2c_read_byte_data(this.pi, this.i2cHand, this.REGISTER_DIG_H5);
|
||||||
|
let h5_1 = await this.pig._i2c_read_byte_data(this.pi, this.i2cHand, this.REGISTER_DIG_H5 + 1);
|
||||||
|
let h6 = await this.pig._i2c_read_byte_data(this.pi, this.i2cHand, this.REGISTER_DIG_H6);
|
||||||
|
|
||||||
|
this.cal = {
|
||||||
|
dig_T1: this.uint16(buffer[1], buffer[0]),
|
||||||
|
dig_T2: this.int16(buffer[3], buffer[2]),
|
||||||
|
dig_T3: this.int16(buffer[5], buffer[4]),
|
||||||
|
|
||||||
|
dig_P1: this.uint16(buffer[7], buffer[6]),
|
||||||
|
dig_P2: this.int16(buffer[9], buffer[8]),
|
||||||
|
dig_P3: this.int16(buffer[11], buffer[10]),
|
||||||
|
dig_P4: this.int16(buffer[13], buffer[12]),
|
||||||
|
dig_P5: this.int16(buffer[15], buffer[14]),
|
||||||
|
dig_P6: this.int16(buffer[17], buffer[16]),
|
||||||
|
dig_P7: this.int16(buffer[19], buffer[18]),
|
||||||
|
dig_P8: this.int16(buffer[21], buffer[20]),
|
||||||
|
dig_P9: this.int16(buffer[23], buffer[22]),
|
||||||
|
|
||||||
|
dig_H1: h1,
|
||||||
|
dig_H2: h2,
|
||||||
|
dig_H3: h3,
|
||||||
|
dig_H4: (h4 << 4) | (h5 & 0xF),
|
||||||
|
dig_H5: (h5_1 << 4) | (h5 >> 4),
|
||||||
|
dig_H6: h6
|
||||||
|
};
|
||||||
|
|
||||||
|
// console.log('BME280 cal = ' + JSON.stringify(this.cal, null, 2));
|
||||||
|
await callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.BME280_DEFAULT_I2C_ADDRESS = () => {
|
||||||
|
return 0x77;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.CHIP_ID1_BMP280 = () => {
|
||||||
|
return 0x56;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.CHIP_ID2_BMP280 = () => {
|
||||||
|
return 0x57;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.CHIP_ID3_BMP280 = () => {
|
||||||
|
return 0x58;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.CHIP_ID_BME280 = () => {
|
||||||
|
return 0x60;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.int16 = (msb, lsb) => {
|
||||||
|
let val = this.uint16(msb, lsb);
|
||||||
|
return val > 32767 ? (val - 65536) : val;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.uint16 = (msb, lsb) => {
|
||||||
|
return msb << 8 | lsb;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.uint20 = (msb, lsb, xlsb) => {
|
||||||
|
return ((msb << 8 | lsb) << 8 | xlsb) >> 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.convertCelciusToFahrenheit = (c) => {
|
||||||
|
return c * 9 / 5 + 32;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.convertHectopascalToInchesOfMercury = (hPa) => {
|
||||||
|
return hPa * 0.02952998751;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.convertMetersToFeet = (m) => {
|
||||||
|
return m * 3.28084;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.calculateHeatIndexCelcius = (temperature_C, humidity) => {
|
||||||
|
return -8.784695 + 1.61139411 * temperature_C + 2.33854900 * humidity +
|
||||||
|
-0.14611605 * temperature_C * humidity + -0.01230809 * Math.pow(temperature_C, 2) +
|
||||||
|
-0.01642482 * Math.pow(humidity, 2) + 0.00221173 * Math.pow(temperature_C, 2) * humidity +
|
||||||
|
0.00072546 * temperature_C * Math.pow(humidity, 2) +
|
||||||
|
-0.00000358 * Math.pow(temperature_C, 2) * Math.pow(humidity, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.calculateDewPointCelcius = (temperature_C, humidity) => {
|
||||||
|
return 243.04 * (Math.log(humidity / 100.0) + ((17.625 * temperature_C) / (243.04 + temperature_C))) /
|
||||||
|
(17.625 - Math.log(humidity / 100.0) - ((17.625 * temperature_C) / (243.04 + temperature_C)));
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.calculateAltitudeMeters = (pressure_hPa, seaLevelPressure_hPa) => {
|
||||||
|
if (!seaLevelPressure_hPa) {
|
||||||
|
seaLevelPressure_hPa = 1013.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (1.0 - Math.pow(pressure_hPa / seaLevelPressure_hPa, (1 / 5.2553))) * 145366.45 * 0.3048;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code was forked from skylarstein's bme280-sensor: https://github.com/skylarstein/bme280-sensor
|
||||||
|
*/
|
56
blocks/sensors/bme280/index.js
Normal file
56
blocks/sensors/bme280/index.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/********* */
|
||||||
|
/** BME280 */
|
||||||
|
/********* */
|
||||||
|
Blockly.Blocks['ugj_bme280'] = {
|
||||||
|
init: function () {
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField("BME280(アドレス")
|
||||||
|
.appendField(new Blockly.FieldDropdown([["0x76", "0x76"], ["0x77", "0x77"]]), "addr")
|
||||||
|
.appendField(")の計測値を取得");
|
||||||
|
this.setInputsInline(true);
|
||||||
|
this.setPreviousStatement(true, null);
|
||||||
|
this.setNextStatement(true, null);
|
||||||
|
this.setStyle('sensor_blocks');
|
||||||
|
this.setTooltip("環境センサーBME280で、気温(摂氏)、湿度(%)、気圧(hPa)を計測します。計測結果は計測値ブロックで参照します。");
|
||||||
|
this.setHelpUrl("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_bme280'] = function (block) {
|
||||||
|
var dropdown_addr = block.getFieldValue('addr');
|
||||||
|
Blockly.JavaScript.provideFunction_(
|
||||||
|
'require_gpio', [`const _pi = require('@ocogeclub/` + elutil.gpio_backend + `');`]
|
||||||
|
);
|
||||||
|
let modpath = elutil.path.join(elutil.blocks_sensors_dir, 'bme280', 'BME280x.js');
|
||||||
|
Blockly.JavaScript.provideFunction_(
|
||||||
|
'require_bme280', [`const _bme280 = require('${modpath}');`]
|
||||||
|
);
|
||||||
|
var code = `const options = {
|
||||||
|
i2cBusNo: ${elutil.i2c_bus},
|
||||||
|
i2cAddress: ${dropdown_addr}
|
||||||
|
};
|
||||||
|
await _bme280.init(options);
|
||||||
|
let _thp = await _bme280.readSensorData();
|
||||||
|
let _bmedata = [];
|
||||||
|
_bmedata[0] = Math.round(_thp.temperature_C * 10) / 10;
|
||||||
|
_bmedata[1] = Math.round(_thp.humidity * 10) / 10;
|
||||||
|
_bmedata[2] = Math.round(_thp.pressure_hPa);
|
||||||
|
await _bme280.cancel();
|
||||||
|
`;
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_bme280_data'] = {
|
||||||
|
init: function () {
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField(new Blockly.FieldDropdown([["気温", "0"], ["湿度", "1"], ["気圧", "2"]]), "thp");
|
||||||
|
this.setInputsInline(true);
|
||||||
|
this.setOutput(true, null);
|
||||||
|
this.setStyle('sensor_blocks');
|
||||||
|
this.setTooltip("BME280 の計測値を返します。");
|
||||||
|
this.setHelpUrl("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_bme280_data'] = function (block) {
|
||||||
|
var dropdown_thp = block.getFieldValue('thp');
|
||||||
|
var code = `_bmedata[${dropdown_thp}]`;
|
||||||
|
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||||||
|
};
|
22
blocks/sensors/bme280/index.json
Normal file
22
blocks/sensors/bme280/index.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"kind": "label",
|
||||||
|
"text": "温湿度気圧センサー BME280",
|
||||||
|
"web-line": "4.0",
|
||||||
|
"web-line-width": "200"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_bme280",
|
||||||
|
"fields": {
|
||||||
|
"addr": "0x76"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_bme280_data",
|
||||||
|
"fields": {
|
||||||
|
"thp": "0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
171
blocks/sensors/dht11/dht11.py
Normal file
171
blocks/sensors/dht11/dht11.py
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||||
|
|
||||||
|
import time
|
||||||
|
import pigpio
|
||||||
|
|
||||||
|
|
||||||
|
class DHT11(object):
|
||||||
|
"""
|
||||||
|
The DHT11 class is a stripped version of the DHT22 sensor code by joan2937.
|
||||||
|
You can find the initial implementation here:
|
||||||
|
- https://github.com/srounet/pigpio/tree/master/EXAMPLES/Python/DHT22_AM2302_SENSOR
|
||||||
|
|
||||||
|
example code:
|
||||||
|
>>> pi = pigpio.pi()
|
||||||
|
>>> sensor = DHT11(pi, 4) # 4 is the data GPIO pin connected to your sensor
|
||||||
|
>>> for response in sensor:
|
||||||
|
.... print("Temperature: {}".format(response['temperature']))
|
||||||
|
.... print("Humidity: {}".format(response['humidity']))
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, pi, gpio):
|
||||||
|
"""
|
||||||
|
pi (pigpio): an instance of pigpio
|
||||||
|
gpio (int): gpio pin number
|
||||||
|
"""
|
||||||
|
self.pi = pi
|
||||||
|
self.gpio = gpio
|
||||||
|
self.high_tick = 0
|
||||||
|
self.bit = 40
|
||||||
|
self.temperature = 0
|
||||||
|
self.humidity = 0
|
||||||
|
self.either_edge_cb = None
|
||||||
|
self.setup()
|
||||||
|
|
||||||
|
def setup(self):
|
||||||
|
"""
|
||||||
|
Clears the internal gpio pull-up/down resistor.
|
||||||
|
Kills any watchdogs.
|
||||||
|
"""
|
||||||
|
self.pi.set_pull_up_down(self.gpio, pigpio.PUD_OFF)
|
||||||
|
self.pi.set_watchdog(self.gpio, 0)
|
||||||
|
self.register_callbacks()
|
||||||
|
|
||||||
|
def register_callbacks(self):
|
||||||
|
"""
|
||||||
|
Monitors RISING_EDGE changes using callback.
|
||||||
|
"""
|
||||||
|
self.either_edge_cb = self.pi.callback(
|
||||||
|
self.gpio, pigpio.EITHER_EDGE, self.either_edge_callback
|
||||||
|
)
|
||||||
|
|
||||||
|
def either_edge_callback(self, gpio, level, tick):
|
||||||
|
"""
|
||||||
|
Either Edge callbacks, called each time the gpio edge changes.
|
||||||
|
Accumulate the 40 data bits from the dht11 sensor.
|
||||||
|
"""
|
||||||
|
level_handlers = {
|
||||||
|
pigpio.FALLING_EDGE: self._edge_FALL,
|
||||||
|
pigpio.RISING_EDGE: self._edge_RISE,
|
||||||
|
pigpio.EITHER_EDGE: self._edge_EITHER,
|
||||||
|
}
|
||||||
|
handler = level_handlers[level]
|
||||||
|
diff = pigpio.tickDiff(self.high_tick, tick)
|
||||||
|
handler(tick, diff)
|
||||||
|
|
||||||
|
def _edge_RISE(self, tick, diff):
|
||||||
|
"""
|
||||||
|
Handle Rise signal.
|
||||||
|
"""
|
||||||
|
val = 0
|
||||||
|
if diff >= 50:
|
||||||
|
val = 1
|
||||||
|
if diff >= 200: # Bad bit?
|
||||||
|
self.checksum = 256 # Force bad checksum
|
||||||
|
|
||||||
|
if self.bit >= 40: # Message complete
|
||||||
|
self.bit = 40
|
||||||
|
elif self.bit >= 32: # In checksum byte
|
||||||
|
self.checksum = (self.checksum << 1) + val
|
||||||
|
if self.bit == 39:
|
||||||
|
# 40th bit received
|
||||||
|
self.pi.set_watchdog(self.gpio, 0)
|
||||||
|
total = self.humidity + self.temperature
|
||||||
|
# is checksum ok ?
|
||||||
|
if not (total & 255) == self.checksum:
|
||||||
|
raise
|
||||||
|
elif 16 <= self.bit < 24: # in temperature byte
|
||||||
|
self.temperature = (self.temperature << 1) + val
|
||||||
|
elif 0 <= self.bit < 8: # in humidity byte
|
||||||
|
self.humidity = (self.humidity << 1) + val
|
||||||
|
else: # skip header bits
|
||||||
|
pass
|
||||||
|
self.bit += 1
|
||||||
|
|
||||||
|
def _edge_FALL(self, tick, diff):
|
||||||
|
"""
|
||||||
|
Handle Fall signal.
|
||||||
|
"""
|
||||||
|
self.high_tick = tick
|
||||||
|
if diff <= 250000:
|
||||||
|
return
|
||||||
|
self.bit = -2
|
||||||
|
self.checksum = 0
|
||||||
|
self.temperature = 0
|
||||||
|
self.humidity = 0
|
||||||
|
|
||||||
|
def _edge_EITHER(self, tick, diff):
|
||||||
|
"""
|
||||||
|
Handle Either signal.
|
||||||
|
"""
|
||||||
|
self.pi.set_watchdog(self.gpio, 0)
|
||||||
|
|
||||||
|
def read(self):
|
||||||
|
"""
|
||||||
|
Start reading over DHT11 sensor.
|
||||||
|
"""
|
||||||
|
self.pi.write(self.gpio, pigpio.LOW)
|
||||||
|
time.sleep(0.017) # 17 ms
|
||||||
|
self.pi.set_mode(self.gpio, pigpio.INPUT)
|
||||||
|
self.pi.set_watchdog(self.gpio, 200)
|
||||||
|
time.sleep(0.2)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
"""
|
||||||
|
Stop reading sensor, remove callbacks.
|
||||||
|
"""
|
||||||
|
self.pi.set_watchdog(self.gpio, 0)
|
||||||
|
if self.either_edge_cb:
|
||||||
|
self.either_edge_cb.cancel()
|
||||||
|
self.either_edge_cb = None
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
"""
|
||||||
|
Support the iterator protocol.
|
||||||
|
"""
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __next__(self):
|
||||||
|
"""
|
||||||
|
Call the read method and return temperature and humidity informations.
|
||||||
|
"""
|
||||||
|
self.read()
|
||||||
|
response = {"humidity": self.humidity, "temperature": self.temperature}
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
|
||||||
|
args = sys.argv
|
||||||
|
pin = int(args[1])
|
||||||
|
pi = pigpio.pi()
|
||||||
|
sensor = DHT11(pi, pin)
|
||||||
|
for d in sensor:
|
||||||
|
# print("temperature: {}".format(d["temperature"]))
|
||||||
|
# print("humidity: {}".format(d["humidity"]))
|
||||||
|
|
||||||
|
print(
|
||||||
|
'{"temperature":'
|
||||||
|
+ str(d["temperature"])
|
||||||
|
+ ',"humidity":'
|
||||||
|
+ str(d["humidity"])
|
||||||
|
+ "}",
|
||||||
|
flush=True,
|
||||||
|
)
|
||||||
|
break
|
||||||
|
# time.sleep(1)
|
||||||
|
sensor.close()
|
41
blocks/sensors/dht11/index.js
Normal file
41
blocks/sensors/dht11/index.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
Blockly.Blocks['ugj_dht11'] = {
|
||||||
|
init: function () {
|
||||||
|
this.appendValueInput("pin")
|
||||||
|
.setCheck("Number")
|
||||||
|
.appendField("GPIO");
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField("の DHT11 センサーの値を取得");
|
||||||
|
this.setInputsInline(true);
|
||||||
|
this.setPreviousStatement(true, null);
|
||||||
|
this.setNextStatement(true, null);
|
||||||
|
this.setTooltip("");
|
||||||
|
this.setHelpUrl("気温・湿度センサーDHT11で、気温(摂氏)、湿度(%)を計測します。計測値は計測値ブロックで参照します。");
|
||||||
|
this.setStyle('sensor_blocks');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_dht11'] = function (block) {
|
||||||
|
var value_pin = Blockly.JavaScript.valueToCode(block, 'pin', Blockly.JavaScript.ORDER_ATOMIC);
|
||||||
|
let pypath = elutil.path.join(elutil.blocks_sensors_dir, 'dht11', 'dht11.py');
|
||||||
|
var code = `let _th = require('child_process').spawnSync('python3', ['${pypath}', '${value_pin}']).stdout.toString();
|
||||||
|
let _dhtdata = JSON.parse(_th);`;
|
||||||
|
// let _dht11data[0] =
|
||||||
|
// console.log('t=' + obj.temperature);
|
||||||
|
// console.log('h=' + obj.humidity);
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_dht11_data'] = {
|
||||||
|
init: function () {
|
||||||
|
this.appendDummyInput()
|
||||||
|
.appendField(new Blockly.FieldDropdown([["気温", "temperature"], ["湿度", "humidity"]]), "th");
|
||||||
|
this.setInputsInline(true);
|
||||||
|
this.setOutput(true, null);
|
||||||
|
this.setStyle('sensor_blocks');
|
||||||
|
this.setTooltip("DHT11 の計測値を返します。");
|
||||||
|
this.setHelpUrl("");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_dht11_data'] = function (block) {
|
||||||
|
var dropdown_th = block.getFieldValue('th');
|
||||||
|
var code = `_dhtdata.${dropdown_th}`;
|
||||||
|
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||||||
|
};
|
29
blocks/sensors/dht11/index.json
Normal file
29
blocks/sensors/dht11/index.json
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"kind": "label",
|
||||||
|
"text": "温湿度センサー DHT11",
|
||||||
|
"web-line": "4.0",
|
||||||
|
"web-line-width": "200"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_dht11",
|
||||||
|
"inputs": {
|
||||||
|
"pin": {
|
||||||
|
"shadow": {
|
||||||
|
"type": "math_number",
|
||||||
|
"fields": {
|
||||||
|
"NUM": "8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_dht11_data",
|
||||||
|
"fields": {
|
||||||
|
"th": "temperature"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
471
blocks/sensors/paj7620/PAJ7620x.js
Normal file
471
blocks/sensors/paj7620/PAJ7620x.js
Normal file
@ -0,0 +1,471 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
const sleep = sec =>
|
||||||
|
new Promise(r => setTimeout(r, sec * 1000));
|
||||||
|
|
||||||
|
const GES_REACTION_TIME = .100; // default:0.5 // You can adjust the reaction time according to the actual circumstance.
|
||||||
|
const GES_ENTRY_TIME = .050; // default:0.8 // When you want to recognize the Forward/Backward gestures, your gestures' reaction time must less than GES_ENTRY_TIME(0.8s).
|
||||||
|
const GES_QUIT_TIME = 1.000;
|
||||||
|
|
||||||
|
const BANK0 = 0;
|
||||||
|
const BANK1 = 1;
|
||||||
|
|
||||||
|
const PAJ7620_ADDR_BASE = 0x00;
|
||||||
|
|
||||||
|
//REGISTER BANK SELECT
|
||||||
|
const PAJ7620_REGITER_BANK_SEL = (PAJ7620_ADDR_BASE + 0xEF); //W
|
||||||
|
|
||||||
|
//DEVICE ID
|
||||||
|
// const PAJ7620_ID = 0x73;
|
||||||
|
|
||||||
|
//REGISTER BANK 0
|
||||||
|
const PAJ7620_ADDR_SUSPEND_CMD = (PAJ7620_ADDR_BASE + 0x3); //W
|
||||||
|
const PAJ7620_ADDR_GES_PS_DET_MASK_0 = (PAJ7620_ADDR_BASE + 0x41); //RW
|
||||||
|
const PAJ7620_ADDR_GES_PS_DET_MASK_1 = (PAJ7620_ADDR_BASE + 0x42); //RW
|
||||||
|
const PAJ7620_ADDR_GES_PS_DET_FLAG_0 = (PAJ7620_ADDR_BASE + 0x43); //R
|
||||||
|
const PAJ7620_ADDR_GES_PS_DET_FLAG_1 = (PAJ7620_ADDR_BASE + 0x44); //R
|
||||||
|
const PAJ7620_ADDR_STATE_INDICATOR = (PAJ7620_ADDR_BASE + 0x45); //R
|
||||||
|
const PAJ7620_ADDR_PS_HIGH_THRESHOLD = (PAJ7620_ADDR_BASE + 0x69); //RW
|
||||||
|
const PAJ7620_ADDR_PS_LOW_THRESHOLD = (PAJ7620_ADDR_BASE + 0x6A); //RW
|
||||||
|
const PAJ7620_ADDR_PS_APPROACH_STATE = (PAJ7620_ADDR_BASE + 0x6B); //R
|
||||||
|
const PAJ7620_ADDR_PS_RAW_DATA = (PAJ7620_ADDR_BASE + 0x6C); //R
|
||||||
|
|
||||||
|
//REGISTER BANK 1
|
||||||
|
const PAJ7620_ADDR_PS_GAIN = (PAJ7620_ADDR_BASE + 0x44); //RW
|
||||||
|
const PAJ7620_ADDR_IDLE_S1_STEP_0 = (PAJ7620_ADDR_BASE + 0x67); //RW
|
||||||
|
const PAJ7620_ADDR_IDLE_S1_STEP_1 = (PAJ7620_ADDR_BASE + 0x68); //RW
|
||||||
|
const PAJ7620_ADDR_IDLE_S2_STEP_0 = (PAJ7620_ADDR_BASE + 0x69); //RW
|
||||||
|
const PAJ7620_ADDR_IDLE_S2_STEP_1 = (PAJ7620_ADDR_BASE + 0x6A); //RW
|
||||||
|
const PAJ7620_ADDR_OP_TO_S1_STEP_0 = (PAJ7620_ADDR_BASE + 0x6B); //RW
|
||||||
|
const PAJ7620_ADDR_OP_TO_S1_STEP_1 = (PAJ7620_ADDR_BASE + 0x6C); //RW
|
||||||
|
const PAJ7620_ADDR_OP_TO_S2_STEP_0 = (PAJ7620_ADDR_BASE + 0x6D); //RW
|
||||||
|
const PAJ7620_ADDR_OP_TO_S2_STEP_1 = (PAJ7620_ADDR_BASE + 0x6E); //RW
|
||||||
|
const PAJ7620_ADDR_OPERATION_ENABLE = (PAJ7620_ADDR_BASE + 0x72); //RW
|
||||||
|
|
||||||
|
//PAJ7620_REGITER_BANK_SEL
|
||||||
|
const PAJ7620_BANK0 = 0;
|
||||||
|
const PAJ7620_BANK1 = 1;
|
||||||
|
|
||||||
|
//PAJ7620_ADDR_SUSPEND_CMD
|
||||||
|
const PAJ7620_I2C_WAKEUP = 1;
|
||||||
|
const PAJ7620_I2C_SUSPEND = 0;
|
||||||
|
|
||||||
|
//PAJ7620_ADDR_OPERATION_ENABLE
|
||||||
|
const PAJ7620_ENABLE = 1;
|
||||||
|
const PAJ7620_DISABLE = 0;
|
||||||
|
|
||||||
|
//ADC, delete
|
||||||
|
const REG_ADDR_RESULT = 0x00;
|
||||||
|
const REG_ADDR_ALERT = 0x01;
|
||||||
|
const REG_ADDR_CONFIG = 0x02;
|
||||||
|
const REG_ADDR_LIMITL = 0x03;
|
||||||
|
const REG_ADDR_LIMITH = 0x04;
|
||||||
|
const REG_ADDR_HYST = 0x05;
|
||||||
|
const REG_ADDR_CONVL = 0x06;
|
||||||
|
const REG_ADDR_CONVH = 0x07;
|
||||||
|
|
||||||
|
const GES_RIGHT_FLAG = 1 << 0;
|
||||||
|
const GES_LEFT_FLAG = 1 << 1;
|
||||||
|
const GES_UP_FLAG = 1 << 2;
|
||||||
|
const GES_DOWN_FLAG = 1 << 3;
|
||||||
|
const GES_FORWARD_FLAG = 1 << 4;
|
||||||
|
const GES_BACKWARD_FLAG = 1 << 5;
|
||||||
|
const GES_CLOCKWISE_FLAG = 1 << 6;
|
||||||
|
const GES_COUNT_CLOCKWISE_FLAG = 1 << 7;
|
||||||
|
const GES_WAVE_FLAG = 1 << 0;
|
||||||
|
|
||||||
|
//Gesture output
|
||||||
|
exports.FORWARD = 1;
|
||||||
|
exports.BACKWARD = 2;
|
||||||
|
exports.RIGHT = 3;
|
||||||
|
exports.LEFT = 4;
|
||||||
|
exports.UP = 5;
|
||||||
|
exports.DOWN = 6;
|
||||||
|
exports.CLOCKWISE = 7;
|
||||||
|
exports.ANTI_CLOCKWISE = 8;
|
||||||
|
exports.WAVE = 9;
|
||||||
|
|
||||||
|
//Initial register state
|
||||||
|
const initRegisterArray = [
|
||||||
|
[0xEF, 0x00],
|
||||||
|
[0x32, 0x29],
|
||||||
|
[0x33, 0x01],
|
||||||
|
[0x34, 0x00],
|
||||||
|
[0x35, 0x01],
|
||||||
|
[0x36, 0x00],
|
||||||
|
[0x37, 0x07],
|
||||||
|
[0x38, 0x17],
|
||||||
|
[0x39, 0x06],
|
||||||
|
[0x3A, 0x12],
|
||||||
|
[0x3F, 0x00],
|
||||||
|
[0x40, 0x02],
|
||||||
|
[0x41, 0xFF],
|
||||||
|
[0x42, 0x01],
|
||||||
|
[0x46, 0x2D],
|
||||||
|
[0x47, 0x0F],
|
||||||
|
[0x48, 0x3C],
|
||||||
|
[0x49, 0x00],
|
||||||
|
[0x4A, 0x1E],
|
||||||
|
[0x4B, 0x00],
|
||||||
|
[0x4C, 0x20],
|
||||||
|
[0x4D, 0x00],
|
||||||
|
[0x4E, 0x1A],
|
||||||
|
[0x4F, 0x14],
|
||||||
|
[0x50, 0x00],
|
||||||
|
[0x51, 0x10],
|
||||||
|
[0x52, 0x00],
|
||||||
|
[0x5C, 0x02],
|
||||||
|
[0x5D, 0x00],
|
||||||
|
[0x5E, 0x10],
|
||||||
|
[0x5F, 0x3F],
|
||||||
|
[0x60, 0x27],
|
||||||
|
[0x61, 0x28],
|
||||||
|
[0x62, 0x00],
|
||||||
|
[0x63, 0x03],
|
||||||
|
[0x64, 0xF7],
|
||||||
|
[0x65, 0x03],
|
||||||
|
[0x66, 0xD9],
|
||||||
|
[0x67, 0x03],
|
||||||
|
[0x68, 0x01],
|
||||||
|
[0x69, 0xC8],
|
||||||
|
[0x6A, 0x40],
|
||||||
|
[0x6D, 0x04],
|
||||||
|
[0x6E, 0x00],
|
||||||
|
[0x6F, 0x00],
|
||||||
|
[0x70, 0x80],
|
||||||
|
[0x71, 0x00],
|
||||||
|
[0x72, 0x00],
|
||||||
|
[0x73, 0x00],
|
||||||
|
[0x74, 0xF0],
|
||||||
|
[0x75, 0x00],
|
||||||
|
[0x80, 0x42],
|
||||||
|
[0x81, 0x44],
|
||||||
|
[0x82, 0x04],
|
||||||
|
[0x83, 0x20],
|
||||||
|
[0x84, 0x20],
|
||||||
|
[0x85, 0x00],
|
||||||
|
[0x86, 0x10],
|
||||||
|
[0x87, 0x00],
|
||||||
|
[0x88, 0x05],
|
||||||
|
[0x89, 0x18],
|
||||||
|
[0x8A, 0x10],
|
||||||
|
[0x8B, 0x01],
|
||||||
|
[0x8C, 0x37],
|
||||||
|
[0x8D, 0x00],
|
||||||
|
[0x8E, 0xF0],
|
||||||
|
[0x8F, 0x81],
|
||||||
|
[0x90, 0x06],
|
||||||
|
[0x91, 0x06],
|
||||||
|
[0x92, 0x1E],
|
||||||
|
[0x93, 0x0D],
|
||||||
|
[0x94, 0x0A],
|
||||||
|
[0x95, 0x0A],
|
||||||
|
[0x96, 0x0C],
|
||||||
|
[0x97, 0x05],
|
||||||
|
[0x98, 0x0A],
|
||||||
|
[0x99, 0x41],
|
||||||
|
[0x9A, 0x14],
|
||||||
|
[0x9B, 0x0A],
|
||||||
|
[0x9C, 0x3F],
|
||||||
|
[0x9D, 0x33],
|
||||||
|
[0x9E, 0xAE],
|
||||||
|
[0x9F, 0xF9],
|
||||||
|
[0xA0, 0x48],
|
||||||
|
[0xA1, 0x13],
|
||||||
|
[0xA2, 0x10],
|
||||||
|
[0xA3, 0x08],
|
||||||
|
[0xA4, 0x30],
|
||||||
|
[0xA5, 0x19],
|
||||||
|
[0xA6, 0x10],
|
||||||
|
[0xA7, 0x08],
|
||||||
|
[0xA8, 0x24],
|
||||||
|
[0xA9, 0x04],
|
||||||
|
[0xAA, 0x1E],
|
||||||
|
[0xAB, 0x1E],
|
||||||
|
[0xCC, 0x19],
|
||||||
|
[0xCD, 0x0B],
|
||||||
|
[0xCE, 0x13],
|
||||||
|
[0xCF, 0x64],
|
||||||
|
[0xD0, 0x21],
|
||||||
|
[0xD1, 0x0F],
|
||||||
|
[0xD2, 0x88],
|
||||||
|
[0xE0, 0x01],
|
||||||
|
[0xE1, 0x04],
|
||||||
|
[0xE2, 0x41],
|
||||||
|
[0xE3, 0xD6],
|
||||||
|
[0xE4, 0x00],
|
||||||
|
[0xE5, 0x0C],
|
||||||
|
[0xE6, 0x0A],
|
||||||
|
[0xE7, 0x00],
|
||||||
|
[0xE8, 0x00],
|
||||||
|
[0xE9, 0x00],
|
||||||
|
[0xEE, 0x07],
|
||||||
|
[0xEF, 0x01],
|
||||||
|
[0x00, 0x1E],
|
||||||
|
[0x01, 0x1E],
|
||||||
|
[0x02, 0x0F],
|
||||||
|
[0x03, 0x10],
|
||||||
|
[0x04, 0x02],
|
||||||
|
[0x05, 0x00],
|
||||||
|
[0x06, 0xB0],
|
||||||
|
[0x07, 0x04],
|
||||||
|
[0x08, 0x0D],
|
||||||
|
[0x09, 0x0E],
|
||||||
|
[0x0A, 0x9C],
|
||||||
|
[0x0B, 0x04],
|
||||||
|
[0x0C, 0x05],
|
||||||
|
[0x0D, 0x0F],
|
||||||
|
[0x0E, 0x02],
|
||||||
|
[0x0F, 0x12],
|
||||||
|
[0x10, 0x02],
|
||||||
|
[0x11, 0x02],
|
||||||
|
[0x12, 0x00],
|
||||||
|
[0x13, 0x01],
|
||||||
|
[0x14, 0x05],
|
||||||
|
[0x15, 0x07],
|
||||||
|
[0x16, 0x05],
|
||||||
|
[0x17, 0x07],
|
||||||
|
[0x18, 0x01],
|
||||||
|
[0x19, 0x04],
|
||||||
|
[0x1A, 0x05],
|
||||||
|
[0x1B, 0x0C],
|
||||||
|
[0x1C, 0x2A],
|
||||||
|
[0x1D, 0x01],
|
||||||
|
[0x1E, 0x00],
|
||||||
|
[0x21, 0x00],
|
||||||
|
[0x22, 0x00],
|
||||||
|
[0x23, 0x00],
|
||||||
|
[0x25, 0x01],
|
||||||
|
[0x26, 0x00],
|
||||||
|
[0x27, 0x39],
|
||||||
|
[0x28, 0x7F],
|
||||||
|
[0x29, 0x08],
|
||||||
|
[0x30, 0x03],
|
||||||
|
[0x31, 0x00],
|
||||||
|
[0x32, 0x1A],
|
||||||
|
[0x33, 0x1A],
|
||||||
|
[0x34, 0x07],
|
||||||
|
[0x35, 0x07],
|
||||||
|
[0x36, 0x01],
|
||||||
|
[0x37, 0xFF],
|
||||||
|
[0x38, 0x36],
|
||||||
|
[0x39, 0x07],
|
||||||
|
[0x3A, 0x00],
|
||||||
|
[0x3E, 0xFF],
|
||||||
|
[0x3F, 0x00],
|
||||||
|
[0x40, 0x77],
|
||||||
|
[0x41, 0x40],
|
||||||
|
[0x42, 0x00],
|
||||||
|
[0x43, 0x30],
|
||||||
|
[0x44, 0xA0],
|
||||||
|
[0x45, 0x5C],
|
||||||
|
[0x46, 0x00],
|
||||||
|
[0x47, 0x00],
|
||||||
|
[0x48, 0x58],
|
||||||
|
[0x4A, 0x1E],
|
||||||
|
[0x4B, 0x1E],
|
||||||
|
[0x4C, 0x00],
|
||||||
|
[0x4D, 0x00],
|
||||||
|
[0x4E, 0xA0],
|
||||||
|
[0x4F, 0x80],
|
||||||
|
[0x50, 0x00],
|
||||||
|
[0x51, 0x00],
|
||||||
|
[0x52, 0x00],
|
||||||
|
[0x53, 0x00],
|
||||||
|
[0x54, 0x00],
|
||||||
|
[0x57, 0x80],
|
||||||
|
[0x59, 0x10],
|
||||||
|
[0x5A, 0x08],
|
||||||
|
[0x5B, 0x94],
|
||||||
|
[0x5C, 0xE8],
|
||||||
|
[0x5D, 0x08],
|
||||||
|
[0x5E, 0x3D],
|
||||||
|
[0x5F, 0x99],
|
||||||
|
[0x60, 0x45],
|
||||||
|
[0x61, 0x40],
|
||||||
|
[0x63, 0x2D],
|
||||||
|
[0x64, 0x02],
|
||||||
|
[0x65, 0x96],
|
||||||
|
[0x66, 0x00],
|
||||||
|
[0x67, 0x97],
|
||||||
|
[0x68, 0x01],
|
||||||
|
[0x69, 0xCD],
|
||||||
|
[0x6A, 0x01],
|
||||||
|
[0x6B, 0xB0],
|
||||||
|
[0x6C, 0x04],
|
||||||
|
[0x6D, 0x2C],
|
||||||
|
[0x6E, 0x01],
|
||||||
|
[0x6F, 0x32],
|
||||||
|
[0x71, 0x00],
|
||||||
|
[0x72, 0x01],
|
||||||
|
[0x73, 0x35],
|
||||||
|
[0x74, 0x00],
|
||||||
|
[0x75, 0x33],
|
||||||
|
[0x76, 0x31],
|
||||||
|
[0x77, 0x01],
|
||||||
|
[0x7C, 0x84],
|
||||||
|
[0x7D, 0x03],
|
||||||
|
[0x7E, 0x01]
|
||||||
|
];
|
||||||
|
|
||||||
|
//Enable debug message
|
||||||
|
const debug = 1;
|
||||||
|
|
||||||
|
const err_msg = 'AMG8833 is already opened. Please close old connection to use new one.';
|
||||||
|
let pig = -1;
|
||||||
|
let pi = -1;
|
||||||
|
let i2c_hand = -1;
|
||||||
|
//Initialize the sensors
|
||||||
|
exports.init = async (i2c_bus, i2c_addr, win = null) => {
|
||||||
|
if (win !== null) {
|
||||||
|
win.addEventListener('beforeunload', async () => {
|
||||||
|
await exports.stop();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
pig = require('@ocogeclub/pigpio');
|
||||||
|
if (pi >= 0) { throw new Error(err_msg); return; }
|
||||||
|
pi = await pig._pigpio_start('', '');
|
||||||
|
if (i2c_hand >= 0) { throw new Error(err_msg); return; }
|
||||||
|
i2c_hand = await pig._i2c_open(pi, i2c_bus, i2c_addr);
|
||||||
|
if (debug)
|
||||||
|
console.log("pi=" + pi + ", i2c_hand=" + i2c_hand);
|
||||||
|
|
||||||
|
await sleep(.001);
|
||||||
|
await paj7620SelectBank(BANK0);
|
||||||
|
await paj7620SelectBank(BANK0);
|
||||||
|
|
||||||
|
let data0 = (await paj7620ReadReg(0, 1))[0];
|
||||||
|
let data1 = (await paj7620ReadReg(1, 1))[0];
|
||||||
|
if (debug)
|
||||||
|
console.log("data0:" + data0 + ", data1:" + data1);
|
||||||
|
if (data0 != 0x20) //or data1 <> 0x76
|
||||||
|
console.log("Error with sensor");
|
||||||
|
//return 0xff
|
||||||
|
if (data0 == 0x20)
|
||||||
|
console.log("wake-up finish.");
|
||||||
|
|
||||||
|
for (let i = 0; i < initRegisterArray.length; i += 1)
|
||||||
|
await paj7620WriteReg(initRegisterArray[i][0], initRegisterArray[i][1]);
|
||||||
|
|
||||||
|
await paj7620SelectBank(BANK0);
|
||||||
|
|
||||||
|
console.log("Paj7620 initialize register finished.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write a byte to a register on the Gesture sensor
|
||||||
|
const paj7620WriteReg = async (addr, cmd) =>
|
||||||
|
await pig._i2c_write_word_data(pi, i2c_hand, addr, cmd);
|
||||||
|
|
||||||
|
//Select a register bank on the Gesture Sensor
|
||||||
|
const paj7620SelectBank = async bank => {
|
||||||
|
if (bank == BANK0)
|
||||||
|
await paj7620WriteReg(PAJ7620_REGITER_BANK_SEL, PAJ7620_BANK0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Read a block of bytes of length "qty" starting at address "addr" from the Gesture sensor
|
||||||
|
const paj7620ReadReg = async (addr, qty) => {
|
||||||
|
return await pig._i2c_read_i2c_block_data(pi, i2c_hand, addr, qty);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Return a vlaue from the gestire sensor which can be used in a program
|
||||||
|
// 0:nothing
|
||||||
|
// 1:Forward
|
||||||
|
// 2:Backward
|
||||||
|
// 3:Right
|
||||||
|
// 4:Left
|
||||||
|
// 5:Up
|
||||||
|
// 6:Down
|
||||||
|
// 7:Clockwise
|
||||||
|
// 8:anti-clockwise
|
||||||
|
// 9:wave
|
||||||
|
exports.return_gesture = async () => {
|
||||||
|
|
||||||
|
let data = (await paj7620ReadReg(0x43, 1))[0];
|
||||||
|
if (data == GES_RIGHT_FLAG) {
|
||||||
|
await sleep(GES_ENTRY_TIME);
|
||||||
|
data = (await paj7620ReadReg(0x43, 1))[0];
|
||||||
|
if (data == GES_FORWARD_FLAG) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (data == GES_BACKWARD_FLAG) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (data == GES_LEFT_FLAG) {
|
||||||
|
await sleep(GES_ENTRY_TIME);
|
||||||
|
data = (await paj7620ReadReg(0x43, 1))[0];
|
||||||
|
if (data == GES_FORWARD_FLAG) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (data == GES_BACKWARD_FLAG) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (data == GES_UP_FLAG) {
|
||||||
|
await sleep(GES_ENTRY_TIME);
|
||||||
|
data = (await paj7620ReadReg(0x43, 1))[0];
|
||||||
|
if (data == GES_FORWARD_FLAG) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (data == GES_BACKWARD_FLAG) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (data == GES_DOWN_FLAG) {
|
||||||
|
await sleep(GES_ENTRY_TIME);
|
||||||
|
data = (await paj7620ReadReg(0x43, 1))[0];
|
||||||
|
if (data == GES_FORWARD_FLAG) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else if (data == GES_BACKWARD_FLAG) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 6;
|
||||||
|
}
|
||||||
|
else if (data == GES_FORWARD_FLAG) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (data == GES_BACKWARD_FLAG) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (data == GES_CLOCKWISE_FLAG)
|
||||||
|
return 7;
|
||||||
|
|
||||||
|
else if (data == GES_COUNT_CLOCKWISE_FLAG)
|
||||||
|
return 8;
|
||||||
|
|
||||||
|
else {
|
||||||
|
let data1 = (await paj7620ReadReg(0x44, 1))[0];
|
||||||
|
if (data1 == GES_WAVE_FLAG)
|
||||||
|
return 9;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.stop = async () => {
|
||||||
|
if (i2c_hand >= 0) {
|
||||||
|
await pig._i2c_close(pi, i2c_hand);
|
||||||
|
i2c_hand = -1;
|
||||||
|
}
|
||||||
|
if (pi >= 0) {
|
||||||
|
await pig._pigpio_stop(pi);
|
||||||
|
pi = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code was ported from "Grove - Gesture Sensor v1.0 Python library and examples": https://github.com/DexterInd/GrovePi/tree/master/Software/Python/grove_gesture_sensor
|
||||||
|
*/
|
89
blocks/sensors/paj7620/index.js
Normal file
89
blocks/sensors/paj7620/index.js
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/********** */
|
||||||
|
/** PAJ7620 */
|
||||||
|
/********** */
|
||||||
|
Blockly.Msg["UGJ_GESTURE_INIT_TITLE"] = "ジェスチャーセンサー(アドレス: %1 )を初期化";
|
||||||
|
Blockly.Msg["UGJ_GESTURE_INIT_TOOLTIP"] = "PAJ7620 ジェスチャーセンサーを使用する準備をします。";
|
||||||
|
Blockly.Msg["UGJ_GESTURE_READ_TITLE"] = "ジェスチャーの値";
|
||||||
|
Blockly.Msg["UGJ_GESTURE_READ_TOOLTIP"] = "センサーから現在のジェスチャーの値(0〜9)を読み込みます";
|
||||||
|
Blockly.Msg["UGJ_GESTURE_STOP_TITLE"] = "ジェスチャーセンサーから切断";
|
||||||
|
Blockly.Msg["UGJ_GESTURE_STOP_TOOLTIP"] = "センサーとの接続を停止します。";
|
||||||
|
|
||||||
|
var ugjGestureInitDefinition = {
|
||||||
|
"type": "ugj_gesture_init",
|
||||||
|
"message0": "%{BKY_UGJ_GESTURE_INIT_TITLE}",
|
||||||
|
"args0": [
|
||||||
|
{
|
||||||
|
"type": "input_value",
|
||||||
|
"name": "i2c_addr",
|
||||||
|
"check": "Number"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"inputsInline": true,
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"tooltip": "%{BKY_UGJ_GESTURE_INIT_TOOLTIP}",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "sensor_blocks"
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_gesture_init'] = {
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit(ugjGestureInitDefinition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_gesture_init'] = function (block) {
|
||||||
|
var value_i2c_addr = Blockly.JavaScript.valueToCode(block, 'i2c_addr', Blockly.JavaScript.ORDER_ATOMIC);
|
||||||
|
Blockly.JavaScript.provideFunction_(
|
||||||
|
'require_gpio', [`const _pi = require('@ocogeclub/` + elutil.gpio_backend + `');`]
|
||||||
|
);
|
||||||
|
let modpath = elutil.path.join(elutil.blocks_sensors_dir, 'paj7620', 'PAJ7620x.js');
|
||||||
|
Blockly.JavaScript.provideFunction_(
|
||||||
|
'require_paj7620', [`const _paj7620 = require('${modpath}');`]
|
||||||
|
);
|
||||||
|
var code = `await _paj7620.init(${elutil.i2c_bus}, ${value_i2c_addr}, window);
|
||||||
|
`;
|
||||||
|
return code;
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************** */
|
||||||
|
/** Gesture Read ** */
|
||||||
|
/****************** */
|
||||||
|
var ugjGestureReadDefinition = {
|
||||||
|
"type": "ugj_gesture_read",
|
||||||
|
"message0": "%{BKY_UGJ_GESTURE_READ_TITLE}",
|
||||||
|
"inputsInline": true,
|
||||||
|
"output": "Number",
|
||||||
|
"tooltip": "%{BKY_UGJ_GESTURE_READ_TOOLTIP}",
|
||||||
|
"helpUrl": "https://ocoge.club/sensors/paj7620.html",
|
||||||
|
"style": "sensor_blocks"
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_gesture_read'] = {
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit(ugjGestureReadDefinition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_gesture_read'] = function (block) {
|
||||||
|
var code = 'await _paj7620.return_gesture()';
|
||||||
|
return [code, Blockly.JavaScript.ORDER_ATOMIC];
|
||||||
|
};
|
||||||
|
/****************** */
|
||||||
|
/** Gesture Stop ** */
|
||||||
|
/****************** */
|
||||||
|
var ugjGestureStopDefinition = {
|
||||||
|
"type": "ugj_gesture_stop",
|
||||||
|
"message0": "%{BKY_UGJ_GESTURE_STOP_TITLE}",
|
||||||
|
"inputsInline": true,
|
||||||
|
"previousStatement": null,
|
||||||
|
"nextStatement": null,
|
||||||
|
"tooltip": "%{BKY_UGJ_GESTURE_STOP_TOOLTIP}",
|
||||||
|
"helpUrl": "",
|
||||||
|
"style": "sensor_blocks"
|
||||||
|
};
|
||||||
|
Blockly.Blocks['ugj_gesture_stop'] = {
|
||||||
|
init: function () {
|
||||||
|
this.jsonInit(ugjGestureStopDefinition);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Blockly.JavaScript['ugj_gesture_stop'] = function (block) {
|
||||||
|
var code = 'await _paj7620.stop();\n';
|
||||||
|
return code;
|
||||||
|
};
|
37
blocks/sensors/paj7620/index.json
Normal file
37
blocks/sensors/paj7620/index.json
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"kind": "label",
|
||||||
|
"text": "ジェスチャーセンサー PAJ7620",
|
||||||
|
"web-line": "4.0",
|
||||||
|
"web-line-width": "200"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_gesture_init",
|
||||||
|
"inputs": {
|
||||||
|
"i2c_addr": {
|
||||||
|
"shadow": {
|
||||||
|
"type": "ugj_hextodec",
|
||||||
|
"inputs": {
|
||||||
|
"hex": {
|
||||||
|
"shadow": {
|
||||||
|
"type": "text",
|
||||||
|
"fields": {
|
||||||
|
"TEXT": "73"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_gesture_read"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"kind": "block",
|
||||||
|
"type": "ugj_gesture_stop"
|
||||||
|
}
|
||||||
|
]
|
77
index.js
77
index.js
@ -372,14 +372,55 @@ const ugj_createCode = (args) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ブロックスクリプト実行
|
// ブロックスクリプト実行
|
||||||
|
// var is_running = false;
|
||||||
|
// var worker;
|
||||||
|
// const ugj_runCode = async () => {
|
||||||
|
// const {
|
||||||
|
// Worker,
|
||||||
|
// isMainThread,
|
||||||
|
// setEnvironmentData,
|
||||||
|
// getEnvironmentData,
|
||||||
|
// } = require('worker_threads');
|
||||||
|
// const stop_icon = `<i class="fas fa-ban"></i> 停止`;
|
||||||
|
// const run_icon = `<i class="fas fa-play-circle"></i> 実行`;
|
||||||
|
// document.activeElement.blur(); //実行ボタンからフォーカスを外す:エンターキー押下が悪さをするため
|
||||||
|
|
||||||
|
// let btnel = document.getElementById('runbtn');
|
||||||
|
// if (is_running) {
|
||||||
|
// worker.terminate();
|
||||||
|
// } else {
|
||||||
|
// if (isMainThread) {
|
||||||
|
// btnel.innerHTML = stop_icon;
|
||||||
|
// let code = ugj_createCode({});
|
||||||
|
// setEnvironmentData('code', code);
|
||||||
|
// worker = new Worker(__filename);
|
||||||
|
// // worker.on('exit', (excode) => {
|
||||||
|
// // btnel.innerHTML = run_icon;
|
||||||
|
// // });
|
||||||
|
// // } else {
|
||||||
|
// // let AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
|
||||||
|
// // let ocogeFunc = new AsyncFunction(getEnvironmentData('code'));
|
||||||
|
// // await ocogeFunc().catch(e => { console.error(e); });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// is_running = !is_running;
|
||||||
|
// if (is_running) btnel.innerHTML = stop_icon;
|
||||||
|
// else btnel.innerHTML = run_icon;
|
||||||
|
|
||||||
|
|
||||||
|
// }
|
||||||
const ugj_runCode = async () => {
|
const ugj_runCode = async () => {
|
||||||
document.activeElement.blur(); //実行ボタンからフォーカスを外す:エンターキー押下が悪さをするため
|
document.activeElement.blur(); //実行ボタンからフォーカスを外す:エンターキー押下が悪さをするため
|
||||||
|
let btnel = document.getElementById('runbtn');
|
||||||
|
btnel.disabled = true;
|
||||||
// let code = ugj_createCode({ 'async': true });
|
// let code = ugj_createCode({ 'async': true });
|
||||||
// await eval(code).catch(e => { alert(e); });
|
// await eval(code).catch(e => { alert(e); });
|
||||||
let AsyncFunction = Object.getPrototypeOf(async function () { }).constructor
|
let AsyncFunction = Object.getPrototypeOf(async function () { }).constructor
|
||||||
let ocogeFunc = new AsyncFunction(ugj_createCode({}));
|
let ocogeFunc = new AsyncFunction(ugj_createCode({}));
|
||||||
await ocogeFunc().catch(e => { window.alert(e); });
|
await ocogeFunc().catch(e => { window.alert(e); });
|
||||||
console.log('Code Execution done.');
|
console.log('Code Execution done.');
|
||||||
|
btnel.disabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// コードをダイアログで表示・保存
|
// コードをダイアログで表示・保存
|
||||||
@ -413,7 +454,7 @@ const ugj_showCode = () => {
|
|||||||
// document... と ugj_... と elutil... をコメントアウト(ブラウザ関連部分の追放という意味では不完全なので注意)
|
// document... と ugj_... と elutil... をコメントアウト(ブラウザ関連部分の追放という意味では不完全なので注意)
|
||||||
// あと正規表現もいい加減
|
// あと正規表現もいい加減
|
||||||
if (chkbox_cli.checked && ext == 'js')
|
if (chkbox_cli.checked && ext == 'js')
|
||||||
code = code.replace(/const appendDiv[^#]*\/\/#/gm, 'const blackboardWrite = text => console.log(text);').replace('window.alert', 'console.log').replace(/ugj_fukidashi(.*), \d+(\);)/gm, 'console.log$1$2').replace(/(^(?=.*document.)[^;]*;)/gm, '/* $1 */').replace(/(^(?=.*ugj_)[^;]*;)/gm, '/* $1 */').replace(/(^(?=.*elutil.)[^;]*;)/gm, '/* $1 */');
|
code = code.replace(/const appendDiv[^#]*\/\/#/gm, 'const blackboardWrite = text => console.log(text);').replace('window.alert', 'console.log').replace(/_fukidashi(.*), \d+(\);)/gm, 'console.log$1$2').replace(/(^(?=.*document.)[^;]*;)/gm, '/* $1 */').replace(/(^(?=.*ugj_)[^;]*;)/gm, '/* $1 */').replace(/(^(?=.*elutil.)[^;]*;)/gm, '/* $1 */');
|
||||||
if (elutil.saveFile(code, ext) === false) {
|
if (elutil.saveFile(code, ext) === false) {
|
||||||
window.alert('保存できませんでした。');
|
window.alert('保存できませんでした。');
|
||||||
}
|
}
|
||||||
@ -439,7 +480,7 @@ const ugj_showCode = () => {
|
|||||||
// フキダシ
|
// フキダシ
|
||||||
let ugj_fdTimeoutID = null;
|
let ugj_fdTimeoutID = null;
|
||||||
let ugj_fdRecentBox = null;
|
let ugj_fdRecentBox = null;
|
||||||
const ugj_fukidashi = (text, sec) => {
|
const _fukidashi = (text, sec) => {
|
||||||
// Canvas Context
|
// Canvas Context
|
||||||
const context = document.getElementById('canvas').getContext('2d');
|
const context = document.getElementById('canvas').getContext('2d');
|
||||||
// 吹き出しを消去する関数
|
// 吹き出しを消去する関数
|
||||||
@ -628,34 +669,10 @@ window.onload = () => {
|
|||||||
// 背景canvas
|
// 背景canvas
|
||||||
ugj_canvasBgImg(elutil.getMascotFilePath(), -1, -1);
|
ugj_canvasBgImg(elutil.getMascotFilePath(), -1, -1);
|
||||||
}
|
}
|
||||||
window.onbeforeunload = () => {
|
window.addEventListener('beforeunload', () => {
|
||||||
|
// window.onbeforeunload = () => {
|
||||||
ugj_saveWorkspace();
|
ugj_saveWorkspace();
|
||||||
elutil.savePrefsToLS();
|
elutil.savePrefsToLS();
|
||||||
elutil.killAllChildren();
|
|
||||||
elutil.cleanupGPIO();
|
elutil.cleanupGPIO();
|
||||||
}
|
// }
|
||||||
|
});
|
||||||
// センサーブロック
|
|
||||||
// ブロックデータ格納ディレクトリのリスト
|
|
||||||
const allDirents = elutil.fs.readdirSync(elutil.blocks_sensors_dir, { withFileTypes: true });
|
|
||||||
const blocks_list = allDirents.filter(dirent => dirent.isDirectory()).map(({ name }) => name);
|
|
||||||
// センサーカテゴリのインスタンス
|
|
||||||
var category_sensors = workspace.getToolbox().getToolboxItemById('category_sensors');
|
|
||||||
var flyout_contents = []; // フライアウトのjsonのリスト
|
|
||||||
for (const sensor_dir of blocks_list) { //ディレクトリ巡り
|
|
||||||
if (sensor_dir.charAt(0) == '.') continue; //隠しディレクトリをスキップ
|
|
||||||
// フライアウトのjsonを取得してパース、リストに追加
|
|
||||||
let fname = elutil.path.join(elutil.blocks_sensors_dir, sensor_dir, 'index.json');
|
|
||||||
let json_text = elutil.fs.readFileSync(fname);
|
|
||||||
let obj = JSON.parse(json_text);
|
|
||||||
flyout_contents = flyout_contents.concat(obj);
|
|
||||||
// ブロック定義のスクリプト要素をbody要素の最後に追加
|
|
||||||
fname = elutil.path.join(elutil.blocks_sensors_dir, sensor_dir, 'index.js');
|
|
||||||
let script = document.createElement('script');
|
|
||||||
script.type = 'text/javascript';
|
|
||||||
script.src = fname;
|
|
||||||
document.body.appendChild(script);
|
|
||||||
}
|
|
||||||
// センサーカテゴリのフライアウトをアップデート
|
|
||||||
category_sensors.updateFlyoutContents(flyout_contents);
|
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ const ugj_const = {
|
|||||||
library_dirname: 'lib',
|
library_dirname: 'lib',
|
||||||
document_root: 'Documents',
|
document_root: 'Documents',
|
||||||
executable_path: '.ocogeclub/apps/',
|
executable_path: '.ocogeclub/apps/',
|
||||||
blocks_sensors_dir: '.ocogeclub/sensors/',
|
blocks_sensors_dir: 'blocks/sensors/',
|
||||||
localStorage_fname: 'ocoge.json',
|
localStorage_fname: 'ocoge.json',
|
||||||
error_ja_all: 'エラーが発生しました。\n『おこげ倶楽部』までお問い合わせください。',
|
error_ja_all: 'エラーが発生しました。\n『おこげ倶楽部』までお問い合わせください。',
|
||||||
pig: 'pigpio',
|
pig: 'pigpio',
|
||||||
@ -35,7 +35,9 @@ class elUtil {
|
|||||||
this.doc_root = this.path.join(process.env["HOME"], ugj_const.document_root);
|
this.doc_root = this.path.join(process.env["HOME"], ugj_const.document_root);
|
||||||
this.doc_current = this.path.join(process.env["HOME"], ugj_const.document_root);
|
this.doc_current = this.path.join(process.env["HOME"], ugj_const.document_root);
|
||||||
this.executable_path = this.path.join(process.env["HOME"], ugj_const.executable_path);
|
this.executable_path = this.path.join(process.env["HOME"], ugj_const.executable_path);
|
||||||
this.blocks_sensors_dir = this.path.join(process.env["HOME"], ugj_const.blocks_sensors_dir);
|
// this.blocks_sensors_dir = this.path.join(process.env["HOME"], ugj_const.blocks_sensors_dir);
|
||||||
|
const EventEmitter = require('events');
|
||||||
|
this.ugjEmitter = new EventEmitter();
|
||||||
}
|
}
|
||||||
// static init = async () => {
|
// static init = async () => {
|
||||||
// return new elUtil(await elUtil.get_app_path());
|
// return new elUtil(await elUtil.get_app_path());
|
||||||
@ -45,6 +47,43 @@ class elUtil {
|
|||||||
this.app_path = await this.ipcRenderer.invoke('get_app_path');
|
this.app_path = await this.ipcRenderer.invoke('get_app_path');
|
||||||
this.mascotFilePath = this.path.join(this.app_path, ugj_const.mascot_dirname, ugj_const.mascot_defname);
|
this.mascotFilePath = this.path.join(this.app_path, ugj_const.mascot_dirname, ugj_const.mascot_defname);
|
||||||
this.library_path = this.path.join(this.app_path, ugj_const.library_dirname);
|
this.library_path = this.path.join(this.app_path, ugj_const.library_dirname);
|
||||||
|
this.blocks_sensors_dir = this.path.join(this.app_path, ugj_const.blocks_sensors_dir);
|
||||||
|
this.loadSensorblocks();
|
||||||
|
}
|
||||||
|
|
||||||
|
// センサーブロックのロード
|
||||||
|
loadSensorblocks() {
|
||||||
|
// ディレクトリの有無
|
||||||
|
if (!this.fs.existsSync(this.blocks_sensors_dir)) return;
|
||||||
|
// ブロックデータ格納ディレクトリのリスト
|
||||||
|
const allDirents = this.fs.readdirSync(this.blocks_sensors_dir, { withFileTypes: true });
|
||||||
|
const blocks_list = allDirents.filter(dirent => dirent.isDirectory()).map(({ name }) => name);
|
||||||
|
// センサーカテゴリのインスタンス
|
||||||
|
let category_sensors = workspace.getToolbox().getToolboxItemById('category_sensors');
|
||||||
|
let flyout_contents = []; // フライアウトのjsonのリスト
|
||||||
|
for (let sensor_dir of blocks_list) { //ディレクトリ巡り
|
||||||
|
if (sensor_dir.charAt(0) == '.') continue; //隠しディレクトリをスキップ
|
||||||
|
// フライアウトのjsonを取得してパース、リストに追加
|
||||||
|
let fname = this.path.join(this.blocks_sensors_dir, sensor_dir, 'index.json');
|
||||||
|
let json_text = this.fs.readFileSync(fname);
|
||||||
|
let obj = JSON.parse(json_text);
|
||||||
|
flyout_contents = flyout_contents.concat(obj);
|
||||||
|
// ブロック定義のスクリプト要素をbody要素の最後に追加
|
||||||
|
fname = this.path.join(this.blocks_sensors_dir, sensor_dir, 'index.js');
|
||||||
|
let script = document.createElement('script');
|
||||||
|
script.type = 'text/javascript';
|
||||||
|
script.src = fname;
|
||||||
|
document.body.appendChild(script);
|
||||||
|
}
|
||||||
|
let lastline = [{
|
||||||
|
"kind": "label",
|
||||||
|
"text": " ",
|
||||||
|
"web-line": "4.0",
|
||||||
|
"web-line-width": "200"
|
||||||
|
}];
|
||||||
|
flyout_contents = flyout_contents.concat(lastline);
|
||||||
|
// センサーカテゴリのフライアウトをアップデート
|
||||||
|
category_sensors.updateFlyoutContents(flyout_contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -200,24 +239,10 @@ class elUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 子プロセス関連
|
|
||||||
// 新しい子プロセスを作成し、配列に保存
|
|
||||||
addChild(child) {
|
|
||||||
this.children.push(child);
|
|
||||||
}
|
|
||||||
// 全ての子プロセスを殺し、配列をクリア
|
|
||||||
killAllChildren() {
|
|
||||||
this.children.forEach(function (child) {
|
|
||||||
child.kill();
|
|
||||||
});
|
|
||||||
this.children = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// GPIO 関連:リロードでGPIOをロックしたままハンドルを失うのを防ぐ
|
// GPIO 関連:リロードでGPIOをロックしたままハンドルを失うのを防ぐ
|
||||||
cleanupGPIO() {
|
cleanupGPIO() {
|
||||||
|
// this.ugjEmitter.emit('device_stop');//デバイス停止イベント
|
||||||
require('@ocogeclub/' + this.gpio_backend).close_all_handle();
|
require('@ocogeclub/' + this.gpio_backend).close_all_handle();
|
||||||
// require('@ocogeclub/paj7620').stop();
|
|
||||||
// require('@ocogeclub/amg8833').stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 設定(保存ファイルパスと未保存フラグ)をローカルストレージに保存
|
// 設定(保存ファイルパスと未保存フラグ)をローカルストレージに保存
|
||||||
@ -318,6 +343,11 @@ class brUtil {
|
|||||||
setWsChanged() { ; }
|
setWsChanged() { ; }
|
||||||
killAllChildren() { ; }
|
killAllChildren() { ; }
|
||||||
cleanupGPIO() { ; }
|
cleanupGPIO() { ; }
|
||||||
|
path = {
|
||||||
|
join: function (a = '', b = '', c = '', d = '', e = '') {
|
||||||
|
return a + b + c + d + e;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Electron 動作 / ブラウザ動作自動判別
|
// Electron 動作 / ブラウザ動作自動判別
|
||||||
@ -339,11 +369,11 @@ if (!is_el) {
|
|||||||
var require = module_name => {
|
var require = module_name => {
|
||||||
let block;
|
let block;
|
||||||
switch (module_name) {
|
switch (module_name) {
|
||||||
case '@tensorflow/tfjs-node':
|
case '@tensorflow/tfjs':
|
||||||
block = 'TensorFlow';
|
block = 'TensorFlow';
|
||||||
break;
|
break;
|
||||||
case '@vladmandic/face-api':
|
case '@tensorflow-models/blazeface':
|
||||||
block = 'Face-API';
|
block = '顔認識';
|
||||||
break;
|
break;
|
||||||
case 'axios':
|
case 'axios':
|
||||||
block = 'URLを取得';
|
block = 'URLを取得';
|
||||||
@ -354,15 +384,6 @@ if (!is_el) {
|
|||||||
case '@ocogeclub/pigpio':
|
case '@ocogeclub/pigpio':
|
||||||
block = 'GPIO';
|
block = 'GPIO';
|
||||||
break;
|
break;
|
||||||
case '@ocogeclub/bme280':
|
|
||||||
block = 'BME280';
|
|
||||||
break;
|
|
||||||
case '@ocogeclub/amg8833':
|
|
||||||
block = '赤外線アレイセンサ';
|
|
||||||
break;
|
|
||||||
case '@ocogeclub/paj7620':
|
|
||||||
block = 'ジェスチャーセンサー';
|
|
||||||
break;
|
|
||||||
case 'fs':
|
case 'fs':
|
||||||
block = 'ファイル';
|
block = 'ファイル';
|
||||||
break;
|
break;
|
||||||
|
77
package-lock.json
generated
77
package-lock.json
generated
@ -1,22 +1,21 @@
|
|||||||
{
|
{
|
||||||
"name": "ocoge",
|
"name": "ocoge",
|
||||||
"version": "0.1.5",
|
"version": "0.1.6",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ocoge",
|
"name": "ocoge",
|
||||||
"version": "0.1.5",
|
"version": "0.1.6",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ocogeclub/amg8833": "file:local_modules/@ocogeclub/amg8833",
|
|
||||||
"@ocogeclub/pigpio": "file:local_modules/@ocogeclub/pigpio",
|
"@ocogeclub/pigpio": "file:local_modules/@ocogeclub/pigpio",
|
||||||
"@tensorflow-models/blazeface": "^0.0.7",
|
"@tensorflow-models/blazeface": "^0.0.7",
|
||||||
"@tensorflow-models/knn-classifier": "^1.2.2",
|
"@tensorflow-models/knn-classifier": "^1.2.2",
|
||||||
"@tensorflow-models/mobilenet": "^2.1.0",
|
"@tensorflow-models/mobilenet": "^2.1.0",
|
||||||
"@tensorflow/tfjs": "^3.13.0",
|
"@tensorflow/tfjs": "^3.13.0",
|
||||||
"@tensorflow/tfjs-backend-wasm": "^3.13.0",
|
"@tensorflow/tfjs-backend-wasm": "^3.13.0",
|
||||||
"axios": "^0.25.0",
|
"axios": "^0.26.0",
|
||||||
"electron-squirrel-startup": "^1.0.0",
|
"electron-squirrel-startup": "^1.0.0",
|
||||||
"nodemailer": "^6.7.2",
|
"nodemailer": "^6.7.2",
|
||||||
"tensorset": "^1.2.9"
|
"tensorset": "^1.2.9"
|
||||||
@ -27,12 +26,13 @@
|
|||||||
"@electron-forge/maker-rpm": "^6.0.0-beta.63",
|
"@electron-forge/maker-rpm": "^6.0.0-beta.63",
|
||||||
"@electron-forge/maker-squirrel": "6.0.0-beta.33",
|
"@electron-forge/maker-squirrel": "6.0.0-beta.33",
|
||||||
"@electron-forge/maker-zip": "^6.0.0-beta.63",
|
"@electron-forge/maker-zip": "^6.0.0-beta.63",
|
||||||
"electron": "^17.0.0",
|
"electron": "^17.1.0",
|
||||||
"electron-rebuild": "^3.2.7"
|
"electron-rebuild": "^3.2.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"local_modules/@ocogeclub/amg8833": {
|
"local_modules/@ocogeclub/amg8833": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
|
"extraneous": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ocogeclub/pigpio": "file:../pigpio"
|
"@ocogeclub/pigpio": "file:../pigpio"
|
||||||
@ -1420,10 +1420,6 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@ocogeclub/amg8833": {
|
|
||||||
"resolved": "local_modules/@ocogeclub/amg8833",
|
|
||||||
"link": true
|
|
||||||
},
|
|
||||||
"node_modules/@ocogeclub/pigpio": {
|
"node_modules/@ocogeclub/pigpio": {
|
||||||
"resolved": "local_modules/@ocogeclub/pigpio",
|
"resolved": "local_modules/@ocogeclub/pigpio",
|
||||||
"link": true
|
"link": true
|
||||||
@ -1959,11 +1955,11 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/axios": {
|
"node_modules/axios": {
|
||||||
"version": "0.25.0",
|
"version": "0.26.0",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.0.tgz",
|
||||||
"integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==",
|
"integrity": "sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"follow-redirects": "^1.14.7"
|
"follow-redirects": "^1.14.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/balanced-match": {
|
"node_modules/balanced-match": {
|
||||||
@ -2829,9 +2825,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/electron": {
|
"node_modules/electron": {
|
||||||
"version": "17.0.0",
|
"version": "17.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/electron/-/electron-17.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/electron/-/electron-17.1.0.tgz",
|
||||||
"integrity": "sha512-3UXcBQMwbMWdPvGHaSdPMluHrd+/bc+K143MyvE5zVZ+S1XCHt4sau7dj6svJHns5llN0YG/c6h/vRfadIp8Zg==",
|
"integrity": "sha512-X/qdldmQ8lA15NmeraubWCTtMeTO8K9Ser0wtSCgOXVh53Sr1Ea0VQQ7Q9LuGgWRVz4qtr40cntuEdM8icdmTw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@ -3708,6 +3704,7 @@
|
|||||||
"version": "0.1.13",
|
"version": "0.1.13",
|
||||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
||||||
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"iconv-lite": "^0.6.2"
|
"iconv-lite": "^0.6.2"
|
||||||
@ -3717,6 +3714,7 @@
|
|||||||
"version": "0.6.3",
|
"version": "0.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
@ -6896,7 +6894,7 @@
|
|||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
"devOptional": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/seedrandom": {
|
"node_modules/seedrandom": {
|
||||||
"version": "2.4.3",
|
"version": "2.4.3",
|
||||||
@ -9169,12 +9167,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@ocogeclub/amg8833": {
|
|
||||||
"version": "file:local_modules/@ocogeclub/amg8833",
|
|
||||||
"requires": {
|
|
||||||
"@ocogeclub/pigpio": "file:../pigpio"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@ocogeclub/pigpio": {
|
"@ocogeclub/pigpio": {
|
||||||
"version": "file:local_modules/@ocogeclub/pigpio",
|
"version": "file:local_modules/@ocogeclub/pigpio",
|
||||||
"requires": {
|
"requires": {
|
||||||
@ -9207,20 +9199,17 @@
|
|||||||
"@tensorflow-models/blazeface": {
|
"@tensorflow-models/blazeface": {
|
||||||
"version": "0.0.7",
|
"version": "0.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow-models/blazeface/-/blazeface-0.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow-models/blazeface/-/blazeface-0.0.7.tgz",
|
||||||
"integrity": "sha512-+hInPkvHJoubfiXlmNuF3SCucZvU6W1PMC25IV99NSAftJUpKvLokfF93iX8UkOFQCXkPFbnLKacGfGlbjgvMw==",
|
"integrity": "sha512-+hInPkvHJoubfiXlmNuF3SCucZvU6W1PMC25IV99NSAftJUpKvLokfF93iX8UkOFQCXkPFbnLKacGfGlbjgvMw=="
|
||||||
"requires": {}
|
|
||||||
},
|
},
|
||||||
"@tensorflow-models/knn-classifier": {
|
"@tensorflow-models/knn-classifier": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow-models/knn-classifier/-/knn-classifier-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow-models/knn-classifier/-/knn-classifier-1.2.2.tgz",
|
||||||
"integrity": "sha512-QRnkCf7ErOxSRtvJ6yCwhlLREPcBJGaXRanF46f0iY6ii3Sybjb6Ux0qnNPTrHZChD0izPa3Z4GQEgSAykiHkQ==",
|
"integrity": "sha512-QRnkCf7ErOxSRtvJ6yCwhlLREPcBJGaXRanF46f0iY6ii3Sybjb6Ux0qnNPTrHZChD0izPa3Z4GQEgSAykiHkQ=="
|
||||||
"requires": {}
|
|
||||||
},
|
},
|
||||||
"@tensorflow-models/mobilenet": {
|
"@tensorflow-models/mobilenet": {
|
||||||
"version": "2.1.0",
|
"version": "2.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow-models/mobilenet/-/mobilenet-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow-models/mobilenet/-/mobilenet-2.1.0.tgz",
|
||||||
"integrity": "sha512-JjqT9ijHDFA2FEpUGWg7H2lQ0GrMuE2VmiCRBYmUew6b4JKht8LXDjG5HxZh95YH6c/25sZWTpGeHbquloH+hw==",
|
"integrity": "sha512-JjqT9ijHDFA2FEpUGWg7H2lQ0GrMuE2VmiCRBYmUew6b4JKht8LXDjG5HxZh95YH6c/25sZWTpGeHbquloH+hw=="
|
||||||
"requires": {}
|
|
||||||
},
|
},
|
||||||
"@tensorflow/tfjs": {
|
"@tensorflow/tfjs": {
|
||||||
"version": "3.13.0",
|
"version": "3.13.0",
|
||||||
@ -9274,8 +9263,7 @@
|
|||||||
"@tensorflow/tfjs-converter": {
|
"@tensorflow/tfjs-converter": {
|
||||||
"version": "3.13.0",
|
"version": "3.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-3.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-3.13.0.tgz",
|
||||||
"integrity": "sha512-H2VpDTv9Ve0HBt7ttzz46DmnsPaiT0B+yJjVH3NebGZbgY9C8boBgJIsdyqfiqEWBS3WxF8h4rh58Hv5XXMgaQ==",
|
"integrity": "sha512-H2VpDTv9Ve0HBt7ttzz46DmnsPaiT0B+yJjVH3NebGZbgY9C8boBgJIsdyqfiqEWBS3WxF8h4rh58Hv5XXMgaQ=="
|
||||||
"requires": {}
|
|
||||||
},
|
},
|
||||||
"@tensorflow/tfjs-core": {
|
"@tensorflow/tfjs-core": {
|
||||||
"version": "3.13.0",
|
"version": "3.13.0",
|
||||||
@ -9303,8 +9291,7 @@
|
|||||||
"@tensorflow/tfjs-layers": {
|
"@tensorflow/tfjs-layers": {
|
||||||
"version": "3.13.0",
|
"version": "3.13.0",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-3.13.0.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-3.13.0.tgz",
|
||||||
"integrity": "sha512-kTWJ/+9fbNCMDA9iQjDMYHmWivsiWz8CKNSOZdeCW7tiBwF1EiREBVQXMk1JI11ngQa8f+rYSLs7rkhp3SYl5Q==",
|
"integrity": "sha512-kTWJ/+9fbNCMDA9iQjDMYHmWivsiWz8CKNSOZdeCW7tiBwF1EiREBVQXMk1JI11ngQa8f+rYSLs7rkhp3SYl5Q=="
|
||||||
"requires": {}
|
|
||||||
},
|
},
|
||||||
"@tootallnate/once": {
|
"@tootallnate/once": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
@ -9618,11 +9605,11 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"axios": {
|
"axios": {
|
||||||
"version": "0.25.0",
|
"version": "0.26.0",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.0.tgz",
|
||||||
"integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==",
|
"integrity": "sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"follow-redirects": "^1.14.7"
|
"follow-redirects": "^1.14.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
@ -10273,9 +10260,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"electron": {
|
"electron": {
|
||||||
"version": "17.0.0",
|
"version": "17.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/electron/-/electron-17.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/electron/-/electron-17.1.0.tgz",
|
||||||
"integrity": "sha512-3UXcBQMwbMWdPvGHaSdPMluHrd+/bc+K143MyvE5zVZ+S1XCHt4sau7dj6svJHns5llN0YG/c6h/vRfadIp8Zg==",
|
"integrity": "sha512-X/qdldmQ8lA15NmeraubWCTtMeTO8K9Ser0wtSCgOXVh53Sr1Ea0VQQ7Q9LuGgWRVz4qtr40cntuEdM8icdmTw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@electron/get": "^1.13.0",
|
"@electron/get": "^1.13.0",
|
||||||
@ -10948,6 +10935,7 @@
|
|||||||
"version": "0.1.13",
|
"version": "0.1.13",
|
||||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
||||||
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"iconv-lite": "^0.6.2"
|
"iconv-lite": "^0.6.2"
|
||||||
@ -10957,6 +10945,7 @@
|
|||||||
"version": "0.6.3",
|
"version": "0.6.3",
|
||||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||||
|
"dev": true,
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||||
@ -13432,7 +13421,7 @@
|
|||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||||
"devOptional": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"seedrandom": {
|
"seedrandom": {
|
||||||
"version": "2.4.3",
|
"version": "2.4.3",
|
||||||
@ -13883,8 +13872,7 @@
|
|||||||
"@tensorflow/tfjs-converter": {
|
"@tensorflow/tfjs-converter": {
|
||||||
"version": "2.8.6",
|
"version": "2.8.6",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-2.8.6.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-converter/-/tfjs-converter-2.8.6.tgz",
|
||||||
"integrity": "sha512-Uv4YC66qjVC9UwBxz0IeLZ8KS2CReh63WlGRtHcSwDEYiwsa7cvp9H6lFSSPT7kiJmrK6JtHeJGIVcTuNnSt9w==",
|
"integrity": "sha512-Uv4YC66qjVC9UwBxz0IeLZ8KS2CReh63WlGRtHcSwDEYiwsa7cvp9H6lFSSPT7kiJmrK6JtHeJGIVcTuNnSt9w=="
|
||||||
"requires": {}
|
|
||||||
},
|
},
|
||||||
"@tensorflow/tfjs-core": {
|
"@tensorflow/tfjs-core": {
|
||||||
"version": "2.8.6",
|
"version": "2.8.6",
|
||||||
@ -13910,8 +13898,7 @@
|
|||||||
"@tensorflow/tfjs-layers": {
|
"@tensorflow/tfjs-layers": {
|
||||||
"version": "2.8.6",
|
"version": "2.8.6",
|
||||||
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-2.8.6.tgz",
|
"resolved": "https://registry.npmjs.org/@tensorflow/tfjs-layers/-/tfjs-layers-2.8.6.tgz",
|
||||||
"integrity": "sha512-fdZ0i/R2dIKmy8OB5tBAsm5IbAHfJpI6AlbjxpgoU3aWj1HCdDo+pMji928MkDJhP01ISgFTgw/7PseGNaUflw==",
|
"integrity": "sha512-fdZ0i/R2dIKmy8OB5tBAsm5IbAHfJpI6AlbjxpgoU3aWj1HCdDo+pMji928MkDJhP01ISgFTgw/7PseGNaUflw=="
|
||||||
"requires": {}
|
|
||||||
},
|
},
|
||||||
"@types/webgl2": {
|
"@types/webgl2": {
|
||||||
"version": "0.0.5",
|
"version": "0.0.5",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ocoge",
|
"name": "ocoge",
|
||||||
"version": "0.1.5",
|
"version": "0.1.6",
|
||||||
"description": "ブロックベースビジュアルプログラム開発・実行環境",
|
"description": "ブロックベースビジュアルプログラム開発・実行環境",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@ -27,18 +27,17 @@
|
|||||||
"@electron-forge/maker-rpm": "^6.0.0-beta.63",
|
"@electron-forge/maker-rpm": "^6.0.0-beta.63",
|
||||||
"@electron-forge/maker-squirrel": "6.0.0-beta.33",
|
"@electron-forge/maker-squirrel": "6.0.0-beta.33",
|
||||||
"@electron-forge/maker-zip": "^6.0.0-beta.63",
|
"@electron-forge/maker-zip": "^6.0.0-beta.63",
|
||||||
"electron": "^17.0.0",
|
"electron": "^17.1.0",
|
||||||
"electron-rebuild": "^3.2.7"
|
"electron-rebuild": "^3.2.7"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ocogeclub/amg8833": "file:local_modules/@ocogeclub/amg8833",
|
|
||||||
"@ocogeclub/pigpio": "file:local_modules/@ocogeclub/pigpio",
|
"@ocogeclub/pigpio": "file:local_modules/@ocogeclub/pigpio",
|
||||||
"@tensorflow-models/blazeface": "^0.0.7",
|
"@tensorflow-models/blazeface": "^0.0.7",
|
||||||
"@tensorflow-models/knn-classifier": "^1.2.2",
|
"@tensorflow-models/knn-classifier": "^1.2.2",
|
||||||
"@tensorflow-models/mobilenet": "^2.1.0",
|
"@tensorflow-models/mobilenet": "^2.1.0",
|
||||||
"@tensorflow/tfjs": "^3.13.0",
|
"@tensorflow/tfjs": "^3.13.0",
|
||||||
"@tensorflow/tfjs-backend-wasm": "^3.13.0",
|
"@tensorflow/tfjs-backend-wasm": "^3.13.0",
|
||||||
"axios": "^0.25.0",
|
"axios": "^0.26.0",
|
||||||
"electron-squirrel-startup": "^1.0.0",
|
"electron-squirrel-startup": "^1.0.0",
|
||||||
"nodemailer": "^6.7.2",
|
"nodemailer": "^6.7.2",
|
||||||
"tensorset": "^1.2.9"
|
"tensorset": "^1.2.9"
|
||||||
|
298
ugj_blocks.js
298
ugj_blocks.js
@ -1174,7 +1174,7 @@ Blockly.JavaScript['ugj_canvas_say'] = function (block) {
|
|||||||
var value_say = Blockly.JavaScript.valueToCode(block, 'say', Blockly.JavaScript.ORDER_ATOMIC);
|
var value_say = Blockly.JavaScript.valueToCode(block, 'say', Blockly.JavaScript.ORDER_ATOMIC);
|
||||||
var value_sec = Blockly.JavaScript.valueToCode(block, 'sec', Blockly.JavaScript.ORDER_ATOMIC);
|
var value_sec = Blockly.JavaScript.valueToCode(block, 'sec', Blockly.JavaScript.ORDER_ATOMIC);
|
||||||
var code = [
|
var code = [
|
||||||
`ugj_fukidashi(String(${value_say}), ${value_sec});`,
|
`_fukidashi(String(${value_say}), ${value_sec});`,
|
||||||
''
|
''
|
||||||
].join('\n');
|
].join('\n');
|
||||||
return code;
|
return code;
|
||||||
@ -1431,294 +1431,6 @@ Blockly.JavaScript['ugj_canvas_drawrect'] = function (block) {
|
|||||||
return code;
|
return code;
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************** */
|
|
||||||
/** GridEye 表示キャンバス作成 ** */
|
|
||||||
/***************************** */
|
|
||||||
var ugjGridEyeCanvasCreateDefinition = {
|
|
||||||
"type": "ugj_grideye_canvas_create",
|
|
||||||
"message0": "%{BKY_UGJ_GRIDEYE_CANVAS_CREATE_TITLE}",
|
|
||||||
"inputsInline": true,
|
|
||||||
"previousStatement": null,
|
|
||||||
"nextStatement": null,
|
|
||||||
"tooltip": "%{BKY_UGJ_GRIDEYE_CANVAS_CREATE_TOOLTIP}",
|
|
||||||
"helpUrl": "",
|
|
||||||
"style": "multimedia_blocks"
|
|
||||||
};
|
|
||||||
Blockly.Blocks['ugj_grideye_canvas_create'] = {
|
|
||||||
init: function () {
|
|
||||||
this.jsonInit(ugjGridEyeCanvasCreateDefinition);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Blockly.JavaScript['ugj_grideye_canvas_create'] = function (block) {
|
|
||||||
var code = `let _grideye_canvas = document.createElement('canvas');
|
|
||||||
_grideye_canvas.setAttribute('width', 8);
|
|
||||||
_grideye_canvas.setAttribute('height', 8);
|
|
||||||
_grideye_canvas.className = 'subdisplay';
|
|
||||||
_grideye_canvas.style.width = '160px';
|
|
||||||
_grideye_canvas.style.height = '160px';
|
|
||||||
_grideye_canvas.id = 'subcanvas';
|
|
||||||
document.getElementById('display_area').appendChild(_grideye_canvas);
|
|
||||||
_grideye_ctx = _grideye_canvas.getContext('2d');
|
|
||||||
_grideye_imgData = _grideye_ctx.createImageData(8, 8);
|
|
||||||
`;
|
|
||||||
return code;
|
|
||||||
};
|
|
||||||
/********************************************** */
|
|
||||||
/** Draw IR Array Data to Image Data ** */
|
|
||||||
/********************************************** */
|
|
||||||
var ugjDrawGrideyedataDefinition = {
|
|
||||||
"type": "ugj_draw_grideyedata",
|
|
||||||
"message0": "%{BKY_UGJ_DRAW_GRIDEYEDATA_TITLE}",
|
|
||||||
"args0": [
|
|
||||||
{
|
|
||||||
"type": "input_dummy"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "input_value",
|
|
||||||
"name": "amg8833data",
|
|
||||||
"check": "Array",
|
|
||||||
"align": "RIGHT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "field_colour",
|
|
||||||
"name": "color_high",
|
|
||||||
"colour": "#ff0000"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "input_value",
|
|
||||||
"name": "temp_high",
|
|
||||||
"check": "Number",
|
|
||||||
"align": "RIGHT"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "field_colour",
|
|
||||||
"name": "color_low",
|
|
||||||
"colour": "#3333ff"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "input_value",
|
|
||||||
"name": "temp_low",
|
|
||||||
"check": "Number",
|
|
||||||
"align": "RIGHT"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"inputsInline": false,
|
|
||||||
"previousStatement": null,
|
|
||||||
"nextStatement": null,
|
|
||||||
"tooltip": "%{BKY_UGJ_DRAW_GRIDEYEDATA_TOOLTIP}",
|
|
||||||
"helpUrl": "",
|
|
||||||
"style": "multimedia_blocks"
|
|
||||||
};
|
|
||||||
Blockly.Blocks['ugj_draw_grideyedata'] = {
|
|
||||||
init: function () {
|
|
||||||
this.jsonInit(ugjDrawGrideyedataDefinition);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Blockly.JavaScript['ugj_draw_grideyedata'] = function (block) {
|
|
||||||
var value_amg8833data = Blockly.JavaScript.valueToCode(block, 'amg8833data', Blockly.JavaScript.ORDER_ATOMIC);
|
|
||||||
var colour_color_high = block.getFieldValue('color_high');
|
|
||||||
var value_temp_high = Blockly.JavaScript.valueToCode(block, 'temp_high', Blockly.JavaScript.ORDER_ATOMIC);
|
|
||||||
var colour_color_low = block.getFieldValue('color_low');
|
|
||||||
var value_temp_low = Blockly.JavaScript.valueToCode(block, 'temp_low', Blockly.JavaScript.ORDER_ATOMIC);
|
|
||||||
var functionName = Blockly.JavaScript.provideFunction_(
|
|
||||||
'_mapVal',
|
|
||||||
['const ' + Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_ + ' = (val, inMin, inMax, outMin, outMax) => {',
|
|
||||||
`return (val - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;`,
|
|
||||||
'}'
|
|
||||||
]
|
|
||||||
);
|
|
||||||
// 温度カラー
|
|
||||||
let hr, hg, hb, lr, lg, lb;
|
|
||||||
hr = '0x' + colour_color_high.slice(1, 3);
|
|
||||||
hg = '0x' + colour_color_high.slice(3, 5);
|
|
||||||
hb = '0x' + colour_color_high.slice(5, 7);
|
|
||||||
lr = '0x' + colour_color_low.slice(1, 3);
|
|
||||||
lg = '0x' + colour_color_low.slice(3, 5);
|
|
||||||
lb = '0x' + colour_color_low.slice(5, 7);
|
|
||||||
var code = ` const _color_range = [[${lr}, ${hr}], [${lg}, ${hg}], [${lb}, ${hb}]];
|
|
||||||
let _grideye_data = ${value_amg8833data};//読み取りブロックを入力に直接接続できるようにする
|
|
||||||
for (let raw = 0; raw < _grideye_canvas.height; raw++) {
|
|
||||||
for (let col = 0; col < _grideye_canvas.width; col++) {
|
|
||||||
for (let rgb = 0; rgb < 3; rgb++) {
|
|
||||||
let pixel = ${functionName}(_grideye_data[raw][col], ${value_temp_low}, ${value_temp_high}, _color_range[rgb][0], _color_range[rgb][1]);
|
|
||||||
_grideye_imgData.data[((raw * _grideye_canvas.width * 4) + col * 4) + rgb] = pixel;
|
|
||||||
}
|
|
||||||
_grideye_imgData.data[((raw * _grideye_canvas.width * 4) + col * 4) + 3] = 0xff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_grideye_ctx.putImageData(_grideye_imgData, 0, 0);
|
|
||||||
|
|
||||||
`;
|
|
||||||
return code;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**************************** */
|
|
||||||
/** Teachable Machine を開始** */
|
|
||||||
/**************************** */
|
|
||||||
var ugjTeachableMachineDefinition = {
|
|
||||||
"type": "ugj_teachable_machine",
|
|
||||||
"message0": "%{BKY_UGJ_TEACHABLE_MACHINE_TITLE}",
|
|
||||||
"inputsInline": true,
|
|
||||||
"previousStatement": null,
|
|
||||||
"nextStatement": null,
|
|
||||||
"tooltip": "%{BKY_UGJ_TEACHABLE_MACHINE_TOOLTIP}",
|
|
||||||
"helpUrl": "",
|
|
||||||
"style": "multimedia_blocks"
|
|
||||||
};
|
|
||||||
Blockly.Blocks['ugj_teachable_machine'] = {
|
|
||||||
init: function () {
|
|
||||||
this.jsonInit(ugjTeachableMachineDefinition);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Blockly.JavaScript['ugj_teachable_machine'] = function (block) {
|
|
||||||
Blockly.JavaScript.provideFunction_(
|
|
||||||
'require_ts', [`const _tf = require('@tensorflow/tfjs');`]
|
|
||||||
// 'require_ts', [`const _tf = require('@tensorflow/tfjs-node');`]
|
|
||||||
);
|
|
||||||
Blockly.JavaScript.provideFunction_(
|
|
||||||
'require_wasm', [`const _wasm = require('@tensorflow/tfjs-backend-wasm');`]
|
|
||||||
);
|
|
||||||
Blockly.JavaScript.provideFunction_(
|
|
||||||
'require_mobilenet', [`const _mobilenet = require('@tensorflow-models/mobilenet');`]
|
|
||||||
);
|
|
||||||
Blockly.JavaScript.provideFunction_(
|
|
||||||
'require_knn', [`const _knnClassifier = require('@tensorflow-models/knn-classifier');`]
|
|
||||||
);
|
|
||||||
|
|
||||||
var code = `await _tf.setBackend('wasm');
|
|
||||||
const _net = await _mobilenet.load({ version: 1, alpha: 0.25 }); // 高速・低精度
|
|
||||||
const _classifier = _knnClassifier.create();
|
|
||||||
`;
|
|
||||||
return code;
|
|
||||||
};
|
|
||||||
/************************* */
|
|
||||||
/** GridEye で推論を行う ** */
|
|
||||||
/************************* */
|
|
||||||
var ugjGridEyePredictClassDefinition = {
|
|
||||||
"type": "ugj_grideye_predict_class",
|
|
||||||
"message0": "%{BKY_UGJ_GRIDEYE_PREDICT_CLASS_TITLE}",
|
|
||||||
"inputsInline": true,
|
|
||||||
"output": "Number",
|
|
||||||
"tooltip": "%{BKY_UGJ_GRIDEYE_PREDICT_CLASS_TOOLTIP}",
|
|
||||||
"helpUrl": "",
|
|
||||||
"style": "multimedia_blocks"
|
|
||||||
};
|
|
||||||
Blockly.Blocks['ugj_grideye_predict_class'] = {
|
|
||||||
init: function () {
|
|
||||||
this.jsonInit(ugjGridEyePredictClassDefinition);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Blockly.JavaScript['ugj_grideye_predict_class'] = function (block) {
|
|
||||||
var functionName = Blockly.JavaScript.provideFunction_( // left output にするための関数化
|
|
||||||
'_predictClass',
|
|
||||||
[
|
|
||||||
`if (_confidence === undefined) var _confidence;`,
|
|
||||||
`const ${Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_} = async (img, clsfr, mblnet) => {`,
|
|
||||||
`if (clsfr.getNumClasses() > 0) {`,
|
|
||||||
`const result = await clsfr.predictClass(mblnet.infer(img, 'conv_preds'));`,
|
|
||||||
`_confidence = result.confidences[result.label];`,
|
|
||||||
`return result.label;`,
|
|
||||||
`}`,
|
|
||||||
`else return 0;`,
|
|
||||||
`}`
|
|
||||||
]
|
|
||||||
);
|
|
||||||
var code = `await ${functionName}(_grideye_canvas, _classifier, _net)`;
|
|
||||||
return [code, Blockly.JavaScript.ORDER_NONE];
|
|
||||||
};
|
|
||||||
/******************************************** */
|
|
||||||
/** ラベルをつけて Example をデータセットに追加 ** */
|
|
||||||
/******************************************** */
|
|
||||||
var ugjGridEyeAddExampleDefinition = {
|
|
||||||
"type": "ugj_grideye_add_example",
|
|
||||||
"message0": "%{BKY_UGJ_GRIDEYE_ADD_EXAMPLE_TITLE}",
|
|
||||||
"args0": [
|
|
||||||
{
|
|
||||||
"type": "input_value",
|
|
||||||
"name": "class_id",
|
|
||||||
"check": "Number"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"inputsInline": true,
|
|
||||||
"previousStatement": null,
|
|
||||||
"nextStatement": null,
|
|
||||||
"tooltip": "%{BKY_UGJ_GRIDEYE_ADD_EXAMPLE_TOOLTIP}",
|
|
||||||
"helpUrl": "",
|
|
||||||
"style": "multimedia_blocks"
|
|
||||||
};
|
|
||||||
Blockly.Blocks['ugj_grideye_add_example'] = {
|
|
||||||
init: function () {
|
|
||||||
this.jsonInit(ugjGridEyeAddExampleDefinition);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Blockly.JavaScript['ugj_grideye_add_example'] = function (block) {
|
|
||||||
var value_class_id = Blockly.JavaScript.valueToCode(block, 'class_id', Blockly.JavaScript.ORDER_ATOMIC);
|
|
||||||
var code = `_classifier.addExample (_net.infer(_grideye_canvas, true), ${value_class_id});`;
|
|
||||||
return code;
|
|
||||||
};
|
|
||||||
/*************************** */
|
|
||||||
/** 学習したクラスを文字列化 ** */
|
|
||||||
/*************************** */
|
|
||||||
var ugjTensorsetStringifyDefinition = {
|
|
||||||
"type": "ugj_tensorset_stringify",
|
|
||||||
"message0": "%{BKY_UGJ_TENSORSET_STRINGIFY_TITLE}",
|
|
||||||
"output": null,
|
|
||||||
"tooltip": "%{BKY_UGJ_TENSORSET_STRINGIFY_TOOLTIP}",
|
|
||||||
"helpUrl": "",
|
|
||||||
"style": "multimedia_blocks"
|
|
||||||
};
|
|
||||||
Blockly.Blocks['ugj_tensorset_stringify'] = {
|
|
||||||
init: function () {
|
|
||||||
this.jsonInit(ugjTensorsetStringifyDefinition);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Blockly.JavaScript['ugj_tensorset_stringify'] = function (block) {
|
|
||||||
Blockly.JavaScript.provideFunction_(
|
|
||||||
'require_tensorset', [`const _Tensorset = require('tensorset');`]
|
|
||||||
);
|
|
||||||
var code = `await _Tensorset.stringify(_classifier.getClassifierDataset())`;
|
|
||||||
return [code, Blockly.JavaScript.ORDER_NONE];
|
|
||||||
};
|
|
||||||
/***************************************** */
|
|
||||||
/** jsonをデータセットに戻して分類器にセット ** */
|
|
||||||
/***************************************** */
|
|
||||||
var ugjTensorsetParseDefinition = {
|
|
||||||
"type": "ugj_tensorset_parse",
|
|
||||||
"message0": "%{BKY_UGJ_TENSORSET_PARSE_TITLE}",
|
|
||||||
"args0": [
|
|
||||||
{
|
|
||||||
"type": "input_value",
|
|
||||||
"name": "class_data_json",
|
|
||||||
"check": "String"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"previousStatement": null,
|
|
||||||
"nextStatement": null,
|
|
||||||
"tooltip": "%{BKY_UGJ_TENSORSET_PARSE_TOOLTIP}",
|
|
||||||
"helpUrl": "",
|
|
||||||
"style": "multimedia_blocks"
|
|
||||||
};
|
|
||||||
Blockly.Blocks['ugj_tensorset_parse'] = {
|
|
||||||
init: function () {
|
|
||||||
this.jsonInit(ugjTensorsetParseDefinition);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Blockly.JavaScript['ugj_tensorset_parse'] = function (block) {
|
|
||||||
Blockly.JavaScript.provideFunction_(
|
|
||||||
'require_tensorset', [`const _Tensorset = require('tensorset');`]
|
|
||||||
);
|
|
||||||
var value_class_data_json = Blockly.JavaScript.valueToCode(block, 'class_data_json', Blockly.JavaScript.ORDER_ATOMIC);
|
|
||||||
var code = `try {
|
|
||||||
let _class_dataset = _Tensorset.parse(${value_class_data_json});
|
|
||||||
_classifier.setClassifierDataset(_class_dataset);
|
|
||||||
} catch (error) {
|
|
||||||
alert('Could not load class dataset.');
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
return code;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/****************************** */
|
/****************************** */
|
||||||
/** KeyUpDown Event Listener ** */
|
/** KeyUpDown Event Listener ** */
|
||||||
/****************************** */
|
/****************************** */
|
||||||
@ -2415,7 +2127,7 @@ Blockly.JavaScript['ugj_event_answer'] = function (block) {
|
|||||||
// var variable_answer = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('answer'), Blockly.Variables.NAME_TYPE);
|
// var variable_answer = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('answer'), Blockly.Variables.NAME_TYPE);
|
||||||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||||||
var code = [
|
var code = [
|
||||||
`ugj_fukidashi(${value_question}, 0);`,
|
`_fukidashi(${value_question}, 0);`,
|
||||||
`_inputForm = document.getElementById('inputForm');`,
|
`_inputForm = document.getElementById('inputForm');`,
|
||||||
`_inputBox = document.getElementById('inputBox');`,
|
`_inputBox = document.getElementById('inputBox');`,
|
||||||
"_inputForm.style.display = 'inline-block'",
|
"_inputForm.style.display = 'inline-block'",
|
||||||
@ -2493,18 +2205,16 @@ Blockly.Blocks['ugj_spawn'] = {
|
|||||||
Blockly.JavaScript['ugj_spawn'] = function (block) {
|
Blockly.JavaScript['ugj_spawn'] = function (block) {
|
||||||
var value_childprocess = Blockly.JavaScript.valueToCode(block, 'childprocess', Blockly.JavaScript.ORDER_NONE);
|
var value_childprocess = Blockly.JavaScript.valueToCode(block, 'childprocess', Blockly.JavaScript.ORDER_NONE);
|
||||||
var value_data = Blockly.JavaScript.valueToCode(block, 'data', Blockly.JavaScript.ORDER_ATOMIC);
|
var value_data = Blockly.JavaScript.valueToCode(block, 'data', Blockly.JavaScript.ORDER_ATOMIC);
|
||||||
// var variable_data = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('data'), Blockly.Variables.NAME_TYPE);
|
|
||||||
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
|
||||||
|
|
||||||
var code = [
|
var code = [
|
||||||
`let _child = require('child_process').spawn(${value_childprocess});`,
|
`let _child = require('child_process').spawn(${value_childprocess});`,
|
||||||
`elutil.addChild(_child);`,
|
|
||||||
"_child.stderr.on('data', _data => { console.error(_data.toString()) })",
|
"_child.stderr.on('data', _data => { console.error(_data.toString()) })",
|
||||||
"_child.stdout.on('data', async _data => {",
|
"_child.stdout.on('data', async _data => {",
|
||||||
`${value_data} = _data.toString();`,
|
`${value_data} = _data.toString();`,
|
||||||
statements_do,
|
statements_do,
|
||||||
"})",
|
"})",
|
||||||
"_child.on('close', (_code, _signal) => { if (_code !== 0) { console.error(`process exited with code ${_code}, signal ${_signal}`)}",
|
`window.addEventListener( 'beforeunload', function() { _child.kill() }, false );`,
|
||||||
"})",
|
|
||||||
''
|
''
|
||||||
].join("\n");
|
].join("\n");
|
||||||
return code;
|
return code;
|
||||||
|
Loading…
Reference in New Issue
Block a user