mirror of
https://github.com/ocogeclub/ocoge.git
synced 2024-11-24 00:19:48 +00:00
Orange Pi 5 + rgpio で GPIO や I2C の一部動作を確認
This commit is contained in:
parent
af9749333b
commit
7a2997c35a
35
apptool.js
35
apptool.js
@ -14,7 +14,7 @@ const ugj_const = {
|
||||
localStorage_fname: 'ocoge.json',
|
||||
error_ja_all: 'エラーが発生しました。\n『おこげ倶楽部』までお問い合わせください。',
|
||||
pig: 'pigpio',
|
||||
lg: 'lgpio', // 対応未定
|
||||
rg: 'rgpio',
|
||||
i2c_defbus: '1', // 文字列リテラルで指定
|
||||
lang: 'js',
|
||||
dev_hash: '4e9205f9b7e571bec1aa52ab7871f420684fcf96149672a4d550a95863d6b072'
|
||||
@ -31,7 +31,7 @@ class appTool {
|
||||
this.saveFilepath = null;
|
||||
this.wsChanged = false;
|
||||
this.children = [];
|
||||
this.gpio_backend = ugj_const.pig;
|
||||
this.gpio_lib = ugj_const.pig;
|
||||
this.i2c_bus = ugj_const.i2c_defbus;
|
||||
this.lang = ugj_const.lang;
|
||||
this.doc_root = this.path.join(process.env["HOME"], ugj_const.document_root);
|
||||
@ -207,7 +207,7 @@ class appTool {
|
||||
// GPIO 関連:リロードでGPIOをロックしたままハンドルを失うのを防ぐ
|
||||
cleanupGPIO() {
|
||||
// this.ugjEmitter.emit('device_stop');//デバイス停止イベント
|
||||
require('@ocoge.club/' + this.gpio_backend).close_all_handle();
|
||||
require('@ocoge.club/' + this.gpio_lib).close_all_handle();
|
||||
}
|
||||
|
||||
// 設定(保存ファイルパスと未保存フラグ)をローカルストレージに保存
|
||||
@ -221,7 +221,8 @@ class appTool {
|
||||
'mascotFilePath': this.mascotFilePath,
|
||||
'doc_current': this.doc_current,
|
||||
'i2c_bus': this.i2c_bus,
|
||||
'lang': this.lang
|
||||
'lang': this.lang,
|
||||
'gpio_lib': this.gpio_lib
|
||||
};
|
||||
let s = JSON.stringify(o);
|
||||
localStorage.setItem(ugj_const.localStorage_fname, s);
|
||||
@ -242,8 +243,15 @@ class appTool {
|
||||
this.ipcRenderer.send('i2c_check_menu', 'i2c-' + this.i2c_bus);
|
||||
}
|
||||
if (o.lang) {
|
||||
this.setLang(o.lang);
|
||||
this.ipcRenderer.send('lang_check_menu', this.lang);
|
||||
let l;
|
||||
if (o.lang == 'js' || o.gpio_lib) {
|
||||
l = o.lang + '-' + o.gpio_lib;
|
||||
} else {
|
||||
l = o.lang;
|
||||
}
|
||||
this.setLang(l);
|
||||
console.log(`l= ${l}`);
|
||||
this.ipcRenderer.send('lang_check_menu', l);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -261,11 +269,18 @@ class appTool {
|
||||
this.i2c_bus = n;
|
||||
}
|
||||
|
||||
// 言語変更
|
||||
// 言語/GPIOライブラリ変更
|
||||
setLang(l) {
|
||||
this.lang = l;
|
||||
if (l == 'js-pigpio') {
|
||||
this.lang = 'js';
|
||||
this.gpio_lib = ugj_const.pig;
|
||||
} else if (l == 'js-rgpio') {
|
||||
this.lang = 'js';
|
||||
this.gpio_lib = ugj_const.rg;
|
||||
} else this.lang = 'py';
|
||||
|
||||
const exp = document.getElementById('dlgExport');
|
||||
if (l == 'js') {
|
||||
if (this.lang == 'js') {
|
||||
exp.innerText = 'ファイルへ保存';
|
||||
exp.title = 'ソースコードをファイルに保存します。';
|
||||
} else {
|
||||
@ -300,7 +315,7 @@ class appTool {
|
||||
class webTool {
|
||||
constructor() {
|
||||
// GPIOブロックは使えません
|
||||
this.gpio_backend = ugj_const.pig;
|
||||
this.gpio_lib = ugj_const.pig;
|
||||
this.lang = 'js';
|
||||
this.blocks_dir = ugj_const.blocks_dir;
|
||||
}
|
||||
|
@ -185,7 +185,7 @@ Blockly.Blocks['ugj_gpio_open'] = {
|
||||
};
|
||||
Blockly.JavaScript['ugj_gpio_open'] = function (block) {
|
||||
Blockly.JavaScript.provideFunction_(
|
||||
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_backend + `');`]
|
||||
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
|
||||
);
|
||||
var code = `await _pi.gpio_open();\n`; //
|
||||
return code;
|
||||
@ -540,7 +540,7 @@ Blockly.JavaScript['ugj_serial_open'] = function (block) {
|
||||
// var value_tty = Blockly.JavaScript.valueToCode(block, 'tty', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
var dropdown_baud = block.getFieldValue('baud');
|
||||
Blockly.JavaScript.provideFunction_(
|
||||
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_backend + `');`]
|
||||
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
|
||||
);
|
||||
var code = `await _pi.serial_open('/dev/serial0', ${dropdown_baud});\n`;
|
||||
return code;
|
||||
@ -680,7 +680,7 @@ Blockly.Blocks['ugj_i2c_open'] = {
|
||||
Blockly.JavaScript['ugj_i2c_open'] = function (block) {
|
||||
var value_i2c_address = Blockly.JavaScript.valueToCode(block, 'i2c_address', Blockly.JavaScript.ORDER_ATOMIC);
|
||||
Blockly.JavaScript.provideFunction_(
|
||||
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_backend + `');`]
|
||||
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
|
||||
);
|
||||
var code = `await _pi.i2c_open(${apptool.i2c_bus}, ${value_i2c_address});\n`;
|
||||
return code;
|
||||
|
55
blocks/sensors/amg8833/AMG8833x_rgpio.js
Normal file
55
blocks/sensors/amg8833/AMG8833x_rgpio.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('@ocoge.club/rgpio');
|
||||
|
||||
let pi = -1;
|
||||
let i2c_hand = -1;
|
||||
exports.init = async (i2c_bus, i2c_addr, wael = null) => {
|
||||
if (wael !== null) {
|
||||
wael('beforeunload', async () => {
|
||||
await exports.stop();
|
||||
});
|
||||
}
|
||||
if (pi >= 0) { throw new Error(err_msg); return; }
|
||||
pi = await pig._rgpiod_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, 0);
|
||||
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._rgpiod_stop(pi);
|
||||
pi = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This code was ported from https://www.denshi.club/pc/raspi/5raspberry-pi-zeroiot381i2c-amg8833.html
|
||||
*/
|
@ -53,10 +53,10 @@ Blockly.defineBlocksWithJsonArray([{
|
||||
}]);
|
||||
Blockly.JavaScript['ugj_grideye_init'] = function (block) {
|
||||
var dropdown_addr = block.getFieldValue('addr');
|
||||
Blockly.JavaScript.provideFunction_(
|
||||
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_backend + `');`]
|
||||
);
|
||||
let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'amg8833', 'AMG8833x.js');
|
||||
// Blockly.JavaScript.provideFunction_(
|
||||
// 'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
|
||||
// );
|
||||
let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'amg8833', `AMG8833x_${apptool.gpio_lib}.js`);
|
||||
Blockly.JavaScript.provideFunction_(
|
||||
'require_amg8833', [`const _amg8833 = require('${modpath}');`]
|
||||
);
|
||||
|
@ -18,7 +18,7 @@ Blockly.Blocks['ugj_bme280'] = {
|
||||
Blockly.JavaScript['ugj_bme280'] = function (block) {
|
||||
var dropdown_addr = block.getFieldValue('addr');
|
||||
Blockly.JavaScript.provideFunction_(
|
||||
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_backend + `');`]
|
||||
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
|
||||
);
|
||||
let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'bme280', 'BME280x.js');
|
||||
Blockly.JavaScript.provideFunction_(
|
||||
|
@ -33,7 +33,7 @@ Blockly.Blocks['ugj_gesture_init'] = {
|
||||
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('@ocoge.club/` + apptool.gpio_backend + `');`]
|
||||
'require_gpio', [`const _pi = require('@ocoge.club/` + apptool.gpio_lib + `');`]
|
||||
);
|
||||
let modpath = apptool.path.join(apptool.blocks_dir, 'sensors', 'paj7620', 'PAJ7620x.js');
|
||||
Blockly.JavaScript.provideFunction_(
|
||||
|
12
local_modules/rgpio/binding.gyp
Normal file
12
local_modules/rgpio/binding.gyp
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"targets": [
|
||||
{
|
||||
"target_name": "rgpio",
|
||||
"sources": ["rgpio.cpp"],
|
||||
"defines": ["NAPI_DISABLE_CPP_EXCEPTIONS"],
|
||||
"include_dirs": ["<!@(node -p \"require( 'node-addon-api' ).include\")"],
|
||||
"dependencies": ["<!(node -p \"require('node-addon-api').gyp\")"],
|
||||
"libraries": ["-lrgpio"],
|
||||
}
|
||||
]
|
||||
}
|
70
local_modules/rgpio/index.js
Normal file
70
local_modules/rgpio/index.js
Normal file
@ -0,0 +1,70 @@
|
||||
module.exports = require('bindings')('rgpio');
|
||||
|
||||
// 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;
|
||||
|
||||
const CHIP_COUNT = 5;
|
||||
const port = '';
|
||||
|
||||
let sbc = -1;
|
||||
let gpiochip_hand = [];
|
||||
let ser_hand = -1;
|
||||
let i2c_hand = -1;
|
||||
module.exports.gpio_open = async () => {
|
||||
sbc = await module.exports._rgpiod_start('', port);
|
||||
if (sbc < 0) return sbc;
|
||||
for (let i = 0; i < CHIP_COUNT; i++) {
|
||||
gpiochip_hand.push(await module.exports._gpiochip_open(sbc, i));
|
||||
}
|
||||
return gpiochip_hand;
|
||||
}
|
||||
module.exports.gpio_close = async () => {
|
||||
for (let i = 0; i < CHIP_COUNT; i++) {
|
||||
await module.exports._gpiochip_close(sbc, gpiochip_hand[i]);
|
||||
}
|
||||
gpiochip_hand = [];
|
||||
await module.exports._rgpiod_stop(sbc);
|
||||
sbc = -1;
|
||||
}
|
||||
module.exports.gpio_set_output = async gpio => {
|
||||
let chip = Math.floor(gpio / 32);
|
||||
let pin = Math.floor(gpio % 32);
|
||||
if (gpiochip_hand[chip] >= 0) return await module.exports._gpio_claim_output(sbc, gpiochip_hand[chip], pin);
|
||||
}
|
||||
module.exports.gpio_write = async (gpio, value) => {
|
||||
let chip = Math.floor(gpio / 32);
|
||||
let pin = Math.floor(gpio % 32);
|
||||
if (gpiochip_hand[chip] >= 0) return await module.exports._gpio_write(sbc, gpiochip_hand[chip], pin, value);
|
||||
}
|
||||
module.exports.i2c_open = async (i2c_bus, i2c_address) => {
|
||||
if (i2c_hand >= 0) await module.exports._i2c_close(i2c_hand); // 勝手に閉じる
|
||||
i2c_hand = await module.exports._i2c_open(sbc, i2c_bus, i2c_address, 0);
|
||||
return i2c_hand;
|
||||
}
|
||||
module.exports.i2c_close = async () => {
|
||||
if (i2c_hand >= 0) await module.exports._i2c_close(sbc, i2c_hand);
|
||||
i2c_hand = -1;
|
||||
}
|
||||
module.exports.i2c_write_byte_data = async (reg, byte_val) => {
|
||||
if (i2c_hand >= 0) return await module.exports._i2c_write_byte_data(sbc, i2c_hand, reg, byte_val);
|
||||
}
|
||||
module.exports.i2c_write_i2c_block_data = async (reg, data) => {
|
||||
if (i2c_hand >= 0) return await module.exports._i2c_write_i2c_block_data(sbc, i2c_hand, reg, Buffer.from(data));
|
||||
}
|
||||
module.exports.i2c_read_word_data = async reg => {
|
||||
if (i2c_hand >= 0) return await module.exports._i2c_read_word_data(sbc, i2c_hand, reg);
|
||||
}
|
||||
|
||||
// 終了処理
|
||||
module.exports.close_all_handle = async () => {
|
||||
await module.exports.gpio_close();
|
||||
// await module.exports.serial_close();
|
||||
await module.exports.i2c_close();
|
||||
}
|
11
local_modules/rgpio/package.json
Normal file
11
local_modules/rgpio/package.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "@ocoge.club/rgpio",
|
||||
"version": "0.0.1",
|
||||
"main": "index.js",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bindings": "^1.5.0",
|
||||
"node-addon-api": "^1.7.1"
|
||||
}
|
||||
}
|
337
local_modules/rgpio/rgpio.cpp
Normal file
337
local_modules/rgpio/rgpio.cpp
Normal file
@ -0,0 +1,337 @@
|
||||
/** lgpio を Node.js から利用するモジュール ** */
|
||||
/** 関数名・書式は lgpio Python に準拠 ******************* */
|
||||
|
||||
#include <napi.h>
|
||||
#include <rgpio.h>
|
||||
#include <unistd.h>
|
||||
#include <string>
|
||||
|
||||
using namespace Napi;
|
||||
|
||||
// rgpio デーモンに接続
|
||||
Promise _rgpiodStart(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 2)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
if (!info[0].IsString() || !info[1].IsString())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string ipaddr = info[0].As<String>().Utf8Value();
|
||||
std::string port = info[1].As<String>().Utf8Value();
|
||||
deferred.Resolve(Number::New(env, rgpiod_start(ipaddr.c_str(), port.c_str())));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
// rgpioデーモンとの接続を閉じる
|
||||
Promise _rgpiodStop(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 1)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
if (!info[0].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
rgpiod_stop(sbc);
|
||||
deferred.Resolve(env.Null());
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// gpiochipデバイスを開く
|
||||
Promise _gpiochipOpen(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 2)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
if (!info[0].IsNumber() || !info[1].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
int gpioDev = info[1].As<Number>().Int32Value();
|
||||
deferred.Resolve(Number::New(env, gpiochip_open(sbc, gpioDev)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// gpiochipデバイスを閉じる
|
||||
Promise _gpiochipClose(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 2)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
if (!info[0].IsNumber() || !info[1].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
int handle = info[1].As<Number>().Int32Value();
|
||||
deferred.Resolve(Number::New(env, gpiochip_close(sbc, handle)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// GPIO のモードを出力にする(ことを要求?)
|
||||
Promise _gpioClaimOutput(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 3)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
int handle = info[1].As<Number>().Int32Value();
|
||||
int gpio = info[2].As<Number>().Int32Value();
|
||||
|
||||
deferred.Resolve(Number::New(env, gpio_claim_output(sbc, handle, 0, gpio, 0)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// GPIO のモードを入力にする(ことを要求?)
|
||||
// GPIOの電圧を読む
|
||||
|
||||
// GPIO の電圧をセットする
|
||||
Promise _gpioWrite(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 4)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
int handle = info[1].As<Number>().Int32Value();
|
||||
int gpio = info[2].As<Number>().Int32Value();
|
||||
int value = info[3].As<Number>().Int32Value();
|
||||
|
||||
deferred.Resolve(Number::New(env, gpio_write(sbc, handle, gpio, value)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// I2Cバスアドレスのデバイスのハンドルを返す
|
||||
Promise _i2cOpen(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 4)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
unsigned int i2c_bus = info[1].As<Number>().Uint32Value();
|
||||
unsigned int i2c_addr = info[2].As<Number>().Uint32Value();
|
||||
int flags = 0;
|
||||
deferred.Resolve(Number::New(env, i2c_open(sbc, i2c_bus, i2c_addr, flags)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
// オープン済みI2Cハンドルを閉じる
|
||||
Promise _i2cClose(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 2)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
unsigned int handle = info[1].As<Number>().Uint32Value();
|
||||
deferred.Resolve(Number::New(env, i2c_close(sbc, handle)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタに1バイトを書き込む
|
||||
Promise _i2cWriteByteData(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 4)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
unsigned int handle = info[1].As<Number>().Uint32Value();
|
||||
unsigned int i2c_reg = info[2].As<Number>().Uint32Value();
|
||||
unsigned int bVal = info[3].As<Number>().Uint32Value();
|
||||
deferred.Resolve(Number::New(env, i2c_write_byte_data(sbc, handle, i2c_reg, bVal)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタからcountバイトを読み込む。countは1~32。
|
||||
Promise _i2cReadI2cBlockData(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 4)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = 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(sbc, handle, i2cReg, buf, count);
|
||||
auto outBuf = Buffer<char>::Copy(env, buf, rxCount);
|
||||
deferred.Resolve(outBuf);
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタに最大32バイトのデータを書き込む。
|
||||
Promise _i2cWriteI2cBlockData(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 4)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber() || !info[3].IsBuffer())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
unsigned int handle = info[1].As<Number>().Uint32Value();
|
||||
unsigned int i2c_reg = info[2].As<Number>().Uint32Value();
|
||||
auto buf = info[3].As<Buffer<char>>();
|
||||
|
||||
unsigned int count = buf.Length();
|
||||
deferred.Resolve(Number::New(env, i2c_write_i2c_block_data(sbc, handle, i2c_reg, buf.Data(), count)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
// I2Cハンドルに関連付けられているデバイスの指定されたレジスタから単一の16ビットワードを読み取る
|
||||
Promise _i2cReadWordData(const CallbackInfo &info)
|
||||
{
|
||||
Env env = info.Env();
|
||||
auto deferred = Napi::Promise::Deferred::New(env);
|
||||
if (info.Length() != 3)
|
||||
{
|
||||
deferred.Reject(
|
||||
TypeError::New(env, "Invalid argument count").Value());
|
||||
}
|
||||
else if (!info[0].IsNumber() || !info[1].IsNumber() || !info[2].IsNumber())
|
||||
{
|
||||
deferred.Reject(
|
||||
Napi::TypeError::New(env, "Invalid argument types").Value());
|
||||
}
|
||||
else
|
||||
{
|
||||
int sbc = info[0].As<Number>().Int32Value();
|
||||
unsigned int handle = info[1].As<Number>().Uint32Value();
|
||||
unsigned int i2c_reg = info[2].As<Number>().Uint32Value();
|
||||
deferred.Resolve(Number::New(env, i2c_read_word_data(sbc, handle, i2c_reg)));
|
||||
}
|
||||
return deferred.Promise();
|
||||
}
|
||||
|
||||
Object
|
||||
Init(Env env, Object exports)
|
||||
{
|
||||
exports.Set(String::New(env, "_rgpiod_start"), Function::New(env, _rgpiodStart));
|
||||
exports.Set(String::New(env, "_rgpiod_stop"), Function::New(env, _rgpiodStop));
|
||||
exports.Set(String::New(env, "_gpiochip_open"), Function::New(env, _gpiochipOpen));
|
||||
exports.Set(String::New(env, "_gpiochip_close"), Function::New(env, _gpiochipClose));
|
||||
exports.Set(String::New(env, "_gpio_claim_output"), Function::New(env, _gpioClaimOutput));
|
||||
exports.Set(String::New(env, "_gpio_write"), Function::New(env, _gpioWrite));
|
||||
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_data"), Function::New(env, _i2cWriteByteData));
|
||||
exports.Set(String::New(env, "_i2c_read_i2c_block_data"), Function::New(env, _i2cReadI2cBlockData));
|
||||
exports.Set(String::New(env, "_i2c_write_i2c_block_data"), Function::New(env, _i2cWriteI2cBlockData));
|
||||
exports.Set(String::New(env, "_i2c_read_word_data"), Function::New(env, _i2cReadWordData));
|
||||
return exports;
|
||||
}
|
||||
|
||||
NODE_API_MODULE(rgpio, Init)
|
94
main.js
94
main.js
@ -53,14 +53,14 @@ function createWindow() {
|
||||
}
|
||||
|
||||
const toggleCheck_i2c = checked_id => {
|
||||
const menus = ['i2c-1', 'i2c-6'];
|
||||
const menus = ['i2c-1', 'i2c-5', 'i2c-6'];
|
||||
menus.forEach(id => {
|
||||
menu.getMenuItemById(id).checked = (id == checked_id);
|
||||
})
|
||||
|
||||
}
|
||||
const toggleCheck_lang = checked_id => {
|
||||
const menus = ['js', 'py'];
|
||||
const menus = ['js-pigpio', 'js-rgpio', 'py'];
|
||||
menus.forEach(id => {
|
||||
menu.getMenuItemById(id).checked = (id == checked_id);
|
||||
})
|
||||
@ -155,48 +155,32 @@ let template = [
|
||||
{
|
||||
label: "Settings",
|
||||
submenu: [
|
||||
{
|
||||
label: "i2c bus",
|
||||
submenu: [
|
||||
{
|
||||
label: "1",
|
||||
id: "i2c-1",
|
||||
type: 'checkbox',
|
||||
checked: true,
|
||||
click: (item, focusedWindow) => {
|
||||
if (focusedWindow) {
|
||||
toggleCheck_i2c("i2c-1");
|
||||
focusedWindow.webContents.executeJavaScript('apptool.setI2cbusNo("1")');
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "6",
|
||||
id: "i2c-6",
|
||||
type: 'checkbox',
|
||||
click: (item, focusedWindow) => {
|
||||
if (focusedWindow) {
|
||||
toggleCheck_i2c("i2c-6");
|
||||
focusedWindow.webContents.executeJavaScript('apptool.setI2cbusNo("6")');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
label: "Language",
|
||||
submenu: [
|
||||
{
|
||||
label: "JavaScript",
|
||||
id: "js",
|
||||
label: "JavaScript (pigpio)",
|
||||
id: "js-pigpio",
|
||||
type: 'checkbox',
|
||||
checked: true,
|
||||
click: (item, focusedWindow) => {
|
||||
if (focusedWindow) {
|
||||
// menu.getMenuItemById('py').checked = false;
|
||||
toggleCheck_lang("js");
|
||||
focusedWindow.webContents.executeJavaScript('apptool.setLang("js")');
|
||||
toggleCheck_lang("js-pigpio");
|
||||
focusedWindow.webContents.executeJavaScript('apptool.setLang("js-pigpio")');
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "JavaScript (rgpio)",
|
||||
id: "js-rgpio",
|
||||
type: 'checkbox',
|
||||
checked: true,
|
||||
click: (item, focusedWindow) => {
|
||||
if (focusedWindow) {
|
||||
// menu.getMenuItemById('py').checked = false;
|
||||
toggleCheck_lang("js-rgpio");
|
||||
focusedWindow.webContents.executeJavaScript('apptool.setLang("js-rgpio")');
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -215,6 +199,46 @@ let template = [
|
||||
|
||||
]
|
||||
|
||||
},
|
||||
{
|
||||
label: "i2c bus",
|
||||
submenu: [
|
||||
{
|
||||
label: "1",
|
||||
id: "i2c-1",
|
||||
type: 'checkbox',
|
||||
checked: true,
|
||||
click: (item, focusedWindow) => {
|
||||
if (focusedWindow) {
|
||||
toggleCheck_i2c("i2c-1");
|
||||
focusedWindow.webContents.executeJavaScript('apptool.setI2cbusNo("1")');
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "5",
|
||||
id: "i2c-5",
|
||||
type: 'checkbox',
|
||||
click: (item, focusedWindow) => {
|
||||
if (focusedWindow) {
|
||||
toggleCheck_i2c("i2c-5");
|
||||
focusedWindow.webContents.executeJavaScript('apptool.setI2cbusNo("5")');
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
label: "6",
|
||||
id: "i2c-6",
|
||||
type: 'checkbox',
|
||||
click: (item, focusedWindow) => {
|
||||
if (focusedWindow) {
|
||||
toggleCheck_i2c("i2c-6");
|
||||
focusedWindow.webContents.executeJavaScript('apptool.setI2cbusNo("6")');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
58
package-lock.json
generated
58
package-lock.json
generated
@ -1,16 +1,15 @@
|
||||
{
|
||||
"name": "ocoge",
|
||||
"version": "0.1.10",
|
||||
"version": "0.1.11",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ocoge",
|
||||
"version": "0.1.10",
|
||||
"version": "0.1.11",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@blockly/field-slider": "^4.0.12",
|
||||
"@ocoge.club/pigpio": "file:local_modules/pigpio",
|
||||
"@tensorflow-models/blazeface": "^0.0.7",
|
||||
"@tensorflow-models/knn-classifier": "^1.2.4",
|
||||
"@tensorflow-models/mobilenet": "^2.1.0",
|
||||
@ -29,6 +28,10 @@
|
||||
"@electron-forge/maker-deb": "^6.1.1",
|
||||
"@electron/rebuild": "^3.2.10",
|
||||
"electron": "^24.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@ocoge.club/pigpio": "file:local_modules/pigpio",
|
||||
"@ocoge.club/rgpio": "file:local_modules/rgpio"
|
||||
}
|
||||
},
|
||||
"node_modules/@blockly/field-slider": {
|
||||
@ -668,6 +671,7 @@
|
||||
"resolved": "file:local_modules/pigpio",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"bindings": "^1.5.0",
|
||||
"node-addon-api": "^1.7.1"
|
||||
@ -676,7 +680,25 @@
|
||||
"node_modules/@ocoge.club/pigpio/node_modules/node-addon-api": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
|
||||
"integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg=="
|
||||
"integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@ocoge.club/rgpio": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "file:local_modules/rgpio",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"bindings": "^1.5.0",
|
||||
"node-addon-api": "^1.7.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@ocoge.club/rgpio/node_modules/node-addon-api": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
|
||||
"integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@sindresorhus/is": {
|
||||
"version": "4.6.0",
|
||||
@ -1347,6 +1369,7 @@
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
|
||||
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"file-uri-to-path": "1.0.0"
|
||||
}
|
||||
@ -2741,7 +2764,8 @@
|
||||
"node_modules/file-uri-to-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
|
||||
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/filename-reserved-regex": {
|
||||
"version": "2.0.0",
|
||||
@ -6779,6 +6803,7 @@
|
||||
},
|
||||
"@ocoge.club/pigpio": {
|
||||
"version": "0.0.1",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"bindings": "^1.5.0",
|
||||
"node-addon-api": "^1.7.1"
|
||||
@ -6787,7 +6812,24 @@
|
||||
"node-addon-api": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
|
||||
"integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg=="
|
||||
"integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==",
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@ocoge.club/rgpio": {
|
||||
"version": "0.0.1",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"bindings": "^1.5.0",
|
||||
"node-addon-api": "^1.7.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"node-addon-api": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz",
|
||||
"integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==",
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -7320,6 +7362,7 @@
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
|
||||
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"file-uri-to-path": "1.0.0"
|
||||
}
|
||||
@ -8356,7 +8399,8 @@
|
||||
"file-uri-to-path": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
|
||||
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
|
||||
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
|
||||
"optional": true
|
||||
},
|
||||
"filename-reserved-regex": {
|
||||
"version": "2.0.0",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ocoge",
|
||||
"version": "0.1.10",
|
||||
"version": "0.1.11",
|
||||
"description": "ブロックベースビジュアルプログラム開発・実行環境",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
@ -29,7 +29,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@blockly/field-slider": "^4.0.12",
|
||||
"@ocoge.club/pigpio": "file:local_modules/pigpio",
|
||||
"@tensorflow-models/blazeface": "^0.0.7",
|
||||
"@tensorflow-models/knn-classifier": "^1.2.4",
|
||||
"@tensorflow-models/mobilenet": "^2.1.0",
|
||||
@ -43,6 +42,10 @@
|
||||
"nodemailer": "^6.9.1",
|
||||
"prismjs": "^1.29.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@ocoge.club/pigpio": "file:local_modules/pigpio",
|
||||
"@ocoge.club/rgpio": "file:local_modules/rgpio"
|
||||
},
|
||||
"config": {
|
||||
"forge": {
|
||||
"packagerConfig": {},
|
||||
|
Loading…
Reference in New Issue
Block a user