ラベル おもちゃ の投稿を表示しています。 すべての投稿を表示
ラベル おもちゃ の投稿を表示しています。 すべての投稿を表示

2025年3月25日火曜日

デジタルゴチゾウを作ってみよう:ハードウェア編

前回の記事でソフトウェアの準備が出来ましたので、今度はハードウェア面を作成します

最初にヒダカヒロジさんの「デジタルゴチゾウをつくる | MUDAなことをしよう。」サイトを参考にしてか回路を作成します。当初は、サイズが小さい点からMCP4661を単体で購入して作成するつもりでしたが、部品サイトを検索しても見つからなかったため同じモジュールを使用することにしました。なので、ヒダカヒロジさんの紹介している回路と全く同じ構成になりますので、回路詳細は「デジタルゴチゾウをつくる | MUDAなことをしよう。」サイトをご覧ください

上側の6角形にした基板には、M5STICKC Plus2を接続するためのピンヘッダーを搭載しています。下側のピンヘッダはゴチゾウ側の基板、およびスイッチを接続します。配線が切れない様にホットボンドで固定してあります

さて、ケースですが我が家には3Dプリンタはありません。たとえ、合ったとしてもデータが作れないので、ゴチゾウを切った貼ったして加工しました。途中で、タイクーンはてれびくんの付録ゴチゾウだったことを思い出し、違うのを試用すればよかったと後悔することになりました

ゴチゾウ側の基板からの配線になります。こちらも断線防止のためにホットボンドで固定しています。ゴチゾウの下部スイッチは再利用して、中にマイクロスイッチ(uxcell 20pcs 4mm x 2mm SPST 瞬間押しボタン パネルPCB)を付けています。なお、株スイッチは奥まで押し込まれますので、それに合わせてください(スイッチを貼り付けるためにスイッチの出っ張りを切り落としています)


で、組み立てるとこんな感じになります。ホットボンドやレジンで補強しまくっています

ピンヘッダーに合わせて、M5STICKC Plus2を刺すことができます

この状態でガヴベルトに接続してテストを行いました。特に高さがありませので、動作テストとベルトとの干渉をチェックしています(少し余裕があるていどで使用できます)

ここで、我が家のちびちゃんにみつかりました。遊びたいオーラ出しまくりですが、M5STICKC Plus2が不安定なので渡せません。急いで上部を作成することにしました

いらない穴をふさいで、スクリーン用の穴を空けて、次は細かい傷を消そうというところで、ちびちゃんの玩具になりました。とりあえず、不安定では無いのでちびちゃんが遊んでも簡単には壊れないと思います

とりあえず、動作画面を載せておきます




レジェンドライダーを選択した時は、ライダーズクレストが表示されます

強奪されたので、これで完成にしました。気が向いたら細かい傷取りや塗装もしたいと思ってます...

2025年3月24日月曜日

デジタルゴチゾウを作ってみよう:ソフトウェア編

現在、我が家のちびちゃんは仮面ライダーガヴにはまっており、色々なゴチゾウに興味があります。一時期よりは手に入るようになりましたが、それでも手に入らない物もありますよね

そんな中、X(旧Twitter)を眺めていたところヒダカヒロジさんの投稿でデジタルゴチゾウが紹介されていました。早速、リンク先の「デジタルゴチゾウをつくる | MUDAなことをしよう。」を拝見したところ、スケッチ(ソースコードをこういう風に言うらしい)を含む制作過程がすべて紹介されていました。

M5STAMP製品どころかArduinoも使用したことありませんが、ここまで情報があればきっと作ることが出来ると見切り発車で~す

ヒダカヒロジさんは、ヴァレンバスターをターゲットにしていますので横向き使用となっておりますが、我が家ではガヴドライバでの使用を想定しています。そのため、ヒダカヒロジさんのソースコードから下記内容を変更しています

  1. 縦型表示
    • select_gochizou 関数内の画面サイズ、およびsetup 関数内のsetRotation()の設定値を変更
    • 各種描画位置、サイズを変更
  2. ゴチゾウのカテゴリ、名称の日本語表示
    ちびちゃんはまだ読めませんが、今後の勉強もかねて
    • M5Unified.h をインクルードし、setup 関数内でsetTextFontでgfxJapanGothic_8 フォントを設定
      縦型、日本語化に伴い、このサイズを選択しています
  3. カテゴリアイコンをゴチゾウ画像化
    ちびちゃんにはこちらの方が判りますので...
    • 85x85 の画像データを作成し、こちらのサイトからバイナリ化してimg_icon.hを作成しています
  4. ゴチゾウの目を丸型化
    横幅が狭いので変更。ま、こっちの方が好みなんですけど
    • ヒダカヒロジさんの瞳作成を参考にし、縦型変更に伴うサイズ、位置設定を変更してます
    • 瞳を閉じている目、初期状態の目も描画で作成したので、img_gochizou.hは使用してません
    • 白目の部分は黒めにしています(ゴチゾウのイメージカラーで白がいるため)
  5. デバッグモードを追加
    描画動作のデバッグの容易化のため
    • 4項のデバッグのため、ボタンBの設定を拡張スイッチと同様の内容に変更
    • デバッグモード時、I2C アクセスは行わない様になっています
  6. その他
    • 75x75でライダーズクレスト画像を作成し、img_crest.hに設定
    • サポートゴチゾウを増やしています(クレーンの丈さんの調査結果を参考にしました)
    • ブンブンジャー選択時もクレスト画像を表示っするようにしています

完成したソースコードは以下になります:

#include <M5StickCPlus2.h>
#include "M5Unified.h" // 日本語フォントを使用するために追加
#include "MCP4661_asukiaaa.hpp"
#include "img_icon.h"
#include "img_crest.h"
#include "Wire.h"

#define PIN_SW 25 // Extra SW
#define ON  LOW
#define OFF HIGH
uint8_t sw = OFF;
uint8_t prev_sw = OFF;

#define STATE_INIT     0
#define STATE_GOCHIZOU 1
#define STATE_CHANGE   2
#define STATE_FINISH   3
uint8_t state = STATE_INIT;
uint8_t prev_state = STATE_INIT;

#define STATE_FINISH_TO_CHANGE_TIME_MS 10000
unsigned long state_change_point_ms = 0;

// #define debug // I2C 通信オフ

void change_state(uint8_t new_state){
  state = new_state;
  Serial.print(F("State: "));
  switch(state){
  case STATE_INIT:     Serial.println(F("INIT"));     break;
  case STATE_GOCHIZOU: Serial.println(F("GOCHIZOU")); break;
  case STATE_CHANGE:   Serial.println(F("CHANGE"));   break;
  case STATE_FINISH:   Serial.println(F("FINISH"));   break;
  default: ;
  }
}

MCP4661_asukiaaa::Core potentio(&Wire, MCP4661_asukiaaa::DeviceAddress::A0H_A1H_A2H);

#define R_VALUE_MAX 256

int RrA_value = 0;
int RrB_value = 0;

// 257ステップで100kΩなので、1ステップあたり0.389Ω。
#define R_62K  162 // 145 ~ 179
#define R_47K  121 // 114 ~ 132
#define R_39K  102 //  95 ~ 108
#define R_30K   78 //  74 ~  82
#define R_24K   63 //  60 ~  65
#define R_20K   52 //  50 ~  54
#define R_16K   42 //  39 ~  44
#define R_12K   31 //  29 ~  32
#define R_10K   26 //  25 ~  27
#define R_8_2K  21 //  20 ~  22
#define R_6_8K  17 //  17 ~  18
#define R_5_6K  14 //  14 ~  15

void printLogAboutWrite(Stream* serial, uint8_t channel, uint16_t valWrote, int result) {
  serial->print("write " + String(valWrote) + " for wiper" + String(channel) +
                " ");
  serial->println(result == 0 ? "succeeded"
                              : "failed by error " + String(result));
}

#define CATEGORY_GUMMY         0
#define CATEGORY_SNACK         1
#define CATEGORY_CHOCOLATE     2
#define CATEGORY_MARSHMALLOW   3
#define CATEGORY_CANDY         4
#define CATEGORY_RAMUNE        5
#define CATEGORY_POPCORN       6
#define CATEGORY_RICE_CRACKER  7
#define CATEGORY_JELLY         8
#define CATEGORY_MACARON       9
#define CATEGORY_DONUT        10
#define CATEGORY_CARAMEL      11
#define CATEGORY_COOKIE       12
#define CATEGORY_PUDDING      13
#define CATEGORY_CAKE         14
#define CATEGORY_SPECIAL      15
#define CATEGORY_LEGEND_RIDER 16
#define CATEGORY_SUPER_SENTAI 17
#define CATEGORY_SWEETS       18

typedef struct {
  char* name_1; // 全角 8文字 
  char* name_2; // 全角 8文字 
  uint32_t color; // 0x000000Uの形で表現
  uint16_t r_A;
  uint16_t r_B;
} gochizou;

