[update] GPIOバックエンドを pigpio に戻した。lgpio でサーボモータのジッタの発生を確認したため。

This commit is contained in:
ocogeclub 2021-10-08 22:30:52 +09:00
parent 141192c70d
commit 3f2d06bb51
15 changed files with 966 additions and 532 deletions

57
.vscode/settings.json vendored
View File

@ -1,3 +1,58 @@
{
"python.formatting.provider": "black"
"python.formatting.provider": "black",
"files.associations": {
"array": "cpp",
"atomic": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"chrono": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"condition_variable": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"list": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"set": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iosfwd": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"ostream": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp"
},
"C_Cpp.errorSquiggles": "Disabled"
}

View File

@ -83,8 +83,8 @@ Blockly.JavaScript.math_constrain=function(a){var b=Blockly.JavaScript.valueToCo
Blockly.JavaScript.math_random_int=function(a){var b=Blockly.JavaScript.valueToCode(a,"FROM",Blockly.JavaScript.ORDER_NONE)||"0";a=Blockly.JavaScript.valueToCode(a,"TO",Blockly.JavaScript.ORDER_NONE)||"0";return[Blockly.JavaScript.provideFunction_("mathRandomInt",["function "+Blockly.JavaScript.FUNCTION_NAME_PLACEHOLDER_+"(a, b) {"," if (a > b) {"," // Swap a and b to ensure a is smaller."," var c = a;"," a = b;"," b = c;"," }"," return Math.floor(Math.random() * (b - a + 1) + a);",
"}"])+"("+b+", "+a+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};Blockly.JavaScript.math_random_float=function(a){return["Math.random()",Blockly.JavaScript.ORDER_FUNCTION_CALL]};Blockly.JavaScript.math_atan2=function(a){var b=Blockly.JavaScript.valueToCode(a,"X",Blockly.JavaScript.ORDER_NONE)||"0";return["Math.atan2("+(Blockly.JavaScript.valueToCode(a,"Y",Blockly.JavaScript.ORDER_NONE)||"0")+", "+b+") / Math.PI * 180",Blockly.JavaScript.ORDER_DIVISION]};Blockly.JavaScript.procedures={};
Blockly.JavaScript.procedures_defreturn=function(a){var b=Blockly.JavaScript.nameDB_.getName(a.getFieldValue("NAME"),Blockly.PROCEDURE_CATEGORY_NAME),c="";Blockly.JavaScript.STATEMENT_PREFIX&&(c+=Blockly.JavaScript.injectId(Blockly.JavaScript.STATEMENT_PREFIX,a));Blockly.JavaScript.STATEMENT_SUFFIX&&(c+=Blockly.JavaScript.injectId(Blockly.JavaScript.STATEMENT_SUFFIX,a));c&&(c=Blockly.JavaScript.prefixLines(c,Blockly.JavaScript.INDENT));var d="";Blockly.JavaScript.INFINITE_LOOP_TRAP&&(d=Blockly.JavaScript.prefixLines(Blockly.JavaScript.injectId(Blockly.JavaScript.INFINITE_LOOP_TRAP,
a),Blockly.JavaScript.INDENT));var e=Blockly.JavaScript.statementToCode(a,"STACK"),f=Blockly.JavaScript.valueToCode(a,"RETURN",Blockly.JavaScript.ORDER_NONE)||"",g="";e&&f&&(g=c);f&&(f=Blockly.JavaScript.INDENT+"return "+f+";\n");for(var h=[],l=a.getVars(),k=0;k<l.length;k++)h[k]=Blockly.JavaScript.nameDB_.getName(l[k],Blockly.VARIABLE_CATEGORY_NAME);c="function "+b+"("+h.join(", ")+") {\n"+c+d+e+g+f+"}";c=Blockly.JavaScript.scrub_(a,c);Blockly.JavaScript.definitions_["%"+b]=c;return null};
Blockly.JavaScript.procedures_defnoreturn=Blockly.JavaScript.procedures_defreturn;Blockly.JavaScript.procedures_callreturn=function(a){for(var b=Blockly.JavaScript.nameDB_.getName(a.getFieldValue("NAME"),Blockly.PROCEDURE_CATEGORY_NAME),c=[],d=a.getVars(),e=0;e<d.length;e++)c[e]=Blockly.JavaScript.valueToCode(a,"ARG"+e,Blockly.JavaScript.ORDER_NONE)||"null";return[b+"("+c.join(", ")+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};
a),Blockly.JavaScript.INDENT));var e=Blockly.JavaScript.statementToCode(a,"STACK"),f=Blockly.JavaScript.valueToCode(a,"RETURN",Blockly.JavaScript.ORDER_NONE)||"",g="";e&&f&&(g=c);f&&(f=Blockly.JavaScript.INDENT+"return "+f+";\n");for(var h=[],l=a.getVars(),k=0;k<l.length;k++)h[k]=Blockly.JavaScript.nameDB_.getName(l[k],Blockly.VARIABLE_CATEGORY_NAME);c="async function "+b+"("+h.join(", ")+") {\n"+c+d+e+g+f+"}";c=Blockly.JavaScript.scrub_(a,c);Blockly.JavaScript.definitions_["%"+b]=c;return null};
Blockly.JavaScript.procedures_defnoreturn=Blockly.JavaScript.procedures_defreturn;Blockly.JavaScript.procedures_callreturn=function(a){for(var b=Blockly.JavaScript.nameDB_.getName(a.getFieldValue("NAME"),Blockly.PROCEDURE_CATEGORY_NAME),c=[],d=a.getVars(),e=0;e<d.length;e++)c[e]=Blockly.JavaScript.valueToCode(a,"ARG"+e,Blockly.JavaScript.ORDER_NONE)||"null";return['await '+b+"("+c.join(", ")+")",Blockly.JavaScript.ORDER_FUNCTION_CALL]};
Blockly.JavaScript.procedures_callnoreturn=function(a){return Blockly.JavaScript.procedures_callreturn(a)[0]+";\n"};
Blockly.JavaScript.procedures_ifreturn=function(a){var b="if ("+(Blockly.JavaScript.valueToCode(a,"CONDITION",Blockly.JavaScript.ORDER_NONE)||"false")+") {\n";Blockly.JavaScript.STATEMENT_SUFFIX&&(b+=Blockly.JavaScript.prefixLines(Blockly.JavaScript.injectId(Blockly.JavaScript.STATEMENT_SUFFIX,a),Blockly.JavaScript.INDENT));a.hasReturnValue_?(a=Blockly.JavaScript.valueToCode(a,"VALUE",Blockly.JavaScript.ORDER_NONE)||"null",b+=Blockly.JavaScript.INDENT+"return "+a+";\n"):b+=Blockly.JavaScript.INDENT+
"return;\n";return b+"}\n"};Blockly.JavaScript.texts={};Blockly.JavaScript.text=function(a){return[Blockly.JavaScript.quote_(a.getFieldValue("TEXT")),Blockly.JavaScript.ORDER_ATOMIC]};Blockly.JavaScript.text_multiline=function(a){a=Blockly.JavaScript.multiline_quote_(a.getFieldValue("TEXT"));var b=-1!=a.indexOf("+")?Blockly.JavaScript.ORDER_ADDITION:Blockly.JavaScript.ORDER_ATOMIC;return[a,b]};

View File

@ -318,9 +318,9 @@
<sep></sep>
<category name="GPIO" css-icon="customIcon fab fa-raspberry-pi" categorystyle="gpio_category">
<label text="基本"></label>
<block type="ugj_gpiochip_open"></block>
<block type="ugj_gpiochip_close"></block>
<block type="ugj_gpio_claim_output">
<block type="ugj_gpio_open"></block>
<block type="ugj_gpio_close"></block>
<block type="ugj_gpio_set_output">
<value name="gpio">
<shadow type="math_number">
<field name="NUM">5</field>
@ -335,7 +335,7 @@
</value>
<field name="level">1</field>
</block>
<block type="ugj_gpio_claim_input">
<block type="ugj_gpio_set_input">
<field name="lflag">pi.SET_PULL_DOWN</field>
<value name="gpio">
<shadow type="math_number">
@ -351,7 +351,7 @@
</value>
</block>
<label text="パルス" web-line="4.0" web-line-width="200"></label>
<block type="ugj_tx_pwm">
<block type="ugj_pwm">
<value name="gpio">
<shadow type="math_number">
<field name="NUM">5</field>
@ -368,7 +368,7 @@
</shadow>
</value>
</block>
<block type="ugj_tx_servo">
<block type="ugj_servo">
<value name="gpio">
<shadow type="math_number">
<field name="NUM">12</field>
@ -592,11 +592,6 @@
<block type="ugj_sound_play">
<field name="sound">meow</field>
</block>
<block type="ugj_multimedia_webspeech_recognition" disabled="true">
<field name="transcript" id="=3;~1sjv_R.pRhO)=wQY" variabletype="">ことば</field>
<field name="continuous">once</field>
<field name="interim">TRUE</field>
</block>
<label text="顔認識" web-line="4.0" web-line-width="200"></label>
<block type="ugj_faceapi">
<field name="with_landmark">FALSE</field>
@ -610,17 +605,6 @@
<field name="h" id="8+E.-dP-Omt}v2~DCC]M" variabletype="">高さ</field>
</block>
<block type="ugj_face_drawrect"></block>
<label text="画像認識" web-line="4.0" web-line-width="200"></label>
<block type="ugj_library_load">
<value name="lib">
<shadow type="ugj_library_tensorflow"></shadow>
</value>
</block>
<block type="ugj_tfpredict_init"></block>
<block type="ugj_tfpredict_loadmodel"></block>
<block type="ugj_tfpredict_predict">
<field name="result" id="!=~_{T-;nZXP-rWM|beL" variabletype="">結果</field>
</block>
<label text="_" web-line="4.0" web-line-width="200"></label>
</category>

