Grove Gesture v1.0 を obniz で動かしてみたメモ

この記事は obniz Advent Calendar 2019 の7日目の記事です。

Grove Gesture v1.0 を obniz で動かしてみたメモです。

動かしてみたもの

このように動作させました。実際、公開してなかったので、これを機会にまとめました!

https://twitter.com/hayato__morita/status/1202107506157178880

興味持っていただきありがとうございます!

参考にしたArduinoソース

Grove – Gesture V1.0 – Seeed Wiki

ここから、

/*
The following simple demo will show you a very easy application: When you move up, the red led will be turned on, otherwise the red led will be turned off.
*/
#include <Wire.h>
#include "paj7620.h"

void setup()
{
  paj7620Init();
}

void loop()
{
    uint8_t data = 0;  // Read Bank_0_Reg_0x43/0x44 for gesture result.

    paj7620ReadReg(0x43, 1, &data);  // When different gestures be detected, the variable 'data' will be set to different values by paj7620ReadReg(0x43, 1, &data).

    if (data == GES_UP_FLAG)        // When up gesture be detected,the variable 'data' will be set to GES_UP_FLAG.
        digitalWrite(4, HIGH);      // turn the LED on (HIGH is the voltage level)
    if (data == GES_DOWN_FLAG)      // When down gesture be detected,the variable 'data' will be set to GES_DOWN_FLAG.
        digitalWrite(4, LOW);       // turn the LED off by making the voltage LOW
}

を追います。

Seeed-Studio/Gesture_PAJ7620

ライブラリを見に行きました。

obnizはこのあたりを参考にします。

obniz的書き換えの方法を追う

I2C系の分かりやすいS11059の挙動を参考にしました。

obniz/index.js at master · obniz/obniz

レジスタなど挙動を把握

以下を見つつ、どんなデータをやり取りしてるか確認。

image

image

image

image

実際に動いたソースはこちら

かなり泥臭くもともとのArduinoからソースを置き換えていったのですが、なんとか動いたのがこちらです。

Arduinoの置き換えのナレッジを記録したいためにコメントが色々はいっています。

<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@2.2.0/obniz.js" crossorigin="anonymous"></script>
</head>
<body>

<div id="obniz-debug"></div>
<h1>obniz instant HTML</h1>
<button id="on">ON</button>
<button id="off">OFF</button>
<div id="print"></div>

<script>

const obniz = new Obniz('Obniz_ID')

const ic2Address = 0x73; // http://wiki.seeedstudio.com/Grove-Gesture_v1.0/
  
// 定数系は https://github.com/Seeed-Studio/Gesture_PAJ7620/blob/master/paj7620.h から変換
const PAJ7620_ADDR_BASE = 0x00;
const PAJ7620_REGITER_BANK_SEL = PAJ7620_ADDR_BASE + 0xEF;
const PAJ7620_BANK0 = 0 << 0;
const PAJ7620_BANK1 = 1 << 0;