#define C_BLACK       0x000000U
#define C_NAVY        0x000080U
#define C_DARKGREEN   0x008000U
#define C_DARKCYAN    0x008080U
#define C_MAROON      0x800000U
#define C_PURPLE      0x800080U
#define C_OLIVE       0x808000U
#define C_LIGHTGREY   0xC0C0C0U
#define C_DARKGREY    0x808080U
#define C_BLUE        0x0000FFU
#define C_GREEN       0x00FF00U
#define C_CYAN        0x00FFFFU
#define C_RED         0xFF0000U
#define C_MAGENTA     0xFF00FFU
#define C_YELLOW      0xFFFF00U
#define C_WHITE       0xFFFFFFU
#define C_ORANGE      0xFFA500U
#define C_GREENYELLOW 0xADFF2FU
#define C_PINK        0xFFC0CBU
#define C_BROWN       0x964B00U
#define C_GOLD        0xFFD700U
#define C_SILVER      0xC0C0C0U
#define C_SKYBLUE     0x87CEEBU
#define C_VIOLET      0xB42EE2U

gochizou selected_gochizou = {"ポッピンググミ", NULL, C_PURPLE, R_62K, R_62K};

gochizou gochizou_gummy[] = {
  {"ポッピンググミ",   NULL, C_PURPLE,   R_62K, R_62K}, //017
  {"キッキンググミ",   NULL, C_ORANGE,   R_62K, R_47K}, //018
  {"パンチンググミ",   NULL, C_SKYBLUE,  R_62K, R_39K}, //019
  {"フィッシンググミ", NULL, C_CYAN,     R_62K, R_30K}, //020
  {"アメージンググミ", NULL, C_PURPLE,    R_62K, R_24K}, //021
  {"スパーキンググミ", NULL, C_DARKGREY, R_62K, R_20K}  //022
};

gochizou gochizou_snack[] = {
  {"ザクザクチップス", NULL,     C_YELLOW, R_62K, R_16K},  //023
  {"ヒリヒリチップス", NULL,     C_RED,    R_62K, R_8_2K}, //026
  {"ショットスナック", NULL,     C_YELLOW,  R_24K, R_10K},  //073
  {"スパイクスナック", NULL,     C_YELLOW, R_24K, R_8_2K}, //074
  {"ショットスナック", "技:シュート", C_YELLOW,  R_20K, R_47K},  //078
  {"スパイクスナック", "技:ニードル", C_YELLOW, R_20K, R_39K},  //079
  {"ポテトチェーン",   NULL,     C_YELLOW, R_20K, R_16K},  //083
  {"シールドスナック", NULL,     C_YELLOW, R_20K, R_12K},  //084
  {"ポテトチェーン",   "技:ストーム",  C_YELLOW, R_20K, R_10K},  //085
  {"シールドスナック", "技:アタック", C_YELLOW, R_20K, R_8_2K}, //086
};

gochizou gochizou_chocolate[] = {
  {"チョコダン",  NULL,           C_RED,       R_62K, R_6_8K}, //027
  {"チョコドン",  "技:バースト", C_BROWN,      R_62K, R_5_6K}, //028
  {"チョコT",     NULL,           C_DARKGREEN, R_47K, R_47K},  //030
  {"チョコホネ" , NULL,           C_DARKGREEN, R_47K, R_39K},  //031
  {"チョコルド",  NULL,           C_DARKGREY,  R_47K, R_30K},  //032
  {"チョコルド",  "技:アタック", C_DARKGREY,   R_47K, R_24K},  //033
  {"チョコスタ" , NULL,           C_BROWN,     R_20K, R_62K},  //077
  {"チョコホネ",  "技:ウォール", C_DARKGREEN,  R_20K, R_30K},  //080
  {"チョコスタ",  "技:シュート", C_BROWN,      R_20K, R_20K}   //082
};

gochizou gochizou_marshmallow[] = {
  {"フワマロ", NULL, C_CYAN, R_47K, R_20K},  //034
  {"マルマロ", NULL, C_PINK, R_47K, R_16K}   //035
};

gochizou gochizou_candy[] = {
  {"ブルキャン", NULL,               C_MAGENTA, R_47K, R_12K},  //036
  {"グルキャン", NULL,               C_SKYBLUE, R_47K, R_10K},  //037
  {"バクキャン", NULL,               C_YELLOW,  R_47K, R_8_2K}, //038
  {"もふパチ",   NULL,               C_PURPLE,  R_39K, R_30K},  //044
  {"もふパチ",   "技:スパーキング", C_PURPLE,  R_30K, R_16K}   //059
};

gochizou gochizou_ramune[] = {
  {"バブルラムネ",  "技:ショック", C_SKYBLUE, R_47K, R_6_8K}, //039
  {"バブルラムネ",  NULL,           C_SKYBLUE, R_47K, R_5_6K}  //040
};

gochizou gochizou_popcorn[] = {
  {"ポップバーン", NULL,         C_SKYBLUE, R_39K, R_16K}, //047
  {"ポップバーン", "技:バーン", C_SKYBLUE, R_30K, R_8_2K} //062
};

gochizou gochizou_rice_cracker[] = {
  {"ビュンベイ", NULL,             C_RED, R_39K, R_10K}, //049
  {"ビュンベイ", "技:ローリング", C_RED, R_30K, R_5_6K} //064
};

gochizou gochizou_jelly[] = {
  {"ぷるゼリー", NULL,            C_MAGENTA, R_39K, R_8_2K}, //050
  {"ぷるゼリー", "技:ショット",  C_MAGENTA, R_24K, R_62K}   //065
};

gochizou gochizou_macaron[] = {
  {"エレガンマカロン", NULL,           C_PINK, R_39K, R_6_8K}, //051
  {"エレガンマカロン", "技:アタック", C_PINK, R_24K, R_47K},  //066
};

gochizou gochizou_donut[] = {
  {"ドーマル", NULL,           C_SKYBLUE, R_39K, R_5_6K}, //052
  {"ドーマル", "技:ショット", C_SKYBLUE, R_24K, R_39K}   //067
};

gochizou gochizou_caramel[] = {
  {"キャラメルメル", NULL,           C_GOLD, R_30K, R_62K}, //053
  {"キャラメルメル", "技:マジック", C_GOLD, R_24K, R_30K}  //068
};

gochizou gochizou_cookie[] = {
  {"クッキッキー", NULL,           C_BLUE, R_30K, R_47K}, //054
  {"クッキッキー", "技:ラッシュ", C_BLUE, R_24K, R_24K}  //069
};

gochizou gochizou_pudding[] = {
  {"どっプリン", NULL,             C_ORANGE, R_30K, R_30K}, //056
  {"どっプリン", "技:インパクト", C_ORANGE, R_24K, R_16K}  //071
};

gochizou gochizou_cake[] = {
  {"ケーキング", NULL,      C_WHITE, R_5_6K, R_39K}, //151
  {"ブッシュ",  "ドノエル", C_GREEN, R_5_6K, R_30K}  //152
};

gochizou gochizou_special[] = {
  {"スペシャル",   NULL,            C_WHITE, R_16K, R_62K}, //089
  {"おめでとう",   NULL,            C_WHITE, R_16K, R_47K}, //090
  {"クリスマス",   NULL,            C_GREEN, R_16K, R_39K}, //091
  {"ハッピー",     "ニューイヤー",  C_RED,   R_16K, R_30K}, //092
  {"ミュージック", NULL,            C_WHITE, R_16K, R_24K}, //093
  {"おめでとう",   "誕生日Ver.",    C_WHITE, R_16K, R_20K}  //094
};

