【M5Stack FACES】GameBoyカバーのボタン入力を得る
新年1つ目の通常投稿は『M5Stack』を触ってみます。
以前、M5Stack FACESにテトリスを入れたのですが、GameBoyカバーのボタンが機能していなかったので、そのボタン対応をして行きたいと思いますよ。
と言っても、ピンポイントな情報が上手く探し出せなかったので、若干手探りでの進行になります。
とりあえず今回は、ボタンの入力を得られるところまで進めたいと思います。
まずは情報収集
何をするにも、まずは公式情報を見ないと始まらなかったりするんですが…
M5Stack FACESの公式情報があやふやになってません?
一応、GitHubのm5stackの中を色々と見てみたんですけど、何が正しい情報なのかよく分からなかった。
m5stack/m5-docs/blob/master/docs/ja/core/face_kit とか
m5stack/m5-docs/blob/master/docs/ja/base/face_base とか
なんか、それっぽい気がするんだけど、画像とかリンク切れてるし!
微妙に欲しい情報(PIN配置とか回路図とか、サンプルコードとか)が見つけられないし!
あとは、SWITCH SCIENCEの販売サイトの各種資料とか。。。
m5stack/M5Stack/blob/master/src/M5Faces.cpp は少し参考になるかな?
でも、これだ!と言う情報を見つけられんかった( > _ < )
最終的にはスケッチ例が一番だった
と、他にも色々それっぽいのを漁ってみたんですが、最終的には…
Arduinoのサンプルスケッチ
[ファイル]->[スケッチ例]->[M5Stack]->[Modules]->[FACES]->[I2C_Keybord]
に行き着きました。
以下は、そのサンプルのコード全文です。
#include <M5Stack.h>
#define KEYBOARD_I2C_ADDR 0X08
#define KEYBOARD_INT 5
void setup()
{
M5.begin();
Wire.begin();
M5.Lcd.setTextFont(2);
M5.Lcd.println("FACES Keyboard I2C Read Example");
pinMode(KEYBOARD_INT, INPUT_PULLUP);
}
void loop()
{
if(digitalRead(KEYBOARD_INT) == LOW) {
Wire.requestFrom(KEYBOARD_I2C_ADDR, 1); // request 1 byte from keyboard
while (Wire.available()) {
uint8_t key_val = Wire.read(); // receive a byte as character
if(key_val != 0) {
if(key_val >= 0x20 && key_val < 0x7F) { // ASCII String
Serial.print((char)key_val);
M5.Lcd.print((char)key_val);
} else {
Serial.printf("0x%02X ",key_val);
M5.Lcd.printf("0x%02X ",key_val);
}
}
}
}
}
これをそのまま動かすだけで、GameBoyカバーのボタン入力が反応します。
とりあえず動かしてみる
何はともあれ、動かしてみましょう。
起動すると、初期表示で
FACES Keyboard I2C Read Example 0xFF
と表示されます。
…何も押してないのに "0xFF" が表示されるのはそう言う仕様かな?
あとは、ボタンを押すたびに、押されたボタンに対応するコードが表示されて行きます。
とりあえず、例でAボタンを押すと
FACES Keyboard I2C Read Example 0xFF 0xEF
と表示されて、 "0xEF"が取得できます。
Aボタンを離すと"0xFF"が再度取得されます。
恐らく、ボタンの変化がある度に値が取得されるのだと思います。
他のボタンも色々押すと、どんどん値が取れて面白いですよ。
ボタン対応表
一通り触ってみると、ボタンの対応が見えてきました。
→:F7 (0bit目)
←:FB (1bit目)
↓:FD (2bit目)
↑:FE (3bit目)
START:7F(4bit目)
SELECT:BF(5bit目)
B:DF (6bit目)
A:EF (7bit目)
このキー入力の対応を、テトリスのコードに埋め込めば、何とか動かすことができるはず!
結局どうやっているの?
実際にどうやって値を取得しているのかと言うと…
setup関数内の
Wire.begin();
で、Wireライブラリを初期化してI2Cを利用できる様にしています。
そして、loop関数内の
Wire.requestFrom(KEYBOARD_I2C_ADDR, 1);
while (Wire.available()) {
uint8_t key_val = Wire.read();
...
}
でI2C(0x08アドレス)から1バイトの値を読み出します。
このコードをテトリスのコードに上手く埋め込めば使える様になるはず!!!
次回は実際にテトリスのコードを変えるよ
今回は、GameBoyカバーでの押下ボタンと取得値の関係性と、
入力値の取得コードを探し出すところまでできました。
これが分かれば、何とかなるはず!
と言う事で、次回は実際にテトリスのコードに手を入れて、GameBoyっぽく操作できる様にしていこうと思います。
乞うご期待!
(おまけ)デフォルトでインストールされているのは、Nintendo エミュレータだった…
前回のM5Stackの投稿で”マリオ(っぽいもの)で遊びたかった”と書いたのですが、
今回色々と調べていたところ、デフォルトでインストールされているのは"Nintendoエミュレータ"であることが分かりました。
そして、同時にマリオ(っぽいもの)のROMが入っているみたいです。
実際にソースコードがあるのかと思っていたのですが…違ったんですね。
今回の対応のついでに、実際に公開されているエミュレータも入れてみたのですけど…
遊べはするけど、処理が重かったりサウンドの音割れが酷かったりして、あまり快適じゃなかったです。
もう少し、最適化されているのかと思ったんですけど、違いましたね。
ちょっと残念でした。
ディスカッション
コメント一覧
まだ、コメントがありません