2015/01/17

続・ひねリモコン(プロトタイプ)

まぁ、プロトタイプにケースなんか必要無いのかもしれませんが、ふと玩具屋さんで
nano blockのコレクションケースを見た時に「これだ!」と思い購入しました。

一番気になったのはArduinoの基板の穴とnano blockの凸が同じサイズか?という所
ですが、1000円以下だったので とりあえず購入。
家に帰り、早速穴とブロックの凸を合わせてみたら、その為に作ったかのように嵌った
のでArduinoの穴位置を確認しながら台座となるプレートにブロックをつけます。

ただ、リセットボタンの横にある穴だけはブロックの凸と位置がずれているので
ブロックはつけませんでした。代わりにUSBコネクタ付近がガタつくので、そこに
ブロックをつけてみました。(効果不明)
組み上げるとこんな感じです。このままではUSBケーブルを挿せないので、一面外すか
穴を開けてしまうかですね。

Arduino、nano blockで検索してみると、ブロックでケースを作る人もいましたので、
意外とArduinoとnano blockは相性がいいのかもしれませんね〜。(^^)

2015/01/08

Intel Curie

http://japanese.engadget.com/2015/01/06/curie-quark-se-soc-6-ble/
CESにてIntelがウェアラブルデバイス向けのモジュール「Curie」を発表しました。
GalileoもEdisonも とても興味があったのですが、CPUボードの枠から出なかったので
Raspberry Piを持っている私は買うまでには至りませんでした。
ただし、今度はモジュール内にBluetoothや6軸モーションセンサーがついているので、
とぉ〜っても興味があります!
後は、市販化するのかという点と価格がどうなるのでしょうか?

2015/01/02

ひねリモコン(プロトタイプ)

夏頃、日本のスタートアップが「Ring」というウェアラブルデバイスを開発している
という記事を読んだ時、ひねった動作でコントロールする物を作りたいなぁ、、、と
ふと思いました。
以前、赤外線LEDを100個まとめ買いしていたので、赤外線、ひねる、リモートコント
ロールというキーワードで、安直にテレビのリモコンを作る事にしました。(^^;
理想はボールのようなケースにボタンが一つ、というようなシンプルな物を作りたいの
ですが、とりあえずはArduino+赤外線LED+ジャイロ(L3GD20)という構成で試す
ことにします。
秋月電子で売られているユニバーサル基板に小型のブレッドボードを付けて2階建て
構造にしました。
接続とソフトについては、以下の2つのサイトを参考にさせてもらいました。

http://eikatou.net/blog/2012/07/1796/
http://n.mtng.org/ele/arduino/tutorial012.html

接続はこんな感じです。

ソフトは上の2つのサイトのソースをほぼコピペで、Y軸の傾きに対して紫外線LEDを
CH upするか、CH downするかという簡単なプログラムです。
#include 

#define LED_PIN 2

//CH up
unsigned int chup[] = {432,1664,352,728,324,708,352,704,356,736,348,1716,364,
696,348,732,328,708,348,1724,396,720,348,704,352,720,352,1716,364,696,396,45856,
364,1712,368,684,356,708,348,704,348,736,364,692,356,1720,356,1716,360,1716,368,
688,352,1720,360,1720,356,1728,356,696,352,1728,392};
//CH down
unsigned int chdown[] = {480,1620,352,704,352,708,344,704,356,740,352,700,360,
1716,352,696,360,696,348,1728,364,688,352,704,360,712,356,1716,364,716,388,45792,
372,1704,364,696,352,700,360,696,356,728,348,1724,368,692,356,1720,360,1708,368,
688,356,1716,368,1708,368,1724,352,704,352,1720,408};

const byte L3GD20_ADDR = B1101010;  // SA0 = GND
//const byte L3GD20_ADDR = B1101011;// SA0 = VDD_IO

const byte L3GD20_WHOAMI = 0x0f;
const byte L3GD20_CTRL1 = 0x20;
const byte L3GD20_CTRL2 = 0x21;
const byte L3GD20_CTRL3 = 0x22;
const byte L3GD20_CTRL4 = 0x23;
const byte L3GD20_CTRL5 = 0x24;
const byte L3GD20_X_L = 0x28;
const byte L3GD20_X_H = 0x29;
const byte L3GD20_Y_L = 0x2A;
const byte L3GD20_Y_H = 0x2B;
const byte L3GD20_Z_L = 0x2C;
const byte L3GD20_Z_H = 0x2D;

void L3GD20_write(byte reg, byte val)
{
  Wire.beginTransmission(L3GD20_ADDR);
  Wire.write(reg);
  Wire.write(val);
  Wire.endTransmission();  
}

byte L3GD20_read(byte reg)
{
  byte ret = 0;
  // request the registor
  Wire.beginTransmission(L3GD20_ADDR);
  Wire.write(reg);
  Wire.endTransmission();  
  // read
  Wire.requestFrom((unsigned int)L3GD20_ADDR, 1);
    while (Wire.available()) {
    ret = Wire.read();
  }
  return ret;
}

void SendData(unsigned int *data, int datasize) {
  Serial.println(datasize);
  for (int i = 0; i < datasize; i++) {
    unsigned long start_t = micros();
    unsigned long length = data[i];
    do {
      digitalWrite(LED_PIN, 1 - (i&1));
      delayMicroseconds(9);
      digitalWrite(LED_PIN, 0);
      delayMicroseconds(7);
    } while(long(start_t + length - micros()) > 0);
  }
}

void setup() {
  Serial.begin(9600);
  while (!Serial) {}

  Wire.begin();
  Serial.println(L3GD20_read(L3GD20_WHOAMI), HEX); // should show D4
  L3GD20_write(L3GD20_CTRL1, B00001111);
  pinMode(LED_PIN, OUTPUT); // LED setup
}

void loop() {
  short X, Y, Z;
  float x, y, z;
  int datasize;

  X = L3GD20_read(L3GD20_X_H);
  x = X = (X << 8) | L3GD20_read(L3GD20_X_L);
  Y = L3GD20_read(L3GD20_Y_H);
  y = Y = (Y << 8) | L3GD20_read(L3GD20_Y_L);
  Z = L3GD20_read(L3GD20_Z_H);
  z = Z = (Z << 8) | L3GD20_read(L3GD20_Z_L);
 
  x *= 0.00875; // +-250dps
  y *= 0.00875; // +-250dps
  z *= 0.00875; // +-250dps
  
  if ( y > 10 ) {
    datasize = sizeof(chup) / sizeof(chup[0]);
    digitalWrite(LED_PIN, HIGH);
    SendData(chup, datasize);
    digitalWrite(LED_PIN, LOW);
    Serial.println("CH up");
  }
  
  if ( y < -10 ) {
    datasize = sizeof(chdown) / sizeof(chdown[0]);
    digitalWrite(LED_PIN, HIGH);
    SendData(chdown, datasize);
    digitalWrite(LED_PIN, LOW);
    Serial.println("CH down");
  }
  
  Serial.print(x);    // X axis (deg/sec)
  Serial.print("\t");
  Serial.print(y);    // Y axis (deg/sec)
  Serial.print("\t");
  Serial.println(z);  // Z axis (deg/sec)

  delay(1000);
}

そう、昔のダイアル型のテレビと同じ動作です。(^^;)
X軸でボリュームまでコントロールする予定です。