gochizou gochizou_legend_rider[] = {
  {"クウガ",      NULL,       C_RED,     R_16K, R_16K},  //095
  {"アギト",      NULL,       C_GOLD,    R_16K, R_12K},  //096
  {"竜騎",        NULL,       C_RED,     R_16K, R_10K},  //097
  {"ファイズ",    NULL,       C_RED,     R_16K, R_8_2K}, //098
  {"ブレード",    NULL,       C_BLUE,    R_16K, R_6_8K}, //099
  {"響",          NULL,       C_PURPLE,  R_16K, R_5_6K}, //100
  {"カブト",      NULL,       C_RED,     R_12K, R_62K},  //101
  {"電王",        NULL,       C_RED,     R_12K, R_47K},  //102
  {"キバ",        NULL,       C_RED,     R_12K, R_39K},  //103
  {"ディケード",  NULL,       C_MAGENTA, R_12K, R_30K},  //104
  {"ダブル",      NULL,       C_PURPLE,   R_12K, R_24K}, //105
  {"オーズ",      NULL,       C_GREEN,   R_12K, R_20K},  //106
  {"フォーゼ",    NULL,       C_WHITE,   R_12K, R_16K},  //107
  {"ウィザード",  NULL,       C_RED,     R_12K, R_12K},  //108
  {"鎧武",        NULL,       C_ORANGE,  R_12K, R_10K},  //109
  {"ドライブ",    NULL,       C_RED,     R_12K, R_8_2K}, //110
  {"ゴースト",    NULL,       C_ORANGE,  R_12K, R_6_8K}, //111
  {"エグゼイド",  NULL,       C_PURPLE,  R_12K, R_5_6K}, //112
  {"ビルド",      NULL,       C_RED,     R_10K, R_62K},  //113
  {"ジオウ"  ,    NULL,       C_PURPLE,  R_10K, R_47K},  //114
  {"ゼロワン",    NULL,       C_YELLOW,  R_10K, R_39K},  //115
  {"セイバー",    NULL,       C_RED,     R_10K, R_30K},  //116
  {"リバイ",      "REVICE",   C_PINK,    R_10K, R_24K},  //117
  {"バイス",      "REVICE",   C_PINK,    R_10K, R_20K},  //118
  {"ギーツ",      NULL,       C_WHITE,   R_10K, R_16K},  //119
  {"タイクーン",  "GEATS",    C_GREEN,   R_10K, R_12K},  //120
  {"バッファ",    "GEATS",    C_PURPLE,  R_10K, R_10K},  //121
  {"ナーゴ",      "GEATS",    C_GOLD,    R_10K, R_8_2K}, //122
  {"ガッチャード", NULL,       C_SKYBLUE, R_10K, R_6_8K}, //123
  {"レジェンド",   "GOTCHARD", C_GOLD,    R_10K, R_5_6K}, //124
  {"マジェード",   "GOTCHARD", C_WHITE,   R_8_2K, R_62K}, //125
  {"ジーン",       "GEATS",    C_BLUE,    R_8_2K, R_47K}, //126
  {"ヴァルバラド", "GOTCHARD", C_PURPLE,  R_8_2K, R_39K}, //127
  {"1号",         NULL,       C_GREEN,   R_8_2K, R_30K}, //128
  {"バルカン",     "ZERO-ONE", C_BLUE,    R_8_2K, R_24K}, //129
  {"ブレイズ",     "SABER",    C_BLUE,    R_8_2K, R_20K}, //130
  {"ライブ",       "REVICE",   C_GOLD,    R_8_2K, R_16K}, //131
  {"ガヴ",         NULL,       C_PURPLE,  R_5_6K, R_24K}, //153
  {"Nextライダー", NULL,       C_GREEN,   R_5_6K, R_20K}, //154
  {"Newヒーロー",  NULL,       C_GREEN,   R_5_6K, R_16K}, //155
  {"仮面ライダー", NULL,       C_GREEN,   R_5_6K, R_12K}  //156
};

gochizou gochizou_super_sentai[] = {
  {"戦隊",     NULL,            C_RED, R_8_2K, R_12K},  //132
  {"ヒーロー", NULL,            C_RED, R_8_2K, R_10K},  //133
  {"爆上戦隊", "ブンブンジャー", C_RED, R_8_2K, R_8_2K}  //134
};

gochizou gochizou_sweets[] = {
  {"おやつ", NULL, C_WHITE, R_24K,  R_6_8K}, // 078
  {"おかし", NULL, C_WHITE, R_24K,  R_5_6K}, // 079
  {"??????", NULL, C_WHITE, R_20K,  R_24K},
  {"??????", NULL, C_WHITE, R_8_2K, R_6_8K},
  {"??????", NULL, C_WHITE, R_8_2K, R_5_6K},
  {"??????", NULL, C_WHITE, R_6_8K, R_62K},
  {"??????", NULL, C_WHITE, R_6_8K, R_47K},
  {"??????", NULL, C_WHITE, R_6_8K, R_39K},
  {"??????", NULL, C_WHITE, R_6_8K, R_30K},
  {"??????", NULL, C_WHITE, R_6_8K, R_24K},
  {"??????", NULL, C_WHITE, R_6_8K, R_20K},
  {"??????", NULL, C_WHITE, R_6_8K, R_16K},
  {"??????", NULL, C_WHITE, R_6_8K, R_12K},
  {"??????", NULL, C_WHITE, R_6_8K, R_10K},
  {"??????", NULL, C_WHITE, R_6_8K, R_8_2K},
  {"??????", NULL, C_WHITE, R_6_8K, R_6_8K},
  {"??????", NULL, C_WHITE, R_6_8K, R_5_6K},
  {"??????", NULL, C_WHITE, R_6_8K, R_62K},
  {"??????", NULL, C_WHITE, R_6_8K, R_47K},
  {"??????", NULL, C_WHITE, R_6_8K, R_39K},
  {"??????", NULL, C_WHITE, R_6_8K, R_30K},
  {"??????", NULL, C_WHITE, R_6_8K, R_24K},
  {"??????", NULL, C_WHITE, R_6_8K, R_20K},
  {"??????", NULL, C_WHITE, R_6_8K, R_16K},
  {"??????", NULL, C_WHITE, R_6_8K, R_12K},
  {"??????", NULL, C_WHITE, R_6_8K, R_10K},
  {"??????", NULL, C_WHITE, R_6_8K, R_8_2K},
  {"??????", NULL, C_WHITE, R_6_8K, R_6_8K},
  {"??????", NULL, C_WHITE, R_6_8K, R_5_6K},
  {"??????", NULL, C_WHITE, R_5_6K, R_62K},
  {"??????", NULL, C_WHITE, R_5_6K, R_47K}
};

int8_t  gochizou_index = 0;
uint8_t gochizou_category = CATEGORY_GUMMY;
uint8_t gochizou_category_size = sizeof(gochizou_gummy) / sizeof(gochizou);

void change_gochizou_category(){
  // カテゴリー順を編集しやすいよう、この形にする
  switch(gochizou_category){
  case CATEGORY_GUMMY:
    gochizou_category = CATEGORY_SNACK;
    gochizou_category_size = sizeof(gochizou_snack) / sizeof(gochizou);
    break;
  case CATEGORY_SNACK:
    gochizou_category = CATEGORY_CHOCOLATE;
    gochizou_category_size = sizeof(gochizou_chocolate) / sizeof(gochizou);
    break;
  case CATEGORY_CHOCOLATE:
    gochizou_category = CATEGORY_MARSHMALLOW;
    gochizou_category_size = sizeof(gochizou_marshmallow) / sizeof(gochizou);
    break;
  case CATEGORY_MARSHMALLOW:
    gochizou_category = CATEGORY_CANDY;
    gochizou_category_size = sizeof(gochizou_candy) / sizeof(gochizou);
    break;
  case CATEGORY_CANDY:
    gochizou_category = CATEGORY_RAMUNE;
    gochizou_category_size = sizeof(gochizou_ramune) / sizeof(gochizou);
    break;
  case CATEGORY_RAMUNE:
    gochizou_category = CATEGORY_POPCORN;
    gochizou_category_size = sizeof(gochizou_popcorn) / sizeof(gochizou);
    break;
  case CATEGORY_POPCORN:
    gochizou_category = CATEGORY_RICE_CRACKER;
    gochizou_category_size = sizeof(gochizou_rice_cracker) / sizeof(gochizou);
    break;
  case CATEGORY_RICE_CRACKER:
    gochizou_category = CATEGORY_JELLY;
    gochizou_category_size = sizeof(gochizou_jelly) / sizeof(gochizou);
    break;
  case CATEGORY_JELLY:
    gochizou_category = CATEGORY_MACARON;
    gochizou_category_size = sizeof(gochizou_macaron) / sizeof(gochizou);
    break;
  case CATEGORY_MACARON:
    gochizou_category = CATEGORY_DONUT;
    gochizou_category_size = sizeof(gochizou_donut) / sizeof(gochizou);
    break;
  case CATEGORY_DONUT:
    gochizou_category = CATEGORY_CARAMEL;
    gochizou_category_size = sizeof(gochizou_caramel) / sizeof(gochizou);
    break;
  case CATEGORY_CARAMEL:
    gochizou_category = CATEGORY_COOKIE;
    gochizou_category_size = sizeof(gochizou_cookie) / sizeof(gochizou);
    break;
  case CATEGORY_COOKIE:
    gochizou_category = CATEGORY_PUDDING;
    gochizou_category_size = sizeof(gochizou_pudding) / sizeof(gochizou);
    break;
  case CATEGORY_PUDDING:
    gochizou_category = CATEGORY_CAKE;
    gochizou_category_size = sizeof(gochizou_cake) / sizeof(gochizou);
    break;
  case CATEGORY_CAKE:
    gochizou_category = CATEGORY_SPECIAL;
    gochizou_category_size = sizeof(gochizou_special) / sizeof(gochizou);
    break;
  case CATEGORY_SPECIAL:
    gochizou_category = CATEGORY_LEGEND_RIDER;
    gochizou_category_size = sizeof(gochizou_legend_rider) / sizeof(gochizou);
    break;
  case CATEGORY_LEGEND_RIDER:
    gochizou_category = CATEGORY_SUPER_SENTAI;
    gochizou_category_size = sizeof(gochizou_super_sentai) / sizeof(gochizou);
    break;
  case CATEGORY_SUPER_SENTAI:
    //gochizou_category = CATEGORY_SWEETS;
    //gochizou_category_size = sizeof(gochizou_sweets) / sizeof(gochizou);
    gochizou_category = CATEGORY_GUMMY;
    gochizou_category_size = sizeof(gochizou_gummy) / sizeof(gochizou);
    break;
  /*  
  case CATEGORY_SWEETS:
    gochizou_category = CATEGORY_GUMMY;
    gochizou_category_size = sizeof(gochizou_gummy) / sizeof(gochizou);
    break;
  */
  default:
    ;
  }

  gochizou_index = 0;
}