View File

@ -80,23 +80,23 @@ Blockly.Msg["UGJ_FOREACH_TITLE"] = "リスト %1 の各 %2 について %3 %4";
Blockly.Msg["UGJ_FOREACH_ITEM"] = "項目";
Blockly.Msg["UGJ_FOREACH_TOOLTIP"] = "リストの各項目について、その項目を変数「項目」としてステートメントを実行します。";
Blockly.Msg["GPIOCHIP_OPEN_TITLE"] = "GPIO を使えるようにする";
Blockly.Msg["GPIOCHIP_OPEN_TOOLTIP"] = "GPIOを初期化して接続します。";
Blockly.Msg["GPIOCHIP_CLOSE_TITLE"] = "GPIO の後片付けをする";
Blockly.Msg["GPIOCHIP_CLOSE_TOOLTIP"] = "GPIOとの接続を終了します。";
Blockly.Msg["GPIOCHIP_CLOSE_TITLE"] = "GPIO の後片付けをする";
Blockly.Msg["GPIO_CLAIM_INPUT_TITLE"] = "GPIO %1 を入力モードにして %2";
Blockly.Msg["GPIO_CLAIM_INPUT_TOOLTIP"] = "GPIO端子を入力モードにしてプルアッププルダウン無しを設定します";
Blockly.Msg["GPIO_CLAIM_OUTPUT_TITLE"] = "GPIO %1 を出力モードにする";
Blockly.Msg["GPIO_CLAIM_OUTPUT_TOOLTIP"] = "GPIO端子のモードを出力に設定します。";
Blockly.Msg["GPIO_OPEN_TITLE"] = "GPIO を使えるようにする";
Blockly.Msg["GPIO_OPEN_TOOLTIP"] = "GPIOを初期化して接続します。";
Blockly.Msg["GPIO_CLOSE_TITLE"] = "GPIO の後片付けをする";
Blockly.Msg["GPIO_CLOSE_TOOLTIP"] = "GPIOとの接続を終了します。";
Blockly.Msg["GPIO_CLOSE_TITLE"] = "GPIO の後片付けをする";
Blockly.Msg["GPIO_SET_INPUT_TITLE"] = "GPIO %1 を入力モードにして %2";
Blockly.Msg["GPIO_SET_INPUT_TOOLTIP"] = "GPIO端子を入力モードにして、プルアップ・プルダウン・無しを設定します。";
Blockly.Msg["GPIO_SET_OUTPUT_TITLE"] = "GPIO %1 を出力モードにする";
Blockly.Msg["GPIO_SET_OUTPUT_TOOLTIP"] = "GPIO端子のモードを出力に設定します。";
Blockly.Msg["GPIO_READ_TITLE"] = "GPIO %1 の値";
Blockly.Msg["GPIO_READ_TOOLTIP"] = "GPIO端子の値をデジタル値0または1で読み取ります。";
Blockly.Msg["GPIO_WRITE_TITLE"] = "GPIO %1 の値を %2 にする";
Blockly.Msg["GPIO_WRITE_TOOLTIP"] = "GPIO端子の値をデジタル値0または1で出力します。";
Blockly.Msg["TX_SERVO_TITLE"] = "GPIO %1 のサーボモータの回転を %2 にする";
Blockly.Msg["TX_SERVO_TOOLTIP"] = "サーボモータの回転をパルス幅(10002000μsec)までの数値で指定します。";
Blockly.Msg["TX_PWM_TITLE"] = "PWM : GPIO %1 に、パルス周波数 %2 Hz, デューティー比 %3 %%で出力";
Blockly.Msg["TX_PWM_TOOLTIP"] = "パルス周波数をセットして、GPIO端子がPWM出力できるようにします。レンジは100固定です。";
Blockly.Msg["SERVO_TITLE"] = "GPIO %1 のサーボモータの回転を %2 にする";
Blockly.Msg["SERVO_TOOLTIP"] = "サーボモータの回転をパルス幅(10002000μsec)までの数値で指定します。";
Blockly.Msg["PWM_TITLE"] = "PWM : GPIO %1 に、パルス周波数 %2 Hz, デューティー比 %3 %%で出力";
Blockly.Msg["PWM_TOOLTIP"] = "パルス周波数をセットして、GPIO端子がPWM出力できるようにします。レンジは100固定です。";
Blockly.Msg["I2C_OPEN_TITLE"] = "アドレス %1 の I2C デバイスを開く";
Blockly.Msg["I2C_OPEN_TOOLTIP"] = "I2C接続されたデバイスとの通信を開始します。一度にオープンできるI2Cデバイスはひとつだけです。";
Blockly.Msg["SERIAL_OPEN_TITLE"] = "シリアルポートを速度 %1 bpsで開く";
@ -620,6 +620,6 @@ window.onbeforeunload = () => {
ugj_saveWorkspace();
elutil.savePrefsToLS();
elutil.killAllChildren();
elutil.cleanupLGPIO();
elutil.cleanupGPIO();
}

View File

