2016年

4月

15日

Arduino シリアル通信で文字列情報の送受信を考える 2

ArduinoにEthernet シールドを取り付けてシリアル通信で文字列情報の送受信を考える

Arduinoのシリアル通信は基本的に1byteごとにしかポートに来ている情報を読むことができません。
だから、シリアル通信で文字列を渡そうと思ったらなかなか大変です。
そこでシリアル送信側で文字列の最後に終端記号「\0」を送信してもらって、そこまでを読み取るようにします。

WindowsRuntimeの場合このような送信コードで文字列の最後に終端文字を送信します。

cr(\r) LF(\n) CR:0x0d、LF:0x0A

Arduinoスケッチ

シリアル通信 

Sereal.read() で 1 バイト読み込む。何もデータがないときは -1 を返す。

sereal_read_char()              1 個読み込む
serial_read_line(char buf[])    1 行読み込む

void setup(){
     Serial.begin(9600);
}

int serial_read_char(){
  int cha;
  while(1){
    cha = Serial.read();     // 入力なしのとき -1
    if ( cha != -1 ) break;  // 何か入力があったなら、ループ脱出
  }
  return cha;
}  

/* 
シリアルポートから 1 行読み取る。
デリミタが来る前にバッファが一杯になったときは return する。
1 行読み取ったか、バッファが一杯になったかを区別するため、
int 型の関数にして、リターンコードを変えた方が良いと思う。

送り側も自分で作るので、ここではサボっている。
この例ではデリミタは 0x0a ( \n ) としているが、
私は普段はデリミタとして '.' を使っている。そのときは int('.') 

改行記号はシステムによって CR or CR+LF or LF などややこしい。
*/

void serial_read_line(char buf[], int n){
  int i = 0, input;
  
  while(1){
    input = Serial.read();
    if ( input == -1 ) continue;
    if ( input == int('\n') ) {
      buf[i] = '\0';
      return;
    }
    buf[i] = input;
    i++;
    if ( i >= n-1 ) {
      buf[n-1] = '\0';
      return;
    }
  }
}


void loop{

  char str[100];
  sereal_read_line(str,100);
  Serial.println(str);

}

出力は

  Serial.print("a");
  Serial.println(i);
  Serial.write(0x0a);

 

目 次