M5Stack CORE2で15パズルを作ってみた
M5Stack CORE2のタッチパネルを使って15パズルを作ってみましたArduinoIDEでライブラリはなしのデバイス直接制御です
M5Stack BASIC + UiFlowで15パズルの作成はコチラ
電源管理(PMU) AXP192
M5Stack CORE2の電源関係はAXP192で制御されていますTFT液晶とバックライトの電源もAXP192で制御されています
AXP192はI2Cで接続されています
I2Cアドレス | 0x34 |
SCL | 21 |
SDA | 22 |
関係しているレジスタは▼ (ディフォルト値は間違ってるかも)
グループ 1、電力制御クラス | |||
---|---|---|---|
アドレス | レジスタの説明 | R/W | デフォルト値 |
00 | 電源ステータス レジスタ | R | |
01 | 電力モード/充電ステータス レジスタ | R | |
04 | OTG VBUS ステータス レジスタ | R | |
06-0B | データバッファレジスタ 0-5 | R/W | F0/0F/00/FF/00/00 |
10 | EXTEN & DC-DC2 スイッチ制御レジスタ | R/W | X5H |
12 | DC-DC1/3 & LDO2/3 スイッチ制御レジスタ | R/W | XFH |
23 | DC-DC2 電圧設定レジスタ | R/W | 16H |
25 | DC-DC2 電圧スロープパラメータ設定レジスタ | R/W | 00H |
26 | DC-DC1 電圧設定レジスタ | R/W | 68H |
27 | DC-DC3 電圧設定レジスタ ※バックライトの電圧 | R/W | 48H |
28 | LDO2/3 電圧設定レジスタ | R/W | CFH |
30 | VBUS-IPSOUT チャネル設定レジスタ | R/W | 60H |
31 | VOFF シャットダウン電圧設定レジスタ | R/W | X3H |
32 | シャットダウン、バッテリ検出、CHGLED 制御レジスタ | R/W | 46H |
33 | 充電制御レジスタ 1 | R/W | C8H |
34 | 充電制御レジスタ 2 | R/W | 41H |
35 | バックアップ電池充電制御レジスタ | R/W | 22H |
36 | PEK パラメータ設定レジスタ | R/W | 5DH |
37 | DCDCコンバータ動作周波数設定レジスタ | R/W | 08H |
38 | バッテリ充電温度低下アラーム設定レジスタ | R/W | A5H |
39 | バッテリ充電高温アラーム設定レジスタ | R/W | 1FH |
3A | APS ローパワー Level1 設定レジスタ | R/W | 68H |
3B | APS ローパワーレベル 2 設定レジスタ | R/W | 5FH |
3C | 電池放電低温警報設定レジスタ | R/W | FCH |
3D | バッテリ放電高温アラーム設定レジスタ | R/W | 16H |
80 | DCDC 動作モード設定レジスタ | R/W | E0H |
82 | ADC イネーブル設定レジスタ 1 | R/W | 83H |
83 | ADC イネーブル設定レジスタ 2 | R/W | 80H |
84 | ADC サンプリングレート設定、TS 端子制御レジスタ | R/W | 32H |
85 | GPIO [3:0] 入力レンジ設定レジスタ | R/W | X0H |
86 | GPIO1 ADC IRQ 立ち上がりエッジしきい値設定 | R/W | FFH |
87 | GPIO1 ADC IRQ 立ち下がりエッジしきい値設定 | R/W | 00H |
8A | タイマー制御レジスタ | R/W | 00H |
8B | VBUS 監視設定レジスタ | R/W | 00H |
8F | 過熱シャットダウン制御レジスタ | R/W | 01H |
レジスタ詳細
REG 12H: 電源出力制御 | |||
---|---|---|---|
ビット | 説明 | R/W | デフォルト |
7 | 予約済みで変更不可 | R/W | X |
6 | EXTEN スイッチ制御 0: 閉; 1: 開 ※外部出力電源(5V) |
R/W | X |
5 | 予約済みで変更不可 | R/W | X |
4 | DC-DC2 スイッチ制御 0: 閉; 1: 開 | R/W | X ※モーター |
3 | LDO3 スイッチ制御 0: 閉; 1: 開 ※LCDのバックライト |
R/W | X |
2 | LDO2 スイッチ制御 0: 閉; 1: 開 ※LCD |
R/W | X ※TFT液晶 |
1 | DC-DC3 スイッチ制御 0: 閉; 1: 開 | R/W | X ※バックライト |
0 | DC-DC1 スイッチ制御 0: 閉; 1: 開 | R/W | X |
注: REG12Hbit6/4 はそれぞれ REG10Hbit2/0 に対応します。 |
REG 27H: DC-DC3 出力電圧設定 | デフォルト: 48H | ||
---|---|---|---|
ビット | 説明 | R/W | デフォルト |
7 | 予約済みで変更不可 | ||
6 | DC-DC3 出力電圧設定 Bit6 0.7-3.5V, 25mV/step | R/W | 1 |
5 | DC-DC3 出力電圧設定 Bit5 | R/W | 0 |
4 | DC-DC3 出力電圧設定 Bit4 | R/W | 0 |
3 | DC-DC3 出力電圧設定 Bit4 | R/W | 1 |
2 | DC-DC3 出力電圧設定 Bit2 | R/W | 0 |
1 | DC-DC3 出力電圧設定 Bit1 | R/W | 0 |
0 | DC-DC3 出力電圧設定 Bit0 | R/W | 0 |
スペックシートの必要そうなトコだけ翻訳したPDF
TFT液晶 ILI9342C
TFT液晶 ILI9342CはSPIで接続しています接続しているGPIOピンは▼ RST/BL/PowerはAXP192に接続しています
MOSI | GPIO38 |
MISO | GPIO23 |
SCK | GPIO18 |
CS | GPIO5 |
DC | GPIO15 |
RST | AXP_IO4 |
BackLight | AXP_DC3 |
POWER | AXP_LDO2 |
基本的なコマンドは▼
動作 | COMAND | PARAMETA |
---|---|---|
Software Reset ソフトウエア・リセット |
0x01 | パラメタ - なし |
Memory Access Control メモリと画面の対応(表示方向の設定) |
0x36 | パラメタ - 1Byte 横(0xE8) or 縦(0x48) |
COLMOD: Pixel Format Set メモリと表示色の対応(色指定方法の設定) |
0x3A | パラメタ - 1Byte 16bit色(0x55) or 18bit色(0x66) |
Sleep Out スリープモードからの復帰 |
0x11 | パラメタ - なし 【重要】コマンド送信後、電源が安定するまで(5m秒以上)待つ必要がある。 |
Enter Sleep Mode スリープモードに設定 |
0x10 | |
Display ON 表示ON |
0x29 | パラメタ - なし |
Display OFF 表示OFF |
0x28 | |
Display Inversion OFF 表示色反転 OFF |
0x20 | パラメタ - なし |
Display Inversion ON 表示色反転 ON |
0x21 | パラメタ - なし |
Normal Display Mode On 全画面表示 |
0x13 | パラメタ - なし |
Partial Mode ON 部分表示 |
0x12 | パラメタ - なし 範囲はPartial Area command(0x30)で指定 |
Partial Area 部分表示範囲指定 |
0x30 | パラメタ - 2Bayte + 2Bayte |
Column Address Set ドットデータ書き込みカラム位置 |
0x2A | パラメタ - 2Bayte + 2Bayte |
Page Address Set ドットデータ書き込みページ位置 |
0x2B | パラメタ - 2Bayte + 2Bayte |
Memory Write ドットデータ書き込み |
0x2C | パラメタ - N Bayte |
Memory Read ドットデータ読み出し |
0x2E | パラメタ - N Bayte |
Vertical Scrolling Start Address スクロール開始アドレス |
0x37 | パラメタ - 2Bayte |
コマンドは1バイトでパラメタはデータ扱いになります
DCをLOWにしてコマンドを送信、DCをHIGHにしてパラメタを送信の手順で使用します
描画方向は、Memory Access Control(0x36)コマンドのパラメタで設定します
パラメタ設定は▼の通り
D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | |
---|---|---|---|---|---|---|---|---|
コマンド | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 |
パラメタ | MY (Y軸方向) |
MX (X軸方向) |
MV (XY軸入れ替え) |
ML (Y軸更新方向) |
RGB (色割り当て RGB or BGR) |
MH (X軸更新方向) |
- | - |
1Dot(ピクセル)の色を指定する方法(フォーマット)の指定は COLMOD: Pixel Format Setで行います。
M5Stack(CORE2・BASIC共)では表示色を反転モード(INVERT ON)にしないとRGB指定の色が出ないみたいです
Greenが正しい色で表示されないのでBGR表示になっているとかではなく反転しているようです
Memory Writeで書き込む値は 16Bitモードと18Bitモードで▼のようになります
描画は描画範囲を指定し、指定範囲を埋めるBitmapデータを送信する
描画範囲 COLの指定 | 0X2A | SC,EC |
---|---|---|
描画範囲 ROWの指定 | 0x2B | SP,EP |
描画データ送信 | 0x2C | Bitmapデータ |
タッチパネル FT6336U
タッチパネルはFT6336Uで制御されています。FT6336UはI2Cで接続されています
I2Cアドレス | 0x38 |
SCL | 21 |
SDA | 22 |
FT6336Uのレジスタ(PDF)
▲からの抜粋 取りあえず必要な所だけ
レジスタ | R/W | Register symbol | Register name | Register description |
---|---|---|---|---|
00h | RW | Mode_Switch | モードスイッチ | 0x40を書き込むと出荷設定モードに切り替わる 出荷設定モードにはキャリブレーションとかあるのでウッカリ触らない方が無難 |
02h | RO | TD_STATUS | 読み取りポイント数 | 読み取ったポイントの数 0~2 |
03h | RO | P1_XH | タッチイベントフラグ | Bit7~bit6 は 1 点目のタッチイベントフラグ、bit3~bit0 は 1 点目の X 座標の上位 4 ビットです。 |
X1ポイントの座標 上位4ビット | ||||
04h | RO | P1_XL | X1ポイントの座標 下位バイト | |
05h | RO | P1_YH | ポイントID | Bit7~bit4 は最初のポイントの ID、bit3~bit0 は最初のポイントの Y 座標の上位 4 ビットです。 |
Y1ポイントの座標 上位4ビット | ||||
06h | RO | P1_YL | Y1ポイントの座標 下位バイト | |
09h | RO | P2_XH | タッチイベントフラグ | Bit7~bit6 は 2 点目のタッチイベントフラグ、bit3~bit0 は 12点目の X 座標の上位 4 ビットです。 |
X2ポイントの座標 上位4ビット | ||||
0AH | RO | P2_XL | X2ポイントの座標 下位バイト | |
0Bh | RO | P2_YH | ポイントID | Bit7~bit4 は 2 点目の ID、bit3~bit0 は 2 点目の Y 座標の上位 4 ビットです。 |
Y2ポイントの座標 上位4ビット | ||||
0Ch | RO | P2_YL | Y2ポイントの座標 下位バイト |
入力操作の特性
�← な感じで、縦方向にズレた2点は同時入力可能 ボタンはタッチスクリーンに入力で代用されているので 画面とボタンの同時押しは実現できる |
|
← な感じで、縦軸が近い場合には2点の中間点辺りを タッチしていると判定される スマホのようなワイプ操作は出来ない |
タッチしているのが1点の場合、座標はP1に入る。 2点をタッチしている場合、P1,P2に座標が入る。 タッチした順番にポイントID(0~1)が設定される |
|
2点をタッチしてP1,P2に座標が設定されている状態でP1を離すと、P2に入っていた座標がP1に入るようになる この時、ポイントIDは変わらないので、P1に設定されている座標が、元はP2に入っていた座標である事が分かる プログラム的には point[ポイントID].x , point[ポイントID].y で参照すれば P1,P2の状態の変化に影響されない |
タッチスクリーンの座標
タッチスクリーンの座標は (0,0)~(319,279)になっています ※スペックシートに明記されていないので、多分です (0,0)~(319,239)の範囲はTFT液晶の座標と一致しています Y軸が240以上の場合にボタンと判定しすれば良いようです |
15パズル
イメージデータパズルに使用するイメージデータは320x240ドットのJPEGファイルをSDカードから読み込んで使用する
M5CORE2クラスを使えば M5.Lcd.drawJpgFile(SD,"/image1.jpg"); の1行でJPEG画像を表示できます
ここで、イメージの展開先をLCDではなくメモリーバッファに変更できれば、パズルのチップサイズに画像を分割/加工して使用する事ができます。
ArduinoIDEのESP32系マイコンのボードライブラリにはJPEGイメージをBITMAPに展開するオープンスースのライブラリが入っています
ライブラリ名:TJpgDec - Tiny JPEG Decompressorこのライブラリの使用方法は Arduino core ESP32 内のライブラリでJPEGファイルをビットマップに変換(デコード)する を参考にしました。
作者:ChaN氏
ライセンス:BSD
ソース:http://elm-chan.org/fsw/tjpgd/00index.html
※M5Stack CORE2で使用する場合、電源管理の都合(M5Stack BASICとは電源関係の回路が違うの)でM5.begin()をSDカード使用前に行わないと、うまく動きません
Cボタンでイメージ切り替え
SDカードに保存されている image1.jpg ~ image10.jpg を順番に読み込み
読み込めなかった場合(ファイルがないなど) 数字だけの白い画像を表示しimage1.jpgに戻ります。
Aボタンでゲームスタート
15パズルのチップはチップ用のイメージ画像をオーバーラップして作成します
← この画像に この画像 → を合成 |
||
LCD Image Converter で 1Dot/1Byte(256色) のBITMAPデータに変換 白(0x00)と黒(0xFF)だけを元のイメージに上書して 他の色は無視(透過色として扱う) |
イメージ・チップのシャッフル
数字の付いている1~15のチップからランダムに2枚を選んで入れ替えます。
入れ替え回数は必ず偶数回2,4,6,8,10・・・になるようにします。
奇数回の入れ替えでは絶対解けない配置になる事が証明されています
チップの移動
移動できるのはブランクチップ(番号のない真っ黒なチップ::プログラム的には[15]のチップ)とX軸またはY軸のどちらか一方が一致しているチップです。
縦・横にまとめて動かせた方が楽なのでそうしています。
ブランクチップの隣のチップとした方が簡単かもしれません。
ブランクチップからタッチしたチップまでを順に入れ替え
入れ替えたチップを再描画します。
これで、最小範囲の再描画でチップを移動する事ができます。
チップを入れ替えた後に、チップの順番を確認、0~15の順に並んでいたら完成なのでクリア画像をオーバーラップ表示
スケッチ
ILI9342-DEMO.zip 動画 ~前編~ で使用しているILI9432Cの直接制御スケッチFT6336U-DEMO.zip 動画 ~後編~ で使用しているFT6336Uの直接制御スケッチ
15puzzle_CORE2.zip 動画 ~応用編~ で使用している15パズルのスケッチ
動画で使用している ささら&つづみ は著作権の問題で配付できません。
320x240ドットのJPEG画像にimage1.jpg 、image2.jpg ・・・ image10.jpg のファイル名を付けてSDカードに保存してください。