@ -11,7 +11,9 @@ const ugj_const = {
library_path: './lib/',
executable_path: './bin/',
localStorage_fname: 'ocoge.json',
error_ja_all: 'エラーが発生しました。\n『おこげ倶楽部』までお問い合わせください。'
error_ja_all: 'エラーが発生しました。\n『おこげ倶楽部』までお問い合わせください。',
PIG: 'pigpio',
LG: 'lgpio'
}
/** クラス elUtil ****************************************************************** */
@ -26,6 +28,7 @@ class elUtil {
this.wsChanged = false;
this.mascotFilePath = this.path.join(ugj_const.mascot_path, ugj_const.mascot_defname);
this.children = [];
this.gpio_backend = ugj_const.PIG;
}
// 0で数値の桁合わせ : NUM=値 LEN=桁数
zeroPadding(NUM, LEN) {
@ -189,9 +192,9 @@ class elUtil {
this.children = [];
}
// LGPIO 関連リロードでGPIOをロックしたままハンドルを失うのを防ぐ
cleanupLGPIO() {
let pi = require('@ocogeclub/lgpio').close_all_handle();
// GPIO 関連リロードでGPIOをロックしたままハンドルを失うのを防ぐ
cleanupGPIO() {
require('@ocogeclub/' + this.gpio_backend).close_all_handle();
}
// 設定(保存ファイルパスと未保存フラグ)をローカルストレージに保存
@ -273,7 +276,7 @@ class brUtil {
newFile() { ; }
setWsChanged() { ; }
killAllChildren() { ; }
cleanupLGPIO() { ; }
cleanupGPIO() { ; }
}
// Electron 動作 / ブラウザ動作自動判別
@ -303,7 +306,7 @@ if (!is_el) {
case 'nodemailer':
block = 'メール送信';
break;
case '@ocogeclub/lgpio':
case '@ocogeclub/gpio':
block = 'GPIO';
break;
case '@ocogeclub/bme280':

View File

@ -1,22 +1,18 @@
#!/bin/bash -x
# Usage: bash install.sh
NODEJS=14.17.0
NODEVER=14.17.0
# install lgpio (and python3)
# install some packages
sudo apt update
sudo apt install build-essential python3 swig python3-dev python3-setuptools -y
wget http://abyz.me.uk/lg/lg.zip
unzip lg.zip
rm lg.zip
cd lg
make
sudo make install
cd ..
sudo apt install fswebcam -y
# enable pigpiod service
sudo systemctl enable pigpiod.service
sudo systemctl start pigpiod.service
# install node.js (=electron node version) via n (https://github.com/tj/n)
curl -L https://raw.githubusercontent.com/tj/n/master/bin/n -o n
sudo bash n $NODEJS
sudo bash n $NODEVER
# install python code formatter
python3 -m pip install black
# install desktop entry

View File

@ -1,28 +1,32 @@
module.exports = require('bindings')('lgpio');
module.exports.SET_ACTIVE_LOW = 4;
module.exports.SET_OPEN_DRAIN = 8;
module.exports.SET_OPEN_SOURCE = 16;
module.exports.SET_PULL_UP = 32;
module.exports.SET_PULL_DOWN = 64;
module.exports.SET_PULL_NONE = 128;
// module.exports.SET_ACTIVE_LOW = 4;
// module.exports.SET_OPEN_DRAIN = 8;
// module.exports.SET_OPEN_SOURCE = 16;
// module.exports.SET_PULL_UP = 32;
// module.exports.SET_PULL_DOWN = 64;
// module.exports.SET_PULL_NONE = 128;
module.exports.PULL_UP = 32;
module.exports.PULL_DOWN = 64;
module.exports.PULL_NONE = 128;
let gpio_hand = -1;
let ser_hand = -1;
let i2c_hand = -1;
module.exports.gpiochip_open = gpiochip => {
if (gpio_hand < 0) gpio_hand = module.exports._gpiochip_open(gpiochip);
module.exports.gpio_open = () => {
if (gpio_hand < 0) gpio_hand = module.exports._gpiochip_open(0);
return gpio_hand;
}
module.exports.gpiochip_close = () => {
module.exports.gpio_close = () => {
if (gpio_hand >= 0) module.exports._gpiochip_close(gpio_hand);
gpio_hand = -1;
}
module.exports.gpio_claim_output = gpio => {
module.exports.gpio_set_output = gpio => {
if (gpio_hand >= 0) return module.exports._gpio_claim_output(gpio_hand, gpio);
}
module.exports.gpio_claim_input = gpio => {
if (gpio_hand >= 0) return module.exports._gpio_claim_input(gpio_hand, gpio);
module.exports.gpio_set_input = (gpio, lflag) => {
if (gpio_hand >= 0) return module.exports._gpio_claim_input(gpio_hand, gpio, lflag);
}
module.exports.gpio_read = gpio => {
if (gpio_hand >= 0) return module.exports._gpio_read(gpio_hand, gpio);
@ -30,6 +34,12 @@ module.exports.gpio_read = gpio => {
module.exports.gpio_write = (gpio, value) => {
if (gpio_hand >= 0) return module.exports._gpio_write(gpio_hand, gpio, value);
}
module.exports.servo = (gpio, pulse_width) => {
if (gpio_hand >= 0) return module.exports._tx_servo(gpio_hand, gpio, pulse_width);
}
module.exports.pwm = (gpio, pwm_frequency, pwm_duty_cycle) => {
if (gpio_hand >= 0) return module.exports._tx_pwm(gpio_hand, gpio, pwm_frequency, pwm_duty_cycle);
}
module.exports.serial_open = (tty, baud) => {
if (ser_hand >= 0) module.exports._serial_close(ser_hand); // 勝手に閉じる
ser_hand = module.exports._serial_open(tty, baud);
@ -68,7 +78,7 @@ module.exports.i2c_write_device = data => {
}
// 終了処理
module.exports.close_all_handle = () => {
module.exports.gpiochip_close();
module.exports.gpio_close();
module.exports.serial_close();
module.exports.i2c_close();
}

View File

@ -206,9 +206,6 @@ Value serialOpen(const CallbackInfo &info)
}
std::string tty = info[0].As<String>().Utf8Value();
// char *c = new char[tty.size()+1];
// std::strcpy(c, tty.c_str());
// &ser_tty[0] で参照できるらしいけど危険?
int baud = info[1].As<Number>().Int32Value();

View File

@ -0,0 +1,12 @@
{
"targets": [
{
"target_name": "pigpio",
"sources": ["pigpio.cpp"],
"defines": ["NAPI_DISABLE_CPP_EXCEPTIONS"],
"include_dirs": ["<!@(node -p \"require( 'node-addon-api' ).include\")"],
"dependencies": ["<!(node -p \"require('node-addon-api').gyp\")"],
"libraries": ["-lpigpiod_if2", "-lrt"],
}
]
}

View File

@ -0,0 +1,92 @@
module.exports = require('bindings')('pigpio');
// module.exports.INPUT = 0;
// module.exports.OUTPUT = 1;
// module.exports.PUD_OFF = 0;
// module.exports.PUD_DOWN = 1;
// module.exports.PUD_UP = 2;
module.exports.PULL_UP = 2;
module.exports.PULL_DOWN = 1;
module.exports.PULL_NONE = 0;
let pi = -1;
let i2c_hand = -1;
let ser_hand = -1;
module.exports.gpio_open = () => {
if (pi < 0) pi = module.exports._pigpio_start('', '');
return pi;
}
module.exports.gpio_close = () => {
if (pi >= 0) module.exports._pigpio_stop(pi);
pi = -1;
}
module.exports.gpio_set_output = gpio => {
if (pi >= 0) return module.exports._set_mode(pi, gpio, 1);
}
module.exports.gpio_set_input = (gpio, mode) => {
if (pi >= 0) {
let r = module.exports._set_mode(pi, gpio, 0);
if (r == 0)
return module.exports._set_pull_up_down(pi, gpio, mode);
else
return r;
}
}
module.exports.gpio_read = gpio => {
if (pi >= 0) return module.exports._gpio_read(pi, gpio);
}
module.exports.gpio_write = (gpio, value) => {
if (pi >= 0) return module.exports._gpio_write(pi, gpio, value);
}
module.exports.servo = (gpio, pulse_width) => {
if (pi >= 0) return module.exports._set_servo_pulsewidth(pi, gpio, pulse_width);
}
module.exports.pwm = (gpio, pwm_frequency, pwm_duty_cycle) => {
if (pi >= 0) {
module.exports._set_PWM_frequency(pi, gpio, pwm_frequency);
module.exports._set_PWM_dutycycle(pi, gpio, pwm_duty_cycle);
}
}
module.exports.serial_open = (tty, baud) => {
if (ser_hand >= 0) module.exports._serial_close(pi, ser_hand); // 勝手に閉じる
ser_hand = module.exports._serial_open(pi, tty, baud);
return ser_hand;
}
module.exports.serial_close = () => {
if (ser_hand >= 0) module.exports._serial_close(pi, ser_hand);
ser_hand = -1;
}
module.exports.serial_write = data => {
if (ser_hand >= 0) return module.exports._serial_write(pi, ser_hand, Buffer.from(data));
}
module.exports.serial_read = count => {
if (ser_hand >= 0) return module.exports._serial_read(pi, ser_hand, count).toString('utf8');
}
module.exports.i2c_open = (i2c_bus, i2c_address) => {
if (i2c_hand >= 0) module.exports._i2c_close(pi, i2c_hand); // 勝手に閉じる
i2c_hand = module.exports._i2c_open(pi, i2c_bus, i2c_address);
return i2c_hand;
}
module.exports.i2c_close = () => {
if (i2c_hand >= 0) module.exports._i2c_close(pi, i2c_hand);
i2c_hand = -1;
}
module.exports.i2c_write_byte_data = (reg, byte_val) => {
if (i2c_hand >= 0) return module.exports._i2c_write_byte_data(pi, i2c_hand, reg, byte_val);
}
module.exports.i2c_read_byte_data = reg => {
if (i2c_hand >= 0) return module.exports._i2c_read_byte_data(pi, i2c_hand, reg);
}
module.exports.i2c_read_device = count => {
if (i2c_hand >= 0) return module.exports._i2c_read_device(pi, i2c_hand, count).toString('utf8');
}
module.exports.i2c_write_device = data => {
if (i2c_hand >= 0) return module.exports._i2c_write_device(pi, i2c_hand, Buffer.from(data));
}
// 終了処理
module.exports.close_all_handle = () => {
module.exports.serial_close();
module.exports.i2c_close();
module.exports.gpio_close();
}

View File

@ -0,0 +1,11 @@
{
"name": "@ocogeclub/pigpio",
"version": "0.0.1",
"main": "index.js",
"private": true,
"license": "MIT",
"dependencies": {
"bindings": "^1.5.0",
"node-addon-api": "^1.7.1"
}
}

View File

@ -0,0 +1,622 @@
/** PIGPIO デーモンを Node.js から利用するモジュール ** */
/** 関数名・書式は Python Interface に準拠 ******************* */
#include <napi.h>
#include <pigpiod_if2.h>
#include <unistd.h>
#include <string>
using namespace Napi;
// pigpio 初期化
Value _pigpioStart(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 2)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsString() || !info[1].IsString())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
std::string addrStr = info[0].As<String>().Utf8Value();
std::string portStr = info[1].As<String>().Utf8Value();
return Number::New(env, pigpio_start(&addrStr[0], &portStr[0]));
}
// pigpio 後始末
Value _pigpioStop(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 1)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
pigpio_stop(pi);
return env.Null();
}
// GPIO 端子のモードを設定
Value _setMode(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int gpio = info[1].As<Number>().Uint32Value();
unsigned int mode = info[2].As<Number>().Uint32Value();
return Number::New(env,
set_mode(pi, gpio, mode));
}
// GPIO 端子のモードを取得
// Value _GetMode(const CallbackInfo &info)
// {
// Env env = info.Env();
// if (info.Length() < 1)
// {
// TypeError::New(env, "Wrong number of arguments")
// .ThrowAsJavaScriptException();
// return env.Null();
// }
// if (!info[0].IsNumber())
// {
// TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
// return env.Null();
// }
// unsigned int gpio = info[0].As<Number>().DoubleValue();
// return Number::New(env,
// get_mode(pi, gpio));
// }
// GPIOの内部プルアップ/ダウン抵抗の設定/クリア
Value _setPullUpDown(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int gpio = info[1].As<Number>().Uint32Value();
unsigned int pud = info[2].As<Number>().Uint32Value();
return Number::New(env,
set_pull_up_down(pi, gpio, pud));
}
// GPIOの電圧を読む
Value _gpioRead(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 2)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int gpio = info[1].As<Number>().Uint32Value();
return Number::New(env,
gpio_read(pi, gpio));
}
// GPIO の電圧をセットする
Value _gpioWrite(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int gpio = info[1].As<Number>().Uint32Value();
unsigned int value = info[2].As<Number>().Uint32Value();
return Number::New(env,
gpio_write(pi, gpio, value));
}
// サーボパルス幅をセットする
Value _setServoPulsewidth(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int user_gpio = info[1].As<Number>().Uint32Value();
unsigned int pulsewidth = info[2].As<Number>().Uint32Value();
return Number::New(env,
set_servo_pulsewidth(pi, user_gpio, pulsewidth));
}
// PWM周波数を設定する
Value _setPwmFrequency(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int user_gpio = info[1].As<Number>().Uint32Value();
unsigned int frequency = info[2].As<Number>().Uint32Value();
return Number::New(env,
set_PWM_frequency(pi, user_gpio, frequency));
}
// PWMのレンジを設定する
// Value _SetPwmRange(const CallbackInfo &info)
// {
// Env env = info.Env();
// if (info.Length() < 2)
// {
// TypeError::New(env, "Wrong number of arguments")
// .ThrowAsJavaScriptException();
// return env.Null();
// }
// if (!info[0].IsNumber() || !info[1].IsNumber())
// {
// TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
// return env.Null();
// }
// unsigned int user_gpio = info[0].As<Number>().DoubleValue();
// unsigned int range = info[1].As<Number>().DoubleValue();
// return Number::New(env,
// set_PWM_range(pi, user_gpio, range));
// }
// PWMのデューティ比を指定して出力を開始する
Value _setPwmDutycycle(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int user_gpio = info[1].As<Number>().Uint32Value();
unsigned int dutycycle = info[2].As<Number>().Uint32Value();
return Number::New(env,
set_PWM_dutycycle(pi, user_gpio, dutycycle));
}
// シリアルポートを開く
Value _serialOpen(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsString() || !info[2].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
std::string ser_tty = info[1].As<String>().Utf8Value();
unsigned int baud = info[2].As<Number>().Uint32Value();
// &ser_tty[0]
return Number::New(env,
serial_open(pi, (char *)ser_tty.c_str(), baud, 0));
}
// シリアルポートを閉じる
Value _serialClose(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 2)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
return Number::New(env,
serial_close(pi, handle));
}
// シリアルデバイスからデータを読む
Value _serialRead(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int count = info[2].As<Number>().Uint32Value();
char buf[count];
int rxCount = serial_read(pi, handle, buf, count);
auto outBuf = Buffer<char>::Copy(env, buf, rxCount);
return outBuf;
}
// シリアルデバイスにバイト列を書き込む(data: string)
Value _serialWrite(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsBuffer())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
auto buf = info[2].As<Buffer<char>>();
int count = buf.Length();
return Number::New(env,
serial_write(pi, handle, buf.Data(), count));
}
// I2Cバスアドレスのデバイスのハンドルを返す
Value _i2cOpen(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int i2c_bus = info[1].As<Number>().Uint32Value();
unsigned int i2c_addr = info[2].As<Number>().Uint32Value();
return Number::New(env,
i2c_open(pi, i2c_bus, i2c_addr, 0));
}
// オープン済みI2Cハンドルを閉じる
Value _i2cClose(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 2)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[0].As<Number>().Uint32Value();
return Number::New(env,
i2c_close(pi, handle));
}
// デバイスに1バイトを送る
Value _i2cWriteByte(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int bVal = info[2].As<Number>().Uint32Value();
return Number::New(env,
i2c_write_byte(pi, handle, bVal));
}
// デバイスから1バイトを受け取る
Value _i2cReadByte(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 2)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[0].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
return Number::New(env,
i2c_read_byte(pi, handle));
}
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタに1バイトを書き込む
Value _i2cWriteByteData(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 4)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[0].As<Number>().Uint32Value();
unsigned int i2c_reg = info[1].As<Number>().Uint32Value();
unsigned int bVal = info[2].As<Number>().Uint32Value();
return Number::New(env,
i2c_write_byte_data(pi, handle, i2c_reg, bVal));
}
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタから1バイトを読み込む
Value _i2cReadByteData(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int i2c_reg = info[2].As<Number>().Uint32Value();
return Number::New(env,
i2c_read_byte_data(pi, handle, i2c_reg));
}
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタからcountバイトを読み込む。countは132。
Value _i2cReadI2cBlockData(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 4)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int i2cReg = info[2].As<Number>().Uint32Value();
unsigned int count = info[3].As<Number>().Uint32Value();
char buf[count];
int rxCount = i2c_read_i2c_block_data(pi, handle, i2cReg, buf, count);
auto outBuf = Buffer<char>::Copy(env, buf, rxCount);
return outBuf;
}
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタから単一の16ビットワードを読み取る
Value _i2cReadWordData(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int i2c_reg = info[2].As<Number>().Uint32Value();
return Number::New(env,
i2c_read_word_data(pi, handle, i2c_reg));
}
// i2c デバイスからデータを受け取る
Value _i2cReadDevice(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
unsigned int count = info[2].As<Number>().Uint32Value();
char buf[count];
int rxCount = i2c_read_device(pi, handle, buf, count);
auto outBuf = Buffer<char>::Copy(env, buf, rxCount);
return outBuf;
}
// i2c デバイスにバイト列を送る(data: buffer)
Value _i2cWriteDevice(const CallbackInfo &info)
{
Env env = info.Env();
if (info.Length() < 3)
{
TypeError::New(env, "Wrong number of arguments")
.ThrowAsJavaScriptException();
return env.Null();
}
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsBuffer())
{
TypeError::New(env, "Wrong arguments").ThrowAsJavaScriptException();
return env.Null();
}
int pi = info[0].As<Number>().Int32Value();
unsigned int handle = info[1].As<Number>().Uint32Value();
auto buf = info[2].As<Buffer<char>>();
unsigned int count = buf.Length();
return Number::New(env,
i2c_write_device(pi, handle, buf.Data(), count));
}
Object
Init(Env env, Object exports)
{
// exports.Set(String::New(env, "usleep"), Function::New(env, _Usleep));
exports.Set(String::New(env, "_pigpio_start"), Function::New(env, _pigpioStart));
exports.Set(String::New(env, "_pigpio_stop"), Function::New(env, _pigpioStop));
exports.Set(String::New(env, "_set_mode"), Function::New(env, _setMode));
// exports.Set(String::New(env, "get_mode"), Function::New(env, _GetMode));
exports.Set(String::New(env, "_set_pull_up_down"), Function::New(env, _setPullUpDown));
exports.Set(String::New(env, "_gpio_read"), Function::New(env, _gpioRead));
exports.Set(String::New(env, "_gpio_write"), Function::New(env, _gpioWrite));
exports.Set(String::New(env, "_set_servo_pulsewidth"), Function::New(env, _setServoPulsewidth));
exports.Set(String::New(env, "_set_PWM_frequency"), Function::New(env, _setPwmFrequency));
// exports.Set(String::New(env, "set_PWM_range"), Function::New(env, _SetPwmRange));
exports.Set(String::New(env, "_set_PWM_dutycycle"), Function::New(env, _setPwmDutycycle));
exports.Set(String::New(env, "_serial_open"), Function::New(env, _serialOpen));
exports.Set(String::New(env, "_serial_close"), Function::New(env, _serialClose));
exports.Set(String::New(env, "_serial_read"), Function::New(env, _serialRead));
exports.Set(String::New(env, "_serial_write"), Function::New(env, _serialWrite));
exports.Set(String::New(env, "_i2c_open"), Function::New(env, _i2cOpen));
exports.Set(String::New(env, "_i2c_close"), Function::New(env, _i2cClose));
exports.Set(String::New(env, "_i2c_write_byte"), Function::New(env, _i2cWriteByte));
exports.Set(String::New(env, "_i2c_read_byte"), Function::New(env, _i2cReadByte));
exports.Set(String::New(env, "_i2c_write_byte_data"), Function::New(env, _i2cWriteByteData));
exports.Set(String::New(env, "_i2c_read_byte_data"), Function::New(env, _i2cReadByteData));
exports.Set(String::New(env, "_i2c_read_i2c_block_data"), Function::New(env, _i2cReadI2cBlockData));
exports.Set(String::New(env, "_i2c_read_word_data"), Function::New(env, _i2cReadWordData));
exports.Set(String::New(env, "_i2c_write_device"), Function::New(env, _i2cWriteDevice));
exports.Set(String::New(env, "_i2c_read_device"), Function::New(env, _i2cReadDevice));
return exports;
}
NODE_API_MODULE(pigpio, Init)

