かっぱの覚え書き

とりあえずなんかメモ書きとか

ガンデフォン50解析

youtu.be


※公開を再開しました。

ガンデフォン50の赤外線信号解析をして任意に音声を鳴らしてみたいと思います。

必要部品
・seeeduino xiao
https://akizukidenshi.com/catalog/g/gM-15178/
・赤外線LED
https://akizukidenshi.com/catalog/g/gI-03261/
・タクトスイッチ
https://akizukidenshi.com/catalog/g/gP-03647/
・ユニバーサル基板とか配線とかブレッドボードとか

解析用品
オシロスコープ
https://akizukidenshi.com/catalog/g/gM-12972/
アマゾンでも売っていますが私は秋月電子で買いました。秋月電子で買う場合ACアダプタは必ず指定の物を買ってください。


あとはガンデフォン50、バイスタンプ複数個(複数あった方が数値の比較が出来るので解析しやすい)です。私はレックスとバッタしか持っていません。

まずはバイスタンプというかリバイス玩具全般の仕様を簡単に説明します。
何かボタンを押すと赤外線ポートは信号を1分間くらい送信続けます。
ポートは1つで送受信を兼ねています。
バイスドライバーで説明すると押印するとドライバーから信号送信。同時にバイスタンプも押されているので信号送信。バイスタンプをセットした時にお互い信号を送受信し続ける事によって装填していると認識して装填音、待機音。その送受信が途絶えると着脱と認識し着脱音が鳴る仕組みです。
装填中にレバーを倒すと変身音用の信号をスタンプに送信。スタンプは受け取ったらLED発光信号をドライバーに送信して変身動作完了です。
今回はバイスタンプからガンデフォン用の信号を送信のみ再現します。


まずはバイスタンプを開けて赤外線LEDが繋がっている部分を探し出しオシロスコープのプロープが付けられるような線をはんだ付けします。

バイスタンプを起動させ信号の波形を確認します。

オシロスコープの設定は2msにしていますので1メモリは500μsです。ちょっとズレてますが左から線が上に6ms(6000μs)それから500μs下がる、次に1500μs上がって、500μs下がる。これが6回続いて今度は500μs上がって1500μs下がる(画像は1500μs以上下がってますがこれは信号終わりだからです)
この波形は数字に直せます。
それと今の内に上がるをHIGH、下がるをLOWと置き換えます。
最初の6000μsHIGH、500μsLOWはスタートビットなので含みません。
1500μsHIGH、500μsLOWの1セットで0
500μsLOW、1500μsHIGHの1セットで1
これを当てはめて読んでみると
00000001となり2進数表記なんですけど10進数にしてもそのまま1です。信号を読み取ったスタンプはレックスなのでレックスの固有番号は1となります。
それをふまえた上で今度はこっちです。

2進数にすると00100110です。これを10進数にすると38番となります。これはバッタバイスタンプです。

私はこの2つしかないのでこれ以上は調べられないのですがツイッターのタイムラインで流れてきた書き込みにリバイスを1番として逆から仮面ライダーを数えていけば1号は38番なるのでは?との情報があったので調べてみるとまさにその通りでした。

その情報をありがたく使わせて頂きます。

オシロスコープの波形を見続けているとわかるのですがバイスタンプはこの固有番号をループで発信しています。

なのでまずはこの波形を再現します。

再現する上で気をつけなければいけないのが赤外線の送信方法です。

ただ1500μsをHIGH、500μsをLOWにすればいいのではなくHIGHの時は28μsでオンオフを繰り返しています。もっと高額なオシロスコープで赤外線の波形を見ればHIGHの時の線が1本ではなくギザギザになっているとわかりますがこのオシロスコープではよくわかりません。
ここら辺の詳しい情報はarduino 赤外線リモコンなどで検索すれば他の方が詳しく解説させているのでそちらをご参照ください。

それでは先に回路図の方を載せます。
画像はArduino Unoを使っていますが使用しているのはseeeduino xiaoです。
繋げているIO端子の番号は自分の環境に合わせて変えてください。
電源はUSB端子から直接引っ張っています。

そして以下のスケッチがです。

スタンプ固有番号だけだと反応しないのでガンデフォン用の信号を探します。
私がやった探し方はレックスの信号を流しながら2進数の信号を1から順に流してヒットするまで総当りでやってました。
まあ答えを言ってしまうと番号は150番です。
そしてこの2つの信号をガンデフォンに流すとバイスタンプ講座が流れます。

スイッチ単押しで講座音声、長押しでスタンプ切り替えになっています。

