今回やること
Arduinoのシリアル通信を使って、PC等から送られてきた文字列を読み取り、その文字列に対応したプログラムを実行するプログラムを作ります。
(簡単に説明するとciscoとかのコンソールみたいなものを目指します)
最終的にこんな感じ↓
今回使用する物、ソフト
- Arduino(コンソール使えれば種類はなんでも良い)
- ArduinoとPCを繋ぐケーブル(usb等)
- コンソール接続できる端末(パソコン等)
- コンソール接続できるソフト(tera term等)
以上のものがあればできます。
しかしこれだけじゃ面白くないので
- RTC(real time clock)
- LED
も使います。
注意事項
今回作るプログラムはキーを押した瞬間文字がArduino側に送信される事を前提としたプログラムになっています。
なので、Arduino IDEのソフトにあるコンソールのようなEnterを押さないと送信されないような仕組みのソフトは今回は使用することができません。
そこでTera Termを使用します。
このソフトはキーが押された瞬間相手方に入力された文字列を送信してくれます。
あと、マイコンボードに書き込む際は、Tera Termの接続を切断しなければなりません。
面倒臭いですがその辺は頑張ってください。
配線
コード
即席で作ったコードなので突っ込みどころ満載ですが気にしないでください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
#include <DS3232RTC.h> String input_data = "", output_data = "", hostname = "Arduino"; bool input; void setup() { input = false; pinMode(13, OUTPUT); Serial.begin(9600); Serial.setTimeout(5); Serial.println("Please input command."); } void TimeView() { tmElements_t tm; RTC.read(tm); Serial.print(tm.Year + 1970, DEC); Serial.print("年"); Serial.print(tm.Month, DEC); Serial.print("月"); Serial.print(tm.Day, DEC); Serial.print("日"); Serial.print(tm.Hour, DEC); Serial.print("時"); Serial.print(tm.Minute, DEC); Serial.print("分"); Serial.print(tm.Second, DEC); Serial.println("秒"); } void LED_toggle(bool LED){ if(LED == true){ digitalWrite(13, HIGH); } else{ digitalWrite(13, LOW); } } void Command(String temp) { if ( temp == "show time" ) { TimeView(); } ////////////////////////////////////////// else if ( temp == "led on"){ LED_toggle(true); Serial.println("LED turned on."); } else if ( temp == "led off"){ LED_toggle(false); Serial.println("LED turned off."); } ////////////////////////////////////////// else if ( temp == "" ) { Serial.println(""); } else { Serial.println("Unknown command. Type it again."); } } void loop() { if (input == false) { Serial.print(hostname); Serial.print(">"); input = true; } if ( Serial.available() > 0 ) { input_data = Serial.readString(); Serial.print(input_data); if (input_data == "\b"){ Serial.print("\033[2K"); Serial.print("\r"); Serial.print(hostname); Serial.print(">"); output_data = output_data.substring(0, output_data.length() - 1); Serial.print(output_data); input_data = ""; } else if (input_data == "\r") { if (output_data == "") {} else { Serial.println(); } Command(output_data); output_data = ""; input = false; } else { output_data = output_data + input_data; } } } |
(自分で任意のコマンドを追加したい場合は3つ次の項目でやり方を書きます)
解説
12行目までは説明する必要もないと思うので省略します。
14~29行目はRTC内に保存されている日付をシリアル通信で日本語表示する関数を定義しています。
31~38行目はLEDフラグを見て13番のピンのON、OFFの制御をする関数の定義をしています。
40~60行目はシリアル通信で受信した文字データの比較を行い、一致する文字列に合ったプログラムの実行、不一致の場合のプログラムの実行を行う関数の定義をしています。
62~95行目はloop関数に入ります。
63~67行目はinputがfalseの時、hostnameに格納されている文字列を出力したのち”>”を出力して改行してinputをtrueにしています。
68行目はシリアル通信で受信したデータがあったときに実行されます。
69、70行目は受信したデータをinput_dataに格納、出力をします。
71行目はバックスペースが入力されたときに実行されます。
72行目はコンソール画面のカーソルのある行の文字を削除しています。
73行目は(hostname)>が右にずれていかないように改行コードを出力しています。
74、75行目はhostnameと”>”を出力しています。
76、77行目はoutput_dataに格納されているデータの後ろの文字の一文字を削除して出力します。
78行目はinput_dataをクリアしています。
80行目はエンターが押されたときに実行されます。
81行目は、output_dataに何も格納されていなかったな何もしません。
82~84行目はoutput_dataにデータが格納されていた時に改行しています。
85行目はoutput_dataに格納されているデータをCommand関数に受け渡しています。
86行目はoutput_dataをクリアしています。
87行目はinputにfalseを代入しています。
89~91行目は入力されたのがエンター、バックスペース以外の時(文字が入力されたとき)、output_dataの後ろに入力されたデータを追加しています。
コメント