void select_gochizou(){
  if(gochizou_index >= gochizou_category_size){
    gochizou_index = 0;
  }else if(gochizou_index < 0){
    gochizou_index = gochizou_category_size - 1;
  }

  switch(gochizou_category){
  case CATEGORY_GUMMY:        selected_gochizou = gochizou_gummy[gochizou_index];        break;
  case CATEGORY_SNACK:        selected_gochizou = gochizou_snack[gochizou_index];        break;
  case CATEGORY_CHOCOLATE:    selected_gochizou = gochizou_chocolate[gochizou_index];    break;
  case CATEGORY_MARSHMALLOW:  selected_gochizou = gochizou_marshmallow[gochizou_index];  break;
  case CATEGORY_CANDY:        selected_gochizou = gochizou_candy[gochizou_index];        break;
  case CATEGORY_RAMUNE:       selected_gochizou = gochizou_ramune[gochizou_index];       break;
  case CATEGORY_POPCORN:      selected_gochizou = gochizou_popcorn[gochizou_index];      break;
  case CATEGORY_RICE_CRACKER: selected_gochizou = gochizou_rice_cracker[gochizou_index]; break;
  case CATEGORY_JELLY:        selected_gochizou = gochizou_jelly[gochizou_index];        break;
  case CATEGORY_MACARON:      selected_gochizou = gochizou_macaron[gochizou_index];      break;
  case CATEGORY_DONUT:        selected_gochizou = gochizou_donut[gochizou_index];        break;
  case CATEGORY_CARAMEL:      selected_gochizou = gochizou_caramel[gochizou_index];      break;
  case CATEGORY_COOKIE:       selected_gochizou = gochizou_cookie[gochizou_index];       break;
  case CATEGORY_PUDDING:      selected_gochizou = gochizou_pudding[gochizou_index];      break;
  case CATEGORY_CAKE:         selected_gochizou = gochizou_cake[gochizou_index];         break;
  case CATEGORY_SPECIAL:      selected_gochizou = gochizou_special[gochizou_index];      break;
  case CATEGORY_LEGEND_RIDER: selected_gochizou = gochizou_legend_rider[gochizou_index]; break;
  case CATEGORY_SUPER_SENTAI: selected_gochizou = gochizou_super_sentai[gochizou_index]; break;
  case CATEGORY_SWEETS:       selected_gochizou = gochizou_sweets[gochizou_index];       break;
  default: ;
  }
}

M5Canvas canvas_0(&StickCP2.Display); // スプライト1
M5Canvas canvas_1(&StickCP2.Display); // スプライト2

#define DISP_WIDTH  135
#define DISP_HEIGHT 240
#define SWEETS_ICON_WIDTH  85
#define SWEETS_ICON_HEIGHT 85

#define EYE_X 35
#define EYE_Y 140

void update_disp_gochizou_name(){
  if(gochizou_category == CATEGORY_LEGEND_RIDER){
    // ダブルとビルドのみ、上下で帯の色を変える
    switch(gochizou_index){
    case 10: StickCP2.Display.fillRect(0, 0, DISP_WIDTH, 25, C_GREEN); break; // W
    case 18: StickCP2.Display.fillRect(0, 0, DISP_WIDTH, 25, C_BLUE);  break; // Build
    default: StickCP2.Display.fillRect(0, 0, DISP_WIDTH, 25, selected_gochizou.color);
    }
  }else{
    StickCP2.Display.fillRect(0, 0, DISP_WIDTH, 25, selected_gochizou.color);
  }
  StickCP2.Display.fillRect(0, 215, DISP_WIDTH, 25, selected_gochizou.color);

  StickCP2.Display.fillRect(0, 130, DISP_WIDTH, 85, TFT_BLACK);
  if(selected_gochizou.name_2 == NULL){
    StickCP2.Display.setCursor(0,170);
    StickCP2.Display.print(selected_gochizou.name_1);
  }else{
    StickCP2.Display.setCursor(0,150);
    StickCP2.Display.print(selected_gochizou.name_1);
    StickCP2.Display.setCursor(0,185);
    StickCP2.Display.print(selected_gochizou.name_2);
  }
}

void update_disp_gochizou_category(){
  StickCP2.Display.fillRect(0, 25, DISP_WIDTH, 105, C_BLACK);
  switch(gochizou_category){
  case CATEGORY_GUMMY:        StickCP2.Display.drawPng((std::uint8_t*)gummy,        12425, 25, 35); break;
  case CATEGORY_SNACK:        StickCP2.Display.drawPng((std::uint8_t*)snack,        14633, 25, 35); break;
  case CATEGORY_CHOCOLATE:    StickCP2.Display.drawPng((std::uint8_t*)chocolate,    12294, 25, 35); break;
  case CATEGORY_MARSHMALLOW:  StickCP2.Display.drawPng((std::uint8_t*)marshmallow,  10978, 25, 35); break;
  case CATEGORY_CANDY:        StickCP2.Display.drawPng((std::uint8_t*)candy,        11478, 25, 35); break;
  case CATEGORY_RAMUNE:       StickCP2.Display.drawPng((std::uint8_t*)ramune,       14219, 25, 35); break;
  case CATEGORY_POPCORN:      StickCP2.Display.drawPng((std::uint8_t*)popcorn,      13037, 25, 35); break;
  case CATEGORY_RICE_CRACKER: StickCP2.Display.drawPng((std::uint8_t*)rice_cracker, 12937, 25, 35); break;
  case CATEGORY_JELLY:        StickCP2.Display.drawPng((std::uint8_t*)jelly,        15142, 25, 35); break;
  case CATEGORY_MACARON:      StickCP2.Display.drawPng((std::uint8_t*)macaron,      12466, 25, 35); break;
  case CATEGORY_DONUT:        StickCP2.Display.drawPng((std::uint8_t*)donut,        15886, 25, 35); break;
  case CATEGORY_CARAMEL:      StickCP2.Display.drawPng((std::uint8_t*)caramel,      12346, 25, 35); break;
  case CATEGORY_COOKIE:       StickCP2.Display.drawPng((std::uint8_t*)cookie,       12419, 25, 35); break;
  case CATEGORY_PUDDING:      StickCP2.Display.drawPng((std::uint8_t*)pudding,      15329, 25, 35); break;
  case CATEGORY_CAKE:         StickCP2.Display.drawPng((std::uint8_t*)cake,          9209, 25, 35); break;
  case CATEGORY_SPECIAL:      StickCP2.Display.drawPng((std::uint8_t*)special,      12475, 25, 35); break;
  case CATEGORY_LEGEND_RIDER: StickCP2.Display.drawPng((std::uint8_t*)rider,         2467, 25, 35); break;
  case CATEGORY_SUPER_SENTAI: StickCP2.Display.drawPng((std::uint8_t*)sentai,        5287, 25, 35); break;
  //case CATEGORY_SWEETS:
  //  break;
  default: ;
  } 
}


void show_gochizou_face_init(){
  canvas_0.fillSprite(C_WHITE);
  canvas_1.fillSprite(C_WHITE);
  // 右目
  canvas_0.fillCircle(EYE_X-4, EYE_Y+5, 28, C_BLACK);
  canvas_0.fillCircle(EYE_X, EYE_Y, 21, C_SILVER);
  if(gochizou_category == CATEGORY_LEGEND_RIDER){
    // ダブルとビルドのみ、左右で目の色を変える
    switch(gochizou_index){
    case 10: canvas_0.fillCircle(EYE_X, EYE_Y, 15, C_GREEN); break;
    case 18: canvas_0.fillCircle(EYE_X, EYE_Y, 15, C_BLUE);  break;
    default: canvas_0.fillCircle(EYE_X, EYE_Y, 15, selected_gochizou.color);
    }
  }else{
    canvas_0.fillCircle(EYE_X, EYE_Y, 15, selected_gochizou.color);;
  }
  // 左目
  canvas_0.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 28, C_BLACK);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y, 21, C_SILVER);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y, 15, selected_gochizou.color);
  // 両ハイライト
  canvas_0.fillCircle(EYE_X+7, EYE_Y-7,  5, C_WHITE);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X-7, EYE_Y-7,  5, C_WHITE);
  canvas_0.pushSprite(0,0);
  
  // 目を閉じる方は準備だけ
  canvas_1.fillCircle(EYE_X-4, EYE_Y+5, 28, C_BLACK);
  canvas_1.fillCircle(EYE_X-4, EYE_Y+5, 26, C_WHITE);
  // 左目
  canvas_1.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 28, C_BLACK);
  canvas_1.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 26, C_WHITE);
}

