オリジナルライドウォッチをつくる 〜ハード編〜
オリジナルライドウォッチ改造記事のラストです。実際に遊べる形に持っていくための、ハード改造編です。必要な具材、プログラムにつきましては、それぞれ前々回、前回の記事をご参照くださいませ。
前回は私の万丈ライドウォッチというよりかは、「普通のライドウォッチ」の動きを再現するためのプログラムについて説明しました。今回も同じように「普通のライドウォッチ」を作るための説明をした方が親切だとは思うのですが、申し訳ないことに今の私の手元には万丈ライドウォッチしかありませんので、万丈ライドウォッチの作り方としてご説明します。といっても、普通のライドウォッチとの違いは、ハード的には「普通のLEDを使うかフルカラーLEDを使うか」と、「フォームチェンジを認識させるためのリードスイッチを入れるか入れないか」だけの違いですので、ここで説明する内容はほぼそのまま、普通のライドウォッチを作るときにも使えるハズです。
まず、DX版ライドウォッチをバラバラに分解します。分解の際は、バネがどこかに飛んでいってしまわないようご注意ください。特に、リングの回転をロックする部分のバネは飛んでいってしまいやすいので注意です(←やりました)。バネが飛んでいってしまって見つからない場合には、例えばノック式ボールペンに入っているバネなどを短く切って代用するなどしても良いと思います。
上の写真の分解はまだ不充分で、ここからさらにクリアパーツ、リングの回転をロックする部分を外す必要があります。分解が済んだら、ネジやバネ、細かいパーツはどこかになくしてしまわないように、小皿などにちゃんと分けておきましょう。また、ライダーの顔を別のものに付け替える場合は、シールを剥がす必要があります。経験的には、ドライヤーで温めてからだと比較的綺麗に剥がせる気がします。
塗装が必要な場合は、このタイミングで塗装してしまっても良いと思います。ただ、作業の途中でなんやかんや加工して塗装が一部剥がれてしまうということはよくあるので、気になる方は全て組み上がってから塗装した方がよいと思います。自分は後先考えずにまずはエイヤと作業してしまいましたので、このタイミングで塗装しています。
今回自分が作った万丈ライドウォッチの場合は、基本のクローズのイメージに近づけるため、本体部分(上写真左側)を黒に、リングやら竜頭やらの部分(上写真右側)を青に塗装します。なお、ベースはビルドライドウォッチですが、ジクウドライバーにはクローズとして認識させたいので、認識プレートの部分だけはクローズライドウォッチのものを使用しています。
とりあえずエイヤっとまとめてサーフェイサー。ちなみに自分は塗装に関しては素人というかかなり雑なので、あまり参考にしない方がよいと思います。
サーフェイサーが乾いたら、メタルブラックとメタルブルーのスプレーをそれぞれ吹っかけました。
ここで一個ミスに気づきました。ライドウォッチ本体のこの部分、実はLEDの発光を透過させるためのクリアパーツが入っていたのですが、それに気づかずサーフェイサーやらスプレーを吹っかけてしまいました。この部分は裏のネジを外せば外すことができるので、最初に忘れず分解しておきましょう。
塗装が終わったら、好きなタイミングでラベルシールをクリアパーツとリングパーツに貼り付けます。画像データは、元々のライドウォッチのシールを剥がしてスキャナでスキャンして取得する、あるいは誰かが提供してくれているものを利用させてもらうとして、それをどれぐらいのサイズで印刷すれば良いかはトライ&エラーです。自分の場合は、パワーポイントにいくつか大きさの微妙に違う画像データを並べて普通のA4用紙に印刷してみて、実際それを切ってみて丁度良いサイズが見つかったら、それをラベルシールの用紙に印刷するようにしています。
以上で入れ物の準備は完了です。いよいよメインの電子回路の部分に入ります。はじめに、作る回路の全体像を共有しておきます。
前回ご紹介したものとほぼ同じですが、LEDがフルカラーLEDに変わり、フォームチェンジを認識させるためのリードスイッチが追加されています。これらの変化に伴い、ピンの配置も少し変わっているのでご注意ください。普通のライドウォッチを作りたい方は、前回紹介した回路図の方を参照してください。
まずはブレッドボード上に上図のとおり配線してみて、プログラムが正しく動作するかを確認しましょう。
ちなみにすみません、リードスイッチを取り付けた状態の写真を撮り損ねました。実際には上図にさらにフォームチェンジ用のリードスイッチも配線する必要があります。また、万丈ライドウォッチ用のプログラムは本記事の最後に掲載しています。
動作が確認できたら、ライドウォッチ本体の加工に入っていきます。
まずはジクウドライバーとの連携部分、前回のプログラム解説で言うところのSW-1とSW-2の認識部分の作成です。一番最初にいきなりで申し訳ないのですが、ここがこのライドウォッチ作成で一番神経をつかうところです。ここを雑に作ってしまうと、せっかく作ってもジクウドライバーと連動しない、ということになってしまいます。
こんな感じで、1.2mm厚のプラ板に穴を開けて、ディテクタスイッチ2つを並行に並べます。プラ板と穴のサイズの目安は以下のようになります。
あくまで目安ですので、最終的には微調整が必要だと思います。
最終的にはこんな感じでプラ板をはめ込んで、SW-1とSW-2が押されたら、それぞれ対応するディテクタスイッチがONになるようにします。が、ここで注意点が2つあります。
まず、2つのディテクタスイッチが、上写真で言うところの左端からの位置ができるだけ揃うように位置を調整する必要があります。というのも、この位置関係がずれてしまうと、ジクウドライバーにライドウォッチをセットしたときに、本来満たされるべき「SW-1とSW-2が同時に押される」という条件が満たされず、代わりに「SW-1の後にSW-2が押される」というような別の条件が満たされてしまう可能性があります。
もう一つの注意点として、SW-1とSW-2が少しでも押されたらディテクタスイッチが反応するよう、ディテクタスイッチの位置を調整する必要があります。ライドウォッチの実物をお持ちの方はよくご存知だと思いますが、このSW-1とSW-2の部分は少しでも触ると反応してしまうぐらい感度が良くて、音声(特にライドウォッチを取り外したときの音)を暴発させてしまうことがよくあると思います。ああいう仕様になっているのはそれ相応の理由があって、
SW-1とSW-2は、ジクウドライバーのこの部分で実際に押し込まれることになるのですが、この押し込みの深さが結構浅いのです。そのため、「スイッチを深く押し込まないと反応しない」というような状態では、ライドウォッチをジクウドライバーにセットしたとしても、スイッチが反応してくれないのです。
そのため、位置決めが済んで、配線の半田付けと(ホットボンドでの)スイッチの位置の固定ができたら、
こんな感じで、他のパーツを組み付けていく前に、ブレッドボード上で「スイッチの同時押しが認識される」「スイッチを軽く押したら反応してくれる」というのを確認しておくことをオススメします。できれば、この状態でジクウドライバーにセットして、ドライバーを回転させたときにスイッチが押されるかを確認するのがベストです。パーツを全部組み付けてから戻ってきて微調整するのは、結構面倒臭いです。
SW-1, 2の感度が鈍い場合は、こんな感じでディテクタスイッチとの接触部分に薄いプラ板を貼ることで、ある程度は感度を調整できます。
「SW-1, 2を押すとディテクタスイッチは押されるけど、SW-1, 2が押されたままになってしまう」というときは、ディテクタスイッチがSW-1, 2に近づき過ぎているので、プラ板などでディタクタスイッチの高さを微調整してあげましょう。かといって、ディテクタスイッチの位置を高くし過ぎると、今度はSW-1, SW-2が押し込まれてもディテクタスイッチが反応しない…ということにもなるので、ここはもう、辛抱強く微調整する必要があります。
この微調整が辛過ぎる、という方は、元々のDX用基板のディテクタスイッチ部分だけを基板ごと切り離して持ってくる、という手もあるかもしれません。自分は試していませんが。
SW-1, 2の部分の処理が済んだら、次はその上に、配線済みのDFPlayerを被せます。DFPlayerのスピーカーには、元々ライドウォッチに組み込まれていたスピーカーと接続しています。
そのまま被せると、最後にライドウォッチの蓋が閉じなくなってしまうので、ピンを全体的に少し短く切ってあげましょう。あんまり切り過ぎると、先にセットしたディテクタスイッチとモロに干渉してしまうので、ほどほどに。
Tipsですが、DFPlayerには2つのGND端子があります。この2つは内部的には当然繋がっているので、DFPlayerの一つのGNDを後でArduino基板のGNDに繋いでしまえば、先ほどのディテクタスイッチのGND側の配線は、Arduino基板ではなくDFPlayerのもう一方のGNDに繋いでしまって問題ありません。こうすることで、配線数が増えがちなGND端子への接続を少し分散させることができます。
続いて、竜頭スイッチ(SW-C)の処理です。こちらは簡単。
「やわらかいタクトスイッチ」に配線したものを1.2mmプラ板にホットボンドで固定して、
元々LEDの基板が入っていたところにはめ込みます。竜頭スイッチ側の方は元々の出っ張り部分をカットして、その部分に薄いプラ板を貼り付けておけば、やわらかいタクトスイッチを良い感じに押せるようになります。
ここからは、本体の蓋側の方の処理になります。まずはフルカラーLEDの処理です。
最終的にこんな感じで、フルカラーLEDがライドウォッチの蓋側の小さな窓(クリアーパーツがあったところ)から顔を出してほしいので、
フルカラーLEDをギリギリまでカットします。これぐらいカットしてしまっても、配線さえ正しければちゃんと動きます。
本体裏側から、カットしたフルカラーLEDを差し込みます。
おそらくブカブカになってしまうので、小さく切ったプラ板をスペーサーとして差し込んでフルカラーLEDを固定させます。これでフルカラーLEDの処理はとりあえず終了です。
続いて、フォームチェンジ用のリードスイッチの処理です。この処理は、フォームチェンジ機能が不要であればいりません。
リードスイッチを反応させるためのネオジム磁石はリングの突起部分に取り付けることになるのですが、いくらネオジム磁石が強力といえども、本体内側にあるリードスイッチを反応させようと思うと結構距離が厳しくなります。
リードスイッチの対向のネオジム磁石はこんな感じでリングにはめ込むことになるのですが、モノによってはスッと入らず、ニッパやヤスリで多少穴を大きくしてやる必要があります。これが面倒だからといって小さめのネオジム磁石にすると、今度は磁力が弱くなってリードスイッチが反応しない…ということもあり得るので、ここは多少トライ&エラーが必要かもしれません。
リードスイッチを固定してしまう前に、仮で位置決めし、リングの回転に応じてリードスイッチが反応するかどうかを必ず確認するようにしましょう。反応することが確認できたら、ホットボンドなどでリードスイッチを固定します。なお、リードスイッチは非常に脆い部品ですので、取り扱いに充分ご注意ください。
本体蓋側に必要な部品はフルカラーLEDとリードスイッチの2つだけですので、それらの取り付けが終わったら、本体下側と接続するためのピンヘッダを作ります。GNDをフルカラーLEDとリードスイッチでまとめてしまえば、ピンヘッダは4本になります。
さて、本体下側に戻り、Arduino基板に諸々配線していきます。
いきなり完成形で申し訳ありませんが、配線はこんな感じになります。写真では見辛いですが、最初の回路図の通りです。本体蓋部との接続が必要な部分は、ピンソケットにまとめています。GNDのとりかたは、できるだけArduino基板のGND端子で全部をまとめてしまわないよう、DFPlayerのGNDを活用するなどして、できるだけ分散させるようにしています。
というのも、実は、最初に作ったときにやらかしてしまっていて、GND線とプラス線をArduino基板上の端子にまとめ過ぎて、Arduino基板上でそれらが接触してショートし、基板とDFPlayerを壊してしまいました。そのため、実は一回、ほぼ作り直しになっています。
こちらが最初に作成したときの配線になります。GND端子とプラス端子(RAW端子)がArduino Pro mini上では隣り合わせであるにも関わらず、上図のように危険極まりないことをしてしまいました。反省。
気を取り直して、少し細部をみます。
電源スイッチ(スライドスイッチ)は、この位置に入れています。
この部分は元々スリット状になっているので、少し加工してやれば、スライドスイッチが顔を出せるようになります。
リチウムイオンポリマー充電池は、最小のものを用意して、コードを巻いてこの位置に。細めのピンソケットを使えば、リチウムイオンポリマー充電池用のコネクタ(2ピンPHコネクタ)を使わずとも電力をとれます。
全ての配線ができていることを確認したら、本体蓋部と下部のピンヘッダ・ピンソケットを接続して、本体を閉じる前に一度電源スイッチを入れてみましょう。
この状態で、まずは正しく動作するかの確認です。確認ができたら、本体を閉じてネジ止めし、再度動作するかを確認しましょう。
自分の経験的に「本体を閉じる前は正しく動作していたのに、本体を閉じると動作しなくなる」ということは、とてもよくあります。この現象の原因はほぼ100%、接触不良によるものです。つまり、本体を閉じる前は配線としては問題なかったが、本体を閉じると、本体内で無理な力が局所的にかかってしまい、リード線の断線や他の線との接触、半田外れが発生してしまうということです。対策としては、ピンソケットやピンヘッダ、基板端子部など、半田付けが発生しているところをことごとくホットボンド(グルーガン)で保護してしまう、という手があります。上の方の写真でも、透明なゲル状のものがArduinoの端子やピンヘッダ・ピンソケットについているのが見えると思います。これをやっておくと、多少力がかかるぐらいでは、断線や半田の外れは起こらなくなります。まあ、そもそもは内部に局所的な力が発生しないように、余裕を持った設計をするのが一番なのですが…
さて、ここまでくればほとんど終わったようなもので、あとは最後の仕上げです。
フルカラーLEDはこんな感じで顔を出しているのですが、光が直進的過ぎて、クリアパーツが思ったより綺麗に発光してくれないと感じる場合があります。
その場合は、フルカラーLEDとクリアパーツの間に、光拡散キャップを四角く切ったものを挟んであげましょう。これで、光がうまく混ざって拡散するようになります。
最後に、リングパーツをはめ込んで完成です。おつかれさまでした。
ということで、私なりのオリジナルライドウォッチの作成方法を全てご紹介しました。結構力技で押し切っている部分もありますので(特にSW-1, 2の処理)、本記事を見て、「ここはこう処理した方がもっとスマートだ!」というやり方を考案された方がおられましたら、是非是非教えて頂ければと思います。
最後に、私の万丈ライドウォッチのソースコードを公開して終わりにしたいと思います。前回申し上げましたとおり、このコードについては特に説明は加えませんが、前回公開したソースコードを理解された方であれば、フォームチェンジのためにフルカラーLEDとリードスイッチの処理が追加されているだけですので、問題なく理解できると思います。
#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
#include <Adafruit_NeoPixel.h>
SoftwareSerial ss_mp3_player(2, 3); // RX, TX
#define LED_PIN 4
#define SW_C_PIN 5
#define SW_1_PIN 6
#define SW_2_PIN 7
#define REED_PIN 8
#define LOOP_INTERVAL_MS 20
#define ON LOW
#define OFF HIGH
#define N_BUTTON 3
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 };
#define STATE_SINGLE_A 1
#define STATE_SINGLE_B 2
#define STATE_READY_WP 3
#define STATE_WEAPON 4
#define STATE_READY_CH 5
#define STATE_CHANGED 6
#define STATE_READY_CR 7
#define STATE_CRITICAL 8
#define SIDE_NONE 0
#define SIDE_ARMOR_TIME 1
#define SIDE_RIDER_TIME 2
#define FORM_STATE_CROSS_Z 0
#define FORM_STATE_CHARGE 1
#define FORM_STATE_MAGMA 2
uint8_t prev_state = STATE_SINGLE_A;
uint8_t state = STATE_SINGLE_A;
uint8_t prev_side = SIDE_NONE;
uint8_t side = SIDE_NONE;
uint8_t prev_relay = OFF;
uint8_t relay = OFF;
uint8_t form_state = FORM_STATE_CROSS_Z;
uint8_t rider_time_counter = 0;
uint8_t armor_time_counter = 0;
uint8_t form_change_counter = 0;
uint8_t prev_sw[] = {OFF, OFF, OFF};
uint8_t sw[] = {OFF, OFF, OFF};
//--------------------------------------------------------------------------//
// 効果音処理
#define SOUND_START 1
#define SOUND_EJECT 2
#define SOUND_CHANGE_CROSS_Z 3
#define SOUND_SINGLE_A_CROSS_Z 4
#define SOUND_SINGLE_B_CROSS_Z 5
#define SOUND_RIDER_TIME_CROSS_Z 6
#define SOUND_ARMOR_TIME_CROSS_Z 7
#define SOUND_WEAPON_CROSS_Z 8
#define SOUND_CRITICAL_READY_CROSS_Z 9
#define SOUND_CRITICAL_CROSS_Z 10
#define SOUND_CHANGE_CHARGE 11
#define SOUND_SINGLE_A_CHARGE 12
#define SOUND_SINGLE_B_CHARGE 13
#define SOUND_RIDER_TIME_CHARGE 14
#define SOUND_ARMOR_TIME_CHARGE 15
#define SOUND_WEAPON_CHARGE 16
#define SOUND_CRITICAL_READY_CHARGE 17
#define SOUND_CRITICAL_CHARGE 18
#define SOUND_CHANGE_MAGMA 19
#define SOUND_SINGLE_A_MAGMA 20
#define SOUND_SINGLE_B_MAGMA 21
#define SOUND_RIDER_TIME_MAGMA 22
#define SOUND_ARMOR_TIME_MAGMA 23
#define SOUND_WEAPON_MAGMA 24
#define SOUND_CRITICAL_READY_MAGMA 25
#define SOUND_CRITICAL_MAGMA 26
#define ARMOR_TIME_WAIT 6500
#define RIDER_TIME_WAIT 1000
#define CRITICAL_WAIT_SHORT 1000
#define CRITICAL_WAIT_LONG 2000
unsigned long sound_wait_start_time = 0;
boolean is_armor_time_waiting = false;
boolean is_rider_time_waiting = false;
boolean is_armor_time_critical_waiting = false;
boolean is_rider_time_critical_waiting = false;
DFRobotDFPlayerMini mp3_player;
void play_sound(){
if(prev_state != state){
switch(state){
case STATE_SINGLE_A:
switch(prev_state){
case STATE_SINGLE_B:
switch(form_state){
case FORM_STATE_CROSS_Z: mp3_player.playMp3Folder(SOUND_SINGLE_A_CROSS_Z); break;
case FORM_STATE_CHARGE: mp3_player.playMp3Folder(SOUND_SINGLE_A_CHARGE); break;
case FORM_STATE_MAGMA: mp3_player.playMp3Folder(SOUND_SINGLE_A_MAGMA); break;
default: ;
}
break;
case STATE_READY_WP:
case STATE_WEAPON:
case STATE_READY_CH:
case STATE_CHANGED:
case STATE_READY_CR:
case STATE_CRITICAL:
mp3_player.playMp3Folder(SOUND_EJECT);
break;
default:
;
}
break;
case STATE_SINGLE_B:
switch(form_state){
case FORM_STATE_CROSS_Z:mp3_player.playMp3Folder(SOUND_SINGLE_B_CROSS_Z); break;
case FORM_STATE_CHARGE: mp3_player.playMp3Folder(SOUND_SINGLE_B_CHARGE); break;
case FORM_STATE_MAGMA: mp3_player.playMp3Folder(SOUND_SINGLE_B_MAGMA); break;
default: ;
}
break;
case STATE_READY_WP:
if(prev_state != STATE_WEAPON){
mp3_player.pause();
}
break;
case STATE_WEAPON:
switch(form_state){
case FORM_STATE_CROSS_Z:mp3_player.playMp3Folder(SOUND_WEAPON_CROSS_Z); break;
case FORM_STATE_CHARGE: mp3_player.playMp3Folder(SOUND_WEAPON_CHARGE); break;
case FORM_STATE_MAGMA: mp3_player.playMp3Folder(SOUND_WEAPON_MAGMA); break;
default: ;
}
break;
case STATE_READY_CH:
mp3_player.pause();
break;
case STATE_CHANGED:
if(side == SIDE_RIDER_TIME){
sound_wait_start_time = millis();
is_rider_time_waiting = true;
}else if(side == SIDE_ARMOR_TIME){
sound_wait_start_time = millis();
is_armor_time_waiting = true;
}
break;
case STATE_READY_CR:
switch(form_state){
case FORM_STATE_CROSS_Z:mp3_player.playMp3Folder(SOUND_CRITICAL_READY_CROSS_Z); break;
case FORM_STATE_CHARGE: mp3_player.playMp3Folder(SOUND_CRITICAL_READY_CHARGE); break;
case FORM_STATE_MAGMA: mp3_player.playMp3Folder(SOUND_CRITICAL_READY_MAGMA); break;
default: ;
}
break;
case STATE_CRITICAL:
if(side == SIDE_RIDER_TIME){
sound_wait_start_time = millis();
is_rider_time_critical_waiting = true;
}else if(side == SIDE_ARMOR_TIME){
sound_wait_start_time = millis();
is_armor_time_critical_waiting = true;
}
break;
default:
;
}
}else{
unsigned long now = millis();
if(is_rider_time_waiting){
if(now - sound_wait_start_time >= RIDER_TIME_WAIT){
switch(form_state){
case FORM_STATE_CROSS_Z:mp3_player.playMp3Folder(SOUND_RIDER_TIME_CROSS_Z); break;
case FORM_STATE_CHARGE: mp3_player.playMp3Folder(SOUND_RIDER_TIME_CHARGE); break;
case FORM_STATE_MAGMA: mp3_player.playMp3Folder(SOUND_RIDER_TIME_MAGMA); break;
default: ;
}
is_rider_time_waiting = false;
}
}else if(is_armor_time_waiting){
if(now - sound_wait_start_time >= ARMOR_TIME_WAIT){
switch(form_state){
case FORM_STATE_CROSS_Z:mp3_player.playMp3Folder(SOUND_ARMOR_TIME_CROSS_Z); break;
case FORM_STATE_CHARGE: mp3_player.playMp3Folder(SOUND_ARMOR_TIME_CHARGE); break;
case FORM_STATE_MAGMA: mp3_player.playMp3Folder(SOUND_ARMOR_TIME_MAGMA); break;
default: ;
}
is_armor_time_waiting = false;
}
}else if(is_rider_time_critical_waiting){
if(now - sound_wait_start_time >= CRITICAL_WAIT_LONG){
switch(form_state){
case FORM_STATE_CROSS_Z:mp3_player.playMp3Folder(SOUND_CRITICAL_CROSS_Z); break;
case FORM_STATE_CHARGE: mp3_player.playMp3Folder(SOUND_CRITICAL_CHARGE); break;
case FORM_STATE_MAGMA: mp3_player.playMp3Folder(SOUND_CRITICAL_MAGMA); break;
default: ;
}
is_rider_time_critical_waiting = false;
}
}else if(is_armor_time_critical_waiting){
if(now - sound_wait_start_time >= CRITICAL_WAIT_SHORT){
switch(form_state){
case FORM_STATE_CROSS_Z:mp3_player.playMp3Folder(SOUND_CRITICAL_CROSS_Z); break;
case FORM_STATE_CHARGE: mp3_player.playMp3Folder(SOUND_CRITICAL_CHARGE); break;
case FORM_STATE_MAGMA: mp3_player.playMp3Folder(SOUND_CRITICAL_MAGMA); break;
default: ;
}
is_armor_time_critical_waiting = false;
}
}
}
}
//--------------------------------------------------------------------------//
// 発光処理
#define LED_COUNT_MAX 1500 // LOOP_INTERVAL_MSが20msで、30sまでの発光定義を想定
#define N_LED 1
#define COLOR_R_CROSS_Z 0
#define COLOR_G_CROSS_Z 0
#define COLOR_B_CROSS_Z 255
#define COLOR_R_CHARGE 255
#define COLOR_G_CHARGE 255
#define COLOR_B_CHARGE 0
#define COLOR_R_MAGMA 255
#define COLOR_G_MAGMA 102
#define COLOR_B_MAGMA 0
uint16_t led_counter = LED_COUNT_MAX;
unsigned long blink_time = 0;
unsigned long prev_blink_time = 0;
unsigned long inc_dim_start_time = 0;
boolean is_lighting = false;
boolean is_inc = false;
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(N_LED, LED_PIN, NEO_GRB);
void led_base_pattern_on(uint8_t r, uint8_t g, uint8_t b){
pixels.setPixelColor(0, pixels.Color(r,g,b));
}
void led_base_pattern_off(){
pixels.setPixelColor(0, pixels.Color(0,0,0));
}
void led_base_pattern_blink(uint8_t r, uint8_t g, uint8_t b, int interval_ms){
unsigned long now = millis();
if(now - prev_blink_time >= interval_ms){
if(is_lighting){
pixels.setPixelColor(0, pixels.Color(0,0,0));
}else{
pixels.setPixelColor(0, pixels.Color(r,g,b));
}
is_lighting = !is_lighting;
prev_blink_time = now;
}
}
void led_base_pattern_inc(uint8_t r, uint8_t g, uint8_t b, int interval_ms, uint8_t steps){
unsigned long now = millis();
if(inc_dim_start_time == 0){
inc_dim_start_time = now;
}
int ms_per_step = interval_ms / steps;
int current_step = (now - inc_dim_start_time) / ms_per_step;
uint8_t r_step = r/steps;
uint8_t g_step = g/steps;
uint8_t b_step = b/steps;
pixels.setPixelColor(0, pixels.Color(r_step*current_step, g_step*current_step, b_step*current_step));
if(now - inc_dim_start_time >= interval_ms){
inc_dim_start_time = 0;
}
}
void led_base_pattern_dim(uint8_t r, uint8_t g, uint8_t b, int interval_ms, uint8_t steps){
unsigned long now = millis();
if(inc_dim_start_time == 0){
inc_dim_start_time = now;
}
int ms_per_step = interval_ms / steps;
int current_step = (now - inc_dim_start_time) / ms_per_step;
uint8_t r_step = r/steps;
uint8_t g_step = g/steps;
uint8_t b_step = b/steps;
pixels.setPixelColor(0, pixels.Color(r_step*(steps-current_step), g_step*(steps-current_step), b_step*(steps-current_step)));
if(now - inc_dim_start_time >= interval_ms){
inc_dim_start_time = 0;
}
}
void led_base_pattern_blink_slowly(uint8_t r, uint8_t g, uint8_t b, int interval_ms, uint8_t steps){
unsigned long now = millis();
if(inc_dim_start_time == 0){
inc_dim_start_time = now;
}
int ms_per_step = interval_ms / steps;
int current_step = (now - inc_dim_start_time) / ms_per_step;
uint8_t r_step = r/steps;
uint8_t g_step = g/steps;
uint8_t b_step = b/steps;
if(is_inc){
pixels.setPixelColor(0, pixels.Color(r_step*current_step, g_step*current_step, b_step*current_step));
}else{
pixels.setPixelColor(0, pixels.Color(r_step*(steps-current_step), g_step*(steps-current_step), b_step*(steps-current_step)));
}
if(now - inc_dim_start_time >= interval_ms){
is_inc = !is_inc;
inc_dim_start_time = 0;
}
}
//----------------------//
void led_pattern_single_a_cross_z(uint16_t led_counter_ms){ // 起動音+解説+「クローズだ!」
if(led_counter_ms <= 600){ led_base_pattern_blink(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 80);}
else if( 600 < led_counter_ms && led_counter_ms <= 1800){ led_base_pattern_dim(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 1000, 10);}
else if(1800 < led_counter_ms && led_counter_ms <= 7200){ led_base_pattern_on(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z);}
else if(7200 < led_counter_ms && led_counter_ms <= 9400){ led_base_pattern_blink(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 90);}
else if(9400 < led_counter_ms && led_counter_ms <= 10000){ led_base_pattern_off();}
else{ led_base_pattern_on(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z);}
}
void led_pattern_single_a_charge(uint16_t led_counter_ms){ // 起動音+解説+「万丈だ」
if(led_counter_ms <= 600){ led_base_pattern_blink(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 80);}
else if( 600 < led_counter_ms && led_counter_ms <= 1600){ led_base_pattern_dim(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 1000, 10);}
else if( 1600 < led_counter_ms && led_counter_ms <= 11100){ led_base_pattern_blink_slowly(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 1200, 12);}
else if(11100 < led_counter_ms && led_counter_ms <= 15300){ led_base_pattern_blink(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 90);}
else if(15300 < led_counter_ms && led_counter_ms <= 16000){ led_base_pattern_off();}
else{ led_base_pattern_on(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE);}
}
void led_pattern_single_a_magma(uint16_t led_counter_ms){ // 起動音+解説+「俺だ」
if(led_counter_ms <= 600){ led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 80);}
else if( 600 < led_counter_ms && led_counter_ms <= 1800){ led_base_pattern_dim(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 1200, 10);}
else if(1800 < led_counter_ms && led_counter_ms <= 3000){ led_base_pattern_on(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA);}
else if(3000 < led_counter_ms && led_counter_ms <= 5200){ led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 90);}
else if(5200 < led_counter_ms && led_counter_ms <= 5900){ led_base_pattern_off();}
else{ led_base_pattern_on(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA);}
}
//----------------------//
void led_pattern_single_b_cross_z(uint16_t led_counter_ms){ // 起動音+起動音+「クローズ!」
if(led_counter_ms <= 600){ led_base_pattern_blink(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 80);}
else if( 600 < led_counter_ms && led_counter_ms <= 1600){ led_base_pattern_dim(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 1000, 10);}
else if(1600 < led_counter_ms && led_counter_ms <= 3200){ led_base_pattern_blink(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 40);}
else{ led_base_pattern_on(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z);}
}
void led_pattern_single_b_charge(uint16_t led_counter_ms){ // 起動音+起動音+「クローズチャージ!」
if(led_counter_ms <= 600){ led_base_pattern_blink(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 80);}
else if( 600 < led_counter_ms && led_counter_ms <= 1600){ led_base_pattern_dim(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 1000, 10);}
else if(1600 < led_counter_ms && led_counter_ms <= 3100){ led_base_pattern_blink(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 40);}
else if(3100 < led_counter_ms && led_counter_ms <= 3750){ led_base_pattern_dim(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 650, 10);}
else{ led_base_pattern_on(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE);}
}
void led_pattern_single_b_magma(uint16_t led_counter_ms){ // 起動音+起動音+「クローズマグマ!」
if(led_counter_ms <= 600){ led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 80);}
else if( 600 < led_counter_ms && led_counter_ms <= 1600){ led_base_pattern_dim(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 1000, 10);}
else if(1600 < led_counter_ms && led_counter_ms <= 3100){ led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 40);}
else if(3100 < led_counter_ms && led_counter_ms <= 4400){ led_base_pattern_dim(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA,1300, 10);}
else{ led_base_pattern_on(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA);}
}
//----------------------//
void led_pattern_weapon_cross_z(uint16_t led_counter_ms){ // 「クローズ!」
if(led_counter_ms <= 300){ led_base_pattern_blink(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 40);}
else{ led_base_pattern_on(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z);}
}
void led_pattern_weapon_charge(uint16_t led_counter_ms){ // 「クローズチャージ!」
if(led_counter_ms <= 800){ led_base_pattern_blink(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 40);}
else{ led_base_pattern_on(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE);}
}
void led_pattern_weapon_magma(uint16_t led_counter_ms){ // 「クローズマグマ!」
if(led_counter_ms <= 1500){ led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 40);}
else{ led_base_pattern_on(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA);}
}
//----------------------//
void led_pattern_rider_time_cross_z(uint16_t led_counter_ms){
if(led_counter_ms <= 1100){ led_base_pattern_off();}
else if(1100 < led_counter_ms && led_counter_ms <= 1900){ led_base_pattern_dim(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 800, 10);}
else if(1900 < led_counter_ms && led_counter_ms <= 2800){ led_base_pattern_dim(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 900, 10);}
else{ led_base_pattern_on(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z);}
}
void led_pattern_rider_time_charge(uint16_t led_counter_ms){
if(led_counter_ms <= 1100){ led_base_pattern_off();}
else if(1100 < led_counter_ms && led_counter_ms <= 1900){ led_base_pattern_dim(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 800, 10);}
else if(1900 < led_counter_ms && led_counter_ms <= 2800){ led_base_pattern_dim(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 900, 10);}
else if(2800 < led_counter_ms && led_counter_ms <= 6800){ led_base_pattern_on(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE);}
else if(6800 < led_counter_ms && led_counter_ms <= 7800){ led_base_pattern_blink(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 60);}
else{ led_base_pattern_on(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE);}
}
void led_pattern_rider_time_magma(uint16_t led_counter_ms){
if(led_counter_ms <= 1100){ led_base_pattern_off();}
else if(1100 < led_counter_ms && led_counter_ms <= 1900){ led_base_pattern_dim(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 800, 10);}
else if(1900 < led_counter_ms && led_counter_ms <= 2800){ led_base_pattern_dim(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 900, 10);}
else if(2800 < led_counter_ms && led_counter_ms <= 7300){ led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA,180);}
else if(7300 < led_counter_ms && led_counter_ms <= 9000){ led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 60);}
else if(9000 < led_counter_ms && led_counter_ms <= 9200){ led_base_pattern_off();}
else if(9200 < led_counter_ms && led_counter_ms <= 11400){ led_base_pattern_dim(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 2200, 20);}
else{ led_base_pattern_on(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA);}
}
//----------------------//
void led_pattern_armor_time_cross_z(uint16_t led_counter_ms){
if(led_counter_ms <= 6600){ led_base_pattern_off();}
else if(6600 < led_counter_ms && led_counter_ms <= 7400){ led_base_pattern_dim(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 800, 10);}
else if(7400 < led_counter_ms && led_counter_ms <= 8600){ led_base_pattern_dim(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 1200, 10);}
else{ led_base_pattern_on(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z);}
}
void led_pattern_armor_time_charge(uint16_t led_counter_ms){
if(led_counter_ms <= 6600){ led_base_pattern_off();}
else if( 6600 < led_counter_ms && led_counter_ms <= 7400){ led_base_pattern_dim(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 800, 10);}
else if( 7400 < led_counter_ms && led_counter_ms <= 8600){ led_base_pattern_dim(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 1200, 10);}
else if( 8600 < led_counter_ms && led_counter_ms <= 12600){ led_base_pattern_on(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE);}
else if(12600 < led_counter_ms && led_counter_ms <= 13600){ led_base_pattern_blink(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 60);}
else{ led_base_pattern_on(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE);}
}
void led_pattern_armor_time_magma(uint16_t led_counter_ms){
if(led_counter_ms <= 6600){ led_base_pattern_off();}
else if( 6600 < led_counter_ms && led_counter_ms <= 7400){ led_base_pattern_dim(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 800, 10);}
else if( 7400 < led_counter_ms && led_counter_ms <= 8600){ led_base_pattern_dim(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 1200, 10);}
else if( 8600 < led_counter_ms && led_counter_ms <= 13100){ led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA,180);}
else if(13100 < led_counter_ms && led_counter_ms <= 14800){ led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 60);}
else if(14800 < led_counter_ms && led_counter_ms <= 15000){ led_base_pattern_off();}
else if(15000 < led_counter_ms && led_counter_ms <= 17200){ led_base_pattern_dim(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 2200, 20);}
else{ led_base_pattern_on(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA);}
}
//----------------------//
void led_pattern_ready_critical_cross_z(uint16_t led_counter_ms){ // 起動音+「クローズ!」+待機
if(led_counter_ms <= 600){ led_base_pattern_blink(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 80);}
else if( 600 < led_counter_ms && led_counter_ms <= 1600){ led_base_pattern_dim(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 1000, 10);}
else if(1600 < led_counter_ms && led_counter_ms <= 3100){ led_base_pattern_on(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z);}
else{ led_base_pattern_blink(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 800);}
}
void led_pattern_ready_critical_charge(uint16_t led_counter_ms){ // 起動音+「クローズチャージ!」+待機
if(led_counter_ms <= 600){ led_base_pattern_blink(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 80);}
else if( 600 < led_counter_ms && led_counter_ms <= 1600){ led_base_pattern_dim(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 1000, 10);}
else if(1600 < led_counter_ms && led_counter_ms <= 2250){ led_base_pattern_dim(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 650, 10);}
else if(2250 < led_counter_ms && led_counter_ms <= 3450){ led_base_pattern_on(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE);}
else{ led_base_pattern_blink(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 800);}
}
void led_pattern_ready_critical_magma(uint16_t led_counter_ms){ // 起動音+「クローズマグマ!」+待機
if(led_counter_ms <= 600){ led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 80);}
else if( 600 < led_counter_ms && led_counter_ms <= 1600){ led_base_pattern_dim(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 1000, 10);}
else if(1600 < led_counter_ms && led_counter_ms <= 2900){ led_base_pattern_dim(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 1300, 10);}
else if(2900 < led_counter_ms && led_counter_ms <= 4400){ led_base_pattern_on(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA);}
else{ led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 800);}
}
//----------------------//
void led_pattern_critical_long_cross_z(uint16_t led_counter_ms){ // 「ドラゴニック!」
if(led_counter_ms <= 2100){ led_base_pattern_off();}
else if(2100 < led_counter_ms && led_counter_ms <= 2600){ led_base_pattern_blink(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 40);}
else{ led_base_pattern_on(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z);}
}
void led_pattern_critical_long_charge(uint16_t led_counter_ms){ // 「ドラゴンジェリー!」
if(led_counter_ms <= 2100){ led_base_pattern_off();}
else if(2100 < led_counter_ms && led_counter_ms <= 2700){ led_base_pattern_blink(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 40);}
else{ led_base_pattern_on(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE);}
}
void led_pattern_critical_long_magma(uint16_t led_counter_ms){ // 「ボルケニック!」
if(led_counter_ms <= 2100){ led_base_pattern_off();}
else if(2100 < led_counter_ms && led_counter_ms <= 2600){ led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 40);}
else{ led_base_pattern_on(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA);}
}
//----------------------//
void led_pattern_critical_short_cross_z(uint16_t led_counter_ms){ // 「ドラゴニック!」
if(led_counter_ms <= 1100){ led_base_pattern_off();}
else if(1100 < led_counter_ms && led_counter_ms <= 1600){ led_base_pattern_blink(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 40);}
else{ led_base_pattern_on(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z);}
}
void led_pattern_critical_short_charge(uint16_t led_counter_ms){ // 「ドラゴンジェリー!」
if(led_counter_ms <= 1100){ led_base_pattern_off();}
else if(1100 < led_counter_ms && led_counter_ms <= 1700){ led_base_pattern_blink(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 40);}
else{ led_base_pattern_on(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE);}
}
void led_pattern_critical_short_magma(uint16_t led_counter_ms){ // 「ボルケニック!」
if(led_counter_ms <= 1100){ led_base_pattern_off();}
else if(1100 < led_counter_ms && led_counter_ms <= 1600){ led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 40);}
else{ led_base_pattern_on(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA);}
}
//----------------------//
void led_pattern_change_cross_z(uint16_t led_counter_ms){ // ドライバー装填音 + 「変身!」
if(led_counter_ms <= 900){ led_base_pattern_dim(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 900, 10);}
else if(900 < led_counter_ms && led_counter_ms <= 1400){ led_base_pattern_blink(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 40);}
else{ led_base_pattern_on(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z);}
}
void led_pattern_change_charge(uint16_t led_counter_ms){ // ドライバー装填音 + 「今の俺は...負ける気がしねえ!」
if(led_counter_ms <= 1100){ led_base_pattern_dim(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 1100, 10);}
else if(1100 < led_counter_ms && led_counter_ms <= 2300){ led_base_pattern_on(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE);}
else if(2300 < led_counter_ms && led_counter_ms <= 3500){ led_base_pattern_dim(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 1200, 10);}
else if(3500 < led_counter_ms && led_counter_ms <= 4500){ led_base_pattern_blink(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 40);}
else{ led_base_pattern_on(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE);}
}
void led_pattern_change_magma(uint16_t led_counter_ms){ // ドライバー装填音 + 「俺のマグマが迸る!」
if(led_counter_ms <= 1200){ led_base_pattern_dim(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 1200, 10);}
else if(1200 < led_counter_ms && led_counter_ms <= 2600){ led_base_pattern_on(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA);}
else if(2600 < led_counter_ms && led_counter_ms <= 2800){ led_base_pattern_dim(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 200, 5);}
else if(2800 < led_counter_ms && led_counter_ms <= 3400){ led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 40);}
else{ led_base_pattern_on(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA);}
}
//----------------------//
void flash_led(){
if(prev_state != state){
if(prev_state != STATE_SINGLE_B && state == STATE_SINGLE_A){
led_counter = LED_COUNT_MAX; // 発光させないように、カウントの上限値にする
}else if((prev_state == STATE_SINGLE_A || prev_state == STATE_SINGLE_B) && state == STATE_READY_WP){
led_counter = LED_COUNT_MAX; // 発光させないように、カウントの上限値にする
}else if(prev_state == STATE_WEAPON && state == STATE_READY_WP){
; // 発光を継続させるためにカウントをリセットしない
}else{
led_counter = 0; // 基本的に状態遷移が発生するとカウントをリセットする
}
}else if(prev_side != side){
led_counter = 0;
}
uint16_t led_counter_ms = led_counter * LOOP_INTERVAL_MS; // LEDはms単位で制御
switch(state){
case STATE_SINGLE_A:
switch(form_state){
case FORM_STATE_CROSS_Z: led_pattern_single_a_cross_z(led_counter_ms); break;
case FORM_STATE_CHARGE: led_pattern_single_a_charge(led_counter_ms); break;
case FORM_STATE_MAGMA: led_pattern_single_a_magma(led_counter_ms); break;
default: ;
}
break;
case STATE_SINGLE_B:
switch(form_state){
case FORM_STATE_CROSS_Z: led_pattern_single_b_cross_z(led_counter_ms); break;
case FORM_STATE_CHARGE: led_pattern_single_b_charge(led_counter_ms); break;
case FORM_STATE_MAGMA: led_pattern_single_b_magma(led_counter_ms); break;
default: ;
}
break;
case STATE_READY_WP:
case STATE_WEAPON:
switch(form_state){
case FORM_STATE_CROSS_Z: led_pattern_weapon_cross_z(led_counter_ms); break;
case FORM_STATE_CHARGE: led_pattern_weapon_charge(led_counter_ms); break;
case FORM_STATE_MAGMA: led_pattern_weapon_magma(led_counter_ms); break;
default: ;
}
break;
case STATE_READY_CH:
switch(form_state){
case FORM_STATE_CROSS_Z: led_base_pattern_blink(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 800); break;
case FORM_STATE_CHARGE: led_base_pattern_blink(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 800); break;
case FORM_STATE_MAGMA: led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 800); break;
default: ;
}
break;
case STATE_CHANGED:
if(side == SIDE_NONE){
switch(form_state){
case FORM_STATE_CROSS_Z: led_base_pattern_blink(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z, 800); break;
case FORM_STATE_CHARGE: led_base_pattern_blink(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE, 800); break;
case FORM_STATE_MAGMA: led_base_pattern_blink(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA, 800); break;
default: ;
}
}else if(side == SIDE_ARMOR_TIME){
switch(form_state){
case FORM_STATE_CROSS_Z: led_pattern_armor_time_cross_z(led_counter_ms); break;
case FORM_STATE_CHARGE: led_pattern_armor_time_charge(led_counter_ms); break;
case FORM_STATE_MAGMA: led_pattern_armor_time_magma(led_counter_ms); break;
default: ;
}
}else if(side == SIDE_RIDER_TIME){
switch(form_state){
case FORM_STATE_CROSS_Z: led_pattern_rider_time_cross_z(led_counter_ms); break;
case FORM_STATE_CHARGE: led_pattern_rider_time_charge(led_counter_ms); break;
case FORM_STATE_MAGMA: led_pattern_rider_time_magma(led_counter_ms); break;
default: ;
}
}
break;
case STATE_READY_CR:
switch(form_state){
case FORM_STATE_CROSS_Z: led_pattern_ready_critical_cross_z(led_counter_ms); break;
case FORM_STATE_CHARGE: led_pattern_ready_critical_charge(led_counter_ms); break;
case FORM_STATE_MAGMA: led_pattern_ready_critical_magma(led_counter_ms); break;
default: ;
}
break;
case STATE_CRITICAL:
if(side == SIDE_ARMOR_TIME){
switch(form_state){
case FORM_STATE_CROSS_Z:led_pattern_critical_short_cross_z(led_counter_ms); break;
case FORM_STATE_CHARGE: led_pattern_critical_short_charge(led_counter_ms); break;
case FORM_STATE_MAGMA: led_pattern_critical_short_magma(led_counter_ms); break;
default: ;
}
}else if(side == SIDE_RIDER_TIME){
switch(form_state){
case FORM_STATE_CROSS_Z:led_pattern_critical_long_cross_z(led_counter_ms); break;
case FORM_STATE_CHARGE: led_pattern_critical_long_charge(led_counter_ms); break;
case FORM_STATE_MAGMA: led_pattern_critical_long_magma(led_counter_ms); break;
default: ;
}
}
break;
default:
;
}
if(led_counter < LED_COUNT_MAX){
led_counter++;
}
pixels.show();
}
//--------------------------------------------------------------------------//
// リセット処理
void reset_rider_time_counter(){
rider_time_counter = 0;
}
void reset_armor_time_counter(){
armor_time_counter = 0;
}
void reset_all(){
switch(form_state){
case FORM_STATE_CROSS_Z: pixels.setPixelColor(0, pixels.Color(COLOR_R_CROSS_Z, COLOR_G_CROSS_Z, COLOR_B_CROSS_Z)); break;
case FORM_STATE_CHARGE: pixels.setPixelColor(0, pixels.Color(COLOR_R_CHARGE, COLOR_G_CHARGE, COLOR_B_CHARGE)); break;
case FORM_STATE_MAGMA: pixels.setPixelColor(0, pixels.Color(COLOR_R_MAGMA, COLOR_G_MAGMA, COLOR_B_MAGMA)); break;
default: ;
}
reset_rider_time_counter();
reset_armor_time_counter();
is_armor_time_waiting = false;
is_rider_time_waiting = false;
is_armor_time_critical_waiting = false;
is_rider_time_critical_waiting = false;
led_counter = LED_COUNT_MAX;
}
//--------------------------------------------------------------------------//
// 起動処理
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
pinMode(SW_C_PIN, INPUT_PULLUP);
pinMode(SW_1_PIN, INPUT_PULLUP);
pinMode(SW_2_PIN, INPUT_PULLUP);
pinMode(REED_PIN, INPUT_PULLUP);
// ---------- MP3プレイヤーセットアップ ----------
ss_mp3_player.begin(9600);
if (!mp3_player.begin(ss_mp3_player)) { //Use softwareSerial to communicate with mp3.
Serial.println(F("Unable to begin music_player:"));
Serial.println(F("1.Please recheck the connection!"));
Serial.println(F("2.Please insert the SD card!"));
while(true);
}
Serial.println(F("mp3_player online."));
mp3_player.setTimeOut(500); //Set serial communictaion time out 500ms
mp3_player.volume(22); //Set volume value (0~30).
// ---------- 初期状態取得 ----------
relay = prev_relay = digitalRead(REED_PIN);
// ---------- 起動エフェクト ----------
mp3_player.playMp3Folder(SOUND_START);
pixels.setPixelColor(0, pixels.Color(0,0,255));
pixels.show();
}
//--------------------------------------------------------------------------//
// メイン処理
void loop() {
sw[0] = digitalRead(SW_C_PIN);
sw[1] = digitalRead(SW_1_PIN);
sw[2] = digitalRead(SW_2_PIN);
prev_state = state;
prev_side = side;
if(memcmp(prev_sw, OFF_OFF_OFF, N_BUTTON) == 0){
if(memcmp(sw, ON_OFF_OFF, N_BUTTON) == 0){
if(prev_state == STATE_SINGLE_A){
state = STATE_SINGLE_B;
}else if(prev_state == STATE_SINGLE_B){
state = STATE_SINGLE_A;
}
}else if(memcmp(sw, OFF_ON_OFF, N_BUTTON) == 0){
if(prev_state == STATE_SINGLE_A || prev_state == STATE_SINGLE_B){
state = STATE_READY_WP;
}
}else if(memcmp(sw, OFF_OFF_ON, N_BUTTON) == 0){
;
}else if(memcmp(sw, ON_ON_OFF, N_BUTTON) == 0){
;
}else if(memcmp(sw, ON_OFF_ON, N_BUTTON) == 0){
;
}else if(memcmp(sw, OFF_ON_ON, N_BUTTON) == 0){
if(prev_state == STATE_SINGLE_A || prev_state == STATE_SINGLE_B){
state = STATE_READY_CH;
}
}else if(memcmp(sw, ON_ON_ON, N_BUTTON) == 0){
;
}
}else if(memcmp(prev_sw, ON_OFF_OFF, N_BUTTON) == 0){
if(memcmp(sw, OFF_OFF_OFF, N_BUTTON) == 0){
;
}else if(memcmp(sw, ON_ON_OFF, N_BUTTON) == 0){
if(prev_state == STATE_SINGLE_A || prev_state == STATE_SINGLE_B){
state = STATE_READY_WP;
}
}else if(memcmp(sw, ON_OFF_ON, N_BUTTON) == 0){
;
}else if(memcmp(sw, OFF_ON_OFF, N_BUTTON) == 0){
;
}else if(memcmp(sw, OFF_OFF_ON, N_BUTTON) == 0){
;
}else if(memcmp(sw, ON_ON_ON, N_BUTTON) == 0){
if(prev_state == STATE_SINGLE_A || prev_state == STATE_SINGLE_B){
state = STATE_READY_CH;
}
}else if(memcmp(sw, OFF_ON_ON, N_BUTTON) == 0){
;
}
}else if(memcmp(prev_sw, OFF_ON_OFF, N_BUTTON) == 0){
if(memcmp(sw, ON_ON_OFF, N_BUTTON) == 0){
if(prev_state == STATE_CHANGED){
reset_all();
state = STATE_READY_CR;
}else if(prev_state == STATE_READY_CR){
reset_all();
prev_state = STATE_CHANGED; // 擬似的に状態変化を起こす
state = STATE_READY_CR;
}
}else if(memcmp(sw, OFF_OFF_OFF, N_BUTTON) == 0){
if(prev_state == STATE_CHANGED || prev_state == STATE_READY_WP || prev_state == STATE_READY_CH || prev_state == STATE_READY_CR){
reset_all();
state = STATE_SINGLE_A;
}
}else if(memcmp(sw, OFF_ON_ON, N_BUTTON) == 0){
if(prev_state == STATE_READY_WP){
state = STATE_WEAPON;
}else if(prev_state == STATE_READY_CH || prev_state == STATE_CHANGED){
rider_time_counter++;
if(rider_time_counter == 2){
prev_state = STATE_READY_CH; // 擬似的に状態変化を起こす
state = STATE_CHANGED;
side = SIDE_RIDER_TIME;
}
}else if(prev_state == STATE_READY_CR){
rider_time_counter++;
if(rider_time_counter == 2){
state = STATE_CRITICAL;
side = SIDE_RIDER_TIME;
}
}
}else if(memcmp(sw, ON_OFF_OFF, N_BUTTON) == 0){
;
}else if(memcmp(sw, ON_ON_ON, N_BUTTON) == 0){
;
}else if(memcmp(sw, OFF_OFF_ON, N_BUTTON) == 0){
;
}else if(memcmp(sw, ON_OFF_ON, N_BUTTON) == 0){
;
}
}else if(memcmp(prev_sw, OFF_OFF_ON, N_BUTTON) == 0){
if(memcmp(sw, ON_OFF_ON, N_BUTTON) == 0){
if(prev_state == STATE_SINGLE_A){
state = STATE_SINGLE_B;
}else if(prev_state == STATE_SINGLE_B){
state = STATE_SINGLE_A;
}else if(prev_state == STATE_CHANGED){
reset_all();
state = STATE_READY_CR;
}else if(prev_state == STATE_READY_CR){
reset_all();
prev_state = STATE_CHANGED; // 擬似的に状態変化を起こす
state = STATE_READY_CR;
}
}else if(memcmp(sw, OFF_ON_ON, N_BUTTON) == 0){
if(prev_state == STATE_SINGLE_A || prev_state == STATE_SINGLE_B){
state = STATE_READY_CH;
}else if(prev_state == STATE_READY_CH || prev_state == STATE_CHANGED){
armor_time_counter++;
if(armor_time_counter == 2){
prev_state = STATE_READY_CH; // 擬似的に状態変化を起こす
state = STATE_CHANGED;
side = SIDE_ARMOR_TIME;
}
}else if(prev_state == STATE_READY_CR){
armor_time_counter++;
if(armor_time_counter == 2){
state = STATE_CRITICAL;
side = SIDE_ARMOR_TIME;
}
}
}else if(memcmp(sw, OFF_OFF_OFF, N_BUTTON) == 0){
if(prev_state == STATE_WEAPON || prev_state == STATE_CHANGED || prev_state == STATE_READY_CH || prev_state == STATE_READY_CR){
reset_all();
state = STATE_SINGLE_A;
}
}else if(memcmp(sw, ON_ON_ON, N_BUTTON) == 0){
;
}else if(memcmp(sw, ON_OFF_OFF, N_BUTTON) == 0){
;
}else if(memcmp(sw, OFF_ON_OFF, N_BUTTON) == 0){
;
}else if(memcmp(sw, ON_ON_OFF, N_BUTTON) == 0){
;
}
}else if(memcmp(prev_sw, ON_ON_OFF, N_BUTTON) == 0){
if(memcmp(sw, OFF_ON_OFF, N_BUTTON) == 0){
;
}else if(memcmp(sw, ON_OFF_OFF, N_BUTTON) == 0){
if(prev_state == STATE_CHANGED || prev_state == STATE_READY_WP || prev_state == STATE_READY_CH || prev_state == STATE_READY_CR){
reset_all();
state = STATE_SINGLE_A;
}
}else if(memcmp(sw, ON_ON_ON, N_BUTTON) == 0){
if(prev_state == STATE_READY_WP){
state = STATE_WEAPON;
}else if(prev_state == STATE_READY_CH || prev_state == STATE_CHANGED){
rider_time_counter++;
if(rider_time_counter == 2){
prev_state = STATE_READY_CH; // 擬似的に状態変化を起こす
state = STATE_CHANGED;
side = SIDE_RIDER_TIME;
}
}else if(prev_state == STATE_READY_CR){
rider_time_counter++;
if(rider_time_counter == 2){
state = STATE_CRITICAL;
side = SIDE_RIDER_TIME;
}
}
}else if(memcmp(sw, OFF_OFF_OFF, N_BUTTON) == 0){
;
}else if(memcmp(sw, OFF_ON_ON, N_BUTTON) == 0){
;
}else if(memcmp(sw, ON_OFF_ON, N_BUTTON) == 0){
;
}else if(memcmp(sw, OFF_OFF_ON, N_BUTTON) == 0){
;
}
}else if(memcmp(prev_sw, ON_OFF_ON, N_BUTTON) == 0){
if(memcmp(sw, OFF_OFF_ON, N_BUTTON) == 0){
;
}else if(memcmp(sw, ON_ON_ON, N_BUTTON) == 0){
if(prev_state == STATE_SINGLE_A || prev_state == STATE_SINGLE_B){
state = STATE_READY_CH;
}else if(prev_state == STATE_READY_CH || prev_state == STATE_CHANGED){
armor_time_counter++;
if(armor_time_counter == 2){
prev_state = STATE_READY_CH; // 擬似的に状態変化を起こす
state = STATE_CHANGED;
side = SIDE_ARMOR_TIME;
}
}else if(prev_state == STATE_READY_CR){
armor_time_counter++;
if(armor_time_counter == 2){
state = STATE_CRITICAL;
side = SIDE_ARMOR_TIME;
}
}
}else if(memcmp(sw, ON_OFF_OFF, N_BUTTON) == 0){
if(prev_state == STATE_WEAPON || prev_state == STATE_CHANGED || prev_state == STATE_READY_CH || prev_state == STATE_READY_CR){
reset_all();
state = STATE_SINGLE_A;
}
}else if(memcmp(sw, OFF_ON_ON, N_BUTTON) == 0){
;
}else if(memcmp(sw, OFF_OFF_OFF, N_BUTTON) == 0){
;
}else if(memcmp(sw, ON_ON_OFF, N_BUTTON) == 0){
;
}else if(memcmp(sw, OFF_ON_OFF, N_BUTTON) == 0){
;
}
}else if(memcmp(prev_sw, OFF_ON_ON, N_BUTTON) == 0){
if(memcmp(sw, ON_ON_ON, N_BUTTON) == 0){
if(prev_state == STATE_CHANGED){
reset_all();
state = STATE_READY_CR;
}else if(prev_state == STATE_READY_CR || prev_state == STATE_CRITICAL){
reset_all();
prev_state = STATE_CHANGED; // 擬似的に状態変化を起こす
state = STATE_READY_CR;
}
}else if(memcmp(sw, OFF_OFF_ON, N_BUTTON) == 0){
if(prev_state == STATE_CHANGED){
side = SIDE_NONE;
if(armor_time_counter == 2){
reset_armor_time_counter();
}
}else if(prev_state == STATE_CRITICAL){
state = STATE_CHANGED;
side = SIDE_NONE;
if(armor_time_counter == 2){
reset_armor_time_counter();
}
}
}else if(memcmp(sw, OFF_ON_OFF, N_BUTTON) == 0){
if(prev_state == STATE_WEAPON){
state = STATE_READY_WP;
}else if(prev_state == STATE_CHANGED){
side = SIDE_NONE;
if(rider_time_counter == 2){
reset_rider_time_counter();
}
}else if(prev_state == STATE_CRITICAL){
state = STATE_CHANGED;
side = SIDE_NONE;
if(rider_time_counter == 2){
reset_rider_time_counter();
}
}
}else if(memcmp(sw, ON_OFF_ON, N_BUTTON) == 0){
;
}else if(memcmp(sw, ON_ON_OFF, N_BUTTON) == 0){
;
}else if(memcmp(sw, OFF_OFF_OFF, N_BUTTON) == 0){
if(prev_state == STATE_WEAPON || prev_state == STATE_CHANGED || prev_state == STATE_READY_CH || prev_state == STATE_READY_CR || prev_state == STATE_CRITICAL){
reset_all();
state = STATE_SINGLE_A;
}
}else if(memcmp(sw, ON_OFF_OFF, N_BUTTON) == 0){
;
}
}else if(memcmp(prev_sw, ON_ON_ON, N_BUTTON) == 0){
if(memcmp(sw, OFF_ON_ON, N_BUTTON) == 0){
;
}else if(memcmp(sw, ON_OFF_ON, N_BUTTON) == 0){
if(prev_state == STATE_CHANGED){
side = SIDE_NONE;
if(armor_time_counter == 2){
reset_armor_time_counter();
}
}else if(prev_state == STATE_CRITICAL){
state = STATE_CHANGED;
side = SIDE_NONE;
if(armor_time_counter == 2){
reset_armor_time_counter();
}
}
}else if(memcmp(sw, ON_ON_OFF, N_BUTTON) == 0){
if(prev_state == STATE_WEAPON){
state = STATE_READY_WP;
}else if(prev_state == STATE_CHANGED){
side = SIDE_NONE;
if(rider_time_counter == 2){
reset_rider_time_counter();
}
}else if(prev_state == STATE_CRITICAL){
state = STATE_CHANGED;
side = SIDE_NONE;
if(rider_time_counter == 2){
reset_rider_time_counter();
}
}
}else if(memcmp(sw, OFF_OFF_ON, N_BUTTON) == 0){
;
}else if(memcmp(sw, OFF_ON_OFF, N_BUTTON) == 0){
;
}else if(memcmp(sw, ON_OFF_OFF, N_BUTTON) == 0){
if(prev_state == STATE_WEAPON || prev_state == STATE_CHANGED || prev_state == STATE_READY_CH || prev_state == STATE_READY_CR || prev_state == STATE_CRITICAL){
reset_all();
state = STATE_SINGLE_A;
}
}else if(memcmp(sw, OFF_OFF_OFF, N_BUTTON) == 0){
;
}
}
/*
Serial.print("State: ");
Serial.println(state);
Serial.print("rider time counter: ");
Serial.println(rider_time_counter);
Serial.print("armor time counter: ");
Serial.println(armor_time_counter);
Serial.println("");
Serial.println(digitalRead(REED_PIN));
*/
play_sound();
flash_led();
prev_sw[0] = sw[0];
prev_sw[1] = sw[1];
prev_sw[2] = sw[2];
// ---------- フォームチェンジ処理 ----------
relay = digitalRead(REED_PIN);
if(prev_relay != relay){
form_change_counter++;
if(form_change_counter == 2){
switch(form_state){
case FORM_STATE_CROSS_Z:
form_state = FORM_STATE_CHARGE;
mp3_player.playMp3Folder(SOUND_CHANGE_CHARGE);
for(uint16_t i=0;i<250;i++){
led_pattern_change_charge(i*LOOP_INTERVAL_MS);
pixels.show();
delay(LOOP_INTERVAL_MS);
}
break;
case FORM_STATE_CHARGE:
form_state = FORM_STATE_MAGMA;
mp3_player.playMp3Folder(SOUND_CHANGE_MAGMA);
for(uint16_t i=0;i<200;i++){
led_pattern_change_magma(i*LOOP_INTERVAL_MS);
pixels.show();
delay(LOOP_INTERVAL_MS);
}
break;
case FORM_STATE_MAGMA:
form_state = FORM_STATE_CROSS_Z;
mp3_player.playMp3Folder(SOUND_CHANGE_CROSS_Z);
for(uint16_t i=0;i<100;i++){
led_pattern_change_cross_z(i*LOOP_INTERVAL_MS);
pixels.show();
delay(LOOP_INTERVAL_MS);
}
break;
default:
;
}
if(state == STATE_SINGLE_A || state == STATE_SINGLE_B){
// ドライバーに装填していない状態でフォームチェンジしたときは、初期状態に戻す
prev_state = state = STATE_SINGLE_A;
reset_all();
}
form_change_counter = 0;
}
}
prev_relay = relay;
delay(LOOP_INTERVAL_MS);
}
ディスカッション
コメント一覧
全4回の記事の作成お疲れ様です。楽しく読ませていただきました。sw1と2のスイッチ部は自作してたんですね。調整がシビアそうなんで流石に真似できません。。やるなら基板ちょん切ります。
1個聞きたいのですがグルーガンで固める方法。便利だと思うのですが剥がしたい時に綺麗に剥がせますか?コテで温めてとかだと焦げてクズが残りそうで再配線が難しそうって思うのですが。
かっぱ次郎 様
ありがとうございます◎ 確かに、SW1&2の微調整は二度とやりたくないですねー。。。これさえなければ、もう少しオリジナルを量産する気にもなるのですが。
最近、細かな微調整が不要な別方式も思いついたのですが、その方式だとジクウドライバーに特化する形になってしまって、ジカンギレードとかの武器やタイムマジーンへのセットができなくなってしまうので、使い所はちょっと考える必要がありそうです。
グルーガンについては、おっしゃる通り、綺麗に剥がすのは難しいです。なので、私の場合は「確実にこの配線で合っている」という確信を得た上で、最後の仕上げとしてグルーガンで固めるようにしています。基本、剥がす必要がないように。そのために、最近は事前に配線図とかを描いて、極力配線ミスが発生しないようにしています。
こんばんは!
ライドウォッチの改造に興味があって見させていただきました。
正直こういった事をした事がなく、ちんぷんかんぷんなんですが素人にもできるでしょうか?
実は息子へのプレゼントで息子の顔と音声が入った物を作ってみたいと思っています。
こういった改造がある事をネットで知り、やれたらと思っているのですがノウハウもありませんし、できる気がしません。
難しいのは百も承知なんですができるでしょうか?
てん様
はじめまして。個人的な感覚になるのですが、ライドウォッチの改造は、「絵柄を変える」→「(ガシャポンや食玩版など、本来光らないものを)発光させる」→「音声を変える」の順に難しくなっていきます。
まず、絵柄を変えるのは比較的簡単で、ライドウォッチのラベルの型に合わせて画像を加工し、それをラベル用のプリンタ用紙に印刷して貼り付ければOKです。
次に本来発光しないものを発光させる改造ですが、これには電子工作の初心者レベルのスキルが必要です。最低限、はんだごてなどの道具や、LED、抵抗器などのパーツを扱える必要があります。
最後に音声を変える改造ですが、これには電子工作の中級者レベルのスキルが必要です。前記のスキルに加え、プログラミングのスキルが必要になってきます。音声を変更する改造をしている人が少ないのは、このハードルの高さが原因かと思います。
できるかできないかと問われれば、できないことはないと思います。ただ、それ相応に努力というか、積み重ねは必要だと思います。私も必要であれば可能な限りはサポート致しますが、ライドウォッチとは特に関係のない基礎的なこと(例えばはんだつけの方法や、プログラミング言語の仕様、プログラムのハードウェアへの書き込み方法等)は自力で調べて頂くことになりますので、予めご了承ください。
ご返信ありがとうございます!
音声の変更はパソコンなどを使用するのでしょうか?
てん様
私のやり方の場合は、最終的に音声はMP3ファイルを再生する形になり、そのMP3ファイルの作成にPCを使っています。
私の場合は、やり方としてはかなりアナログですが、以下の手順で任意の音声を作っています。
1. iPhoneのボイスメモアプリで玩具の音声を録音
2. PC(私の場合はMac)と同期させて、iTunesに録音した音声を取り込み
3. iTunes上で録音した音声をMP3ファイルに変換
4. 変換したMP3ファイルをGaragebandに取り込み
5. Garageband上で好きなように音声を編集
6. 編集した音声をiTunesに出力
7. 出力されたファイルをiTunes上でMP3ファイルに変換
最終的にMP3ファイルを作れさえすれば良いので、やり方はこれに限定されません。
そうですか。
親切にご説明いただきありがとうございます!
とても不躾なお願い、質問で申し訳無いのですが
どご指導いただきながら素人が今日からクリスマスまでに音声含めてオリジナルのライドウォッチ作れますか?
努力はします!
どうでしょうか?
てん様
> ご指導いただきながら素人が今日からクリスマスまでに音声含めてオリジナルのライドウォッチ作れますか?
正直に申し上げて、今まで一度も電子工作をしたことがないということであれば、かなりハードルは高いと思いますが。。。
プログラムについては、この一つ前の記事で紹介しているソースコードをそのまま使えば良いので、とりあえずは中身の理解を後にしても良いのであれば、何とかなると思います。まずは、ArduinoのIDEでこのソースコードをコンパイルできるようにしてください。その際には、DFPlayer Miniのライブラリを事前にインストールしていないとエラーになります。
そこは越えられたとして、最終的に部品を色々半田付けしていく必要があり、ここがある程度経験がないと、かなり大変だと思います。また、私が使用している部品のうち、DFPlayer miniはAmazonで買うと安いですが、海外からの発送になるため、入手に2〜3週間かかります。クリスマスまでに間に合わせるのであれば、値段はだいぶ高くなりますが、秋月などから買う方が良いと思います。できれば、部品が途中で壊れる可能性が大いにあるため、複数買っておいた方がよいです。
最後に、私がどこまでサポートできるかですが、私にも本業と育児がありますので、申し訳ありませんがつきっきりでサポートすることはできません。ご質問を頂いても、回答は致しますが、数日お時間を頂くことになることをご了承ください。ほとんどの問題は、ネットで調べて自己解決頂くことが必要になると思います。
こんにちは、いつも楽しく見させて頂いています。
あなたのオリジナルガシャットやライドウォッチの記事を拝見して興味を持ち、電子工作を始めました者です。
当方エンジニアどころか、半田ごても握ったことのないズブの素人ですが、記事を参考に、見様見真似で、タクトスイッチの押下でスクラッシュドライバーの音声が流れる装置をブレッドボード上で作った所、3歳の息子が大喜びしてくれました。
また当方、今年、興味本位で3dプリンターを購入し、色々とおもちゃを出力して遊んでいたのですが、こちらのブログを見て、市販のおもちゃと電子工作、それに3dモデリングを組み合わせると色々な事が出来そうだと気付き、ワクワクしています。
以前の記事で、フルボトルのマスタープレートを作成されていましたよね。あの記事に触発され、cadでマスタープレートをモデリングして出力してみたところ、見事認識に成功しました。
一旦マスターを作ってしまえば、データを少し修正するだけで様々なピン配列が出来るため、今では息子よりも、私のほうがビルドドライバーを楽しんでいます(笑)
電子工作も3dモデリングも始めたばかりで、知らないことばかりですが、おもちゃを通じて自分のスキルが向上するのを実感するって楽しいですね!
今後も更新を楽しみにしていますです。
へっどらいと様
このブログを始めてから頂いたコメントの中で、一番嬉しいお言葉を頂いた気がします。ありがとうございます◎
「勉強のための勉強」はやっぱり全然楽しくなくて、「こういうことをやりたい!」という目的があって勉強する方がよほど楽しいし健全じゃないかなあ、と思うのです。それで、「どこかの誰かにとっての『こういことをやりたい!』になり得るものを自分の方で示せれば」と思って続けているブログでしたので、あなたのような方にちゃんと届いたということが、とても嬉しいです。あ、もちろん、自分自身もちゃんと楽しんで続けています◎
Twitterの方はたまにつぶやいていますが、基本的にこちらのブログの更新頻度はとても少なくて申し訳ないなあと思っています。が、止めるつもりはまだ全然ありませんので、今後もふと思い出した時ぐらいに覗きに来てくださると嬉しいです。とりあえず、年末に一本、今年作ったものを振り返る記事を更新予定です。それから、今新しい作品が八割ぐらいはできてきたので、順調に行けば、年明けに新しい作品をご紹介できる。。。かもしれません。
電子工作未経験者です。素晴らしい改造で自分も興味が湧きました。素朴な疑問ですが純正の基板のプログラムは触ることができたりするものなのでしょうか?
てつ様
はい。Arduinoはそもそも、中のプログラムを自分で書き換えて使うものです。
回答ありがとうございます。純正というのは、元々ついている緑の基板のことです。言葉足らずでした…やっぱり不可能でしょうか?
てつ様
おそらく、無理ではないかと思います。少なくとも、私には方法はわかりません。