const GES_RIGHT_FLAG			= 1 << 0; // PAJ7620_VAL(1,0)
const GES_LEFT_FLAG				= 1 << 1; // PAJ7620_VAL(1,1)
const GES_UP_FLAG				= 1 << 2; // PAJ7620_VAL(1,2)
const GES_DOWN_FLAG				= 1 << 3; // PAJ7620_VAL(1,3)
const GES_FORWARD_FLAG			= 1 << 4; // PAJ7620_VAL(1,4)
const GES_BACKWARD_FLAG			= 1 << 5; // PAJ7620_VAL(1,5)
const GES_CLOCKWISE_FLAG		= 1 << 6; // PAJ7620_VAL(1,6)
const GES_COUNT_CLOCKWISE_FLAG	= 1 << 7; // PAJ7620_VAL(1,7)
const GES_WAVE_FLAG				= 1 << 8; // PAJ7620_VAL(1,0)
/*
console.log("GES_RIGHT_FLAG" , GES_RIGHT_FLAG);
console.log("GES_LEFT_FLAG" , GES_LEFT_FLAG);
console.log("GES_UP_FLAG" , GES_UP_FLAG);
console.log("GES_DOWN_FLAG" , GES_DOWN_FLAG);
console.log("GES_FORWARD_FLAG" , GES_FORWARD_FLAG);
console.log("GES_BACKWARD_FLAG" , GES_BACKWARD_FLAG);
console.log("GES_CLOCKWISE_FLAG" , GES_CLOCKWISE_FLAG);
console.log("GES_WAVE_FLAG" , GES_WAVE_FLAG);
*/
const initRegisterArray = [	// Initial Gesture
    [0xEF,0x00],
	[0x32,0x29],
	[0x33,0x01],
	[0x34,0x00],
	[0x35,0x01],
	[0x36,0x00],
	[0x37,0x07],
	[0x38,0x17],
	[0x39,0x06],
	[0x3A,0x12],
	[0x3F,0x00],
	[0x40,0x02],
	[0x41,0xFF],
	[0x42,0x01],
	[0x46,0x2D],
	[0x47,0x0F],
	[0x48,0x3C],
	[0x49,0x00],
	[0x4A,0x1E],
	[0x4B,0x00],
	[0x4C,0x20],
	[0x4D,0x00],
	[0x4E,0x1A],
	[0x4F,0x14],
	[0x50,0x00],
	[0x51,0x10],
	[0x52,0x00],
	[0x5C,0x02],
	[0x5D,0x00],
	[0x5E,0x10],
	[0x5F,0x3F],
	[0x60,0x27],
	[0x61,0x28],
	[0x62,0x00],
	[0x63,0x03],
	[0x64,0xF7],
	[0x65,0x03],
	[0x66,0xD9],
	[0x67,0x03],
	[0x68,0x01],
	[0x69,0xC8],
	[0x6A,0x40],
	[0x6D,0x04],
	[0x6E,0x00],
	[0x6F,0x00],
	[0x70,0x80],
	[0x71,0x00],
	[0x72,0x00],
	[0x73,0x00],
	[0x74,0xF0],
	[0x75,0x00],
	[0x80,0x42],
	[0x81,0x44],
	[0x82,0x04],
	[0x83,0x20],
	[0x84,0x20],
	[0x85,0x00],
	[0x86,0x10],
	[0x87,0x00],
	[0x88,0x05],
	[0x89,0x18],
	[0x8A,0x10],
	[0x8B,0x01],
	[0x8C,0x37],
	[0x8D,0x00],
	[0x8E,0xF0],
	[0x8F,0x81],
	[0x90,0x06],
	[0x91,0x06],
	[0x92,0x1E],
	[0x93,0x0D],
	[0x94,0x0A],
	[0x95,0x0A],
	[0x96,0x0C],
	[0x97,0x05],
	[0x98,0x0A],
	[0x99,0x41],
	[0x9A,0x14],
	[0x9B,0x0A],
	[0x9C,0x3F],
	[0x9D,0x33],
	[0x9E,0xAE],
	[0x9F,0xF9],
	[0xA0,0x48],
	[0xA1,0x13],
	[0xA2,0x10],
	[0xA3,0x08],
	[0xA4,0x30],
	[0xA5,0x19],
	[0xA6,0x10],
	[0xA7,0x08],
	[0xA8,0x24],
	[0xA9,0x04],
	[0xAA,0x1E],
	[0xAB,0x1E],
	[0xCC,0x19],
	[0xCD,0x0B],
	[0xCE,0x13],
	[0xCF,0x64],
	[0xD0,0x21],
	[0xD1,0x0F],
	[0xD2,0x88],
	[0xE0,0x01],
	[0xE1,0x04],
	[0xE2,0x41],
	[0xE3,0xD6],
	[0xE4,0x00],
	[0xE5,0x0C],
	[0xE6,0x0A],
	[0xE7,0x00],
	[0xE8,0x00],
	[0xE9,0x00],
	[0xEE,0x07],
	[0xEF,0x01],
	[0x00,0x1E],
	[0x01,0x1E],
	[0x02,0x0F],
	[0x03,0x10],
	[0x04,0x02],
	[0x05,0x00],
	[0x06,0xB0],
	[0x07,0x04],
	[0x08,0x0D],
	[0x09,0x0E],
	[0x0A,0x9C],
	[0x0B,0x04],
	[0x0C,0x05],
	[0x0D,0x0F],
	[0x0E,0x02],
	[0x0F,0x12],
	[0x10,0x02],
	[0x11,0x02],
	[0x12,0x00],
	[0x13,0x01],
	[0x14,0x05],
	[0x15,0x07],
	[0x16,0x05],
	[0x17,0x07],
	[0x18,0x01],
	[0x19,0x04],
	[0x1A,0x05],
	[0x1B,0x0C],
	[0x1C,0x2A],
	[0x1D,0x01],
	[0x1E,0x00],
	[0x21,0x00],
	[0x22,0x00],
	[0x23,0x00],
	[0x25,0x01],
	[0x26,0x00],
	[0x27,0x39],
	[0x28,0x7F],
	[0x29,0x08],
	[0x30,0x03],
	[0x31,0x00],
	[0x32,0x1A],
	[0x33,0x1A],
	[0x34,0x07],
	[0x35,0x07],
	[0x36,0x01],
	[0x37,0xFF],
	[0x38,0x36],
	[0x39,0x07],
	[0x3A,0x00],
	[0x3E,0xFF],
	[0x3F,0x00],
	[0x40,0x77],
	[0x41,0x40],
	[0x42,0x00],
	[0x43,0x30],
	[0x44,0xA0],
	[0x45,0x5C],
	[0x46,0x00],
	[0x47,0x00],
	[0x48,0x58],
	[0x4A,0x1E],
	[0x4B,0x1E],
	[0x4C,0x00],
	[0x4D,0x00],
	[0x4E,0xA0],
	[0x4F,0x80],
	[0x50,0x00],
	[0x51,0x00],
	[0x52,0x00],
	[0x53,0x00],
	[0x54,0x00],
	[0x57,0x80],
	[0x59,0x10],
	[0x5A,0x08],
	[0x5B,0x94],
	[0x5C,0xE8],
	[0x5D,0x08],
	[0x5E,0x3D],
	[0x5F,0x99],
	[0x60,0x45],
	[0x61,0x40],
	[0x63,0x2D],
	[0x64,0x02],
	[0x65,0x96],
	[0x66,0x00],
	[0x67,0x97],
	[0x68,0x01],
	[0x69,0xCD],
	[0x6A,0x01],
	[0x6B,0xB0],
	[0x6C,0x04],
	[0x6D,0x2C],
	[0x6E,0x01],
	[0x6F,0x32],
	[0x71,0x00],
	[0x72,0x01],
	[0x73,0x35],
	[0x74,0x00],
	[0x75,0x33],
	[0x76,0x31],
	[0x77,0x01],
	[0x7C,0x84],
	[0x7D,0x03],
	[0x7E,0x01]
];
  