void show_gochizou_face_change(){
  canvas_0.fillSprite(C_WHITE);
  canvas_1.fillSprite(C_WHITE);
  // 右目
  canvas_0.fillCircle(EYE_X-4, EYE_Y+5, 28, C_BLACK);
  canvas_0.fillCircle(EYE_X, EYE_Y, 21, C_SILVER);
  if(gochizou_category == CATEGORY_LEGEND_RIDER){
    // ダブルとビルドのみ、左右で目の色を変える
    switch(gochizou_index){
    case 10: canvas_0.fillCircle(EYE_X, EYE_Y, 15, C_GREEN); break;
    case 18: canvas_0.fillCircle(EYE_X, EYE_Y, 15, C_BLUE);  break;
    default: canvas_0.fillCircle(EYE_X, EYE_Y, 15, selected_gochizou.color);
    }
  }else{
    canvas_0.fillCircle(EYE_X, EYE_Y, 15, selected_gochizou.color);;
  }
  canvas_0.fillCircle(EYE_X, EYE_Y, 6, C_SILVER);
  canvas_0.fillCircle(EYE_X, EYE_Y,  2, C_BLACK);
  // 左目
  canvas_0.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 28, C_BLACK);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y, 21, C_SILVER);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y, 15, selected_gochizou.color);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y,  6, C_SILVER);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y,  2, C_BLACK);
  // 両まぶた
  canvas_0.fillTriangle(EYE_X-24, EYE_Y-26, EYE_X+26, EYE_Y+5, EYE_X+26, EYE_Y-26, C_WHITE);
  canvas_0.fillTriangle(DISP_WIDTH - EYE_X+24, EYE_Y-26, DISP_WIDTH - EYE_X-26, EYE_Y+5, DISP_WIDTH - EYE_X-26, EYE_Y-26, C_WHITE);
  // 両ハイライト
  canvas_0.fillCircle(EYE_X-7, EYE_Y+9,  5, C_WHITE);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X+7, EYE_Y+9,  5, C_WHITE);

 // canvas_0.drawPng((std::uint8_t*)gochizou_init, 548, 0, 0);
  if(gochizou_category == CATEGORY_LEGEND_RIDER){
    switch(gochizou_index){
    case 0:  canvas_0.drawPng((std::uint8_t*)kuuga,    2136, 30, 50); break;
    case 1:  canvas_0.drawPng((std::uint8_t*)agito,    1897, 30, 50); break;
    case 2:  canvas_0.drawPng((std::uint8_t*)ryuki,    2100, 30, 50); break;
    case 3:  canvas_0.drawPng((std::uint8_t*)faiz,     1884, 30, 50); break;
    case 4:  canvas_0.drawPng((std::uint8_t*)blade,    1357, 30, 50); break;
    case 5:  canvas_0.drawPng((std::uint8_t*)hibiki,   2128, 30, 50); break;
    case 6:  canvas_0.drawPng((std::uint8_t*)kabuto,   2654, 30, 50); break;
    case 7:  canvas_0.drawPng((std::uint8_t*)deno,     3238, 30, 50); break;
    case 8:  canvas_0.drawPng((std::uint8_t*)kiva,     2509, 30, 50); break;
    case 9:  canvas_0.drawPng((std::uint8_t*)decade,   1612, 30, 50); break;
    case 10: canvas_0.drawPng((std::uint8_t*)w,        1535, 30, 50); break;
    case 11: canvas_0.drawPng((std::uint8_t*)ooo,      4088, 30, 50); break;
    case 12: canvas_0.drawPng((std::uint8_t*)fourze,   4203, 30, 50); break;
    case 13: canvas_0.drawPng((std::uint8_t*)wizard,   4437, 30, 50); break;
    case 14: canvas_0.drawPng((std::uint8_t*)gaim,     2921, 30, 50); break;
    case 15: canvas_0.drawPng((std::uint8_t*)drive,    1850, 30, 50); break;
    case 16: canvas_0.drawPng((std::uint8_t*)ghost,    2158, 30, 50); break;
    case 17: canvas_0.drawPng((std::uint8_t*)exaid,    2450, 30, 50); break;
    case 18: canvas_0.drawPng((std::uint8_t*)build,    1963, 30, 50); break;
    case 19: canvas_0.drawPng((std::uint8_t*)zio,      2045, 30, 50); break;
    case 20: canvas_0.drawPng((std::uint8_t*)zeroone,  2182, 30, 50); break;
    case 21: canvas_0.drawPng((std::uint8_t*)saber,    2461, 30, 50); break;
    case 22: canvas_0.drawPng((std::uint8_t*)revice,   2183, 30, 50); break;
    case 23: canvas_0.drawPng((std::uint8_t*)revice,   2183, 30, 50); break;
    case 24: canvas_0.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    /*
    case 25: canvas_0.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    case 26: canvas_0.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    case 27: canvas_0.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    */
    case 28: canvas_0.drawPng((std::uint8_t*)gotchard, 2453, 30, 50); break;
    case 29: canvas_0.drawPng((std::uint8_t*)legend,   3035, 30, 50); break;
    case 30: canvas_0.drawPng((std::uint8_t*)majede,   2743, 30, 50); break;
    // case 31: canvas_0.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    case 32: canvas_0.drawPng((std::uint8_t*)valvarad, 2630, 30, 50); break;
    case 33: canvas_0.drawPng((std::uint8_t*)ichigo,   3302, 30, 50); break;
    /*
    case 34: canvas_0.drawPng((std::uint8_t*)zeroone,  2182, 30, 50); break;
    case 35: canvas_0.drawPng((std::uint8_t*)saber,    2461, 30, 50); break;
    case 36: canvas_0.drawPng((std::uint8_t*)revice,   2183, 30, 50); break;
    */
    case 37: canvas_0.drawPng((std::uint8_t*)gavv,     2121, 30, 50); break;
    /*
    case 38: canvas_0.drawPng((std::uint8_t*)raider,   2467, 30, 50); break;
    case 39: canvas_0.drawPng((std::uint8_t*)raider,   2467, 30, 50); break;
    case 40: canvas_0.drawPng((std::uint8_t*)raider,   2467, 30, 50); break;
    */
    default: ;
    }
  } else if(gochizou_category == CATEGORY_SUPER_SENTAI){
    switch(gochizou_index){
    //case 0:  canvas_0.drawPng((std::uint8_t*)sentai,    5287, 30, 50); break;
    //case 1:  canvas_0.drawPng((std::uint8_t*)sentai,    5287, 30, 50); break;
    case 2:  canvas_0.drawPng((std::uint8_t*)boonboom,    3597, 30, 50); break;
    default: ;
    }
  }
  canvas_0.pushSprite(0,0);

  // 目を閉じる方は準備だけ
  canvas_1.fillCircle(EYE_X-4, EYE_Y+5, 28, C_BLACK);
  canvas_1.fillCircle(EYE_X-4, EYE_Y+5, 26, C_WHITE);
  // 左目
  canvas_1.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 28, C_BLACK);
  canvas_1.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 26, C_WHITE);
 // canvas_1.drawPng((std::uint8_t*)gochizou_blink, 1070, 0, 0);
  if(gochizou_category == CATEGORY_LEGEND_RIDER){
    switch(gochizou_index){
    case 0:  canvas_1.drawPng((std::uint8_t*)kuuga,    2136, 30, 50); break;
    case 1:  canvas_1.drawPng((std::uint8_t*)agito,    1897, 30, 50); break;
    case 2:  canvas_1.drawPng((std::uint8_t*)ryuki,    2100, 30, 50); break;
    case 3:  canvas_1.drawPng((std::uint8_t*)faiz,     1884, 30, 50); break;
    case 4:  canvas_1.drawPng((std::uint8_t*)blade,    1357, 30, 50); break;
    case 5:  canvas_1.drawPng((std::uint8_t*)hibiki,   2128, 30, 50); break;
    case 6:  canvas_1.drawPng((std::uint8_t*)kabuto,   2654, 30, 50); break;
    case 7:  canvas_1.drawPng((std::uint8_t*)deno,     3238, 30, 50); break;
    case 8:  canvas_1.drawPng((std::uint8_t*)kiva,     2509, 30, 50); break;
    case 9:  canvas_1.drawPng((std::uint8_t*)decade,   1612, 30, 50); break;
    case 10: canvas_1.drawPng((std::uint8_t*)w,        1535, 30, 50); break;
    case 11: canvas_1.drawPng((std::uint8_t*)ooo,      4088, 30, 50); break;
    case 12: canvas_1.drawPng((std::uint8_t*)fourze,   4203, 30, 50); break;
    case 13: canvas_1.drawPng((std::uint8_t*)wizard,   4437, 30, 50); break;
    case 14: canvas_1.drawPng((std::uint8_t*)gaim,     2921, 30, 50); break;
    case 15: canvas_1.drawPng((std::uint8_t*)drive,    1850, 30, 50); break;
    case 16: canvas_1.drawPng((std::uint8_t*)ghost,    2158, 30, 50); break;
    case 17: canvas_1.drawPng((std::uint8_t*)exaid,    2450, 30, 50); break;
    case 18: canvas_1.drawPng((std::uint8_t*)build,    1963, 30, 50); break;
    case 19: canvas_1.drawPng((std::uint8_t*)zio,      2045, 30, 50); break;
    case 20: canvas_1.drawPng((std::uint8_t*)zeroone,  2182, 30, 50); break;
    case 21: canvas_1.drawPng((std::uint8_t*)saber,    2461, 30, 50); break;
    case 22: canvas_1.drawPng((std::uint8_t*)revice,   2183, 30, 50); break;
    case 23: canvas_1.drawPng((std::uint8_t*)revice,   2183, 30, 50); break;
    case 24: canvas_1.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    /*
    case 25: canvas_1.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    case 26: canvas_1.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    case 27: canvas_1.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    */
    case 28: canvas_1.drawPng((std::uint8_t*)gotchard, 2453, 30, 50); break;
    case 29: canvas_1.drawPng((std::uint8_t*)legend,   3035, 30, 50); break;
    case 30: canvas_1.drawPng((std::uint8_t*)majede,   2743, 30, 50); break;
    // case 31: canvas_1.drawPng((std::uint8_t*)geats,    2640, 30, 50); break;
    case 32: canvas_1.drawPng((std::uint8_t*)valvarad, 2630, 30, 50); break;
    case 33: canvas_1.drawPng((std::uint8_t*)ichigo,   3302, 30, 50); break;
    /*
    case 34: canvas_1.drawPng((std::uint8_t*)zeroone,  2182, 30, 50); break;
    case 35: canvas_1.drawPng((std::uint8_t*)saber,    2461, 30, 50); break;
    case 36: canvas_1.drawPng((std::uint8_t*)revice,   2183, 30, 50); break;
    */
    case 37: canvas_1.drawPng((std::uint8_t*)gavv,     2121, 30, 50); break;
    /*
    case 38: canvas_1.drawPng((std::uint8_t*)raider,   2467, 30, 50); break;
    case 39: canvas_1.drawPng((std::uint8_t*)raider,   2467, 30, 50); break;
    case 40: canvas_1.drawPng((std::uint8_t*)raider,   2467, 30, 50); break;
    */
    default: ;
    }
  } else if (gochizou_category == CATEGORY_SUPER_SENTAI){
    switch(gochizou_index){
    //case 0:  canvas_1.drawPng((std::uint8_t*)sentai,    5287, 30, 50); break;
    //case 1:  canvas_1.drawPng((std::uint8_t*)sentai,    5287, 30, 50); break;
    case 2:  canvas_1.drawPng((std::uint8_t*)boonboom,    3597, 30, 50); break;
    default: ;
    }
  }
}

