M5Stackでコマンド操作

##1. はじめに
[Arduino Leonardoで多目的ツールの製作](https://qiita.com/pbjpkas/items/97dbf835b0aab6725e94)の[CLI](https://www.google.co.jp/search?hl=ja&as_q=CLI)(Command Line Interface)のコア部分をM5Stackに移植しました。
![typesize.png](https://qiita-image-store.s3.amazonaws.com/0/221758/706f20eb-3078-4f87-5d99-a82b1adc9fda.png)

##2. 型のサイズを調べる
typesizeというchar、short、int、long、long longのサイズ(バイト数)を調べるコマンドを作成しました。その実行結果を以下に示します。Arduino Leonardoに搭載されているAVRマイコンとint型のサイズが異なっていることがわかりました(AVRマイコンのint型は2バイトです)。

|型        |サイズ(バイト数)
|----------|---
|char      | 1
|short     | 2
|int       | 4
|long      | 4
|long long | 8

##3. プログラム
``` C
#include <M5Stack.h>

void setup();
void loop();
void cmd_print_help(void);
void cmd_print_ver(void);
int  cmd_execute(char *buf);
void cmd_rx_data(void);

// the setup routine runs once when M5Stack starts up
void setup(){

    // Initialize the M5Stack object
    M5.begin();
    Serial.begin(115200);

    // LCD display
    M5.Lcd.print("MyM5STACK Ver.001");
}

// the loop routine runs over and over again forever
void loop() {
    if(Serial.available()) {
        cmd_rx_data();
    }
}

/***********************************************************************
  Command Mode
 ***********************************************************************/
#define CMD_QUIT          1
#define CMD_OK            0
#define CMD_INVALID      -1
#define CMD_MALLOC_ERR   -2
#define CMD_BUF_LENGTH   64 // 63+1
#define CMD_MAX_LENGTH   64 // 63+1
#define ARG_MAX_LENGTH   64 // 63+1

void cmd_print_help(void)
{
    Serial.print("Available Command:\r\n");
    Serial.print("help, ?    : Print Help Messages\r\n");
    Serial.print("ver        : Print Version Information\r\n");
    Serial.print("typesize   : print type's size\r\n");
    Serial.print("quit, exit : Quit Command Control Mode\r\n");
}

void cmd_print_ver(void)
{
    Serial.print("This is ");
    Serial.print(__FILE__);
    Serial.print(" ");
    Serial.print("Build at ");
    Serial.print(__DATE__);
    Serial.print(" ");
    Serial.print(__TIME__);
    Serial.print("\r\n");
}

int cmd_execute(char *buf)
{
    int i, x, y;
    unsigned int ux;
    int return_val = CMD_OK;
    char cmd[CMD_MAX_LENGTH];
    char arg1[ARG_MAX_LENGTH];
    char arg2[ARG_MAX_LENGTH];

    strcpy(cmd, "");
    strcpy(arg1, "");
    strcpy(arg2, "");
    sscanf(buf, "%s %s %s", &cmd, &arg1, &arg2);

    if     (strcmp(cmd, "help")==0){ cmd_print_help(); }
    else if(strcmp(cmd, "?"   )==0){ cmd_print_help(); }
    else if(strcmp(cmd, "ver" )==0){ cmd_print_ver();  }

    else if((strcmp(cmd, "quit")==0) or (strcmp(cmd, "exit")==0))
    {
        return CMD_QUIT;
    }

    else if(strcmp(cmd, "typesize")==0)
    {
        Serial.print("char      : ");
        Serial.print( sizeof(char) );
        
        Serial.print("\r\nshort     : ");
        Serial.print( sizeof(short) );

        Serial.print("\r\nint       : ");
        Serial.print( sizeof(int) );

        Serial.print("\r\nlong      : ");
        Serial.print( sizeof(long) );

        Serial.print("\r\nlong long : ");
        Serial.print( sizeof(long long) );

        Serial.print("\r\n");
    }

    else
    {
        return CMD_INVALID;
    }

    return return_val;

}

void cmd_rx_data(void)
{
    int i;
    int return_val = CMD_OK;
    char buf[CMD_BUF_LENGTH];

    /* モード切替時の "Hit any key" のキー操作を捨てる */
    while(Serial.available()){ Serial.read(); }

    Serial.print("\r\n### Command Mode. ###\r\n");
    Serial.print("### Hit ? to help.###\r\n");
    Serial.print("$");

    i=0;
    while(1)
    {
        if(Serial.available())
        {
            buf[i] = Serial.read();
            Serial.print(buf[i]); //echo-back

            if ( (buf[i] == 0x08) or (buf[i] == 0x7f) ) //BackSpace, Delete
            {
                buf[i] = '\0';
                if(i) i--;
            }
            else if( (buf[i] == '\r') or (buf[i] == '\n') )
            {
                Serial.print( F("\r\n") );
                buf[i] = '\0';
                return_val = cmd_execute(&buf[0]);
                for(i=0; i<CMD_BUF_LENGTH; i++) buf[i] = '\0';
                i=0;

                if(return_val == CMD_QUIT)
                {
                    Serial.print("### Quit Command Mode. ###\r\n");
                    return;
                }
                else if(return_val == CMD_INVALID)
                {
                    Serial.print("?\r\n");
                    Serial.print("$");
                }
                else
                {
                    Serial.print("OK\r\n$");
                }
            }
            else
            {
                i++;
                if(i>=CMD_BUF_LENGTH)
                {
                    Serial.print("### CMD BUFFER FULL, CLEAR. ###\r\n");
                    for(i=0; i<CMD_BUF_LENGTH; i++) buf[i] = '\0';
                    i=0;
                }
            }
        }
    }// while
}
```