M5.Lcd.*の関数をシリアルモニタで操作する

##1. はじめに
M5.Lcd.*の関数をシリアルモニタで操作できるようにしました。画面設計のお供に。
![m5lcd.png](https://qiita-image-store.s3.amazonaws.com/0/221758/d2017f8c-23bb-27b1-a30b-e43d44875a22.png)

![MyM5Stack_LCDdraw.jpg](https://qiita-image-store.s3.amazonaws.com/0/221758/f301bc4f-e7df-ce19-3564-4f4db3d04360.jpeg)

##2. プログラム
m5lcdコマンドとm5btnコマンドを追加しました。

###2.1 MyM5Stack004.ino
[M5StackにRTCを接続しI2C通信で時刻の設定、取得を行う](https://qiita.com/pbjpkas/items/cc3bf43a5f9fd2c3415d)の[6.プログラム](https://qiita.com/pbjpkas/items/cc3bf43a5f9fd2c3415d#6-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0)との差分を以下に示します。

####2.1.1 MyM5Utils.hのインクルード

```c:MyM5Stack004.ino
#include "MyM5Utils.h"
```

####2.1.2 Command Modeのマクロの多重定義よけ
\_CMD_でくくります。

```c
#ifndef _CMD_
#define _CMD_
#define CMD_QUIT             1
#define CMD_OK          ERR_OK
#define CMD_BUF_LENGTH      64 // 63+1
#define CMD_MAX_LENGTH      64 // 63+1
#define ARG_MAX_LENGTH      64 // 63+1
#endif
```

####2.1.3 cmd_print_help()
ヘルプを追加します。

```c
    Serial.print("m5lcd      : M5Stack Lcd function\r\n");
    Serial.print("m5btn      : M5Stack Btn function\r\n");
```

####2.1.4 cmd_execute()
呼び出し側を追加します。

```c
    else if(strcmp(cmd, "m5lcd")==0)
    {
        my_m5_lcd();
    }
    else if(strcmp(cmd, "m5btn")==0)
    {
        my_m5_btn();
    }
```

###2.2 MyM5Utils.h

```c:MyM5Utils.h
#ifndef _MYM5UTILS_H_
#define _MYM5UTILS_H_

#ifndef _CMD_
#define _CMD_
#define CMD_QUIT             1
#define CMD_OK          ERR_OK
#define CMD_BUF_LENGTH      64 // 63+1
#define CMD_MAX_LENGTH      64 // 63+1
#define ARG_MAX_LENGTH      64 // 63+1
#endif

int my_m5_lcd();
int my_m5_btn();

#endif
```

###2.3 MyM5Utils.cpp
[M5Stack.h](https://github.com/m5stack/M5Stack/blob/master/src/M5Stack.h)に記載の関数を呼び出します。

- 未実装のものもあります。
- 25.drawCentreStringと26.drawRightStringのフォントはTFT_Clockに記載のコメントをご参照ください。

```c:TFT_Clock.ino
// Only font numbers 2,4,6,7 are valid. Font 6 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 : . - a p m
// Font 7 is a 7 segment font and only contains characters [space] 0 1 2 3 4 5 6 7 8 9 : .
```

```c:MyM5Utils.cpp
#include <M5Stack.h>
#include "MyM5Utils.h"
extern int cmd_getstr(char *buf);
extern int cmd_getnum(int type);

int my_m5_lcd()
{
    int      ret;
    uint8_t  select = 0;
    char     buf[CMD_MAX_LENGTH];

    boolean  wrap;
    int16_t  x, y, x0, y0, x1, y1, x2, y2;
    int16_t  w, h, radius, r, delta;
    int      dX, poY, font;
    
    uint8_t  ubrightness, ucornername, usize;
    uint16_t ucolor, ubg;
    uint16_t ux, uy, ux0, uy0;

    while( select != 99 )
    {
        Serial.print("----------------\r\n");
        Serial.print(" 1.setBrightness\r\n");
        Serial.print(" 2.drawPixel\r\n");
        Serial.print(" 3.drawLine\r\n");
        Serial.print(" 4.fillRect\r\n");
        Serial.print(" 5.fillScreen\r\n");
        Serial.print(" 6.drawCircle\r\n");
        Serial.print(" 7.drawCircleHelper\r\n");
        Serial.print(" 8.fillCircle\r\n");
        Serial.print(" 9.fillCircleHelper\r\n");
        Serial.print("10.drawTriangle\r\n");
        Serial.print("11.fillTriangle\r\n");
        Serial.print("12.drawRoundRect\r\n");
        Serial.print("13.fillRoundRect\r\n");
//        Serial.print("14.drawBitmap    (Unimplemented)\r\n");
//        Serial.print("15.drawRGBBitmap (Unimplemented)\r\n");
        Serial.print("16.drawChar\r\n");
        Serial.print("17.setCursor\r\n");
        Serial.print("18.setTextColor\r\n");
        Serial.print("19.setTextColor /w bgcolor\r\n");
        Serial.print("20.setTextSize\r\n");
        Serial.print("21.setTextWrap\r\n");
        Serial.print("23.print\r\n");
        Serial.print("25.drawCentreString\r\n");
        Serial.print("26.drawRightString\r\n");
//        Serial.print("27.drawJpg     (Unimplemented)\r\n");
//        Serial.print("28.drawJpgFile (Unimplemented)\r\n");
//        Serial.print("29.drawBmpFile (Unimplemented)\r\n");
        Serial.print("99.exit\r\n");
        Serial.print("select : ");
        select = cmd_getnum(DEC);
        Serial.print("\r\n");
        switch(select)
        {
            case 1:
                Serial.print("Brightness(0-255) : "); ubrightness = cmd_getnum(DEC); Serial.print("\r\n");
                M5.Lcd.setBrightness(ubrightness);
                break;
            case 2:
                Serial.print("x     : ");   x      = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y     : ");   y      = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("color : 0x"); ucolor = cmd_getnum(HEX); Serial.print("\r\n");
                M5.Lcd.drawPixel(x, y, ucolor);
                break;
            case 3:
                Serial.print("x0    : ");   x0     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y0    : ");   y0     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("x1    : ");   x1     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y1    : ");   y1     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("color : 0x"); ucolor = cmd_getnum(HEX); Serial.print("\r\n");
                M5.Lcd.drawLine(x0, y0, x1, y1, ucolor);
                break;
            case 4:
                Serial.print("x     : ");   x      = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y     : ");   y      = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("w     : ");   w      = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("h     : ");   h      = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("color : 0x"); ucolor = cmd_getnum(HEX); Serial.print("\r\n");
                M5.Lcd.fillRect(x, y, w, h, ucolor);
                break;
            case 5:
                Serial.print("color : 0x"); ucolor = cmd_getnum(HEX); Serial.print("\r\n");
                M5.Lcd.fillScreen(ucolor);
                break;
            case 6:
                Serial.print("x0    : ");   x0     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y0    : ");   y0     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("r     : ");   r      = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("color : 0x"); ucolor = cmd_getnum(HEX); Serial.print("\r\n");
                M5.Lcd.drawCircle(x0, y0, r, ucolor);
                break;
            case 7:
                Serial.print("x0         : ");   x0          = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y0         : ");   y0          = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("r          : ");   r           = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("cornername : ");   ucornername = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("color      : 0x"); ucolor      = cmd_getnum(HEX); Serial.print("\r\n");
                M5.Lcd.drawCircleHelper(x0, y0, r, ucornername, ucolor);
                break;
            case 8:
                Serial.print("x0    : ");   x0     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y0    : ");   y0     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("r     : ");   r      = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("color : 0x"); ucolor = cmd_getnum(HEX); Serial.print("\r\n");
                M5.Lcd.fillCircle(x0, y0, r, ucolor);
                break;
            case 9:
                Serial.print("x0         : ");   x0          = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y0         : ");   y0          = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("r          : ");   r           = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("cornername : ");   ucornername = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("delta      : ");   delta       = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("color      : 0x"); ucolor      = cmd_getnum(HEX); Serial.print("\r\n");
                M5.Lcd.fillCircleHelper(x0, y0, r, ucornername, delta, ucolor);
                break;
            case 10:
                Serial.print("x0    : ");   x0     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y0    : ");   y0     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("x1    : ");   x1     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y1    : ");   y1     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("x2    : ");   x2     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y2    : ");   y2     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("color : 0x"); ucolor = cmd_getnum(HEX); Serial.print("\r\n");
                M5.Lcd.drawTriangle(x0, y0, x1, y1, x2, y2, ucolor);
                break;
            case 11:
                Serial.print("x0    : ");   x0     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y0    : ");   y0     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("x1    : ");   x1     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y1    : ");   y1     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("x2    : ");   x2     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y2    : ");   y2     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("color : 0x"); ucolor = cmd_getnum(HEX); Serial.print("\r\n");
                M5.Lcd.fillTriangle(x0, y0, x1, y1, x2, y2, ucolor);
                break;
            case 12:
                Serial.print("x0     : ");   x0     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y0     : ");   y0     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("w      : ");   w      = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("h      : ");   h      = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("radius : ");   radius = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("color  : 0x"); ucolor = cmd_getnum(HEX); Serial.print("\r\n");
                M5.Lcd.drawRoundRect(x0, y0, w, h, radius, ucolor);
                break;
            case 13:
                Serial.print("x0     : ");   x0     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y0     : ");   y0     = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("w      : ");   w      = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("h      : ");   h      = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("radius : ");   radius = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("color  : 0x"); ucolor = cmd_getnum(HEX); Serial.print("\r\n");
                M5.Lcd.fillRoundRect(x0, y0, w, h, radius, ucolor);
                break;
            case 16:
                Serial.print("x     : ");   ux     = cmd_getnum(DEC);     Serial.print("\r\n");
                Serial.print("y     : ");   uy     = cmd_getnum(DEC);     Serial.print("\r\n");
                Serial.print("char  : ");   ret    = cmd_getstr(&buf[0]); Serial.print("\r\n");
                Serial.print("color : 0x"); ucolor = cmd_getnum(HEX);     Serial.print("\r\n");
                Serial.print("bg    : 0x"); ubg    = cmd_getnum(HEX);     Serial.print("\r\n");
                Serial.print("size  : ");   usize  = cmd_getnum(DEC);     Serial.print("\r\n");
                M5.Lcd.drawChar(ux, uy, buf[0], ucolor, ubg, usize);
                break;
            case 17:
                Serial.print("x0 : "); ux0 = cmd_getnum(DEC); Serial.print("\r\n");
                Serial.print("y0 : "); uy0 = cmd_getnum(DEC); Serial.print("\r\n");
                M5.Lcd.setCursor(ux0, uy0);
                break;
            case 18:
                Serial.print("TextColor : 0x"); ucolor = cmd_getnum(HEX); Serial.print("\r\n");
                M5.Lcd.setTextColor(ucolor);
                break;
            case 19:
                Serial.print("TextColor : 0x"); ucolor = cmd_getnum(HEX); Serial.print("\r\n");
                Serial.print("bg        : 0x"); ubg    = cmd_getnum(HEX); Serial.print("\r\n");
                M5.Lcd.setTextColor(ucolor, ubg);
                break;
            case 20:
                Serial.print("TextSize : "); usize = cmd_getnum(DEC); Serial.print("\r\n");
                M5.Lcd.setTextSize(usize);
                break;
            case 21:
                Serial.print("TextWrap (0 or 1): "); wrap = cmd_getnum(DEC); Serial.print("\r\n");
                M5.Lcd.setTextWrap(wrap);
                break;
            case 23:
                Serial.print("str : "); ret = cmd_getstr(&buf[0]); Serial.print("\r\n");
                M5.Lcd.print(buf);
                break;
            case 25:
                Serial.print("str  : "); ret  = cmd_getstr(&buf[0]); Serial.print("\r\n");
                Serial.print("dX   : "); dX   = cmd_getnum(DEC);     Serial.print("\r\n");
                Serial.print("poY  : "); poY  = cmd_getnum(DEC);     Serial.print("\r\n");
                Serial.print("font : "); font = cmd_getnum(DEC);     Serial.print("\r\n");
                M5.Lcd.drawCentreString(buf, dX, poY, font);
                break;
            case 26:
                Serial.print("str  : "); ret  = cmd_getstr(&buf[0]); Serial.print("\r\n");
                Serial.print("dX   : "); dX   = cmd_getnum(DEC);     Serial.print("\r\n");
                Serial.print("poY  : "); poY  = cmd_getnum(DEC);     Serial.print("\r\n");
                Serial.print("font : "); font = cmd_getnum(DEC);     Serial.print("\r\n");
                M5.Lcd.drawRightString(buf, dX, poY, font);
                break;
            case 99:
                break;
            default:
                break;
        }
    }
    return 0;
}

int my_m5_btn()
{
    uint8_t  select = 0;

    while( select != 99 )
    {
        Serial.print("----------------\r\n");
        Serial.print(" 1.BtnA/B/C.read\r\n");
        Serial.print("99.exit\r\n");
        Serial.print("select : ");
        select = cmd_getnum(DEC);
        Serial.print("\r\n");
        switch(select)
        {
            case 1:
                M5.Lcd.fillScreen(0xffff); // white
                M5.Lcd.setCursor(10, 10); M5.Lcd.print("BtnA:"); M5.Lcd.println( M5.BtnA.read() );
                M5.Lcd.setCursor(10, 30); M5.Lcd.print("BtnB:"); M5.Lcd.println( M5.BtnB.read() );
                M5.Lcd.setCursor(10, 50); M5.Lcd.print("BtnC:"); M5.Lcd.println( M5.BtnC.read() );
                break;
            case 99:
                break;
            default:
                break;
        }
    }
    return 0;
}
```


##3. 使い方
1. M5Stackを起動しUARTで何かキーを送ってCommand Modeへ遷移します。
2. m5lcdコマンドを実行します。
3. メニューが表示されるので5番のfillScreenを実行してLCDの画面を初期化します。
  - 色は[Lesson 1.1. LCD. Graphics](http://forum.m5stack.com/topic/41/lesson-1-1-lcd-graphics)を参照
  - 0xffffで白画面になります
4. 99でメニューから抜けてCommand Modeに戻ります。

##4. おわりに
ちょっと前に某界隈で話題になったリバーシの盤面を描いてみました。
![M5Stack_LCD_Reversi.jpg](https://qiita-image-store.s3.amazonaws.com/0/221758/72e5f729-b0d5-fb44-5b4d-4ef501280ccd.jpeg)

- 5.fillScreenでLCDをグリーンにペイント
- 3.drawLineで格子状に描線
- 8.fillCircleでコマを配置