オリジナルガシャットをつくる 〜スーパーマリオブラザーズガシャット〜
前回、前々回とでライダーガシャットの仕組みについておおよそは理解したので、今回は学んだことを活かして、オリジナルのライダーガシャットを作ってみたいと思います。カラーリングとかLEDの色とかだけじゃなくて、音声もLEDの発光パターンも全部独自のものに差し替えたいと思います。
ガシャットをつくるということは何かしらのゲームを題材にするということなのですが、最初に作るべきものは何かと考えたら、自分の中では答えは一つでした。
ということで作ってみました、『スーパーマリオブラザーズガシャット』。
ゲームの代名詞と言っても過言ではなく、一発目に作るものとしてはこれ以上にふさわしいものはないと思います。
ということで、以下ではマリオを題材に、どんな感じで作ったのかを簡単にご紹介していきたいと思います。
(以下、2017/1/21追記)
コメント欄で「もう少し詳しい情報が欲しい」という依頼をいただきましたので、もう少しだけ詳しく書いた記事を上げなおしました。
- マリオガシャット詳細 その1(英訳付き) Details of the Mario Gashat −Part 1
- マリオガシャット詳細 その2(英訳付き) Details of the Mario Gashat −Part 2
(以上、2017/1/21追記)
今回使用した主な具材は以下になります。
ベースとなるガシャットは何でもよいですが、作りたいイメージの色に合うガシャットがあるなら、それを使うと塗装しなくて良いのでラクです。ただ、いずれにせよ徹底的に破壊することになる点だけご注意ください。
HYPER DETAIL GEARのときも使用しましたが、今回もお世話になります。これにプログラムを書いて全体を制御します。
こちらのセットもHYPER DETAIL GEARのときに使用しましたが、音声再生はこれにかかっています。なかなか気難しいモジュールですが。
それから、小型・薄型のスピーカーが別途必要です。ガシャットの中はスペースの余裕が全然ないので、元々ガシャットに入っている大きめのスピーカーは外して、代わりに小型・薄型のものを使うことでMP3プレーヤーを入れるスペースを確保します。
こちらもHYPER DETAIL GEARのときに使用しました。フルカラーLEDなので、(今のところの)普通のガシャットではできない色変化が可能になります。
実はこれが今回の工作の要かもしれません。最初はデフォルトのLR44電池3個、ないしは1個追加の4個で電力を賄えないか頑張ってみたのですが、LEDも音声モジュールも、どうしても安定してくれませんでした。そこで、やむなしでリチウムイオンポリマー電池を使うことにしました。ここで紹介している電池で、無事にArduino, LED, 音声モジュールを安定して動作させることができました。
ただ、ご存知の方は多いと思いますが、リチウムイオン電池は取り扱い方を誤ると非常に危険です。利用にあたっては自己責任で、細心の注意を払って利用するようにしてください。一緒に紹介している充電器を使用することを強くお勧めします。
今回、ガシャットに入っている元々の基板は使いません。ただ、それと同サイズの板が必要になるので、1.2mmのプラ板を基板と同サイズに切って使用します。
あとは細々したところで、導線やスライドスイッチ、絶縁テープなどが必要です。
以上が、電子的なところで必要な具材です。次は見た目を変えるために必要な具材です。
自分はどうしてもマリオのゲームソフトと同じ色にしたかったので、上記の色を使いました。スイッチのパーツを厚く塗ってしまうと、あとでスイッチがうまく稼動しなくなったりするので、そこだけ注意が必要です(後で削ったり色々大変でした)。
ホワイトの方が持ち手のところのラベル用と発光部分のイラスト用、透明の方が背中のガシャット名のところ用です。自分は塗装技術が全然なので、印刷したものを貼り付ける、というやり方で見た目を変えました。ただ、このやり方だと白色の印刷ができないという難点があります。自分で塗装ができる人なら、ガシャットのクリアパーツについては、自分で白を塗装した方が、ドライバーの中で綺麗に見えると思います。
なお、このプリントしたものを貼って見た目を変えるやり方は、こちらのめたルスさんのガシャットのカスタム方法を参考にさせていただきました。クリアパーツとラベルの処理がとても綺麗です。
あとは、もともとクリアーパーツにプリントされているものを消すものが必要です。自分はマニキュアの除光液を使いましたが、こちらで書いているとおり、どうしても全体が白っぽくなってしまうので、他に良いやり方を知っている方は是非教えてください。
必要なものは以上です。あとは、これらをスペースに余裕のないガシャット内部にどう詰め込んでいくかですが、その前に先に、プログラムの方を片付けておきます。
プログラムについては、基本は前々回に調べた内容を実装するだけです。以下、少し長いですが、全文掲載します。
#include <string.h> #include <SoftwareSerial.h> #include <DFPlayer_Mini_Mp3.h> #include <Adafruit_NeoPixel.h> #define BUTTON_1_PIN 4 #define BUTTON_2_PIN 5 #define BUTTON_3_PIN 6 #define LED_PIN 7 #define NUM_OF_LED 1 #define GASHAT_OFF 0 #define GASHAT_NAME 1 #define GAME_CLEAR 2 #define GAME_OVER 3 #define LEVEL_1 4 #define LEVEL_2 5 #define LEVEL_3 6 #define GASHAT_IN 7 #define GASHAT_OUT 8 #define DRIVER_CLOSE 9 #define CRITICAL_STRIKE 10 #define CRITICAL_READY 11 #define CRITICAL_FINISH 12 #define GENRE 13 #define N_BUTTON 3 #define ON HIGH #define OFF LOW #define LED_PATTERN 200 Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUM_OF_LED, LED_PIN, NEO_GRB + NEO_KHZ400); SoftwareSerial mySerial(2, 3); // RX, TX const uint8_t OFF_OFF_OFF[] = {OFF, OFF, OFF}; const uint8_t ON_OFF_OFF[] = {ON, OFF, OFF}; const uint8_t OFF_ON_OFF[] = {OFF, ON, OFF}; const uint8_t OFF_OFF_ON[] = {OFF, OFF, ON }; const uint8_t ON_ON_OFF[] = {ON, ON, OFF}; const uint8_t ON_OFF_ON[] = {ON, OFF, ON }; const uint8_t OFF_ON_ON[] = {OFF, ON, ON }; const uint8_t ON_ON_ON[] = {ON, ON, ON }; const uint8_t LED_GASHAT_NAME[][3] PROGMEM = { {128, 0, 0},{ 0, 0, 0},{128, 0, 0},{108, 0, 0},{ 88, 0, 0},{ 68, 0, 0},{ 48, 0, 0},{ 28, 0, 0},{ 8, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{ 0, 0, 0},{128, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{ 0, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {120, 0, 0},{108, 0, 0},{ 96, 0, 0},{ 84, 0, 0},{ 72, 0, 0},{ 64, 0, 0},{ 48, 0, 0},{ 32, 0, 0},{ 24, 0, 0},{ 12, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0} }; const uint8_t LED_GAME_CLEAR[][3] PROGMEM = { { 0, 0, 12},{ 0, 0, 24},{ 0, 0, 32},{ 0, 0, 48},{ 0, 0, 60},{ 0, 0, 72},{ 0, 0, 84},{ 0, 0, 96},{ 0, 0,108},{ 0, 0,120}, { 0, 0, 96},{ 0, 0, 72},{ 0, 0, 48},{ 0, 0, 24},{ 0, 0, 0},{ 0, 0, 12},{ 0, 0, 24},{ 0, 0, 32},{ 0, 0, 48},{ 0, 0, 60}, { 0, 0, 72},{ 0, 0, 84},{ 0, 0, 96},{ 0, 0,108},{ 0, 0,120},{ 0, 0, 96},{ 0, 0, 72},{ 0, 0, 48},{ 0, 0, 24},{ 0, 0, 0}, { 0, 0, 12},{ 0, 0, 24},{ 0, 0, 32},{ 0, 0, 48},{ 0, 0, 60},{ 0, 0, 72},{ 0, 0, 84},{ 0, 0, 96},{ 0, 0,108},{ 0, 0,120}, { 0, 0, 96},{ 0, 0, 72},{ 0, 0, 48},{ 0, 0, 24},{ 0, 0, 0},{ 0, 0, 12},{ 0, 0, 24},{ 0, 0, 32},{ 0, 0, 48},{ 0, 0, 60}, { 0, 0, 72},{ 0, 0, 84},{ 0, 0, 96},{ 0, 0,108},{ 0, 0,120},{ 0, 0, 96},{ 0, 0, 72},{ 0, 0, 48},{ 0, 0, 24},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0} }; const uint8_t LED_GAME_OVER[][3] PROGMEM = { { 0, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0} }; const uint8_t LED_GASHAT_LEVEL1[][3] PROGMEM = { {128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 64, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 64, 0, 0},{128, 0, 0}, {108, 0, 0},{ 88, 0, 0},{ 68, 0, 0},{ 48, 0, 0},{ 28, 0, 0},{ 8, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{ 32, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{ 64, 0, 0},{ 32, 0, 0},{ 0, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{ 64, 0, 0},{ 32, 0, 0},{ 0, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{ 64, 0, 0},{ 32, 0, 0},{ 0, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{ 64, 0, 0},{ 32, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{ 64, 0, 0},{ 32, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 32, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{108, 0, 0},{ 96, 0, 0},{ 84, 0, 0},{ 72, 0, 0},{ 64, 0, 0}, { 32, 0, 0},{ 24, 0, 0},{ 12, 0, 0},{128, 0, 0},{ 64, 0, 0},{ 32, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {108, 0, 0},{ 96, 0, 0},{ 84, 0, 0},{ 72, 0, 0},{ 60, 0, 0},{ 48, 0, 0},{ 32, 0, 0},{ 24, 0, 0},{ 12, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 12, 0, 0},{ 24, 0, 0},{ 36, 0, 0},{ 48, 0, 0},{ 60, 0, 0},{ 72, 0, 0},{ 84, 0, 0},{ 96, 0, 0},{108, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{108, 0, 0},{ 96, 0, 0},{ 84, 0, 0},{ 72, 0, 0},{ 60, 0, 0}, { 48, 0, 0},{ 32, 0, 0},{ 24, 0, 0},{ 12, 0, 0},{ 0, 0, 0} }; const uint8_t LED_GASHAT_LEVEL2[][3] PROGMEM = { {128, 0, 0},{ 64, 0, 0},{ 32, 0, 0},{128, 0, 0},{108, 0, 0},{ 88, 0, 0},{ 68, 0, 0},{ 48, 0, 0},{ 28, 0, 0},{ 20, 0, 0}, { 8, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{ 64, 0, 0}, { 32, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{108, 0, 0},{ 96, 0, 0},{ 84, 0, 0},{ 72, 0, 0}, { 36, 0, 0},{ 18, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0}, {128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0}, {128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0}, {128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{128, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{ 32, 0, 0},{128, 0, 0},{ 32, 0, 0},{128, 0, 0}, { 32, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {108, 0, 0},{ 96, 0, 0},{ 84, 0, 0},{ 72, 0, 0},{ 60, 0, 0},{ 48, 0, 0},{ 32, 0, 0},{ 24, 0, 0},{ 12, 0, 0},{ 0, 0, 0} }; const uint8_t LED_GASHAT_LEVEL3[][3] PROGMEM = { {128, 0, 0},{ 64, 0, 0},{ 32, 0, 0},{128, 0, 0},{108, 0, 0},{ 88, 0, 0},{ 68, 0, 0},{ 48, 0, 0},{ 28, 0, 0},{ 20, 0, 0}, { 8, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{ 64, 0, 0}, { 32, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{108, 0, 0},{ 96, 0, 0},{ 84, 0, 0},{ 72, 0, 0}, { 36, 0, 0},{ 18, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, {128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0},{128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0}, {128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0},{128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0}, {128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0},{128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0}, {128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0},{128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0}, {128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0},{128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0}, {128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0},{128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0}, {128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0},{128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0}, {128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0},{128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0}, {128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0},{128,128, 0},{128,128, 0},{ 64, 64, 0},{ 32, 32, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0,128, 0},{ 0,128, 0},{ 0,128, 0},{ 0,128, 0},{ 0,128, 0}, { 0,128, 0},{ 0,128, 0},{ 0,128, 0},{ 0,128, 0},{ 0,128, 0},{ 0,128, 0},{ 0,128, 0},{ 0,128, 0},{ 0,128, 0},{ 0,128, 0}, { 0,128, 0},{ 0,128, 0},{ 0,128, 0},{ 0,128, 0},{ 0,128, 0},{ 0,108, 0},{ 0, 96, 0},{ 0, 84, 0},{ 0, 72, 0},{ 0, 60, 0}, { 0, 48, 0},{ 0, 36, 0},{ 0, 24, 0},{ 0, 12, 0},{ 0, 0, 0} }; const uint8_t LED_GASHAT_IN[][3] PROGMEM = { {128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 64, 0, 0},{128, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 64, 0, 0},{128, 0, 0}, {108, 0, 0},{ 88, 0, 0},{ 68, 0, 0},{ 48, 0, 0},{ 28, 0, 0},{ 8, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0} }; const uint8_t LED_GASHAT_OUT[][3] PROGMEM = { { 64, 0, 0},{128, 0, 0},{128, 0, 0},{108, 0, 0},{ 88, 0, 0},{ 68, 0, 0},{ 48, 0, 0},{ 28, 0, 0},{ 20, 0, 0},{ 8, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0} }; const uint8_t LED_DRIVER_CLOSE[][3] PROGMEM = { {128, 0, 0},{ 0, 0, 0},{128, 0, 0},{108, 0, 0},{ 88, 0, 0},{ 68, 0, 0},{ 48, 0, 0},{ 28, 0, 0},{ 20, 0, 0},{ 8, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0} }; const uint8_t LED_CRITICAL_STRIKE[][3] PROGMEM = { {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{108, 0, 0},{ 96, 0, 0},{ 84, 0, 0},{ 72, 0, 0},{ 60, 0, 0}, { 48, 0, 0},{ 32, 0, 0},{ 24, 0, 0},{ 12, 0, 0},{128, 0, 0},{108, 0, 0},{ 96, 0, 0},{ 84, 0, 0},{ 72, 0, 0},{ 60, 0, 0}, { 48, 0, 0},{ 32, 0, 0},{ 24, 0, 0},{ 12, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{108, 0, 0}, { 96, 0, 0},{ 84, 0, 0},{ 72, 0, 0},{ 60, 0, 0},{ 48, 0, 0},{ 36, 0, 0},{ 24, 0, 0},{ 12, 0, 0},{ 0, 0,128},{ 0, 0,128}, { 64, 64,128},{ 64, 64,128},{ 0, 0, 64},{ 0, 0, 64},{ 64, 0,128},{ 64, 0,128},{ 64, 0, 64},{ 64, 0, 64},{128, 0,128},{128, 0,128}, {128, 0, 64},{128, 0, 64},{128, 0, 0},{128, 0, 0},{ 64, 0, 0},{ 64, 0, 0},{128, 64, 64},{128, 64, 64},{128, 64, 0},{128, 64, 0}, {128, 128, 0},{128,128, 0},{ 64, 64, 0},{ 64, 64, 0},{ 64,128, 0},{ 64,128, 0},{ 0,128, 0},{ 0,128, 0},{ 64,128, 64},{ 64,128, 64}, { 0, 64, 0},{ 0, 64, 0},{ 0,128, 64},{ 0,128, 64},{ 0,128,128},{ 0,128,128},{ 0, 64, 64},{ 0, 64, 64},{ 0, 64,128},{128, 0, 0}, { 64, 0, 0},{128, 0, 0},{128, 0, 0},{108, 0, 0},{ 96, 0, 0},{ 84, 0, 0},{ 72, 0, 0},{ 60, 0, 0},{ 48, 0, 0},{ 36, 0, 0}, { 24, 0, 0},{ 12, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0} }; const uint8_t LED_CRITICAL_READY[][3] PROGMEM = { {128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 64, 0, 0},{ 64, 0, 0},{128, 64, 64},{128, 64, 64},{128, 64, 0},{128, 64, 0},{128, 128, 0},{128,128, 0}, { 64, 64, 0},{ 64, 64, 0},{ 64,128, 0},{ 64,128, 0},{ 0,128, 0},{ 0,128, 0},{ 64,128, 64},{ 64,128, 64},{ 0, 64, 0},{ 0, 64, 0}, { 0,128, 64},{ 0,128, 64},{ 0,128,128},{ 0,128,128},{ 0, 64, 64},{ 0, 64, 64},{ 0, 64,128},{ 0, 64,128},{ 0, 0,128},{ 0, 0,128}, { 64, 64,128},{ 64, 64,128},{ 0, 0, 64},{ 0, 0, 64},{ 64, 0,128},{ 64, 0,128},{ 64, 0, 64},{ 64, 0, 64},{128, 0,128},{128, 0,128}, {128, 0, 64},{128, 0, 64},{128, 0, 0},{128, 0, 0},{ 64, 0, 0},{ 64, 0, 0},{128, 64, 64},{128, 64, 64},{128, 64, 0},{128, 64, 0}, {128, 128, 0},{128,128, 0},{ 64, 64, 0},{ 64, 64, 0},{ 64,128, 0},{ 64,128, 0},{ 0,128, 0},{ 0,128, 0},{ 64,128, 64},{ 64,128, 64}, { 0, 64, 0},{ 0, 64, 0},{ 0,128, 64},{ 0,128, 64},{ 0,128,128},{ 0,128,128},{ 0, 64, 64},{ 0, 64, 64},{ 0, 64,128},{ 0, 64,128}, { 0, 0,128},{ 0, 0,128},{ 64, 64,128},{ 64, 64,128},{ 0, 0, 64},{ 0, 0, 64},{ 64, 0,128},{ 64, 0,128},{ 64, 0, 64},{ 64, 0, 64}, {128, 0,128},{128, 0,128},{128, 0, 64},{128, 0, 64},{128, 0, 0},{128, 0, 0},{ 64, 0, 0},{ 64, 0, 0},{128, 64, 64},{128, 64, 64}, {128, 64, 0},{128, 64, 0},{128, 128, 0},{128,128, 0},{ 64, 64, 0},{ 64, 64, 0},{ 64,128, 0},{ 64,128, 0},{ 0,128, 0},{ 0,128, 0}, { 64,128, 64},{ 64,128, 64},{ 0, 64, 0},{ 0, 64, 0},{ 0,128, 64},{ 0,128, 64},{ 0,128,128},{ 0,128,128},{ 0, 64, 64},{ 0, 64, 64}, { 0, 64,128},{ 0, 64,128},{ 0, 0,128},{ 0, 0,128},{ 64, 64,128},{ 64, 64,128},{ 0, 0, 64},{ 0, 0, 64},{ 64, 0,128},{ 64, 0,128}, { 64, 0, 64},{ 64, 0, 64},{128, 0,128},{128, 0,128},{128, 0, 64},{128, 0, 64},{128, 0, 0},{128, 0, 0},{ 64, 0, 0},{ 64, 0, 0}, {128, 64, 64},{128, 64, 64},{128, 64, 0},{128, 64, 0},{128, 128, 0},{128,128, 0},{ 64, 64, 0},{ 64, 64, 0},{ 64,128, 0},{ 64,128, 0}, { 0,128, 0},{ 0,128, 0},{ 64,128, 64},{ 64,128, 64},{ 0, 64, 0},{ 0, 64, 0},{ 0,128, 64},{ 0,128, 64},{ 0,128,128},{ 0,128,128}, { 0, 64, 64},{ 0, 64, 64},{ 0, 64,128},{ 0, 64,128},{ 0, 0,128},{ 0, 0,128},{ 64, 64,128},{ 64, 64,128},{ 0, 0, 64},{ 0, 0, 64}, { 64, 0,128},{ 64, 0,128},{ 64, 0, 64},{ 64, 0, 64},{128, 0,128},{128, 0,128},{128, 0, 64},{128, 0, 64},{128, 0, 0},{128, 0, 0}, { 64, 0, 0},{ 64, 0, 0},{128, 64, 64},{128, 64, 64},{128, 64, 0},{128, 64, 0},{128, 128, 0},{128,128, 0},{ 64, 64, 0},{ 64, 64, 0}, { 64,128, 0},{ 64,128, 0},{ 0,128, 0},{ 0,128, 0},{ 64,128, 64},{ 64,128, 64},{ 0, 64, 0},{ 0, 64, 0},{ 0, 0, 0},{ 0, 0, 0} }; const uint8_t LED_CRITICAL_FINISH[][3] PROGMEM = { { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{108, 0, 0}, { 96, 0, 0},{ 84, 0, 0},{ 72, 0, 0},{ 60, 0, 0},{ 48, 0, 0},{ 32, 0, 0},{ 24, 0, 0},{ 12, 0, 0},{128, 0, 0},{108, 0, 0}, { 96, 0, 0},{ 84, 0, 0},{ 72, 0, 0},{ 60, 0, 0},{ 48, 0, 0},{ 32, 0, 0},{ 24, 0, 0},{ 12, 0, 0},{128, 0, 0},{128, 0, 0}, {128, 0, 0},{128, 0, 0},{128, 0, 0},{108, 0, 0},{ 96, 0, 0},{ 84, 0, 0},{ 72, 0, 0},{ 60, 0, 0},{ 48, 0, 0},{ 36, 0, 0}, { 24, 0, 0},{ 12, 0, 0},{ 0, 0,128},{ 0, 0,128},{ 64, 64,128},{ 64, 64,128},{ 0, 0, 64},{ 0, 0, 64},{ 64, 0,128},{ 64, 0,128}, { 64, 0, 64},{ 64, 0, 64},{128, 0,128},{128, 0,128},{128, 0, 64},{128, 0, 64},{128, 0, 0},{128, 0, 0},{ 64, 0, 0},{ 64, 0, 0}, {128, 64, 64},{128, 64, 64},{128, 64, 0},{128, 64, 0},{128, 128, 0},{128,128, 0},{ 64, 64, 0},{ 64, 64, 0},{ 64,128, 0},{ 64,128, 0}, { 0,128, 0},{ 0,128, 0},{ 64,128, 64},{ 64,128, 64},{ 0, 64, 0},{ 0, 64, 0},{ 0,128, 64},{ 0,128, 64},{ 0,128,128},{ 0,128,128}, { 0, 64, 64},{ 0, 64, 64},{ 0, 64,128},{128, 0, 0},{ 64, 0, 0},{128, 0, 0},{128, 0, 0},{108, 0, 0},{ 96, 0, 0},{ 84, 0, 0}, { 72, 0, 0},{ 60, 0, 0},{ 48, 0, 0},{ 36, 0, 0},{ 24, 0, 0},{ 12, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0} }; const uint8_t LED_GENRE[][3] PROGMEM = { { 64, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0},{128, 0, 0}, {108, 0, 0},{ 96, 0, 0},{ 84, 0, 0},{ 72, 0, 0},{ 60, 0, 0},{ 48, 0, 0},{ 32, 0, 0},{ 24, 0, 0},{ 12, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0}, { 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0},{ 0, 0, 0} }; void setup () { mySerial.begin (9600); mp3_set_serial (mySerial); //set softwareSerial for DFPlayer-mini mp3 module mp3_set_volume (25); pinMode(BUTTON_1_PIN, INPUT_PULLUP); pinMode(BUTTON_2_PIN, INPUT_PULLUP); pinMode(BUTTON_3_PIN, INPUT_PULLUP); pixels.begin(); pixels.show(); } uint8_t before_state[] = {OFF, OFF, OFF}; uint8_t current_state[] = {OFF, OFF, OFF}; uint8_t single_mode_flag = OFF; uint8_t game_clear_flag = OFF; uint8_t critical_mode_flag = OFF; uint8_t action = GASHAT_OFF; uint8_t led_index = 0; void loop(){ current_state[0] = digitalRead(BUTTON_1_PIN); current_state[1] = digitalRead(BUTTON_2_PIN); current_state[2] = digitalRead(BUTTON_3_PIN); if(memcmp(before_state, OFF_OFF_OFF, N_BUTTON) == 0){ if(memcmp(current_state, OFF_OFF_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_OFF_OFF, N_BUTTON) == 0){ action = set_action(LEVEL_1); }else if(memcmp(current_state, OFF_ON_OFF, N_BUTTON) == 0){ action = set_action(GASHAT_IN); }else if(memcmp(current_state, OFF_OFF_ON, N_BUTTON) == 0){ if(single_mode_flag == OFF){ action = set_action(GASHAT_NAME); }else{ if(game_clear_flag){ action = set_action(GAME_CLEAR); }else{ action = set_action(GAME_OVER); } game_clear_flag = !game_clear_flag; } single_mode_flag = !single_mode_flag; }else if(memcmp(current_state, ON_ON_OFF, N_BUTTON) == 0){ action = set_action(GASHAT_IN); }else if(memcmp(current_state, ON_OFF_ON, N_BUTTON) == 0){ action = set_action(LEVEL_1); }else if(memcmp(current_state, OFF_ON_ON, N_BUTTON) == 0){ action = set_action(GASHAT_IN); }else if(memcmp(current_state, ON_ON_ON, N_BUTTON) == 0){ if(critical_mode_flag == OFF){ action = set_action(CRITICAL_READY); }else{ action = set_action(CRITICAL_STRIKE); } critical_mode_flag = !critical_mode_flag; } }else if(memcmp(before_state, ON_OFF_OFF, N_BUTTON) == 0){ if(memcmp(current_state, OFF_OFF_OFF, N_BUTTON) == 0){ action = set_action(GASHAT_OUT); }else if(memcmp(current_state, ON_OFF_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, OFF_ON_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, OFF_OFF_ON, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_ON_OFF, N_BUTTON) == 0){ action = set_action(LEVEL_2); }else if(memcmp(current_state, ON_OFF_ON, N_BUTTON) == 0){ ; }else if(memcmp(current_state, OFF_ON_ON, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_ON_ON, N_BUTTON) == 0){ action = set_action(LEVEL_2); } }else if(memcmp(before_state, OFF_ON_OFF, N_BUTTON) == 0){ if(memcmp(current_state, OFF_OFF_OFF, N_BUTTON) == 0){ action = set_action(GASHAT_OUT); }else if(memcmp(current_state, ON_OFF_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, OFF_ON_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, OFF_OFF_ON, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_ON_OFF, N_BUTTON) == 0){ action = set_action(LEVEL_3); }else if(memcmp(current_state, ON_OFF_ON, N_BUTTON) == 0){ ; }else if(memcmp(current_state, OFF_ON_ON, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_ON_ON, N_BUTTON) == 0){ action = set_action(LEVEL_3); } }else if(memcmp(before_state, OFF_OFF_ON, N_BUTTON) == 0){ if(memcmp(current_state, OFF_OFF_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_OFF_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, OFF_ON_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, OFF_OFF_ON, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_ON_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_OFF_ON, N_BUTTON) == 0){ action = set_action(LEVEL_1); }else if(memcmp(current_state, OFF_ON_ON, N_BUTTON) == 0){ action = set_action(GASHAT_IN); }else if(memcmp(current_state, ON_ON_ON, N_BUTTON) == 0){ if(critical_mode_flag == OFF){ action = set_action(CRITICAL_READY); }else{ action = set_action(CRITICAL_STRIKE); } critical_mode_flag = !critical_mode_flag; } }else if(memcmp(before_state, ON_ON_OFF, N_BUTTON) == 0){ if(memcmp(current_state, OFF_OFF_OFF, N_BUTTON) == 0){ action = set_action(GASHAT_OUT); }else if(memcmp(current_state, ON_OFF_OFF, N_BUTTON) == 0){ action = set_action(DRIVER_CLOSE); }else if(memcmp(current_state, OFF_ON_OFF, N_BUTTON) == 0){ action = set_action(DRIVER_CLOSE); }else if(memcmp(current_state, OFF_OFF_ON, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_ON_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_OFF_ON, N_BUTTON) == 0){ ; }else if(memcmp(current_state, OFF_ON_ON, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_ON_ON, N_BUTTON) == 0){ if(critical_mode_flag == OFF){ action = set_action(CRITICAL_READY); }else{ action = set_action(CRITICAL_STRIKE); } critical_mode_flag = !critical_mode_flag; } }else if(memcmp(before_state, ON_OFF_ON, N_BUTTON) == 0){ if(memcmp(current_state, OFF_OFF_OFF, N_BUTTON) == 0){ action = set_action(GASHAT_OUT); }else if(memcmp(current_state, ON_OFF_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, OFF_ON_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, OFF_OFF_ON, N_BUTTON) == 0){ action = set_action(GASHAT_OUT); }else if(memcmp(current_state, ON_ON_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_OFF_ON, N_BUTTON) == 0){ ; }else if(memcmp(current_state, OFF_ON_ON, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_ON_ON, N_BUTTON) == 0){ action = set_action(LEVEL_2); } }else if(memcmp(before_state, OFF_ON_ON, N_BUTTON) == 0){ if(memcmp(current_state, OFF_OFF_OFF, N_BUTTON) == 0){ action = set_action(GASHAT_OUT); }else if(memcmp(current_state, ON_OFF_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, OFF_ON_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, OFF_OFF_ON, N_BUTTON) == 0){ action = set_action(GASHAT_OUT); }else if(memcmp(current_state, ON_ON_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_OFF_ON, N_BUTTON) == 0){ ; }else if(memcmp(current_state, OFF_ON_ON, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_ON_ON, N_BUTTON) == 0){ action = set_action(LEVEL_3); } }else if(memcmp(before_state, ON_ON_ON, N_BUTTON) == 0){ if(memcmp(current_state, OFF_OFF_OFF, N_BUTTON) == 0){ action = set_action(GASHAT_OUT); }else if(memcmp(current_state, ON_OFF_OFF, N_BUTTON) == 0){ action = set_action(CRITICAL_FINISH); }else if(memcmp(current_state, OFF_ON_OFF, N_BUTTON) == 0){ action = set_action(GENRE); }else if(memcmp(current_state, OFF_OFF_ON, N_BUTTON) == 0){ action = set_action(GASHAT_OUT); }else if(memcmp(current_state, ON_ON_OFF, N_BUTTON) == 0){ ; }else if(memcmp(current_state, ON_OFF_ON, N_BUTTON) == 0){ action = set_action(CRITICAL_FINISH); }else if(memcmp(current_state, OFF_ON_ON, N_BUTTON) == 0){ action = set_action(GENRE); }else if(memcmp(current_state, ON_ON_ON, N_BUTTON) == 0){ ; } } flash_led(action); before_state[0] = current_state[0]; before_state[1] = current_state[1]; before_state[2] = current_state[2]; delay(100); } uint8_t set_action(uint8_t action){ mp3_play(action); led_index = 0; return action; } void flash_led(uint8_t action){ switch(action){ case GASHAT_NAME: pixels.setPixelColor(0, pixels.Color(pgm_read_byte(&(LED_GASHAT_NAME[led_index][0])), pgm_read_byte(&(LED_GASHAT_NAME[led_index][1])), pgm_read_byte(&(LED_GASHAT_NAME[led_index][2])))); break; case GAME_CLEAR: pixels.setPixelColor(0, pixels.Color(pgm_read_byte(&(LED_GAME_CLEAR[led_index][0])), pgm_read_byte(&(LED_GAME_CLEAR[led_index][1])), pgm_read_byte(&(LED_GAME_CLEAR[led_index][2])))); break; case GAME_OVER: pixels.setPixelColor(0, pixels.Color(pgm_read_byte(&(LED_GAME_OVER[led_index][0])), pgm_read_byte(&(LED_GAME_OVER[led_index][1])), pgm_read_byte(&(LED_GAME_OVER[led_index][2])))); break; case LEVEL_1: pixels.setPixelColor(0, pixels.Color(pgm_read_byte(&(LED_GASHAT_LEVEL1[led_index][0])), pgm_read_byte(&(LED_GASHAT_LEVEL1[led_index][1])), pgm_read_byte(&(LED_GASHAT_LEVEL1[led_index][2])))); break; case LEVEL_2: pixels.setPixelColor(0, pixels.Color(pgm_read_byte(&(LED_GASHAT_LEVEL2[led_index][0])), pgm_read_byte(&(LED_GASHAT_LEVEL2[led_index][1])), pgm_read_byte(&(LED_GASHAT_LEVEL2[led_index][2])))); break; case LEVEL_3: pixels.setPixelColor(0, pixels.Color(pgm_read_byte(&(LED_GASHAT_LEVEL3[led_index][0])), pgm_read_byte(&(LED_GASHAT_LEVEL3[led_index][1])), pgm_read_byte(&(LED_GASHAT_LEVEL3[led_index][2])))); break; case GASHAT_IN: pixels.setPixelColor(0, pixels.Color(pgm_read_byte(&(LED_GASHAT_IN[led_index][0])), pgm_read_byte(&(LED_GASHAT_IN[led_index][1])), pgm_read_byte(&(LED_GASHAT_IN[led_index][2])))); break; case GASHAT_OUT: pixels.setPixelColor(0, pixels.Color(pgm_read_byte(&(LED_GASHAT_OUT[led_index][0])), pgm_read_byte(&(LED_GASHAT_OUT[led_index][1])), pgm_read_byte(&(LED_GASHAT_OUT[led_index][2])))); break; case DRIVER_CLOSE: pixels.setPixelColor(0, pixels.Color(pgm_read_byte(&(LED_DRIVER_CLOSE[led_index][0])), pgm_read_byte(&(LED_DRIVER_CLOSE[led_index][1])), pgm_read_byte(&(LED_DRIVER_CLOSE[led_index][2])))); break; case CRITICAL_STRIKE: pixels.setPixelColor(0, pixels.Color(pgm_read_byte(&(LED_CRITICAL_STRIKE[led_index][0])), pgm_read_byte(&(LED_CRITICAL_STRIKE[led_index][1])), pgm_read_byte(&(LED_CRITICAL_STRIKE[led_index][2])))); break; case CRITICAL_READY: pixels.setPixelColor(0, pixels.Color(pgm_read_byte(&(LED_CRITICAL_READY[led_index][0])), pgm_read_byte(&(LED_CRITICAL_READY[led_index][1])), pgm_read_byte(&(LED_CRITICAL_READY[led_index][2])))); break; case CRITICAL_FINISH: pixels.setPixelColor(0, pixels.Color(pgm_read_byte(&(LED_CRITICAL_FINISH[led_index][0])), pgm_read_byte(&(LED_CRITICAL_FINISH[led_index][1])), pgm_read_byte(&(LED_CRITICAL_FINISH[led_index][2])))); break; case GENRE: pixels.setPixelColor(0, pixels.Color(pgm_read_byte(&(LED_GENRE[led_index][0])), pgm_read_byte(&(LED_GENRE[led_index][1])), pgm_read_byte(&(LED_GENRE[led_index][2])))); break; case GASHAT_OFF: default: pixels.setPixelColor(0, pixels.Color(0,0,0)); } if(led_index < LED_PATTERN){ led_index++; }else{ pixels.setPixelColor(0, pixels.Color(0,0,0)); } pixels.show(); }
最初の方にずらずらっと大量の配列がありますが、この部分で、音声再生中のLEDの発光パターンをおよそ0.1秒間隔でRGB指定できるようにしています。実際の音声に同期させようとするとトライ&エラーが超超超めんどくさいですが、簡単に済ませたいなら全部同じ値にしてしまってもよいと思います。
プログラムができたら、いきなりガシャットに組み込む前に、ブレッドボードでプロトタイピングします。
見ての通り、配線はとてもシンプルです。ただ、これを実際にガシャットの中に組み込もうとすると、いつものごとくエライことに。。。ブレッドボードは本当に便利だなあと思います。
以下、動作の様子です。
ちなみに、上記のプロトの段階では、スイッチのON/OFFの定義(29, 30行目)が、最終的にガシャットに組み込むときと逆になっています(ON:LOW, OFF:HIGH)。上で公開しているソースは、最終的にガシャットに組み込むArduinoに書き込むソースになります。
これで制御ロジックの方はOKなので、後は実際に組み込むだけです。
で、いきなりですがこんな風になります。とにかく邪魔になりそうなものはすべてカットして、できるだけスペースを確保するようにしています。
元々スピーカーがあった部分には、小型スピーカーとMP3プレーヤー、それから元々はなかったスライドスイッチを追加しています。さすがに常時通電にしてしまうと、リチウムイオン電池があっという間になくなってしまうので。
ちなみに、MP3プレーヤーはMicroSDカード内の音声を再生しているだけなので、音声の差し替えは簡単にできます。ただ、先にも書いたとおり、LEDの発光パターンを音声に同期させようと思うと、それは相当面倒なことになりますので、頻繁に音声を差し替えたい方は、LEDの発光パターンはシンプルなものにしておいた方がよいと思います。
ど真ん中に、Arduino Pro Miniとリチウムイオンポリマー電池を入れています。絶縁対策は最小限です。本当はもっとちゃんとした方が良いと思うのですが、すみません、力尽きました。
元々基板があった部分には、同サイズに切ったプラ板(1.2mm)を当て込み、そこに穴を開けたりして色々組み付けています。
実は一番大変だったのが、物理スイッチの実装でした。元々の基板にあった仕組みは使えないので、何とか別の手段で再現を試みたところ、誤作動の連発。。。最後は微調整の嵐で、何とか元々のガシャットと同様に動作するようになりました。ただ、結構奇跡的なバランス(?)で成り立っている気がするので、時が経てばうまく動かなくなってしまうかもしれません。ああもう、自分で基板を起こせる人が本当に羨ましい。。。
まあともあれ、これで何とか動いてくれました。あとは見た目とか音声とか、コンテンツの準備ですが。。。
まず、ライダーガシャットの音声。これについては、以下のようにしてMP3データを用意しました。
- 実物のガシャットの音声をiPhoneのボイスメモで録音
- ボイスメモアプリ上で必要な部分のみトリミング
- PCとiPhoneを同期させてiTunesにボイスメモを取り込み
- iTunes上で、取り込んだボイスメモのファイルをMP3に変換
音量が小さかったりした場合は、さらに音声編集ソフト(自分の場合はMacのGarageBand)で音量を調整しました。
次にマリオ関係のデータですが。。。当然、マリオは任天堂の財産です。そのため、マリオの画像や音声の使用には任天堂の許可が必要という認識ですが(ガシャットもですが)、今回はあくまで個人が趣味で楽しむ範囲内での創作として、非営利目的での使用として何とか許容してもらえないでしょうか。。。と、お祈りだけはさせていただいて、以下進みます。
マリオのBGMについては、手持ちの以下のCDのデータを使いました。
マリオの効果音については、以下のソフトの特典CD(SUPER MARIO HISTORY 1985-2010)のデータを使いました。
マリオのボイスについては、こちらの方が公開されていたデータを使用させていただきました。
これらのマリオの音声データと、あとは先に録音したガシャットの音声データを音声編集ソフト(自分の場合はMacのGarageBand)で切ったり貼ったり音量調整したりしながら、必要な音声データを作成していきました。これも地味に、かなり時間がかかりました。。。
最後に、イラスト関係です。
ラベルについては、これはネット上にあったマリオブラザーズのパッケージイラストに対して、パワーポイントのワードアートでタイトルをつけて、ホワイトラベルの用紙に印刷し、シャカリキスポーツガシャットのラベルの大きさに合わせてカットしただけです。ゲーマドライバーのロゴ?(GD)と黒枠については、シャカリキスポーツガシャットのものを切り取って上から貼り付けています。
こちらについては、シャカリキスポーツのイラストを溶かして消した後、ホワイトラベルにドット絵マリオを印刷して、クリアパーツを分解した中に貼り付けました。初めは透明ラベルに印刷したものを貼り付けていたのですが、ドライバーの中で全然見えなかったので、ホワイトラベルに印刷したものを上から重ねて貼りつけました。
さて、随分長くなってしまいましたが、これで何とか完成です。ではいざ!
うん、塗装が雑なのが心残りと言えば心残りですが、まあ何とか出来上がって良かった。。。ちなみに動画には収めていませんが、ちゃんと「クリティカルフィニッシュ!」とジャンル名の音声(「アクション!」)にも対応しています。「会心の一発!」は、ちょっと力尽きてしまって入れていません。レベル1については、あくまで「スーパーマリオブラザーズ」の「ライダーガシャット」という位置付けにしておりますので、ここは『I’m a Kamen Rider!』のままにしています。
ということで、思った以上に苦労してしまいましたが、何とかオリジナルガシャットを作成することができました。今回はマリオを題材に作りましたが、ゼルダとかドラクエとか、ロックマンとかを題材に作ってみるのも楽しいと思います。
最後に事務連絡(?)ですが、本業のお仕事の方が本気で頑張らないと大変にマズそうですので、ちょっと一ヶ月ぐらい更新がストップする見込みです。また遅くとも年末ぐらいには戻ってくると思いますので、宜しければまたそのときにでも訪れていただければ幸いでございます。
ディスカッション
コメント一覧
Hi there, I’m am planning on making my own original gashat as well. Can I get a better pictures of the inside and outside of your gashat and label the parts inside the gashat. Thank you.
Hi Alex.
Thank you for your comment. I’m sorry for my late reply.
Now I’m taking new photos and writing additional explanations in English. I’m going to publish new articles about this on January 7th and 14th, 2017. Thank you for your patience.
Hi! I wish to make my own gashat as well, however I wish to make one with the Drago Knight Hunter Z as a base. (Multiple forms in one gashat) I was wondering code you modify the code or provide a code for that? Thank you
Hi, Mr.Killerurban3.
It is interesting to me to use the Drago Knight Hunter Z gashat. I want to see your original gashat!
Unfortunately, I don’t have the Drago Knight Hunter Z, so I don’t have a source code for it now. But, this is just between you and me, I’m making a new gashat, which have multiple forms in one gashat! That base is “Mighty Brothers XX” gashat, but the source code may be useful for your own gashat. I’m going to publish the gashat on February 25th, and to publish the source code on March 4th. Thank you for your patience.
I can’t wait! I’m excited for your next gashat. Hopefully i can get all the materials by then and make it asap 🙂 If you do manage to get a Drago Knight Hunter Z will you be releasing the source code as well?
If I finish the gashat i’ll send some pics and a mini video.
Thank for all the information!
>> If you do manage to get a Drago Knight Hunter Z will you be releasing the source code as well?
Hmm. If I can get it, and if I can come across a new interesting idea, I’ll do it. But sorry, I have no idea now…
>> If I finish the gashat i’ll send some pics and a mini video.
Thanks! I’m looking forward to it!
とても参考にさせていただいてます。
無知の素人ながら自分でもやってみようとガチャので挑戦しようと思っております。
スイッチ③のみ使用でLED使わないでやろうと考えています。
プログラムからLED部分、ボタン組合せを除いたプログラムで動かすことは出来ますでしょうか?
参考までに教えていただけましたら幸いです。
アーグ様
ご連絡が遅くなり、大変申し訳ありません。本業の方で珍しく長期出張だったため、しばらく家を空けてしまっておりました。。。
お問い合わせ頂いた件ですが、LEDを使わず、スイッチ3のみでの音声差し替えということでしたら、プログラムは非常にシンプルになりますので、こちらは問題ないと思います。
一つ懸念があるとすれば、ソフトではなくハードの方になります。音声差し替えをしたい場合、Arduno Pro Mini + MP3プレーヤー + スピーカー + リチウムイオンポリマー充電池をガシャットの内部に入れ込まないといけないのですが、おそらくガチャ版のガシャットはパーツ分割の都合上、内部スペースがかなり狭くなっているのではないかと思います。そのため、可能であれば、ガチャ版より食玩版の方がまだスペース的にはやりやすいかな、と思います。
私も他の人が作ったガシャットを見てみたいと思いますので、今後も可能な限りはサポートさせていただきます。何か不明点がございましたら、お気軽にご連絡ください。
いろいろとご指摘頂きましてありがとうございます。
食玩版を手に入れましたのでそちらでやってみます。
ボタン1と2に使ってるスイッチはボタン3とは違うタクトスイッチを使われていると思うのですが、どのボタンが良いのでしょうか?
こちらの記事を見ていただきたいのですが、まずボタン3はこちらで紹介している「やわらかいタクトスイッチ」を使うのがよいと思います。ボタン1と2の処理は、おそらくこの工作で一番難しいところです。スペースの都合でタクトスイッチで置き換えることが難しいため、小さく切った導電ゴムを貼り付ける方法をとっています。
いろいろとありがとうございます。
今までこのような事をやったことのない超ド素人なのでこのようなアドバイスはとても参考になります。
現在、書き込みエラーでなかなか書き込めなくてあれこれネットで調べながらいろいろと試しております。
ケーブルは百均のケーブルを利用し、通信の互換機にスイッチサイエンスさんオリジナルのを使用しております。
その他音源等の素材は揃ってはきております。
途中報告も併せてご連絡です。
アーグ様
ご連絡頂きありがとうございます。また、返事が遅くなってしまい申し訳ありません。その後、書き込みはうまくいきましたでしょうか。
私の方で書き込みが失敗するときによくあるのは、USB接続しているはずのArduinoが、そもそもPCに認識されていないというケースです。再起動することで認識されることがよくありますが、たまに、USBケーブルを別のものに変えると認識されるということもあります。100均で売っているUSBケーブルだと、充電専用で通信線がカットされているものもありますのでご注意ください。
ケーブルは通信用のものなのでやりとりはできております。
抜き差しなど試しても途中で拒否されたり、COMが見つからないなど出てしまいます。
再起動はやったことがなかったので試してます。
お世話になってます。
先ほど書き込みに成功いたしました。
ブレッドボードで配線確認に移ります。
ジャンパワイヤー不足はコードを切って差し込んでみたりしてますが、部品に多少の不安もあるので来週末に秋葉原にいく予定なのでパーツの調達してから再度チャレンジ予定です。
ご連絡ありがとうございます。無事に書き込みができて良かったです◎
ブレッドボード上で正しく動いてくれれば、六割方は出来たと言って良いと思います。もしブレッドボード上で配線してもうまく動いてくれない場合は、ガシャット本体にパーツを押し込む前にご相談ください。
先日はTwitter上でもありがとうございました。
ブレッドボード上で試してみました。
動画の位置を参考にやってみましたが、通電が出来ていないのかランプすら付かない状態でした。
リチウムイオンはしっかり充電できていて通電も出来ています。
コードは全てジャンパワイヤーを使ってはいます。
もう少し調整しながら試してみます。
アーグ様
配線についてですが、こちらの記事の配線図の方がわかりやすいかと思いますので、こちらをご参照ください。また、ソースコードも同じページにあるものを使う方が良いです。
もし必要でしたら、ソースコードと配線の写真をお送りくだされば、こちらでコードと配線をチェックすることも可能です。すぐには無理ですが、幸いゴールデンウィーク休暇がありますので、その間には対応できると思います。
作り方を参考にさせていただき、やってみたのですが、失敗の連続です。
自己責任になるのは承知で、制作していただけないでしょうか?または、購入させていただけないでしょうか?お願い致します。
ひかる様
ヒダカヒロジです。お世話になっております。
「販売」という形は色々問題になってしまいますのでお受けできないのですが、ひかる様自身のガシャット制作のサポートであれば、お受けできるかもしれません。具体的には、ひかる様のガシャットで発生している問題点と、配線の写真やソースコードを私に送ってもらって、おかしいと思われるところをこちらでわかる範囲でお調べする、という形です。本業と育児の合間を縫っての作業になりますので、レスポンスはどうしても遅くなってしまいますが。。。いかがでしょうか? それでよいということでしたら、改めて私の連絡先をご連絡させていただきます。
初めまして。
今更ながら、ガシャットを作ろうと思い、記事を読んだのですが、
LEDのテープが品切れで、何か互換性のある物はありませんか?
また、arduinoは触ったこともなく、スケッチに使う言語の文法
がわかりません。できれば、スケッチだけでも作成していただけませんか?
以下、内容です
内容的には、プレバンガシャットに近く、ボタン操作でボイスモード
になるようにしたいのです。(ボイスモード4つと通常モード1つがあり、各ボイスモードごとに4つ音声を入れたいです。切り替え時にも音がなるように
したいです。通常モードは音声3つほどです。)
ずうずうしくてすいません。
よろしくおねがいします
すみません追記です。
各モードで変身音を変えるというのを書くのを忘れてました。
具体的には、レベル1音声以外は全てバラバラにしたいんです。
できれば、お願いします。
クオリア様
ご覧いただきありがとうございます。
> LEDのテープが品切れで、何か互換性のある物はありませんか?
私の方で検証はしていませんが、おそらく、以下が後継品のハズです。スイッチサイエンスで販売しています。
https://www.switch-science.com/catalog/1399/
https://www.switch-science.com/catalog/1398/
また、スケッチの作成につきましては、申し訳ありませんがお受けすることができません。本業と育児で、このブログの更新が滞ってしまうぐらい、工作のための時間を確保することができていないためです。申し訳ありません。お約束はできませんが、ご自身で作業を進めて頂き、何か不明点が出てきましたら、お問い合わせ頂ければアドバイスぐらいはなんとかできるかもしれません。
ガシャットの制作は、Arduinoの初心者の方には結構ハードルが高いと思います。そのため、始めから完成形を目指すのではなく、「ボタンに反応させる」「音を鳴らす」「光らせる」等の個別の要素をまずはサンプルとして単独で動かしてみて、それらを十分に扱えるようになったら、私の公開しているソースコードを参考に、各要素をまとめ上げるように進めていくと良いと思います。
わざわざすいません。
スケッチのほうはなんとか自分でやってみようと思います。
返答ありがとうございました。
お久しぶりです。
ソフト面でなく、ハード面の質問なのですが、バッテリーとarduinoの接続方法を教えていただけませんか?
専用のプラグとかが必要なんでしょうか。
クオリア様
お世話になっております。私と同じようなリチウムイオン充電池を使用しているのであれば、下記のようなコネクタがあった方が接続しやすいと思います。
JST製2ピンPHコネクタ用ソケット
https://www.switch-science.com/catalog/2090/
お久しぶりです。
hidaka_hiroji さんのコードを参考に自分もコードを書いてみたのですが、
エラーが出てしまいます。どうやら、
mp3_set_serial (mySerial);
のところでエラーが出ているようなのですが、最初にきちんと
#include
#include
#include //環境に合わせて変更
#include
と書いてあるはずなんですよね。ちなみに
DFRobotDFPlayerMini.hと
Adafruit_NeoPixel.hはどちらも最新版?を使っています。
(DFplayerは1.0.2で、NeoPixelのほうは1.1.6です。)
返答お願いします。
追記:htmlがつかえること忘れてました。
#include
のあとには、上から
string.h
SoftwareSerial.h
DFRobotDFPlayerMini.h
Adafruit_NeoPixel.h
がきちんと括弧のなかにはいっています。
クオリア様
ご連絡が遅くなり申し訳ありません。本業の方の出張でしばらく家を空けていました。
ちたけうどん様がコメントくださっているように、最新版のDFPlayerMiniのライブラリ(DFRobotDFPlayerMini.h)を使用している場合は、それに応じて使用する関数名を変更してやる必要があります。例えば、古いライブラリ(DFPlayer_Mini_Mp3.h)でmp3_set_serial(mySerial)とmp3_play(25)であったものは、それぞれ
DFRobotDFPlayerMini myDFPlayer;
myDFPlayer.begin(mySerial);
myDFPlayer.playMp3Folder(25);
のように置き換えれば動くはずです。詳しくはこちらのページのSample Code “FullFunction”をご参照ください。
横から失礼します。
私もDFRobotDFPlayerMini.hのライブラリ版に改修中なので、同様の問題に突き当りましたが、mp3_set_serial (mySerial)やmp3_set_volume (25)、 mp3_play(action)の部分はDFRobotDFPlayerMini.h用のコードに修正しないとエラーが出ちゃうみたいです。
とはいえ、我が家の試作環境では、コードを修正してもDFplayerが正常に動作してくれなかったので、当面の間はDFPlayer_Mini_Mp3.hライブラリを使用する予定ですが…
ちたけうどん様
ご連絡が遅くなり申し訳ありません。本業の出張でしばらく家を空けていました。フォロー頂きありがとうございます。
私も最近別の工作でDFPlayerMiniの新しいライブラリを使い始めました。とういうのも、旧ライブラリだと、番号が大きい曲(0312.mp3)などがうまく再生できず。。。これは、新しいライブラリでplayMp3Folder()関数を使うとちゃんと再生してくれました。一応、少なくともこちらの環境では新しいライブラリ+Arduino Unoでは動作確認できているので安心していたのですが、おっしゃる感じですと、別のArduino環境に変えたときにうまく動いてくれないかもしれないですね。。。
hidaka_hiroji 様
コメントありがとうございます。
DFPlayerの新しいライブラリは、私にとってタイムリーな話題だったので書き込んでしまいました。
クオリア様あての返信を見る限り、私の修正した内容とほぼ同じだったのですが、一部だけ異なったのは、myDFPlayer.begin(mySerial)の所をサンプルコードと同様にif (!myDFPlayer.begin(mySerial))~にしていた所でした。もしかしたら、ここが動作不良の原因かもしれないので後でスケッチを修正して確認してみます。
ちたけうどん様
クオリア様のコメント欄では簡略化して
DFRobotDFPlayerMini myDFPlayer;
myDFPlayer.begin(mySerial);
で書かせていただいていますが、実際には私もサンプルコードのとおり
mySerial.begin (9600);
if(!myDFPlayer.begin(mySerial)) {
Serial.println(F(“Unable to begin:”));
Serial.println(F(“1.Please recheck the connection!”));
Serial.println(F(“2.Please insert the SD card!”));
while(true);
}
と記入しています。そのため、この部分は特に問題ではないかもしれません。となると、あとは電源の問題か、繋ぎ方の問題か。。。ちなみに、使用しているArduinoは何になりますか?5V系のArduinoの場合は、ソフトウェアシリアルの接続の間に1kΩの抵抗を挟まないとうまく動作しなかったりしますので、念のため。。。
以上、取り急ぎ。
hidaka_hiroji 様
再度コメントありがとうございます。
>使用しているArduinoは何になりますか?
Arduio互換のPro Micro 3.3V版を購入したつもりだったのですが、先程、仕様を確認するため同製品のページを見直したところ、半年ほど前のレビューに「3.3V表記は嘘で、VCCはJ1 open状態で5Vです。」とあったので、原因は5Vみたいです…
今までの試作がよく無事に動作したなとは思います。
ちたけうどん様
すみません、レスポンスが遅れてしまいました。。。Microということは、ATmega32u4ということでしょうか。その系列は、実はほとんど使ったことがないのです。よくはわかっていないのですが、UNOやPro miniで使われているATmega328系とはちょっと挙動が違うのかなあと思って、これまで避けていました。そのへんの相性もあるのかもしれませんね。
ちたけうどん様とhidaka_hiroji 様の会話についていけないです(笑)
aruduinoに関しては初心者なので、なんとなくでしか聞き取れません。
それはさておき。
紹介してもらった方法でコンパイルしたところ、その部分でのコンパイルは成功したのですが、
before_stateがOFF_ON_OFFの中の
current_stateがOFF_OFF_ONの部分で、
‘set_action’was not declared in this scope
と出てきてしまいました。
その上の
action = set_action(LEVEL_3);
ではエラーが出なかったのです。
…なぜでしょうか?
クオリア様
「before_stateがOFF_ON_OFFの中のcurrent_stateがOFF_OFF_ONの部分」では、元々set_actionは呼び出していなかったかと思うのですが。。。
もし何かしら修正を加えられたのだとしたら、おそらくその修正が原因です。申し訳有りませんが、それ以上のことはわかりません。
どうにも原因が解明できないときは、思い切って怪しい部分をまるっとコメントアウトしてコンパイルを試してみるというのも手です。
それでコンパイルが通るのであれば、コメントアウトした部分に100%原因があることになりますし、コメントアウトしてもエラーが出るのであれば、他にもっと根本的な原因が存在することになります。
問題解決の進め方は、とにかく問題を切り分けて一つずつ検証していくことです。このガシャットのプログラムはおそらくArduinoの初心者には難しい内容も含んでいると思いますので、難しいと感じたら、シンプルにMP3を鳴らすだけ、フルカラーLEDを光らせるだけ、といった機能ごとのサンプルを作って動かせることを確認してから、また戻ってきて進めるようにすると良いと思います。
アドバイスありがとうございます。
試してみます。
毎度毎度お騒がせしてすみません。
最近やっとarduinoIDEに慣れてきて、コンパイラのエラー部分をよく見たら、
すべてのset_actionにエラーが出ていました。
arduino自体触るのが初めてだったので、スケッチも音声を多くしようとした以外ではいじってないはずなのですが…
IDEかライブラリのバージョンのせいでしょうか。
hidaka_hiroji 様のスケッチとにらめっこしても、ほとんど同じですし、
元々のスケッチでも似たエラーが出てしまいます。
クオリア様
こういうときは、自分で適当なダミー関数を定義してみて、それを呼び出したときに同様のエラーが発生しないかどうかなど、試せることは色々あると思います。そうやってTry&Errorを繰り返して、少しずつ原因と思われるところを特定していってください。できる限り質問にはお答えしますが、申し訳ありませんが、私は全てのご質問に答えられる余裕はありません。本業の方がだいぶ忙しくなってきてしまって、自分のための工作すら満足に進められない状況です。そのため、個別の質問にはお答えできない代わりに、基本的な問題解決の手法をお教えしています。それで何とか、自分で解決する術を身につけていってもらえますと幸いです。
お久しぶりです。
ついにスケッチが(少なくともコンパイラー上で)エラーを出さず完成させることができました。ちたけうどん様、hidaka_hiroji 様、本当にありがとうございます。
せっかく教えてもらったDFRobotDFPlayerMiniなのですが、どうしても僕の環境ではエラーがでてしまいました。結局、旧バージョンのスケッチに対応させて、完成しました。度重なる質問に丁寧に答えていただき、ありがとうございます。
クオリア様
ご連絡頂きありがとうございます。クオリア様の粘り強さの賜物だと思います。
コンパイルは通ったということで、これからはいよいよブレッドボード上での試作に入られるかと思います。おそらく十中八九、思うように動作しないということが起こると思いますが、ここから先の修正は、ソースコードの中身の理解と、電気回路についての基礎的な知識が必要になります。難しさの内容がまた一段レベルアップすると思いますが、粘り強く知識を身につけながら取り組んで頂ければと思います。
以上、宜しくお願い致します。
お久しぶりです。
ボード上で組んでみたのですが、おしゃる通り思った通りに動かないですねw
そもそもLEDが光らないという問題です。
LEDにバッテリーから直で3.3vしか与えていないからか、もしくは
まだ音声の加工が終わっていないので、それが原因でしょうか。
あと、DFplayerについてなのですが、電源投入でLEDが光らないと、
初期不良なのでしょうか。僕のは光りませんでした。
作り終わる目標は来年一月なので、のんびり作っていきます。
クオリア様
これもデバッグの基本ですが、Serial.println()とArduino IDEのシリアルモニタを使って、「今どのあたりまで処理が進んでいるのか」を地道に確認するようにしてください。例えばsetup()の中でDFPlayerの起動に失敗して、そこで無限ループに入ってしまったりしていないでしょうか。
また、DFPlayerですが、私もかれこれ10個以上は使っていますが、初期不良にあたったのはそのうちの1回ぐらいです。これもまた、以前から申し上げているのですが、うまくいかない時は問題を小さく分解してください。いきなりガシャットプログラムで動作確認するのではなく、適当な音声を再生するだけの小さなサンプルプログラムを作って、それがまず実際に接続してみて動くかどうかから確認してください。
お騒がせしました。
どうやらSDカードがちゃんと入っていなかったみたいで、もう一度入れなおすと直りました。
僕の環境では、コメントを打つのと作成に使う場所が離れているので、
こんどからはちゃんと試行錯誤してからコメントするようにします。
本当にすいません。
いえ、思ったよりすぐに解決する原因でよかったです。DPPlayerは結構癖のあるモジュールなので、「うまく動作しない」という方が結構多いのです。特に入力電圧の条件が結構シビアな気がします。
もう一つ、問題点を見つけたので(僕が作ってしまったのですが。)
結局DFplayerは買い替えることにします。
なんというか、RX/TXの部分の銀色の丸い部分が
完璧にはがれてしまって(笑)。
届くまで音声加工でもしてようと思います。
お久しぶりです。
とりあえずLEDの発光テストをしようと思い、スケッチからmp3再生系統の
コードを消してテストしてみたのですが、なぜか光りませんでした。
エラーもありませんでしたし、書き込みが完了しました。の表示もきちんと行われました。なぜでしょうか。
ちなみに書き込みはラズベリーパイ3版のarduinnoIDEから行いました。
クオリア様
情報が少ないので正確な判断はできませんが、プログラムに問題がないのであれば、配線側の問題である可能性が高いと思います。今一度、正しく配線がなされているか、また配線の内容とプログラムのGPIOのpinModeの設定が合っているかをご確認ください。
お久しぶりです。
前回の件ですが、多分配線はあってると思います。
一度、僕のコードを確認していただくことは可能でしょうか?
クオリア様
本業+育児であまり時間がとれないため、保証はできませんが、可能な限り見るようには致します。
追って、ご連絡頂いたメールアドレスにご連絡させて頂きます。
さては天才だなオメー(褒め言葉)
チョコバニラ 様
ありがとうございます◎ どちらかというと、努力型の凡人ですよー(笑)
突然失礼します。
オリジナルガシャットを中身まで完成させてしまうとはすごいです。
私もオリジナルガシャットを作ろうと思ったのですが、こちらと改良版の掲載されているソースコードを使用して作ってもよろしいでしょうか?
E.F.B 様
ご丁寧にありがとうございます。はい、問題ありません。
もし作成されたものをどこかに公開するようなことがありましたら、その際には、可能であれば「この人のソースを参考にした」ぐらいを補足頂けましたら嬉しいです。
以上、宜しくお願い致します。
返信ありがとうございます
試作ですがTwitterに挙げさせていただきました(https://twitter.com/EFBlizzard3909/status/1114554158034513920?s=19)
まだLEDパターン書ききれてませんけど
そう言えば他の方のコメントにLEDがつかない、と言ったものがありましたが、恐らく電力不足なだけかと
5VのLEDなので3.3では動かないと言うことではないでしょうか
私の方でも同様な事が起きましたが、arduinoとMP3を3.3Vバッテリーから、LEDをarduinoのVCCから電源を取ると普通に動きましたので参考になれば
EFB様
ありがとうございます、見ました。私の知らない分野ですが、音声の完成度凄く高いですね。
> そう言えば他の方のコメントにLEDがつかない、と言ったものがありましたが、恐らく電力不足なだけかと
> 5VのLEDなので3.3では動かないと言うことではないでしょうか
そうですね。ここで使っているNeoPixelは公式には確か5Vの駆動のはずなので、3.7Vでは何とか動いてくれても、3.3Vでは厳しい、ということなのだと思います。
初めましてヒダカ ヒロジ管理人様
オッカーと申します。
突然ではありますがお礼をさせていただきたくコメント致します。
この度ガシャットの作成に再挑戦しボタン及び音声再生においてほぼ完成を見ました。
挑戦にあたり参考にさせていただき大変助かりました。
ありがとうございます。
LEDについては現在格闘中ですが最終的にはお借りすることになりそうです。
ありがとうございます。
私はPLCのプログラムは書けるのですが、c++は専門外で悪戦苦闘しております。
もしよろしければ相談に乗っていただけませんでしょうか。
動作についてはプログラムをwebページで検索し仮機で動作確認しながら詰めていきました。
そのおかげでほぼ完成させることができました。
問題なのはそのほぼの部分です。
それは音声が鳴っている間ボタンの入力を無効にすることです。
これは1本刺し武器のキメワザなどがDX版ではそのような処理がされています。
タイマーを入れるのが最も簡単ではないかと思いますが、自分としては音声を入れ替えるだけで別物として使えるようにしたいので、音声モジュールの状態を読み取れるといいのですがやり方がどのwebページを見てもさっぱりでした。
ちなみに部品構成はヒダカ ヒロジ様とは大きく変わっていて
本体arduino ss micro(5V)
音声モジュールvoice module V1.0(3.3V)を使用しています。
私が購入したDFPlayer miniはHiLetgo製だったのですがどれだけ試しても通信で音声を鳴らすことができませんでした。5台すべて。
厚かましいお願いだとは存じますが何かアドバイスを頂けると幸いです。
初出での長文失礼いたしました。
オッカー様
DFPlayer miniを使用することができるのであれば、DF Player miniには「BUSY」というピンがありますので、このピンのHIGH/LOW状態をチェックすることで、現在音声が再生されているかいないかをチェックすることができます。私も一度、トランスチームガン・カスタムというものを作ったときに使用したことがあります。
参考:オリジナルベストマッチをつくる 〜トランスチームガン・カスタム〜
音声モジュール(voice module V1.0)というものは、私は使用したことがないので、BUSYピンに相当するものがあるのかどうかはわかりません。
ちょっと気になることとして、既に試された上でうまくいっていないのかもしれませんが、DFPlayer miniは基本的に3.3V付近で動くものなので、5VのArduinoと直接繋いだりした場合にはうまく動かず、間に抵抗を挟むなどして5Vと3.3Vの間のレベル変換が必要だったように思います。
アドバイスありがとうございます。
voice module V1.0にもBUSYの端子があります。
通信をしているので通信でという固定観念に囚われていました。
早速プログラム修正させていただきます。
ありがとうございます。
DFPrayer miniの通信はいろいろなwebページを確認したところ1kΩを入れている方が多かったので試行済みです。
TXのみやRXのみ両方に入れるなどしてみましたが結果はNGでした。
ライブラリが2種類あってどちらかが対応していないと書いてあったりしたのでライブラリの問題かもしれません。
余談ですがvoice module V1.0ではTX、RXに1kΩを入れています。
直でも通信は出来ましたが、通信するたびにスピーカーからノイズ音が出て耳障りでした。
ピンバック & トラックバック一覧
[…] 参考:オリジナルガシャットをつくる 〜スーパーマリオブラザーズガシャット〜 […]
[…] ップ用アイテムである『マイティブラザーズXXガシャット』。自分は前に『スーパーマリオブラザーズガシャット』を作りましたが、こちらが正当なマリオブラザーズモチーフのガシャッ […]
[…] I modified a part of design from that in this article, so the source code also needs to be modified as follow: […]
[…] ーパーマリオブラザーズブラザーズガシャットの作者、ヒダカさんは 制作過程をブログにも掲載されているようですので、 つくり方などが気になった方は、こちらもぜひ併せてご覧にな […]
[…] 自分は特に玩具改造が専門というわけではないので、以前に作ったマリオガシャットは、自分の趣味の電子工作の中でたまたま出来た作品の一つに過ぎませんでした。そのため、ガシャ […]
[…] イド』が始まって一ヶ月ぐらい(2016/11)の頃に作成した、オリジナルの『スーパーマリオブラザーズガシャット』。これのパワーアップ系の音声(レベル3やキメワザ)にはスターの音 […]