void show_gochizou_face_finish(){
  // 天使の輪を描く
  canvas_0.fillSprite(C_WHITE);
  canvas_1.fillSprite(C_WHITE);
  // 右目
  canvas_0.fillCircle(EYE_X-4, EYE_Y+5, 28, C_BLACK);
  canvas_0.fillCircle(EYE_X, EYE_Y, 21, C_SILVER);
  if(gochizou_category == CATEGORY_LEGEND_RIDER){
    // ダブルとビルドのみ、左右で目の色を変える
    switch(gochizou_index){
    case 10: canvas_0.fillCircle(EYE_X, EYE_Y, 15, C_GREEN); break;
    case 18: canvas_0.fillCircle(EYE_X, EYE_Y, 15, C_BLUE);  break;
    default: canvas_0.fillCircle(EYE_X, EYE_Y, 15, selected_gochizou.color);
    }
  }else{
    canvas_0.fillCircle(EYE_X, EYE_Y, 15, selected_gochizou.color);;
  }
  // 左目
  canvas_0.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 28, C_BLACK);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y, 21, C_SILVER);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X, EYE_Y, 15, selected_gochizou.color);
  // 両ハイライト
  canvas_0.fillCircle(EYE_X+7, EYE_Y-7,  5, C_WHITE);
  canvas_0.fillCircle(DISP_WIDTH - EYE_X-7, EYE_Y-7,  5, C_WHITE);
  canvas_0.fillEllipse(DISP_WIDTH/2, 70, 50, 30, C_GOLD);
  canvas_0.fillEllipse(DISP_WIDTH/2, 67, 40, 20, C_WHITE);
  canvas_0.pushSprite(0,0);
  
  // 目を閉じる方は準備だけ
  canvas_1.fillCircle(EYE_X-4, EYE_Y+5, 28, C_BLACK);
  canvas_1.fillCircle(EYE_X-4, EYE_Y+5, 26, C_WHITE);
  // 左目
  canvas_1.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 28, C_BLACK);
  canvas_1.fillCircle(DISP_WIDTH - EYE_X+4, EYE_Y+5, 26, C_WHITE);
  canvas_1.fillEllipse(DISP_WIDTH/2, 70, 50, 30, C_GOLD);
  canvas_1.fillEllipse(DISP_WIDTH/2, 67, 40, 20, C_WHITE);
}

uint8_t blink_state = 0;
unsigned long prev_eye_change_point_ms = 0;