obniz.onconnect = async () => {
  
  /*
  つなぎ方
  
  黒:0番
  赤:1番
  白:2番 SDA
  黄:3番 SCL
  */
  
  await obniz.wait(5000);
  
  // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
  // 初期化の挙動を再現
  // https://github.com/Seeed-Studio/Gesture_PAJ7620/blob/master/paj7620.cpp
  
  obniz.io0.output(false)
  obniz.io1.output(true)
  
  // wakeup the sensor
  // delayMicroseconds(700);	// Wait 700us for PAJ7620U2 to stabilize	
  await obniz.wait(700);
  console.log('await obniz.wait; 1');
  
  // Wire.begin();
  const i2c = obniz.getFreeI2C()
  
  console.log("INIT SENSOR...");
  obniz.display.clear();
  obniz.display.print("Grove-Gesture_v1.0\n")
  obniz.display.print("INIT SENSOR...\n")
  
  obniz.i2c0.start({mode:'master', sda:2, scl:3, clock:400000, pull: '5v'});
  obniz.i2c0.onerror = function(err) {
    // いまは初動だけエラーもみ消しちゃってるのでどうにかしたい
    console.log('Error', err);
  }
  console.log(obniz.i2c0);
  
  // paj7620SelectBank(BANK0);
  //   ↓
  // paj7620WriteReg(PAJ7620_REGITER_BANK_SEL, PAJ7620_BANK1);
  //
  // https://github.com/Seeed-Studio/Gesture_PAJ7620/blob/master/paj7620.h
  //
  // #define PAJ7620_ADDR_BASE				0x00
  // #define PAJ7620_REGITER_BANK_SEL		(PAJ7620_ADDR_BASE + 0xEF)
  // PAJ7620_REGITER_BANK_SEL = 0x00 + 0xEF = 0xEF
  // #define PAJ7620_BANK1	PAJ7620_VAL(1,0)
  // #define PAJ7620_VAL(val, maskbit)		( val << maskbit )
  // 1 << 0  // おそらくビットずらし
  // PAJ7620_BANK1 = 1 << 0
  
  await obniz.wait(700); // 待ち?
  
  console.log('await obniz.wait; 2 ');
  
  // https://obniz.io/ja/doc/sdk/doc/i2c
  // write(address, data);
  // BANK0
  // i2c.write(0xEF, 1 << 0 );  // obniz.i2c0. に変更
  //console.log("PAJ7620_ADDR_BASE" , PAJ7620_ADDR_BASE);
  //console.log("PAJ7620_REGITER_BANK_SEL" , PAJ7620_REGITER_BANK_SEL);
  
  // エラーは出るがこれを使わないとreadWaitがこない
  console.log('PAJ7620_BANK0');
  obniz.i2c0.write(ic2Address, [ PAJ7620_REGITER_BANK_SEL , PAJ7620_BANK0 ] );
  
  // wakeup check
  let res;
  res = await obniz.i2c0.readWait(ic2Address,1);
  console.log(res);
  if(res == 0x20){
    console.log("wake-up finish.");
    obniz.display.clear();
    obniz.display.print("wake-up finish.\n")
  }
  
  /*
  // 合ってる
  // i2c.write(デバイスのアドレス, [コマンドのアドレス, 書き込みたいデータ]) 的な?? https://github.com/obniz/obniz/blob/5d9bce79c87da7ff38012f9ca28a17682fe6fae2/parts/TemperatureSensor/i2c/BME280/index.js#L97;

  //多分最初にbankっていうのを選ばないといけないっぽい?
  //https://github.com/Seeed-Studio/Gesture_PAJ7620/blob/master/paj7620.cpp#L359


  const value = await i2c.readWait(ic2Address, 1)
  console.log(value)
  */
  
  /*
  // Cのコード
	for (i = 0; i < INIT_REG_ARRAY_SIZE; i++) 
	{
		paj7620WriteReg(initRegisterArray[i][0], initRegisterArray[i][1]);
	}
  */
  
  // initRegister
  console.log("initRegister!!");
  obniz.display.print("initRegister!!\n")
  for (i = 0; i < initRegisterArray.length; i++) 
  {
      obniz.i2c0.write( ic2Address , initRegisterArray[i] );
  }
  console.log("Set up gaming mode.");
  
  console.log("PAJ7620_BANK1");
  obniz.i2c0.write(ic2Address, [ PAJ7620_REGITER_BANK_SEL , PAJ7620_BANK1 ] );
  // 
  // paj7620WriteReg(0x65, 0x12);
  // near mode 240 fps
  obniz.i2c0.write(ic2Address, [ 0x65, 0x12 ] );
  console.log("PAJ7620_BANK0");
  obniz.i2c0.write(ic2Address, [ PAJ7620_REGITER_BANK_SEL , PAJ7620_BANK0 ] );
  
  obniz.display.print("initializeed!!\n")
  console.log("Paj7620 initialize register finished.");
  // ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ ここまでが初期化の挙動
  
  // ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
  // ここからは http://wiki.seeedstudio.com/Grove-Gesture_v1.0/ のArduinoコードのループを参考
  // Step 8. Let's try the 9 gestures by select File->Example->Gesture_PAJ7620->paj7620_9gestures のところ
  
  // paj7620ReadReg(0x43, 1, &data)
  while(true){
    obniz.i2c0.write(ic2Address, [ 0x43 ] );
    res = await obniz.i2c0.readWait(ic2Address,1);
    // console.log(res);
    
    // register 0
    // センサーの上を、上下左右に手を通過させると反応します。
    if(GES_RIGHT_FLAG == res){
      console.log('GES_RIGHT_FLAG');
      obniz.display.clear();
      obniz.display.print('RIGHT')
    } else if(GES_LEFT_FLAG == res){
      console.log('GES_LEFT_FLAG');
      obniz.display.clear();
      obniz.display.print('LEFT')
    } else if(GES_UP_FLAG == res){
      console.log('GES_UP_FLAG');
      obniz.display.clear();
      obniz.display.print('UP')
    } else if(GES_DOWN_FLAG == res){
      console.log('GES_DOWN_FLAG');
      obniz.display.clear();
      obniz.display.print('DOWN')
    } else if(GES_FORWARD_FLAG == res){
      console.log('GES_FORWARD_FLAG');
      obniz.display.clear();
      obniz.display.print('FORWARD')
    } else if(GES_BACKWARD_FLAG == res){
      console.log('GES_BACKWARD_FLAG');
      obniz.display.clear();
      obniz.display.print('BACKWARD')
    } else if(GES_CLOCKWISE_FLAG == res){
      console.log('GES_CLOCKWISE_FLAG');
      obniz.display.clear();
      obniz.display.print('CLOCKWISE')
    } else if(GES_COUNT_CLOCKWISE_FLAG == res){
      console.log('GES_COUNT_CLOCKWISE_FLAG');
      obniz.display.clear();
      obniz.display.print('CLOCKWISE_FLAG')
    }
    await obniz.wait(1000);
  }
  
}

</script>
</body>
</html>

明日は

tmisuo0423 さんです!