View File

@ -24,7 +24,7 @@
},
"dependencies": {
"@ocogeclub/bme280": "file:local_modules/@ocogeclub/bme280",
"@ocogeclub/lgpio": "file:local_modules/@ocogeclub/lgpio",
"@ocogeclub/pigpio": "file:local_modules/@ocogeclub/pigpio",
"@tensorflow/tfjs-node": "^3.9.0",
"@vladmandic/face-api": "^1.5.3",
"axios": "^0.21.1",

View File

@ -291,70 +291,67 @@ Blockly.Python['ugj_dectohex'] = function (block) {
/************ */
/** GPIO Open */
/************ */
var ugjGpiochipOpenDefinition = {
"type": "ugj_gpiochip_open",
"message0": "%{BKY_GPIOCHIP_OPEN_TITLE}",
var ugjGpioOpenDefinition = {
"type": "ugj_gpio_open",
"message0": "%{BKY_GPIO_OPEN_TITLE}",
"previousStatement": null,
"nextStatement": null,
"tooltip": "%{BKY_GPIOCHIP_OPEN_TOOLTIP}",
"tooltip": "%{BKY_GPIO_OPEN_TOOLTIP}",
"helpUrl": "",
"style": "gpio_blocks"
};
Blockly.Blocks['ugj_gpiochip_open'] = {
Blockly.Blocks['ugj_gpio_open'] = {
init: function () {
this.jsonInit(ugjGpiochipOpenDefinition);
this.jsonInit(ugjGpioOpenDefinition);
}
};
Blockly.JavaScript['ugj_gpiochip_open'] = function (block) {
Blockly.JavaScript['ugj_gpio_open'] = function (block) {
Blockly.JavaScript.provideFunction_(
'require_oclg', [`const pi = require('@ocogeclub/lgpio');`]
'require_gpio', [`const pi = require('@ocogeclub/` + elutil.gpio_backend + `');`]
);
// var code = `pi.gpio_chip_open(0);\nconsole.log(pi.get_hand());`; //
// var code = `var lgHand = pi.gpiochip_open(0);\n`; //
var code = `pi.gpiochip_open(0);\n`; //
var code = `pi.gpio_open();\n`; //
return code;
};
Blockly.Python['ugj_gpiochip_open'] = function (block) {
Blockly.Python['ugj_gpio_open'] = function (block) {
Blockly.Python.provideFunction_(
'import_lgpio', ['import lgpio as pi']
);
var code = `lgHand = pi.gpiochip_open(0)\n`; //
var code = `gpioHand = pi.gpiochip_open(0)\n`; //
return code;
};
/************* */
/** GPIO Close */
/************* */
var ugjGpiochipCloseDefinition = {
"type": "ugj_gpiochip_close",
"message0": "%{BKY_GPIOCHIP_CLOSE_TITLE}",
var ugjGpioCloseDefinition = {
"type": "ugj_gpio_close",
"message0": "%{BKY_GPIO_CLOSE_TITLE}",
"previousStatement": null,
"nextStatement": null,
"tooltip": "%{BKY_GPIOCHIP_CLOSE_TOOLTIP}",
"tooltip": "%{BKY_GPIO_CLOSE_TOOLTIP}",
"helpUrl": "",
"style": "gpio_blocks"
};
Blockly.Blocks['ugj_gpiochip_close'] = {
Blockly.Blocks['ugj_gpio_close'] = {
init: function () {
this.jsonInit(ugjGpiochipCloseDefinition);
this.jsonInit(ugjGpioCloseDefinition);
}
};
Blockly.JavaScript['ugj_gpiochip_close'] = function (block) {
var code = 'pi.gpiochip_close();\n';
// var code = 'pi.gpiochip_close(lgHand);\n';
Blockly.JavaScript['ugj_gpio_close'] = function (block) {
var code = 'pi.gpio_close();\n';
return code;
};
Blockly.Python['ugj_gpiochip_close'] = function (block) {
var code = 'pi.gpiochip_close(lgHand)\n';
Blockly.Python['ugj_gpio_close'] = function (block) {
var code = 'pi.gpiochip_close(gpioHand)\n';
return code;
};
/*********************** */
/** GPIO Claim Output ** */
/** GPIO Set Output ** */
/*********************** */
var ugjGpioClaimOutputDefinition = {
"type": "ugj_gpio_claim_output",
"message0": "%{BKY_GPIO_CLAIM_OUTPUT_TITLE}",
var ugjGpioSetOutputDefinition = {
"type": "ugj_gpio_set_output",
"message0": "%{BKY_GPIO_SET_OUTPUT_TITLE}",
"args0": [
{
"type": "input_value",
@ -365,32 +362,32 @@ var ugjGpioClaimOutputDefinition = {
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"tooltip": "%{BKY_GPIO_CLAIM_OUTPUT_TOOLTIP}",
"tooltip": "%{BKY_GPIO_SET_OUTPUT_TOOLTIP}",
"helpUrl": "",
"style": "gpio_blocks"
};
Blockly.Blocks['ugj_gpio_claim_output'] = {
Blockly.Blocks['ugj_gpio_set_output'] = {
init: function () {
this.jsonInit(ugjGpioClaimOutputDefinition);
this.jsonInit(ugjGpioSetOutputDefinition);
}
};
Blockly.JavaScript['ugj_gpio_claim_output'] = function (block) {
Blockly.JavaScript['ugj_gpio_set_output'] = function (block) {
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
var code = `pi.gpio_claim_output(${value_gpio});\n`;
var code = `pi.gpio_set_output(${value_gpio});\n`;
return code;
};
Blockly.Python['ugj_gpio_claim_output'] = function (block) {
Blockly.Python['ugj_gpio_set_output'] = function (block) {
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
var code = `pi.gpio_claim_output(${value_gpio})\n`;
var code = `pi.gpio_set_output(${value_gpio})\n`;
return code;
};
/********************** */
/** GPIO Claim Input ** */
/** GPIO Set Input ** */
/********************** */
var ugjGpioClaimInputDefinition = {
"type": "ugj_gpio_claim_input",
"message0": "%{BKY_GPIO_CLAIM_INPUT_TITLE}",
var ugjGpioSetInputDefinition = {
"type": "ugj_gpio_set_input",
"message0": "%{BKY_GPIO_SET_INPUT_TITLE}",
"args0": [
{
"type": "input_value",
@ -419,25 +416,25 @@ var ugjGpioClaimInputDefinition = {
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"tooltip": "%{BKY_GPIO_CLAIM_INPUT_TOOLTIP}",
"tooltip": "%{BKY_GPIO_SET_INPUT_TOOLTIP}",
"helpUrl": "",
"style": "gpio_blocks"
};
Blockly.Blocks['ugj_gpio_claim_input'] = {
Blockly.Blocks['ugj_gpio_set_input'] = {
init: function () {
this.jsonInit(ugjGpioClaimInputDefinition);
this.jsonInit(ugjGpioSetInputDefinition);
}
};
Blockly.JavaScript['ugj_gpio_claim_input'] = function (block) {
Blockly.JavaScript['ugj_gpio_set_input'] = function (block) {
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
var dropdown_lflag = block.getFieldValue('lflag');
var code = `pi.gpio_claim_input(${value_gpio}, ${dropdown_lflag});\n`;
var code = `pi.gpio_set_input(${value_gpio}, ${dropdown_lflag});\n`;
return code;
};
Blockly.Python['ugj_gpio_claim_input'] = function (block) {
Blockly.Python['ugj_gpio_set_input'] = function (block) {
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
var dropdown_lflag = block.getFieldValue('lflag');
var code = `pi.gpio_claim_input(lgHand, ${value_gpio}, ${dropdown_lflag})\n`;
var code = `pi.gpio_set_input(gpioHand, ${value_gpio}, ${dropdown_lflag})\n`;
return code;
};
@ -467,12 +464,12 @@ Blockly.Blocks['ugj_gpio_read'] = {
};
Blockly.JavaScript['ugj_gpio_read'] = function (block) {
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
var code = `pi.gpio_read(lgHand, ${value_gpio})`;
var code = `pi.gpio_read(${value_gpio})`;
return [code, Blockly.JavaScript.ORDER_NONE];
};
Blockly.Python['ugj_gpio_read'] = function (block) {
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
var code = `pi.gpio_read(lgHand, ${value_gpio})`;
var code = `pi.gpio_read(gpioHand, ${value_gpio})`;
return [code, Blockly.Python.ORDER_NONE];
};
@ -524,16 +521,16 @@ Blockly.JavaScript['ugj_gpio_write'] = function (block) {
Blockly.Python['ugj_gpio_write'] = function (block) {
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
var dropdown_level = block.getFieldValue('level');
var code = `pi.gpio_write(lgHand, ${value_gpio}, ${dropdown_level})\n`;
var code = `pi.gpio_write(gpioHand, ${value_gpio}, ${dropdown_level})\n`;
return code;
};
/*****************/
/** Servo motor **/
/*****************/
var ugjTxServoDefinition = {
"type": "ugj_tx_servo",
"message0": "%{BKY_TX_SERVO_TITLE}",
var ugjServoDefinition = {
"type": "ugj_servo",
"message0": "%{BKY_SERVO_TITLE}",
"args0": [
{
"type": "input_value",
@ -549,34 +546,34 @@ var ugjTxServoDefinition = {
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"tooltip": "%{BKY_TX_SERVO_TOOLTIP}",
"tooltip": "%{BKY_SERVO_TOOLTIP}",
"helpUrl": "",
"style": "gpio_blocks"
};
Blockly.Blocks['ugj_tx_servo'] = {
Blockly.Blocks['ugj_servo'] = {
init: function () {
this.jsonInit(ugjTxServoDefinition);
this.jsonInit(ugjServoDefinition);
}
};
Blockly.JavaScript['ugj_tx_servo'] = function (block) {
Blockly.JavaScript['ugj_servo'] = function (block) {
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
var value_pulsewidth = Blockly.JavaScript.valueToCode(block, 'pulsewidth', Blockly.JavaScript.ORDER_ATOMIC);
var code = `pi.tx_servo(lgHand, ${value_gpio}, ${value_pulsewidth});\n`;
var code = `pi.servo(${value_gpio}, ${value_pulsewidth});\n`;
return code;
};
Blockly.Python['ugj_tx_servo'] = function (block) {
Blockly.Python['ugj_servo'] = function (block) {
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
var value_pulsewidth = Blockly.Python.valueToCode(block, 'pulsewidth', Blockly.Python.ORDER_ATOMIC);
var code = `pi.tx_servo(lgHand, ${value_gpio}, ${value_pulsewidth})\n`;
var code = `pi.servo(gpioHand, ${value_gpio}, ${value_pulsewidth})\n`;
return code;
};
/************************************************* */
/** starts software timed PWM on an output GPIO ** */
/************************************************* */
var ugjTxPwmDefinition = {
"type": "ugj_tx_pwm",
"message0": "%{BKY_TX_PWM_TITLE}",
var ugjPwmDefinition = {
"type": "ugj_pwm",
"message0": "%{BKY_PWM_TITLE}",
"args0": [
{
"type": "input_value",
@ -597,27 +594,27 @@ var ugjTxPwmDefinition = {
"inputsInline": true,
"previousStatement": null,
"nextStatement": null,
"tooltip": "%{BKY_TX_PWM_TOOLTIP}",
"tooltip": "%{BKY_PWM_TOOLTIP}",
"helpUrl": "",
"style": "gpio_blocks"
};
Blockly.Blocks['ugj_tx_pwm'] = {
Blockly.Blocks['ugj_pwm'] = {
init: function () {
this.jsonInit(ugjTxPwmDefinition);
this.jsonInit(ugjPwmDefinition);
}
};
Blockly.JavaScript['ugj_tx_pwm'] = function (block) {
Blockly.JavaScript['ugj_pwm'] = function (block) {
var value_gpio = Blockly.JavaScript.valueToCode(block, 'gpio', Blockly.JavaScript.ORDER_ATOMIC);
var value_pwm_frequency = Blockly.JavaScript.valueToCode(block, 'pwm_frequency', Blockly.JavaScript.ORDER_ATOMIC);
var value_pwm_duty_cycle = Blockly.JavaScript.valueToCode(block, 'pwm_duty_cycle', Blockly.JavaScript.ORDER_ATOMIC);
var code = `pi.tx_pwm(lgHand, ${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle});\n`;
var code = `pi.pwm(${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle});\n`;
return code;
};
Blockly.Python['ugj_tx_pwm'] = function (block) {
Blockly.Python['ugj_pwm'] = function (block) {
var value_gpio = Blockly.Python.valueToCode(block, 'gpio', Blockly.Python.ORDER_ATOMIC);
var value_pwm_frequency = Blockly.Python.valueToCode(block, 'pwm_frequency', Blockly.Python.ORDER_ATOMIC);
var value_pwm_duty_cycle = Blockly.Python.valueToCode(block, 'pwm_duty_cycle', Blockly.Python.ORDER_ATOMIC);
var code = `pi.tx_pwm(lgHand, ${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle})\n`;
var code = `pi.pwm(gpioHand, ${value_gpio}, ${value_pwm_frequency}, ${value_pwm_duty_cycle})\n`;
return code;
};
/********************** */
@ -809,7 +806,7 @@ Blockly.JavaScript['ugj_i2c_open'] = function (block) {
Blockly.JavaScript.provideFunction_(
'require_oclg', [`const pi = require('@ocogeclub/lgpio');`]
);
var code = `pi.i2c_open(1, ${value_i2c_address});\n`;
var code = `pi.i2c_open(3, ${value_i2c_address});\n`;
return code;
};
Blockly.Python['ugj_i2c_open'] = function (block) {
@ -1046,7 +1043,7 @@ Blockly.JavaScript['ugj_bme280'] = function (block) {
);
var code = [
`const options = {`,
` i2cBusNo: 1,`,
` i2cBusNo: 3,`,
` i2cAddress: ${value_address}`,
`};`,
`bme280.init(options);`,
@ -1081,110 +1078,6 @@ Blockly.Python['ugj_bme280'] = function (block) {
/** Multimedia *****************************************************************************************************/
/******************* */
/** TensorFlow.js ** */
/******************* */
Blockly.Blocks['ugj_library_tensorflow'] = {
init: function () {
this.appendDummyInput()
.appendField("TensorFlowによる画像認識推論");
this.setOutput(true, "Library");
this.setStyle('special_blocks')
this.setTooltip("tensorflow.jsをロードし、推論ができるようにします。");
this.setHelpUrl("");
}
};
Blockly.JavaScript['ugj_library_tensorflow'] = function (block) {
var code = `'${ugj_const.library_path}tensorflow.min.js'`;
return [code, Blockly.JavaScript.ORDER_NONE];
};
/********************** */
/** Object Detection ** */
/********************** */
Blockly.Blocks['ugj_tfpredict_init'] = {
init: function () {
this.appendDummyInput()
.appendField("画像認識のビデオを表示");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setStyle('multimedia_blocks')
this.setTooltip("画像認識(推論)をするためのビデオストリームを表示します。");
this.setHelpUrl("");
}
};
Blockly.JavaScript['ugj_tfpredict_init'] = function (block) {
var code = [
`const video = document.getElementById('subdisplay');`,
`video.style.display = 'inline-block';`,
`const overlay = document.createElement('canvas');`,
`overlay.setAttribute('width', video.width);`,
`overlay.setAttribute('height', video.height);`,
"const context = overlay.getContext('2d');",
"const stream = await navigator.mediaDevices.getUserMedia({ video: {} });",
"video.srcObject = stream;",
""
].join('\n');
return code;
};
Blockly.Blocks['ugj_tfpredict_loadmodel'] = {
init: function () {
this.appendDummyInput()
.appendField("学習済みの指数えモデル (sign_language_vgg16) を読み込む");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setStyle('multimedia_blocks')
this.setTooltip("ardamavi氏による指数え画像データセットをPonDad氏がts.js用モデルにコンバートしたものです。");
this.setHelpUrl("https://github.com/PonDad/manatee");
}
};
Blockly.JavaScript['ugj_tfpredict_loadmodel'] = function (block) {
var code = [
`const model = await tf.loadModel('${ugj_const.library_path}sign_language_vgg16/model.json');`,
"const CLASSES = {0:'zero', 1:'one', 2:'two', 3:'three', 4:'four',5:'five', 6:'six', 7:'seven', 8:'eight', 9:'nine'};",
""
].join('\n');
return code;
};
Blockly.Blocks['ugj_tfpredict_predict'] = {
init: function () {
this.appendDummyInput()
.appendField("推論をして")
.appendField(new Blockly.FieldVariable("結果"), "result")
.appendField("を取得する");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setStyle('multimedia_blocks')
this.setTooltip("読み込んだモデルを使用してカメラ画像から画像認識を行い、変数に代入します。");
this.setHelpUrl("");
}
};
Blockly.JavaScript['ugj_tfpredict_predict'] = function (block) {
var variable_result = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('result'), Blockly.Variables.NAME_TYPE);
var code = [
"context.drawImage(video, 0, 0, video.width, video.height);",
"let tensor = tf.fromPixels(canvas).resizeNearestNeighbor([100,100]).toFloat();",
"tensor = tensor.div(tf.scalar(255)).expandDims();",
"let prediction = await model.predict(tensor).data();",
"let results = Array.from(prediction).map(function(p,i){",
" return {",
" probability: p,",
" className: CLASSES[i]",
" };",
"}).sort(function(a,b){",
" return b.probability-a.probability;",
"}).slice(0,5);",
"let r = '';",
"results.forEach(function(p){",
" r += `${p.className}:${p.probability.toFixed(6)},`;",
"});",
`${variable_result} = r;`,
""
].join('\n');
return code;
};
/******************** */
/** Face Detection ** */
@ -1707,73 +1600,6 @@ Blockly.JavaScript['ugj_sound_play'] = function (block) {
return code;
};
/*************************** */
/** Web Speech Recognization */
/*************************** */
Blockly.Blocks['ugj_multimedia_webspeech_recognition'] = {
init: function () {
this.appendDummyInput()
.appendField("音声認識で")
.appendField(new Blockly.FieldVariable("ことば"), "transcript")
.appendField("を取得する:")
.appendField(new Blockly.FieldDropdown([["一回のみ", "once"], ["継続", "continue"]]), "continuous")
.appendField(new Blockly.FieldCheckbox("TRUE"), "interim")
.appendField("未確定も取得");
this.appendStatementInput("isFinal_do")
.setCheck(null)
.appendField("確定したら");
this.appendStatementInput("isInterim_do")
.setCheck(null)
.appendField("未確定なら");
this.appendStatementInput("onStart_do")
.setCheck(null)
.appendField("開始したら");
this.appendStatementInput("onError_do")
.setCheck(null)
.appendField("停止したら");
this.setInputsInline(true);
this.setPreviousStatement(true);
this.setStyle('multimedia_blocks')
this.setTooltip("Web Speech API による音声認識を行います。言葉を検知したらステートメントが実行されます。認識途中の暫定結果を取得することもできます。※Web版のみの機能です。");
this.setHelpUrl("");
}
};
Blockly.JavaScript['ugj_multimedia_webspeech_recognition'] = function (block) {
var variable_transcript = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('transcript'), Blockly.Variables.NAME_TYPE);
var dropdown_continuous = block.getFieldValue('continuous');
var checkbox_interim = block.getFieldValue('interim') == 'TRUE';
var statements_isfinal_do = Blockly.JavaScript.statementToCode(block, 'isFinal_do');
var statements_isinterim_do = Blockly.JavaScript.statementToCode(block, 'isInterim_do');
var statements_onStart_do = Blockly.JavaScript.statementToCode(block, 'onStart_do');
var statements_onEnd_do = Blockly.JavaScript.statementToCode(block, 'onError_do');
var code = [
`SpeechRecognition = webkitSpeechRecognition;`,
`let recognizer = new SpeechRecognition();`,
`recognizer.lang = 'ja-JP';`
].join('\n');
if (dropdown_continuous == 'continue') code += 'recognizer.continuous = true;\n';
if (checkbox_interim == true) code += 'recognizer.interimResults = true;\n';
code += [
`recognizer.onresult = (event) => {`,
`let result = event.results[event.resultIndex];`,
`${variable_transcript} = result[0].transcript;`,
`if (result.isFinal) {`,
statements_isfinal_do,
`} else {`,
statements_isinterim_do,
`}`,
`}`,
`recognizer.onstart = () => {`,
statements_onStart_do,
`}`,
`recognizer.onend = () => {`,
statements_onEnd_do,
`}`,
`recognizer.start();`,
''
].join('\n');
return code;
};
@ -3168,183 +2994,3 @@ Blockly.JavaScript['ugj_control_button'] = function (block) {
return code;
};
/** Unused Blocks **********************************************************************************************/
/** Junk: ごみ置き場 廃止になったブロックを、必要なワークスペースの修正が完了するまで保持します。 *********************/
Blockly.Blocks['ugj_gpio_startstop'] = {
init: function () {
this.appendDummyInput()
.appendField("dummy");
this.appendStatementInput("do")
.setCheck(null);
this.setColour(230);
this.setTooltip("");
this.setHelpUrl("");
}
};
Blockly.JavaScript['ugj_gpio_startstop'] = function (block) {
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
// TODO: Assemble JavaScript into code variable.
var code = '...;\n';
return code;
};
/************ */
/** Fetch API */
/************ */
Blockly.Blocks['ugj_network_fetch'] = {
init: function () {
this.appendValueInput("url")
.setCheck(null);
this.appendDummyInput()
.appendField("にリクエストを送信し、")
.appendField(new Blockly.FieldVariable("レスポンス"), "response")
.appendField("を取得する");
this.appendStatementInput("do")
.setCheck(null);
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setStyle('network_blocks')
this.setTooltip("");
this.setHelpUrl("");
}
};
Blockly.JavaScript['ugj_network_fetch'] = function (block) {
var value_url = Blockly.JavaScript.valueToCode(block, 'url', Blockly.JavaScript.ORDER_ATOMIC);
var variable_response = Blockly.JavaScript.nameDB_.getName(block.getFieldValue('response'), Blockly.Variables.NAME_TYPE);
var statements_do = Blockly.JavaScript.statementToCode(block, 'do'); var code = [
`fetch(${value_url})`,
` .then(response => {`,
` if (response.ok) {`,
` return response.text();`,
` } else {`,
` return 'HTTP Status: ' + response.status;`,
` }`,
` })`,
` .then(body => {`,
` ${variable_response} = body;`,
statements_do,
` });`,
''
].join('\n');
return code;
};
/********************* */
/** Print to Blackboard **/
/********************* */
Blockly.Blocks['ugj_texts_print'] = {
init: function () {
this.appendValueInput("text")
.setCheck(null)
this.appendDummyInput()
.appendField("を表示");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(0);
this.setTooltip("テキストや数字などを黒板に表示します。");
this.setHelpUrl("");
}
};
Blockly.JavaScript['ugj_texts_print'] = function (block) {
var value_text = Blockly.JavaScript.valueToCode(block, 'text', Blockly.JavaScript.ORDER_ATOMIC);
var code = `ugj_blackboardWrite(${value_text});\n`;
return code;
};
/************************************** */
/** Print Colorized Text to Blackboard ** */
/************************************** */
Blockly.Blocks['ugj_text_printcolored'] = {
init: function () {
this.appendValueInput("text")
.setCheck(null)
.appendField("黒板に");
this.appendValueInput("color")
.setCheck("Colour")
.appendField("を");
this.appendDummyInput()
.appendField("色で表示");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(0);
this.setTooltip("テキストや数字などを黒板に色付きで表示します。");
this.setHelpUrl("");
}
};
Blockly.JavaScript['ugj_text_printcolored'] = function (block) {
var value_text = Blockly.JavaScript.valueToCode(block, 'text', Blockly.JavaScript.ORDER_ATOMIC);
var value_color = Blockly.JavaScript.valueToCode(block, 'color', Blockly.JavaScript.ORDER_ATOMIC);
var code = `ugj_blackboardWrite(${value_text}, ${value_color});\n`;
return code;
};
/******************************** */
/** Open and Close Serial Port ** */
/******************************** */
Blockly.Blocks['ugj_serial_openclose'] = {
init: function () {
this.appendValueInput("tty")
.setCheck("String")
.appendField("シリアルポート");
this.appendDummyInput()
.appendField("を速度")
.appendField(new Blockly.FieldDropdown([["9600", "9600"], ["19200", "19200"], ["115200", "115200"]]), "baud")
.appendField("bpsで開く");
this.appendStatementInput("do")
.setCheck(null);
this.appendDummyInput()
.appendField("終わったらシリアルポートを閉じる");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setStyle('gpio_blocks')
this.setTooltip("シリアルデバイスとの接続を開き、用事が終わったら閉じます。");
this.setHelpUrl("");
}
};
Blockly.JavaScript['ugj_serial_openclose'] = function (block) {
var value_tty = Blockly.JavaScript.valueToCode(block, 'tty', Blockly.JavaScript.ORDER_ATOMIC);
var dropdown_baud = block.getFieldValue('baud');
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
// TODO: Assemble JavaScript into code variable.
var code = [
`let serhand = pi.serial_open(${value_tty}, ${dropdown_baud}, 0);`,
statements_do,
'pi.serial_close(serhand);',
""
].join('\n');
return code;
};
Blockly.Blocks['ugj_gpio_i2copenclose'] = {
init: function () {
this.appendValueInput("i2c_addr")
.setCheck("String")
.appendField("アドレス");
this.appendDummyInput()
.appendField("の I2C デバイスを開く");
this.appendStatementInput("do")
.setCheck(null);
this.appendDummyInput()
.appendField("デバイスを閉じる");
this.setInputsInline(true);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(230);
this.setTooltip("I2C接続されたデバイスと通信を行います。");
this.setHelpUrl("");
}
};
Blockly.JavaScript['ugj_gpio_i2copenclose'] = function (block) {
var value_i2c_addr = Blockly.JavaScript.valueToCode(block, 'i2c_addr', Blockly.JavaScript.ORDER_ATOMIC);
var statements_do = Blockly.JavaScript.statementToCode(block, 'do');
// TODO: Assemble JavaScript into code variable.
var code = statements_do;
return code;
};

View File

@ -64,7 +64,7 @@
"@ocogeclub/bme280@file:local_modules/@ocogeclub/bme280":
version "0.0.1"
dependencies:
"@ocogeclub/lgpio" "file:../../.cache/yarn/v6/npm-@ocogeclub-bme280-0.0.1-d80e5826-f0f4-4db3-adae-fdd6a16c00e5-1632630994968/node_modules/@ocogeclub/lgpio"
"@ocogeclub/lgpio" "file:../../.cache/yarn/v6/npm-@ocogeclub-bme280-0.0.1-a3a7781d-d04c-4890-9c31-c037b0309492-1633696738699/node_modules/@ocogeclub/lgpio"
"@ocogeclub/lgpio@file:local_modules/@ocogeclub/lgpio":
version "0.0.1"
@ -72,6 +72,12 @@
bindings "^1.5.0"
node-addon-api "^1.7.1"
"@ocogeclub/pigpio@file:local_modules/@ocogeclub/pigpio":
version "0.0.1"
dependencies:
bindings "^1.5.0"
node-addon-api "^1.7.1"
"@sindresorhus/is@^0.14.0":
version "0.14.0"
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
@ -219,14 +225,14 @@
form-data "^3.0.0"
"@types/node@*":
version "16.9.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.9.6.tgz#040a64d7faf9e5d9e940357125f0963012e66f04"
integrity sha512-YHUZhBOMTM3mjFkXVcK+WwAcYmyhe1wL4lfqNtzI0b3qAy7yuSetnM7QJazgE5PFmgVTNGiLOgRFfJMqW7XpSQ==
version "16.10.3"
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.10.3.tgz#7a8f2838603ea314d1d22bb3171d899e15c57bd5"
integrity sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ==
"@types/node@^14.6.2":
version "14.17.18"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.18.tgz#0198489a751005f71217744aa966cd1f29447c81"
integrity sha512-haYyibw4pbteEhkSg0xdDLAI3679L75EJ799ymVrPxOA922bPx3ML59SoDsQ//rHlvqpu+e36kcbR3XRQtFblA==
version "14.17.21"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.21.tgz#6359d8cf73481e312a43886fa50afc70ce5592c6"
integrity sha512-zv8ukKci1mrILYiQOwGSV4FpkZhyxQtuFWGya2GujWg+zVAeRQ4qbaMmWp9vb9889CFA8JECH7lkwCL6Ygg8kA==
"@types/offscreencanvas@~2019.3.0":
version "2019.3.0"
@ -256,9 +262,9 @@
integrity sha512-oGaKsBbxQOY5+aJFV3KECDhGaXt+yZJt2y/OZsnQGLRkH6Fvr7rv4pCt3SRH1somIHfej/c4u7NSpCyd9x+1Ow==
"@vladmandic/face-api@^1.5.3":
version "1.5.3"
resolved "https://registry.yarnpkg.com/@vladmandic/face-api/-/face-api-1.5.3.tgz#517dc18535c537b2f3bb479874775ed4e6cf00ee"
integrity sha512-7u2GI/jeQg6ldGQItSHX/RM36Eic/Wpv14G8RVA3GBhOnkwP+JSfQpEUKtoAGYvvfX58jYy/AJcD2wMF9n24Iw==
version "1.5.4"
resolved "https://registry.yarnpkg.com/@vladmandic/face-api/-/face-api-1.5.4.tgz#1b3e6f0f5e4e79f7e876d5ae32703ec811952e76"
integrity sha512-c7JUioHosPfkDKpj6mciYCrksSokmGCuAInzG6nC94bD5PtxgWFoVHiZpgdmwgX6IIBuXWoJMA2S4IJi9SYbtw==
abbrev@1:
version "1.1.1"
@ -266,9 +272,9 @@ abbrev@1:
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
adm-zip@^0.5.2:
version "0.5.6"
resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.5.6.tgz#c540f4d62b0f07a716bce4c8a24545b1f0b33027"
integrity sha512-nUeYhBHLG08VFOkVwai0pLXge6NNlahH+ccwxXodvl+SLa5l9mXHjg40jRVzofRPz29goiTGze7vIKmCltKtSA==
version "0.5.9"
resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.5.9.tgz#b33691028333821c0cf95c31374c5462f2905a83"
integrity sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==
agent-base@6, agent-base@^6.0.2:
version "6.0.2"
@ -498,9 +504,9 @@ cli-cursor@^3.1.0:
restore-cursor "^3.1.0"
cli-spinners@^2.5.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939"
integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==
version "2.6.1"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d"
integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==
cliui@^7.0.2:
version "7.0.4"
@ -581,9 +587,9 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0:
integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
core-js@3, core-js@^3.6.5:
version "3.18.0"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.18.0.tgz#9af3f4a6df9ba3428a3fb1b171f1503b3f40cc49"
integrity sha512-WJeQqq6jOYgVgg4NrXKL0KLQhi0CT4ZOCvFL+3CQ5o7I6J8HkT5wd53EadMfqTDp1so/MT1J+w2ujhWcCJtN7w==
version "3.18.2"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.18.2.tgz#63a551e8a29f305cd4123754846e65896619ba5b"
integrity sha512-zNhPOUoSgoizoSQFdX1MeZO16ORRb9FFQLts8gSYbZU5FcgXhp24iMWMxnOQo5uIaIG7/6FA/IqJPwev1o9ZXQ==
core-util-is@~1.0.0:
version "1.0.3"
@ -926,9 +932,9 @@ globalthis@^1.0.1:
define-properties "^1.1.3"
google-protobuf@^3.9.2:
version "3.18.0"
resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.18.0.tgz#687449d8e858305d658dc1145852c306d8222f5a"
integrity sha512-WlaQWRkUOo/lm9uTgNH6nk9IQt814RggWPzKBfnAVewOFzSzRUSmS1yUWRT6ixW1vS7er5p6tmLSmwzpPpmc8A==
version "3.18.1"
resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.18.1.tgz#31de10b65e833aa5bbd44680e8a748fa54c920f6"
integrity sha512-cDqSamZ8rGs+pOzhIsBte7wpezUKg/sggeptDWN5odhnRY/eDLa5VWLeNeQvcfiqjS3yUwgM+6OePCJMB7aWZA==
got@^11.7.0:
version "11.8.2"
@ -1240,17 +1246,17 @@ matcher@^3.0.0:
dependencies:
escape-string-regexp "^4.0.0"
mime-db@1.49.0:
version "1.49.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.49.0.tgz#f3dfde60c99e9cf3bc9701d687778f537001cbed"
integrity sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==
mime-db@1.50.0:
version "1.50.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.50.0.tgz#abd4ac94e98d3c0e185016c67ab45d5fde40c11f"
integrity sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==
mime-types@^2.1.12:
version "2.1.32"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.32.tgz#1d00e89e7de7fe02008db61001d9e02852670fd5"
integrity sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==
version "2.1.33"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.33.tgz#1fa12a904472fafd068e48d9e8401f74d3f70edb"
integrity sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==
dependencies:
mime-db "1.49.0"
mime-db "1.50.0"
mimic-fn@^2.1.0:
version "2.1.0"
@ -1751,9 +1757,9 @@ shebang-regex@^3.0.0:
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.4"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.4.tgz#366a4684d175b9cab2081e3681fda3747b6c51d7"
integrity sha512-rqYhcAnZ6d/vTPGghdrw7iumdcbXpsk1b8IG/rz+VWV51DM0p7XCtMoJ3qhPLIbp3tvyt3pKRbaaEMZYpHto8Q==
version "3.0.5"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f"
integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==
smart-buffer@^4.1.0:
version "4.2.0"
@ -2037,9 +2043,9 @@ yargs@^16.0.3:
yargs-parser "^20.2.2"
yargs@^17.0.1:
version "17.2.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.2.0.tgz#ec529632b2cb9044f3927f4b45f9cc4ae2535653"
integrity sha512-UPeZv4h9Xv510ibpt5rdsUNzgD78nMa1rhxxCgvkKiq06hlKCEHJLiJ6Ub8zDg/wR6hedEI6ovnd2vCvJ4nusA==
version "17.2.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.2.1.tgz#e2c95b9796a0e1f7f3bf4427863b42e0418191ea"
integrity sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q==
dependencies:
cliui "^7.0.2"
escalade "^3.1.1"