Skip to content

tetunori/p5.toio

Repository files navigation

p5.toio

build lint test docs code style: prettier Tested with Jest

Description

p5.toio is a library for controlling toio™Core Cube in p5.js environment.
A lot of APIs on toio™Core Cube can be used with just a simple step as below.
Beta-release(0.8.0) Now.

p5.toio consists of 2 classes P5tCube and P5tId.
P5tCube class supplies a lot of APIs and utilities enable us to control Cube easily.
Please refer to the P5tCube class interfaces from here.
P5tId class includes APIs and properties on toioIDs printed on toio™'s mats, cards, stickers.
See interfaces from here for P5tId.

Usage

Environment

Due to the dependency to WebBluetooth, this library works with the following environment.

  • OS: Windows, macOS, Android. iOS/iPadOS does not support(Please use Bluefy app instead).
  • Browser: Latest version of Google Chrome is highly recommended.

You can check & use immediately via OpenProcessing: p5.toio Basic Sample.

Import library

Just insert a sigle script after 2 dependent scripts p5.js and p5.sound.min.js in your <head>.

<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/addons/p5.sound.min.js"></script>

<!-- INSERT HERE -->
<script src="https://tetunori.github.io/p5.toio/dist/0.8.0/p5.toio.min.js"></script>

We can also use the non-minified code.

<script src="https://tetunori.github.io/p5.toio/dist/0.8.0/p5.toio.js"></script>

Use in your Sketch

Search and Connect to toio™Core Cube

Call P5tCube.connectNewP5tCube() and receive P5tCube instance in Promise as below.
This library depends on WebBluetooth so that this API must be called in a user-action function like mouseClicked() or keyPressed() etc.

const gCubes = [];

function mouseClicked() {
  P5tCube.connectNewP5tCube().then( cube => {
    // 'cube' is an instance of connected toio™Core Cube.
    // Now you can call any API!
    gCubes.push( cube );
  } );
}

OpenProcessing Sample: Turn Light On

Issue some APIs

Basically, please refer to the TypeDoc API references P5tCube and P5tId.
Some actual examples are listed below.

Example 1: Turn the light on

// Turn the light on with white
cube?.turnLightOn( 'white' );

OpenProcessing Sample: Turn Light On

Example 2: Play MIDI melody

// Play sequence C-D-E
cube?.playMelody( [ 
  { note: 0x3C, duration: 0x1E }, 
  { note: 0x3E, duration: 0x1E }, 
  { note: 0x40, duration: 0x1E } 
] );

OpenProcessing Sample: Play MIDI melody

Example 3: Interaction with mouse X.

// Keep on gazing at mouse point
for( const cube of connectedCubeArray ){
  const x = Math.floor(mouseX * 300 / windowWidth + 200);
  const y = 144;
  const speed = 115; 
  cube?.turnToXY( x, y, speed );
}

OpenProcessing Sample: Keep on gazing at mouse point

Example 4: Interaction with 2 Cubes.

4-1: Keep on gazing at the othre Cube
// Keep on gazing at the othre Cube
const speed = 115;
cubeP?.turnToCube( cubeQ, speed );

OpenProcessing Sample: Keep on gazing at the other Cube

4-2: Keep on chasing the othre Cube
// Keep on chasing the othre Cube
const moveType = P5tCube.moveTypeId.withoutBack;
const speed = 80;
cubeP?.moveToCube( cubeQ, speed, moveType );

OpenProcessing Sample: Keep on chasing the other Cube

Example 5: Get color from ColorTileMat.

// Set background color with touched colored tile on mat
const color = P5tId.ColorTileMat.getTileColor(cube?.x, cube?.y);
background( color );

OpenProcessing Sample: Change background color with touched mat color

Example 6: Random tile move on SimpleMat.

const targetMat = P5tId.SimpleTileMat;
// const targetMat = P5tId.ColorTileMat; // can apply for ColorTileMat

const columnRand = Math.floor( Math.random() * targetMat.matrixColumns);
const rowRand = Math.floor( Math.random() * targetMat.matrixRows);

// Move to random tile.
cube?.moveTo(targetMat.getTileCenter(rowRand, columnRand), 80);

OpenProcessing Sample: Move random tiles on TileMat
Press Space Key to move after connection.

Example 7: Move to start position on RingMat.

cubeP?.moveTo({
  x: P5tId.RingMat.startPointGreenSideX,
  y: P5tId.RingMat.startPointGreenSideY,
  angle: -Math.PI / 2,
  angleType: 0
}, 80);

cubeQ?.moveTo({
  x: P5tId.RingMat.startPointBlueSideX,
  y: P5tId.RingMat.startPointBlueSideY,
  angle: Math.PI / 2,
  angleType: 0
}, 80);

OpenProcessing Sample: Move to start position on RingMat.
Press Space Key to move after connection.

Event listning

This library supplies 2 methods addEventListener and definition of callback to recieve notification.

Example: addEventListner

// Button press event
const type = 'buttonpress';
cube?.addEventListener(type, ()=>{
  console.log(type);
});
// Posture change event
const type = 'sensorposturechange';
cube?.addEventListener(type, (posture)=>{
  console.log(type, posture);
});

p5.js Web Editor Sample: addEventListner

Example: Definition of callback

If you define callback functions as below, it will call when notified.

const cubePositionIdChanged = (info) => {
  console.log('cubePositionIdChanged!', info);
}

const cubeStandardIdChanged = (info) => {
  console.log('cubeStandardIdChanged!', info);
}

p5.js Web Editor Sample: Callback definition

Here are the all callback function name.

const onButtonPressed();
const onButtonReleased();
const onBatteryLevelChanged(batteryLevel: number);
const onFlatChanged(flat: boolean);
const onCollisionOccurred();
const onDoubleTapped();
const onPostureChanged(posture: string);
const onShakeLevelChanged(shakelevel: number);
const onPositionIdChanged(info: positionIdInfo);
const onStandardIdChanged(info: standardIdInfo);

Tips

Improve Performance

Use async function for calling cube API

Depending on your PC environment, performance of the API call or processing sketch visual might be poor.
In those cases, using async function might resolve the issue.

function draw() {
  // Cube control command with async
  asyncCubeControl();

  // Then code your sketch...
  ellipse( mouseX, mouseY, 20, 20 );
}

async function asyncCubeControl() {
  // Cube control.
}

Increase framerate

This library set default frame rate of WebBluetooth communication to 15fps for poor environment as mine🙃.
For your high performance PCs, please increase frame rate (up to 30) by calling setFrameRate.

cube?.setFrameRate(30);

Issue

Only in Windows environment, moveToMulti API does not work correctly with specified more than 3 positions. Please refer to the other issues in Issue on GitHub.

Licence

This software is released under MIT License, see LICENSE.

Author

Tetsunori Nakayama.

References

TypeScript

p5-typescript-starter Gaweph
MIT License, Copyright (c) 2019 Gareth Williams

O'Reilly "Programming TypeScript"
O'Reilly Japan - プログラミングTypeScript

toio

toio Core Cube Specification