void update_face(unsigned long now_ms){
  // 状態遷移時
  switch(prev_state){
  case STATE_INIT:
    if(state == STATE_GOCHIZOU){
      show_gochizou_face_init();
    }
    break;
  case STATE_GOCHIZOU:
    if(state == STATE_INIT){
      update_disp_gochizou_name();
      update_disp_gochizou_category();
    }else if(state == STATE_CHANGE){
      show_gochizou_face_change();
    }
    break;
  case STATE_CHANGE:
    if(state == STATE_INIT){
      update_disp_gochizou_name();
      update_disp_gochizou_category();
    }else if(state == STATE_FINISH){
      show_gochizou_face_change();
    }
    break;
  case STATE_FINISH:
    if(state == STATE_INIT){
      update_disp_gochizou_name();
      update_disp_gochizou_category();
    }else if(state == STATE_CHANGE){
      show_gochizou_face_finish();
    }
    break;
  default:
    ;
  }

  // 時間経過時
  if(state == STATE_GOCHIZOU || state == STATE_CHANGE){
    // まばたき動作
    switch(blink_state){
    case 0:
      if(now_ms - prev_eye_change_point_ms >= 3000){
        canvas_1.pushSprite(0,0); // 目を閉じる
        blink_state++;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    case 1:
      if(now_ms - prev_eye_change_point_ms >= 100){
        canvas_0.pushSprite(0,0); // 目を開く
        blink_state++;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    case 2:
      if(now_ms - prev_eye_change_point_ms >= 5000){
        canvas_1.pushSprite(0,0); // 目を閉じる
        blink_state++;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    case 3:
      if(now_ms - prev_eye_change_point_ms >= 100){
        canvas_0.pushSprite(0,0); // 目を開く
        blink_state++;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    case 4:
      if(now_ms - prev_eye_change_point_ms >= 7000){
        canvas_1.pushSprite(0,0); // 目を閉じる
        blink_state++;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    case 5:
      if(now_ms - prev_eye_change_point_ms >= 100){
        canvas_0.pushSprite(0,0); // 目を開く
        blink_state++;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    case 6:
      if(now_ms - prev_eye_change_point_ms >= 100){
        canvas_1.pushSprite(0,0); // 目を閉じる
        blink_state++;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    case 7:
      if(now_ms - prev_eye_change_point_ms >= 100){
        canvas_0.pushSprite(0,0); // 目を開く
        blink_state = 0;
        prev_eye_change_point_ms = now_ms;
      }
      break;
    default:
      ;
    }
  }
}

void setup(void)
{
  auto cfg = M5.config();
  StickCP2.begin(cfg);

  Wire.end();
  Wire.begin(0, 26); //G0. G26 I2C port

  Serial.begin(115200);

  // 省電力化のため、CPU周波数を少し落とす場合に有効化。最大240MHz。
  setCpuFrequencyMhz(160);

  pinMode(PIN_SW, INPUT_PULLUP);  // 入力として使用する
  gpio_pulldown_dis(GPIO_NUM_36); // 使用しないのでフローティング入力設定
  gpio_pullup_dis(GPIO_NUM_36);   // 使用しないのでフローティング入力設定

  StickCP2.Display.setBrightness(5);
  StickCP2.Display.setRotation(2);  // 画面向き
  StickCP2.Display.setTextSize(2);  // フォントサイズ
  StickCP2.Display.setTextFont(&fonts::lgfxJapanGothic_8);  // フォント
  update_disp_gochizou_name();
  update_disp_gochizou_category();

  // ゴチゾウの表情用スプライトの準備
  canvas_0.createSprite(DISP_WIDTH, DISP_HEIGHT);
  canvas_1.createSprite(DISP_WIDTH, DISP_HEIGHT);
}

void loop(void)
{
  StickCP2.update();
  sw = digitalRead(PIN_SW);

  unsigned long now_ms = millis();

  if(prev_sw == OFF && sw == ON){
    switch(state){
    case STATE_INIT:
      StickCP2.Speaker.tone(5000, 50);
      change_gochizou_category();
      select_gochizou();
      update_disp_gochizou_category();
      update_disp_gochizou_name();
      break;
    case STATE_GOCHIZOU:
      change_state(STATE_CHANGE);
      break;
    case STATE_CHANGE:
      change_state(STATE_FINISH);
      state_change_point_ms = now_ms;
      break;
    case STATE_FINISH:
      break;
    default:
      ;
    }
  }

  if(StickCP2.BtnA.wasClicked()){
    StickCP2.Speaker.tone(5000, 50);
    switch(state){
    case STATE_INIT:
      gochizou_index++;
      select_gochizou();
      update_disp_gochizou_name();
      break;
    case STATE_GOCHIZOU:
      break;
    case STATE_CHANGE:
    case STATE_FINISH:
    default:
      ;
    }
  }

  if(StickCP2.BtnB.wasClicked()){
    switch(state){
    case STATE_INIT:
      StickCP2.Speaker.tone(5000, 50);
      change_gochizou_category();
      select_gochizou();
      update_disp_gochizou_category();
      update_disp_gochizou_name();
      break;
    case STATE_GOCHIZOU:
      change_state(STATE_CHANGE);
      break;
    case STATE_CHANGE:
      change_state(STATE_FINISH);
      state_change_point_ms = now_ms;
      break;
    case STATE_FINISH:
      break;
    default:
      ;
    }
  }


  if(StickCP2.BtnA.wasHold()){
    switch(state){
    case STATE_INIT:
      // 抵抗値をセットする
      int result_a, result_b;

      #ifndef debug
        result_a = potentio.writeWiperRAM(0, selected_gochizou.r_A);
        printLogAboutWrite(&Serial, 0, selected_gochizou.r_A, result_a);
        result_b = potentio.writeWiperRAM(1, selected_gochizou.r_B);
        printLogAboutWrite(&Serial, 1, selected_gochizou.r_B, result_b);
      #else
        result_a = 0;
        result_b = 0;
      #endif

      if(result_a == 0 && result_b == 0){
        StickCP2.Speaker.tone(4000, 50);
        delay(50);
        StickCP2.Speaker.tone(6000, 50);
        change_state(STATE_GOCHIZOU);
      }
      break;
    case STATE_GOCHIZOU:
    case STATE_CHANGE:
    case STATE_FINISH:
      change_state(STATE_INIT);
      break;
    default:
      ;
    }
  }

  // 時間経過処理
  if(state == STATE_FINISH && now_ms - state_change_point_ms >= STATE_FINISH_TO_CHANGE_TIME_MS){
    change_state(STATE_CHANGE);
  }

  update_face(now_ms);

  prev_sw = sw;
  prev_state = state;

  delay(10);
}

完成したスケッチをArduino IDEでコンパイルと検証を行って見たいと思います。その前に準備として、MCP4661_asukiaaaをArduino IDEにインストールしました(関連ライブラリとして、wire_asukiaaa 1.1.13もインストールされました)

コンパイルしたところ、エラーが発生しました

IIn file included from c:\Users\********\Documents\Arduino\libraries\wire_asukiaaa\src/wire_asukiaaa.h:3,
                 from c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:3,
                 from C:\Tools\M5StickCPlus2\gochizou\gochizou.ino:3:
c:\Users\********\Documents\Arduino\libraries\wire_asukiaaa\src/wire_asukiaaa.hpp:8:35: error: 'TwoWire' was not declared in this scope
 typedef PeripheralHandlerTemplate<TwoWire> PeripheralHandler;
                                   ^~~~~~~
c:\Users\********\Documents\Arduino\libraries\wire_asukiaaa\src/wire_asukiaaa.hpp:8:35: note: suggested alternative: 'TwoWire_h'
 typedef PeripheralHandlerTemplate<TwoWire> PeripheralHandler;
                                   ^~~~~~~
                                   TwoWire_h
c:\Users\********\Documents\Arduino\libraries\wire_asukiaaa\src/wire_asukiaaa.hpp:8:42: error: template argument 1 is invalid
 typedef PeripheralHandlerTemplate<TwoWire> PeripheralHandler;
                                          ^
In file included from C:\Tools\M5StickCPlus2\gochizou\gochizou.ino:3:
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:131:3: error: 'TwoWire' does not name a type; did you mean 'TwoWire_h'?
   TwoWire* wire;
   ^~~~~~~
   TwoWire_h
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:133:15: error: expected ')' before '*' token
   Core(TwoWire* wire, uint8_t address) : wire(wire), address(address) {}
       ~       ^
               )
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp: In member function 'int MCP4661_asukiaaa::Core::writeToRegister(uint8_t, uint16_t, uint8_t)':
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:189:5: error: 'wire' was not declared in this scope
     wire->beginTransmission(address);
     ^~~~
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:189:5: note: suggested alternative: 'Core'
     wire->beginTransmission(address);
     ^~~~
     Core
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp: In member function 'int MCP4661_asukiaaa::Core::readFromRegister(uint8_t, uint16_t*, uint8_t)':
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:199:9: error: 'wire' was not declared in this scope
         wire, address, buildFirstByte(registerAddress, command, 0), bytes, 2);
         ^~~~
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:199:9: note: suggested alternative: 'Core'
         wire, address, buildFirstByte(registerAddress, command, 0), bytes, 2);
         ^~~~
         Core
C:\Tools\M5StickCPlus2\gochizou\gochizou.ino: At global scope:
C:\Tools\M5StickCPlus2\gochizou\gochizou.ino:38:84: error: no matching function for call to 'MCP4661_asukiaaa::Core::Core(TwoWire*, const uint8_t&)'
 MCP4661_asukiaaa::Core potentio(&Wire, MCP4661_asukiaaa::DeviceAddress::A0H_A1H_A2H);
                                                                                    ^
In file included from C:\Tools\M5StickCPlus2\gochizou\gochizou.ino:3:
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:129:7: note: candidate: 'constexpr MCP4661_asukiaaa::Core::Core(const MCP4661_asukiaaa::Core&)'
 class Core {
       ^~~~
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:129:7: note:   candidate expects 1 argument, 2 provided
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:129:7: note: candidate: 'constexpr MCP4661_asukiaaa::Core::Core(MCP4661_asukiaaa::Core&&)'
c:\Users\********\Documents\Arduino\libraries\MCP4661_asukiaaa\src/MCP4661_asukiaaa.hpp:129:7: note:   candidate expects 1 argument, 2 provided

exit status 1

Compilation error: no matching function for call to 'MCP4661_asukiaaa::Core::Core(TwoWire*, const uint8_t&)'
エラーメッセージから検索しましたが、さっぱり判りません。そもそもToWireってM5STAMPの標準関数では無いの?!っという疑問しかわきませんでした。記述内容をチェックしても原因が判りません

問題の切り分けのためにMCP4661_asukiaaa.hppにM5StickCPlus2.hのインクルード文を追加したところ同じエラーが発生、さらにwire_asukiaaa.hppにも追加してもエラーが発生しました。
この現象から、ToWireが定義されているwire.hが参照されていないのではなりました。

慣れている人であれば対策を知っているかと思いますが、初めて使用した私からするとこれまたサッパリです。なので、全てのヘッダファイルをローカルにコピーして、インクルード文をローカル参照にすることでコンパイルが正常に終了しました。簡単に書いていますが、一晩悩みましたよ

2024年12月10日火曜日

おそとでノーマット (ジャンク)

久々の仮面ライダー系おもちゃになります。今回は、「仮面ライダーキバ おそとでノーマットV」のジャンク品になります。メル〇リで400円となっていました

動かない、光らないといった内容で、原因は液漏れというのが写真から判断できました(上記写真は修理後)

早速、電池ボックスを開けてみると見事な液漏れです

分解してみると配線がスイッチ基板に接続され、モーターとLEDに接続されています。液漏れの影響はスイッチ基板には達していないため、端子の研磨と配線交換で済みそうです

配線の確認では、写真上部の外れている配線だけが使えませんでした。手持ちの配線と交換します。電池端子は研磨してみたところ、大丈夫そうでした。念のため、削ったところに半田を載せています

これだけで問題なく動作いました。ノーマットVは販売終了品なので直しても目が光る玩具でしかないのですが、我が家のちびちゃんは喜んで遊んでいたので結果オーライです

2024年1月10日水曜日

変身ベルトを拒否しないで

今回は単品では音が鳴るが、変身ベルト(ドライバー)に接続すると音が無くなるケースの修理について記載します

最初はジャンクで購入したDX ライドウォッチ(クーガーとW エクストリーム)になります


竜頭ボタンによる音声はなるため、原因はドライバ接続時に押される2つのスイッチ。早速、分解して該当箇所を確認します(写真はクーガー)



SW2とSW3を手で確認、接触が悪い様です。お約束の接点復活材を噴霧、スイッチを押しまくったところ反応が良くなりました。ドライバーに接続してのテストでも反応するようになりました。

なお、ライドウォッチは食玩やガチャガチャなどでも販売されていましたので、スイッチがダメになっている時はこれらからの移植する方法があります

ライドウォッチだけではなく、ガイアメモリも同様の手段で治る場合があります。こちらは、メルカリで購入したDX ジャーカーメモリになります

ジャンク理由は、LEDは光るが音がしないといった内容になります。スピーカーが壊れたと予想して分解しましたが、配線が切れていることが原因でした。これは、半田付けですぐになおりました

修理後、単体でのチェックはボタンを押すことで音が流れました。しかし、ドライバーに刺すと待機音が鳴らないと言った症状が発生しました。こちらもスイッチの問題である可能性がありますので、分解して確認します


DX ガイアメモリは、裏側のリセットスイッチ、LED の上のスイッチ、白い突起が付いたスイッチの3つがあります。ドライバー接続時に影響するのは白い突起が付いたスイッチで、ドライバー接続時に右か左にこれを倒してスイッチをオンにします(接続位置で切替え)。そのため、ドライバーに刺して音がしない場合、このスイッチが影響します。こちらもジクウドライバーと同じく接点復活材を散布して、軽く左右に動かすことで動作するようになりました

スイッチが壊れていなければ、修理としては簡単な部類ですね。















2024年1月9日火曜日

新しいターゲットは、ディエンドドライバーだ

今回はタイトルにある通り、ディエンドドライバー 初代(ジャンク)の修理に挑戦します。残念ながらこのモデルはカードの個別認識が出来ないので、カードの有無で音が変わります。ま、カード管理の出来ないちびちゃんにはちょうど良いかな?!

写真を見た瞬間から液漏れを疑っていましたが、予想通り液漏れしていましたw

この感じからすると、電池ボックスの修理は必須と予想して早速便介しました

液漏れによって配線は切れており、少し液漏れ跡を落としたくらいでも操作する気がしませんので、いつもの様に金具を外してリューターで削りまくりました。過電流防止用ポリヒューズ(恐らく)も断線していましたので、「DXウィザードドライバ修理、こりゃ無理だ」のウィザードドライバから部品を拝借しました

次にメイン基板ですが、電池ボックスが離れていたので直接ダメージは見られませんでしたが、経年劣化で配線が弱くなっていました。ま、既に電源のマイナス側は切れていましたが...

配線は全て張り替えましたが、手持ち配線が少し太くなってしまいケースに隙間が出来てしまいました(半田の乗りが相変わらず悪い)。気が向いたら細い配線で結線し直したいところですが、恐らくしないと思います


この状態でテストしたところ、LED は光りますが音がしない。これはよくあるスピーカー故障だったのでウィザードドライバからまた拝借して直しました

あとはカード有無の認識ですが、まったく反応しない。カードがあるとスイッチがオンになる仕組みですが、スイッチの通が無い様です。とりあえず、接点復活材を散布してみましたが、反応はイマイチでした。「「宇宙キターッ!」がしたい パート2」の時のスイッチと同じ症状になりますので、スイッチを分解したところ接触面が真っ黒になっていました

こちらもリューターで削って綺麗にして組み込みました(写真下部の金属板)

我が家には仮面ライダー ディケード系の玩具が無かったので、ガンバレジェンズのカードでテストして動作を確認しました。たまたに認識できない場合があるので、上記スイッチの調整が必要ですが、とりあえず終了としました(銀色のスプレー缶があったので、銀色のみ再塗装しています)

早速、ちびちぇんに渡したところ、ご機嫌で遊んでいました

2023年12月25日月曜日

ちょっとひとっ走り付き合うのは大変!

ジャンクのライダーベルトセット」で紹介したDXドライブドライバー&シフトブレスの修理を試みます

最初にドライバー側から分解します。蓋を開けた瞬間、電源が入らない原因が判りました

液漏れが発生して分解して修理しようとしたみたいですが、電源の金具が折れて配線が出来なくなっていました。配線もないので分解されていたのは確実です
とりあえず、電池ケースを加工して配線しました。ちょっと無理やり感がありますね(汗)

また、前オーナーの分解時に配線を挟んだようで、スピーカーケーブルが潰れています。これも交換するしかありません

とりあえず、仮組してテストを行ったところ、音声はなりましたが、モーターも回らずLEDも点灯しません。ロータリートランスを使用して回転部に給電を行っていますので、回転部の2次側電源値を確認しましたが給電されていません。1次側に関しても、電源が出力されていませんでした

音はなっているためメイン基板には給電自体はされているとは思います。老眼の目で確認するとトランジスタらしき部品(TR1, TR2)があります。勝手な予想ですが、このトランジスタによって給電を制御しているのではと考えています。

スマホでトランジスタを確認するとYJと記載されています。s-manuals.com から恐らく抵抗内蔵型トランジスタ (N2109FT)じゃないかなぁとは思います。これどこで買えるの?!っと頓挫しました

あとから気が付きましたが、TR2の表面に破損が見えますので、恐らくごれが原因では無いかと疑っています

仕方が無いので、2個1作戦で動作しないドライバをメル〇リで購入しました。動作確認したところ、こちらも音声のみでモーター回らず、LEDも点灯しません

早速、分解したところ軽い液漏れ跡がありました。清掃しながら分解し、基板を取り出して、この状態で再度テストを行ったところ、動作してしまいました

流石に動作してしまったものから部品を取るのは気が乗らないため、再度組み立てて元の物は修理を断念しました。う~ん、なんだかなぁ~

気を取り直して、シフトブレスの修理を行います。こちらは裏蓋が無いため、裏蓋を自作しました

見た目はあまり綺麗ではありませんが、隠れるところなのでこれで良しとしました

ドライバと組み合わせて動作確認すると、シフトカーを正しく認識できていない症状がでました。手持ちのシフトカー複数でテストしましたが、正しく認識できる車体が一つもありません

そこでスイッチ部分に対して接点復活材を噴霧することにしましたが、ケースのままだと余計な油をふき取れないので分解します

液漏れ跡もなくきれいです。バネもあるので、分解時は飛ばない様に気を付けるひつようがあります

スイッチを見ると違和感があります。そう、1つスイッチが折れてなくなっています

これに関しても交換が必要になります。使えそうなスイッチがあるベルトと言えば、ビルドドライバー、ジクウドライバー、ジオウのディケードライドウォッチあたりかと思います。とりあえず、ジャンクのジクウドライバーがあるので分解して確認します

ちなみにジクウドライバーのジャンク理由は、動作しますがケースが割れており、なにより汚いんです。どこで遊んだんだろうという位に中は真っ白になっています(汚いので、写真は載せません)

スイッチは左側から外すことにしました。使用することは無いと思いますが、右側があればジオウとゲイツにはなれます

写真は裏返しになっていますが、同じスイッチが付いていました。しかし、このスイッチはそれぞれが抱き付いているような構造になっていますので、1つだけ外すのは難しく3個単位で外したほうが簡単に取れます(それでも大変でしたが...)

とりあえず、外して移植しました

指で押してみましたが感触的には問題なさそうです。あとは、組み立ててテストします

写真では取れきれませんでしたが、シフトカーをちゃんと認識し、遊べるようになりました。最近、色々な変身ベルトを弄っていますが、ドライブドライバーが一番面倒くさいと思います

2023年12月5日火曜日

ウィザードリングホルダー、5個は少ないなぁ

最近、仮面ライダーネタばかりですが、今回も続きます(汗

今回は、ワット〇ンで見つけたDXウィザードリングホルダーを改造します。

我が家には、DXウィザードリングが6個ありますが、DXウィザードリングホルダーには5個しか装着出来ないんですよね。それに記憶が定かではありませんが、仮面ライダーウィザードのホルダーには8個くらいついていた記憶があります(ググれば良いのですが面倒なので...)

検索すると上側2個を切って延長した方はいらっしゃい生ましたが、なんかもったいない気がしたので可能な限り使用して延長してみました。出来上がりは下記になります

9個装着が可能となりました。少し曲がっていますが、ご愛嬌と言うことで!

作り方ですが銀色のパーツを外して、そこからカッターなどで分割しています。バランスを見ながらカッターで削りまくりますが、必ず銀色の部分内にはまる程度は残しています。

注意:カッターで削りまくりますので怪我しないようにしてください

そのままだと、スポッと抜けてしまうので、ゼムクリップを針金にし、刺してストッパーにしています。少し太めのゼムクリップを使用する方が良いと思います


これを繰り返して、それぞれを連結していき完成となります。軽く引っ張ってみましたが、簡単には抜けません。作成時間は、およそ2時間程度かかったと思いますが良い感じになりました。

2023年12月4日月曜日

オーズスキャナー治ってなかった

 「液漏れオーズスキャナー、「タトバ」出来るか?!」にて、動作するようになったオーズスキャナーですが、赤LED が点灯していませんでした。いろいろと調べてみると、やはり点灯しないのはおかしい様です。

3つとも点灯しないため、どこか配線なり接続が綺麗ているかと疑い確認しましたが、問題はない様です。配線はアノードコモンとなっており、バンダイの謎チップに接続されていますので、樹脂が邪魔で確認できません。

仕方が無いので、LED の足に3V を直接接続して動作を確認したところ点灯しません(スキャナーの電池は外しています)。基板上のLED1~3の全てが同じ状態です。試しに壊れている方の基板で同じことをすると点灯します。そのため、LED が壊れていると考えられます(写真撮り忘れたので、壊れている方の基板の写真になります)。

手持ちのLEDはサイズが少し大きいですが、ピンピッチ的に同じようだったので気にせず使用しています

LEDは大きくなっていますが、ケースに干渉していません。ただし、チップ抵抗(R18)の上に若干LED2が乗てしまっています。ま、気にしていませんが...

この後、組み立てを行いましたが、配線が弱っているせいで色々と切れまくりましたので再配線地獄が待っていました。あと、写真で拡大すると液漏れ跡がちらほら見てますが、バラスと再度配線切れが発生すると思うのでこのまま放置します(見なかったことに)

早速テストしてみたところ、電源を入れたらすぐに点灯しました。LED 3個が全滅しているとは予想外でした