質問: 0; i < len; i++) { printf("%02X", buf[i]); } printf("\n"); } // エコーバック write(fd, buf, len); } close(fd); // デバイスのクローズ return 0; } ``` このURLから引っ張ってきたコードですが、これではlenの値が正しく反映されません(正しい行数が出てこない)。また出力を10進数で出したいです。 かなり丸投げな質問ですが、よろしくお願いいたします。 ちなみに出力したらこんな感じに出てきます。 ・出力例 313432 31 3436 31 3439 3134 ・本来出て欲しい出力 143 143 142 141 143 142 環境 xcode 9.1 Arduino uno
回答: 送信側からは`142146139...`という文字の並びが順次送られてきています。 一方受信側は、この通信がいつ終わるか分からないので、実はread関数は適当(勝手)なタイミングで受信データを区切って呼出元に返します。 すなわちread関数の結果(バッファの中身)は、`142` `1` `46` `1` `39` ...となっています。 これでは送信した数値の区切りが分かりません。 そこで、送信側で、受信側が**データの区切りが分かるような文字を付加**して送るようにします。 ここで**データ(文字列)+区切り文字**を**行**と表現します。 受信側は区切り文字が来るまで(数値)文字を行バッファに溜めておき、区切り文字が来たら行バッファに溜まった数値文字列を数値に変換すればよいです。 ちなみに、区切り文字は改行文字`\r`,`\n`などを用いるのが一般的です。 以下は疑似的な検証コードです。 ``` // 送信側 // Serial.print(142); Serial.print("\n"); // Serial.print(146); Serial.print("\n"); // Serial.print(139); Serial.print("\n"); const char *aSend[] = {"142\n","1","46","\n1","39\n"}; // 間欠的に受信をシミュレート int readPos = 0; int SEND_CNT = sizeof(aSend)/sizeof(aSend[0]); int dummy_read( char buf[]) { if( readPos >= SEND_CNT) return -1; strcpy( buf, aSend[readPos]); readPos++; return strlen(buf); } void ser_test( void) { char line_buf[256] = ""; // 行バッファ while( 1){ char ser_buf[256] = ""; int len = dummy_read( ser_buf); if( len < 0) break; // 終了 for( int i = 0; i < len; i++){ char c(ser_buf[i]); if( c == '\n'){ // 区切り int num = atoi(line_buf); printf( "%d\n", num); strcpy(line_buf, ""); // 行バッファクリア } else{ // 行バッファに1文字追加 int len = strlen(line_buf); line_buf[len] = c; line_buf[len+1] = '\0'; } } } } ``` 参考:ArduinoとMacでシリアル通信(C言語)