夏頃、日本のスタートアップが「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軸でボリュームまでコントロールする予定です。