長くなりましたが以上です。信号のタイミングはリバイス玩具は全部同じなので応用すればスタンプも鳴らせます。ぜひ挑戦してみてください。

www.youtube.com


  1. //ガンデフォン制御
  2. #define data_pin A2 //赤外線
  3. #define start_pin 1 //スイッチ
  4. unsigned int data_1[] = {0,0,0,0,0,0,0,1};//レックス
  5. unsigned int data_4[] = {0,0,0,0,0,1,0,0};//ブラキオ
  6. unsigned int data_6[] = {0,0,0,0,0,1,1,0};//ジャッカル
  7. unsigned int data_9[] = {0,0,0,0,1,0,0,1};//カマキリ
  8. unsigned int data_11[] = {0,0,0,0,1,0,1,1};//コング
  9. unsigned int data_13[] = {0,0,0,0,1,1,0,1};//イーグル
  10. unsigned int data_14[] = {0,0,0,0,1,1,1,0};//メガロドン
  11. unsigned int data_16[] = {0,0,0,1,0,0,0,0};//マンモス
  12. unsigned int data_23[] = {0,0,0,1,0,1,1,1};//ライオン
  13. unsigned int data_70[] = {0,1,0,0,0,1,1,0};//汎用
  14. unsigned int data_71[] = {0,1,0,0,0,1,1,1};//新しいリバイスをご覧あれ
  15. unsigned int data_72[] = {0,1,0,0,1,0,0,0};//
  16. unsigned int data_73[] = {0,1,0,0,1,0,0,1};//新しいリバイスをご覧あれ
  17. unsigned int data_74[] = {0,1,0,0,1,0,1,0};//プテラ
  18. unsigned int data_125[] = {0,1,1,1,1,1,0,1};//効果音のみ
  19. unsigned int data_150[] = {1,0,0,1,0,1,1,0};//スタンプ講座用基本信号
  20. unsigned long start_bit_time = 6000;
  21. unsigned long end_bit_time = 198500;
  22. unsigned long ir_long_time = 1500;
  23. unsigned long ir_short_time = 500;
  24. int ir_blinking_seconds = 8;
  25. int i=0;
  26. int start__sw;
  27. int id_number;
  28. int id_count=150;//150はスタンプ講座用基本信号
  29. int id_count_1=1;//
  30. int val;
  31. //-------------------------------------------------------------------------------------
  32. void ir_led_start(){
  33.     unsigned long us = micros();
  34.     
  35.     while (long(us + start_bit_time - micros()) > 0){
  36.       digitalWrite(data_pin, 1); //
  37.       delayMicroseconds(ir_blinking_seconds); //
  38.       digitalWrite(data_pin, 0);
  39.       delayMicroseconds(ir_blinking_seconds);
  40.       }
  41.     us = micros();
  42.     while (long(us + ir_short_time - micros()) > 0){
  43.       digitalWrite(data_pin, 0); //
  44.       delayMicroseconds(ir_blinking_seconds); //
  45.       digitalWrite(data_pin, 0);
  46.       delayMicroseconds(ir_blinking_seconds);
  47.       }
  48. }
  49. //----------------------------------------------------------------------------------------
  50. void ir_led_end(){
  51.     unsigned long us = micros();
  52.     
  53.     while (long(us + end_bit_time - micros()) > 0){
  54.       digitalWrite(data_pin, 0); //
  55.       delayMicroseconds(ir_blinking_seconds); //
  56.       digitalWrite(data_pin, 0);
  57.       delayMicroseconds(ir_blinking_seconds);
  58.       }
  59. }
  60. //----------------------------------------------------------------------------------------
  61. void ir_led_1(){
  62.     unsigned long us = micros();
  63.     
  64.     while (long(us + ir_short_time - micros()) > 0){
  65.       digitalWrite(data_pin, 1); //
  66.       delayMicroseconds(ir_blinking_seconds); //
  67.       digitalWrite(data_pin, 0);
  68.       delayMicroseconds(ir_blinking_seconds);
  69.       }
  70.     us = micros();
  71.     while (long(us + ir_long_time - micros()) > 0){
  72.       digitalWrite(data_pin, 0); //
  73.       delayMicroseconds(ir_blinking_seconds); //
  74.       digitalWrite(data_pin, 0);
  75.       delayMicroseconds(ir_blinking_seconds);
  76.       }
  77. }
  78. //----------------------------------------------------------------------------------------
  79. void ir_led_0(){
  80.     unsigned long us = micros();
  81.     
  82.     while (long(us + ir_long_time - micros()) > 0){
  83.       digitalWrite(data_pin, 1); //
  84.       delayMicroseconds(ir_blinking_seconds); //
  85.       digitalWrite(data_pin, 0);
  86.       delayMicroseconds(ir_blinking_seconds);
  87.       }
  88.     us = micros();
  89.     while (long(us + ir_short_time - micros()) > 0){
  90.       digitalWrite(data_pin, 0); //
  91.       delayMicroseconds(ir_blinking_seconds); //
  92.       digitalWrite(data_pin, 0);
  93.       delayMicroseconds(ir_blinking_seconds);
  94.       }
  95. }
  96. //----------------------------------------------------------------------------------------
  97. void id_Signal(){
  98.  ir_led_start();
  99.  
  100.  switch(id_number){//
  101. case 1 :{ for (int i=0; i <= 7;){if(data_1[i] == 1){ir_led_1();}else{ir_led_0();}i++;}} break;//レックス
  102. case 2 :{ for (int i=0; i <= 7;){if(data_14[i] == 1){ir_led_1();}else{ir_led_0();}i++;}} break;//メガロドン
  103. case 3 :{ for (int i=0; i <= 7;){if(data_13[i] == 1){ir_led_1();}else{ir_led_0();}i++;}} break;//イーグル
  104. case 4 :{ for (int i=0; i <= 7;){if(data_16[i] == 1){ir_led_1();}else{ir_led_0();}i++;}} break;//マンモス
  105. case 5 :{ for (int i=0; i <= 7;){if(data_74[i] == 1){ir_led_1();}else{ir_led_0();}i++;}} break;//プテラ
  106. case 6 :{ for (int i=0; i <= 7;){if(data_23[i] == 1){ir_led_1();}else{ir_led_0();}i++;}} break;//ライオン
  107. case 7 :{ for (int i=0; i <= 7;){if(data_6[i] == 1){ir_led_1();}else{ir_led_0();}i++;}} break;//ジャッカル
  108. case 8 :{ for (int i=0; i <= 7;){if(data_11[i] == 1){ir_led_1();}else{ir_led_0();}i++;}} break;//コング
  109. case 9 :{ for (int i=0; i <= 7;){if(data_9[i] == 1){ir_led_1();}else{ir_led_0();}i++;}} break;//カマキリ
  110. case 10:{ for (int i=0; i <= 7;){if(data_4[i] == 1){ir_led_1();}else{ir_led_0();}i++;}} break;//ブラキオ
  111. case 11:{ for (int i=0; i <= 7;){if(data_70[i] == 1){ir_led_1();}else{ir_led_0();}i++;}} break;//汎用
  112. case 12:{ for (int i=0; i <= 7;){if(data_71[i] == 1){ir_led_1();}else{ir_led_0();}i++;}} break;//新しいリバイスをご覧あれ
  113. case 13:{ for (int i=0; i <= 7;){if(data_72[i] == 1){ir_led_1();}else{ir_led_0();}i++;}} break;//
  114. case 150:{ for (int i=0; i <= 7;){if(data_150[i] == 1){ir_led_1();}else{ir_led_0();}i++;}} break;//スタンプ講座用基本信号
  115. default: ;
  116.  }
  117.   ir_led_end();
  118. }
  119. //-----------------------------------------スタンプチェンジ------------------------------------------
  120. void stamp_change(){
  121.   #define PUSH_SHORT 200000
  122.   unsigned long gauge = 0;
  123.   while (!digitalRead(start_pin)){gauge++;}
  124.   if (gauge < PUSH_SHORT){
  125.     //Serial.println("ボタン単押し");
  126.     id_number=id_count_1;id_Signal();
  127.     id_number=id_count;id_Signal();
  128.     }else{
  129.     //Serial.println("ボタン長押し");
  130.      id_count_1++;
  131.      if(id_count_1 == 14){id_count_1=1;}
  132.      delay(300);
  133.   }
  134. }
  135. //---------------------------------------------------------------------------------------------
  136. void setup() {
  137.   Serial.begin( 9600 );
  138.   pinMode(data_pin, INPUT_PULLUP);
  139.   pinMode(data_pin, OUTPUT);
  140.   pinMode(start_pin, INPUT_PULLUP);
  141. }
  142. void loop() {
  143. if(digitalRead(start_pin) == LOW){delay(300);stamp_change();
  144. Serial.println( id_count_1 );}
  145. }

※デモンズドライバーにこのスケッチをそのまま使うこともできます