2017-01-11 27 views
1

純粋なC++ OOPスタイルのコードで、ArduinoのUARTシリアルポート経由で対話型シェルを実装したいと思います。しかし、コード内のユーザ入力コマンドを判断する際にif-else判定が多すぎると、少し醜いものになると思います。Arduino用UARTシリアル経由のインタラクティブシェル?

ですから、if- else文?例えば、

BEFORE:

while(Serial.available()) 
{ 
    serialReceive = Serial.readString();// read the incoming data as string 
    Serial.println(serialReceive); 
} 

if(serialReceive.equals("factory-reset")) 
{ 
    MyService::ResetSettings(); 
} 
else if(serialReceive.equals("get-freeheap")) 
{ 
    MyService::PrintFreeHeap(); 
} 
else if(serialReceive.equals("get-version")) 
{ 
    MyService::PrintVersion(); 
} 

AFTER:コマンドをトリガー文字列と一緒に関数ポインタを格納する配列を持つことができます

while(Serial.available()) 
{ 
    serialReceive = Serial.readString();// read the incoming data as string 
    Serial.println(serialReceive); 
} 

MagicClass::AssignCommand("factory-reset", MyService::ResetSettings); 
MagicClass::AssignCommand("get-freeheap", MyService::PrintFreeHeap); 
MagicClass::AssignCommand("get-version", MyService::PrintVersion); 

答えて

3

は(あなたがに構造体を作成することができます両方を保存する)。

残念ながら、Arduinoはstd :: vectorクラスをサポートしていません。私の例では、私はc型配列を使用します。しかし、Arduinoのhttps://github.com/maniacbug/StandardCplusplusコマンド配列を初期化するか、これで

//struct that stores function to call and trigger word (can actually have spaces and special characters 
struct shellCommand_t 
{ 
    //function pointer that accepts functions that look like "void test(){...}" 
    void (*f)(void); 
    String cmd; 
}; 

//array to store the commands 
shellCommand_t* commands; 

(また、このライブラリを使用すると、簡単に引数として関数を渡す作るための機能のライブラリを使用することができます)のために、いくつかのSTLのサポートを追加するArduinoのためのライブラリがありますコマンドを追加するたびにサイズを1つに変更したり、サイズを変更したりすることができます。

あなたはすでにあなたが持っているとして、あなたが同様の方法で、あなたのコマンドを追加することができ、あなたのセットアップ関数の中で次に、この

int nCommands = 0; 
void addCommand(String cmd, void (*f)(void)) 
{ 
    shellCommand_t sc; 
    sc.cmd = cmd; 
    sc.f = f; 

    commands[nCommands++] = sc; 
} 

のようになります。コマンドを追加するための配列に十分なスペースが割り当てられていることを前提とし、基本的な機能上の

addCommand("test", test); 
addCommand("hello world", helloWorld); 

最後に、forループを使用してすべてのコマンドを調べることができます。入力文字列をすべてのコマンド文字列と照合します。

あなたはこの

(*(commands[i].f))(); 
のようにマッチしたコマンドの機能を呼び出すことができます
関連する問題