mirror of
https://github.com/chirimen-oh/node-web-i2c.git
synced 2025-01-18 16:08:06 +00:00
initial commit
This commit is contained in:
commit
3c030c7530
8 changed files with 295 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/node_modules/
|
26
README.md
Normal file
26
README.md
Normal file
|
@ -0,0 +1,26 @@
|
|||
# @notweb/i2c
|
||||
|
||||
I2C access with Node.js
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
const { requestI2CAccess } = require("@notweb/i2c");
|
||||
|
||||
const ADT7410_ADDR = 0x48;
|
||||
|
||||
async function main() {
|
||||
const i2cAccess = await requestI2CAccess();
|
||||
const port = gpioAccess.ports.get(1);
|
||||
const i2cSlave = await port.open(ADT7410_ADDR);
|
||||
const temperature =
|
||||
(((await i2cSlave.read8(0x00)) << 8) + (await i2cSlave.read8(0x01))) / 128;
|
||||
console.log(`Temperature: ${temperature} ℃`);
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
## Document
|
||||
|
||||
[Web I2C API](http://browserobo.github.io/WebI2C)
|
32
index.d.ts
vendored
Normal file
32
index.d.ts
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
declare type PortNumber = number;
|
||||
declare type PortName = string;
|
||||
declare type I2CSlaveAddress = number;
|
||||
export declare class I2CAccess {
|
||||
private readonly _ports;
|
||||
constructor(ports?: I2CPortMap);
|
||||
readonly ports: I2CPortMap;
|
||||
}
|
||||
/**
|
||||
* Different from Web GPIO API specification.
|
||||
*/
|
||||
export declare class I2CPortMap extends Map<PortNumber, I2CPort> {
|
||||
getByName(portName: PortName): I2CPort | undefined;
|
||||
}
|
||||
export declare class I2CPort {
|
||||
private readonly _portNumber;
|
||||
constructor(portNumber: PortNumber);
|
||||
readonly portNumber: number;
|
||||
readonly portName: string;
|
||||
open(slaveAddress: I2CSlaveAddress): Promise<I2CSlaveDevice>;
|
||||
}
|
||||
export interface I2CSlaveDevice {
|
||||
readonly slaveAddress: I2CSlaveAddress;
|
||||
read8(registerNumber: number): Promise<number>;
|
||||
read16(registerNumber: number): Promise<number>;
|
||||
write8(registerNumber: number, value: number): Promise<number>;
|
||||
write16(registerNumber: number, value: number): Promise<number>;
|
||||
}
|
||||
export declare class OperationError extends Error {
|
||||
}
|
||||
export declare function requestI2CAccess(): Promise<I2CAccess>;
|
||||
export {};
|
66
index.js
Normal file
66
index.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const i2c_bus_1 = require("i2c-bus");
|
||||
const I2CPortMapSizeMax = 32;
|
||||
const Uint16Max = 65535;
|
||||
function parseUint16(string) {
|
||||
const n = Number.parseInt(string, 10);
|
||||
if (0 <= n && n <= Uint16Max)
|
||||
return n;
|
||||
else
|
||||
throw new RangeError(`Must be between 0 and ${Uint16Max}.`);
|
||||
}
|
||||
class I2CAccess {
|
||||
constructor(ports) {
|
||||
this._ports = ports == null ? new I2CPortMap() : ports;
|
||||
}
|
||||
get ports() {
|
||||
return this._ports;
|
||||
}
|
||||
}
|
||||
exports.I2CAccess = I2CAccess;
|
||||
/**
|
||||
* Different from Web GPIO API specification.
|
||||
*/
|
||||
class I2CPortMap extends Map {
|
||||
getByName(portName) {
|
||||
const matches = /^i2c-(\d+)$/.exec(portName);
|
||||
return matches == null ? undefined : this.get(parseUint16(matches[1]));
|
||||
}
|
||||
}
|
||||
exports.I2CPortMap = I2CPortMap;
|
||||
class I2CPort {
|
||||
constructor(portNumber) {
|
||||
this._portNumber = parseUint16(portNumber.toString());
|
||||
}
|
||||
get portNumber() {
|
||||
return this._portNumber;
|
||||
}
|
||||
get portName() {
|
||||
return `i2c-${this.portNumber}`;
|
||||
}
|
||||
async open(slaveAddress) {
|
||||
const bus = await i2c_bus_1.openPromisified(this.portNumber).catch(error => {
|
||||
throw new OperationError(error);
|
||||
});
|
||||
return {
|
||||
slaveAddress,
|
||||
read8: cmd => bus.readByte(slaveAddress, cmd),
|
||||
read16: cmd => bus.readWord(slaveAddress, cmd),
|
||||
write8: (cmd, byte) => bus.writeByte(slaveAddress, cmd, byte),
|
||||
write16: (cmd, word) => bus.writeWord(slaveAddress, cmd, word)
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.I2CPort = I2CPort;
|
||||
class OperationError extends Error {
|
||||
}
|
||||
exports.OperationError = OperationError;
|
||||
async function requestI2CAccess() {
|
||||
const ports = new I2CPortMap([...Array(I2CPortMapSizeMax).keys()].map(portNumber => [
|
||||
portNumber,
|
||||
new I2CPort(portNumber)
|
||||
]));
|
||||
return new I2CAccess(ports);
|
||||
}
|
||||
exports.requestI2CAccess = requestI2CAccess;
|
90
index.ts
Normal file
90
index.ts
Normal file
|
@ -0,0 +1,90 @@
|
|||
import { openPromisified } from "i2c-bus";
|
||||
|
||||
const I2CPortMapSizeMax = 32;
|
||||
|
||||
const Uint16Max = 65535;
|
||||
|
||||
function parseUint16(string: string) {
|
||||
const n = Number.parseInt(string, 10);
|
||||
if (0 <= n && n <= Uint16Max) return n;
|
||||
else throw new RangeError(`Must be between 0 and ${Uint16Max}.`);
|
||||
}
|
||||
|
||||
type PortNumber = number;
|
||||
type PortName = string;
|
||||
|
||||
type I2CSlaveAddress = number;
|
||||
|
||||
export class I2CAccess {
|
||||
private readonly _ports: I2CPortMap;
|
||||
|
||||
constructor(ports?: I2CPortMap) {
|
||||
this._ports = ports == null ? new I2CPortMap() : ports;
|
||||
}
|
||||
|
||||
get ports() {
|
||||
return this._ports;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Different from Web GPIO API specification.
|
||||
*/
|
||||
export class I2CPortMap extends Map<PortNumber, I2CPort> {
|
||||
getByName(portName: PortName) {
|
||||
const matches = /^i2c-(\d+)$/.exec(portName);
|
||||
return matches == null ? undefined : this.get(parseUint16(matches[1]));
|
||||
}
|
||||
}
|
||||
|
||||
export class I2CPort {
|
||||
private readonly _portNumber: PortNumber;
|
||||
|
||||
constructor(portNumber: PortNumber) {
|
||||
this._portNumber = parseUint16(portNumber.toString());
|
||||
}
|
||||
|
||||
get portNumber() {
|
||||
return this._portNumber;
|
||||
}
|
||||
|
||||
get portName() {
|
||||
return `i2c-${this.portNumber}`;
|
||||
}
|
||||
|
||||
async open(slaveAddress: I2CSlaveAddress): Promise<I2CSlaveDevice> {
|
||||
const bus = await openPromisified(this.portNumber).catch(error => {
|
||||
throw new OperationError(error);
|
||||
});
|
||||
|
||||
return {
|
||||
slaveAddress,
|
||||
read8: cmd => bus.readByte(slaveAddress, cmd),
|
||||
read16: cmd => bus.readWord(slaveAddress, cmd),
|
||||
write8: (cmd, byte) => bus.writeByte(slaveAddress, cmd, byte),
|
||||
write16: (cmd, word) => bus.writeWord(slaveAddress, cmd, word)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface I2CSlaveDevice {
|
||||
readonly slaveAddress: I2CSlaveAddress;
|
||||
|
||||
read8(registerNumber: number): Promise<number>;
|
||||
read16(registerNumber: number): Promise<number>;
|
||||
write8(registerNumber: number, value: number): Promise<number>;
|
||||
write16(registerNumber: number, value: number): Promise<number>;
|
||||
}
|
||||
|
||||
export class OperationError extends Error {}
|
||||
|
||||
export async function requestI2CAccess(): Promise<I2CAccess> {
|
||||
const ports = new I2CPortMap(
|
||||
[...Array(I2CPortMapSizeMax).keys()].map(portNumber => [
|
||||
portNumber,
|
||||
new I2CPort(portNumber)
|
||||
])
|
||||
);
|
||||
|
||||
return new I2CAccess(ports);
|
||||
}
|
25
package.json
Normal file
25
package.json
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "@notweb/i2c",
|
||||
"version": "0.0.1",
|
||||
"description": "I2C access with Node.js",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/kou029w/notweb-i2c.git"
|
||||
},
|
||||
"author": "Kohei Watanabe <kou029w@gmail.com>",
|
||||
"license": "MIT",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"i2c-bus": "^5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^12.7.12",
|
||||
"typescript": "^3.6.4"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc"
|
||||
}
|
||||
}
|
17
tsconfig.json
Normal file
17
tsconfig.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"declaration": true,
|
||||
"noImplicitThis": true,
|
||||
"alwaysStrict": true,
|
||||
"strictBindCallApply": true,
|
||||
"strictNullChecks": true,
|
||||
"strictFunctionTypes": true,
|
||||
"strictPropertyInitialization": true,
|
||||
"noImplicitReturns": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true
|
||||
}
|
||||
}
|
38
yarn.lock
Normal file
38
yarn.lock
Normal file
|
@ -0,0 +1,38 @@
|
|||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@types/node@^12.7.12":
|
||||
version "12.7.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.12.tgz#7c6c571cc2f3f3ac4a59a5f2bd48f5bdbc8653cc"
|
||||
integrity sha512-KPYGmfD0/b1eXurQ59fXD1GBzhSQfz6/lKBxkaHX9dKTzjXbK68Zt7yGUxUsCS1jeTy/8aL+d9JEr+S54mpkWQ==
|
||||
|
||||
bindings@^1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df"
|
||||
integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==
|
||||
dependencies:
|
||||
file-uri-to-path "1.0.0"
|
||||
|
||||
file-uri-to-path@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
|
||||
integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==
|
||||
|
||||
i2c-bus@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/i2c-bus/-/i2c-bus-5.1.0.tgz#7d667d225c09017cf044f75fc593d5ea3e0f4ea6"
|
||||
integrity sha512-u/q1fuZ5xrG77y3uo1rAANycboXsRNjneN+6jXRNMT2yRNpanVkbAP+IArwgsPRCHaY/zKxw7x5G8Y2fSPNseA==
|
||||
dependencies:
|
||||
bindings "^1.5.0"
|
||||
nan "^2.14.0"
|
||||
|
||||
nan@^2.14.0:
|
||||
version "2.14.0"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
|
||||
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
|
||||
|
||||
typescript@^3.6.4:
|
||||
version "3.6.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.4.tgz#b18752bb3792bc1a0281335f7f6ebf1bbfc5b91d"
|
||||
integrity sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==
|
Loading…
Add table
Reference in a new issue