1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Arduinoで使えるコマンドパーサーのテンプレート(関数ポインタ使用)

Posted at

概要

Arduinoで使える シリアル入力コマンドパーサーのテンプレートです。

ポイント

コマンドと、そのコマンドに対応する関数をペアにしてリスト化しています。

注意事項

  • 関数ポインタを受け入れがたい人にはお勧めしません
  • 備忘録的な記事なので、細かい解説は割愛させていただきます

ソースコード

  • "on+改行"を入力するとLedOn()関数が呼ばれてLEDが点灯
  • "off+改行"を入力するとLedOff()関数が呼ばれてLEDが消灯
  • "reset+改行"を入力するとReset()関数が呼ばれてリセットベクタに飛びます
void LedOn(){
  Serial.println("LED is ON");
  digitalWrite(LED_BUILTIN, HIGH);
}
void LedOff(){
  Serial.println("LED is OFF");
  digitalWrite(LED_BUILTIN, LOW);
}
void Reset(){
  asm volatile("jmp 0"); //リセットベクタ(0番地)に飛ぶ
}
//======================================================================
// 
//======================================================================
typedef void (*pFunc)(void);
//コマンド文字列と関数ポインタをセットにした構造体
struct Command {
  String name;   //コマンド文字列
  pFunc action;  //対応する関数へのポインタ
};
//----------------------------------
//コマンドと対応する関数のリスト
//----------------------------------
Command CommandList[] = {
  {"on" , &LedOn},
  {"off", &LedOff},
  {"reset", &Reset},
};
const int CommandCount = sizeof(CommandList) / sizeof(CommandList[0]); // コマンドの数
String SerialBuffer = "";//シリアル受信バッファ
//==================================================================
//初期設定
//==================================================================
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  Serial.begin(115200);//
  Serial.println("--- START PROGRAM ---");
}
//==================================================================
//メインループ
//==================================================================
void loop() {
  CommandCheck();
}
//-------------------------------------------------------------------------------
//シリアルコマンドのチェック
//  シリアル受信した文字を文字列に詰めていく、改行コードが来たらコマンド解析を実行
//-------------------------------------------------------------------------------
void CommandCheck() {
  while(Serial.available()>0){
    char rx = Serial.read();//1バイト読込
    Serial.write(rx);//エコーバック
    if (rx == '\n' || rx == '\r') {// 改行コードでコマンドパース実行
        CommandParse(SerialBuffer);
        SerialBuffer = ""; // バッファをクリア
        return;
    }
    SerialBuffer += rx; //バッファに追加
  }//while
}
//-------------------------------------------------------------------------------
//コマンド解析
//  受信コマンドとコマンドリストをループしながら比較、一致したら関数ポインタで関数を呼ぶ
//-------------------------------------------------------------------------------
void CommandParse(String command) {
  command.trim(); // 前後の空白を削除
  for (int i = 0; i < CommandCount; i++) {
    if (command.equalsIgnoreCase(CommandList[i].name)) {
      (void) (*CommandList[i].action)(); // 対応する関数を呼び出し
      return;
    }
  }//for
  Serial.println("Unknown command.");
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?