「Arduino / ubuntuとシリアル通信してみた」で試してみたターミナルコマンド cu による LED の PWM 制御を、少し改良してみました。
前回は数字を 3つ入力すると LED の明るさが変わるというものでした。これを 0 から 255 までの数字を入力して Enter を押すと、その値に従って LED の明るさを変えるようにしたいと思います。
そのために、桁数の異なる数字をシリアル通信で Arduino に送り、数値として PWM 制御に渡す必要があります。少しググってみたのですが、シリアル通信で数値を送るには、文字列を数値に替えるだけでなく、桁数の違いをどう処理するかなど、けっこう面倒な雰囲気です。単純な処理なのでもっと簡単な方法がないかなと探していたところ、こんなチュートリアルを見つけました。
The toInt() function allows you to convert a String to an integer number.
In this example, the board reads a serial input string until it sees a newline, then converts the string to a number if the characters are digits.
ドンピシャです。文字列を数値に変換する、まさに求めていた内容ですよ。
toInt() は String オブジェクトの関数です… よくわかりません (^_^;) でもこうやって使うとこういう結果が出るということは、簡単に理解できます。なお、このチュートリアルにあるサンプルコードは、IDE のスケッチ例「08.String」に「StringToint」として附属しています。
さて、そのサンプルコードを参考にした、cu から送信するデータに従って 3番ピンに接続した LED を PWM 制御するスケッチです。
-
// PWM control LED from cu 2019/09/09 meyon
-
const int ledPin = 3;
-
String inStr = "";
-
void setup()
-
{
-
pinMode(ledPin, OUTPUT);
-
Serial.begin(9600);
-
}
-
void loop()
-
{
-
while(0 < Serial.available()) {
-
int inChar = Serial.read();
-
Serial.write(inChar);
-
if(isDigit(inChar)) {
-
inStr += (char)inChar;
-
}
-
if(13 == inChar) {
-
int ledBri = inStr.toInt();
-
ledBri = constrain(ledBri, 0, 255);
-
analogWrite(ledPin, ledBri);
-
Serial.print("¥nBrightness: ");
-
Serial.println(ledBri);
-
inStr = "";
-
}
-
}
-
}
16行目は cu へのエコーです。Serial.write() はデータを byte 型で出力するので、受け取った数字の ASCII コードをそのまま cu へ送り返し、入力した数字を表示させることができます。
18行目で入力データが数字かどうかを判断し、数字なら文字列として inStr に追加していきます。
22〜25行目。入力データが Enter の場合 ASCII コード (13) が届きますので、それまでに届いた文字列を数値に変換して 3番ピンへアナログ出力します。
数値は 0〜255 の範囲に制限し、256 以上の場合は 255 としています。int 型なので 32767 を超えると出力は 0 になってしまいますね。また、入力に数字以外が含まれていると無視されます。数字だけを抽出して制御値になります。
これでかなりエクセレントになった気がします (^_^;)