質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

6454閲覧

シリアル通信のwritefile関数の高速化

keni

総合スコア13

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/07/10 14:09

前提・実現したいこと

VisualStudio2017にてC++でシリアル通信をしたいと思っています.
さらにできるだけ早く通信をしたいと思っています.

発生している問題

データの送信にwritefile関数を用いているのですが,writefile関数の処理時間をもっと高速にしたいと考えています.以下のソースコードのようにwritefile関数にかかる時間を測定したところ30~400[ms]ほどの時間がかかることが確認でき,一回当たりのループにかかる時間のほとんどを占めています.

このwritefile関数にかかる時間を少なくする方法を教えていただきたいです.
また,この関数以外にシリアル通信において送受信の時間がかからない関数等あれば教えていただけたら嬉しいです.

知識不足で大変申し訳ありませんが,ご教授お願い致します.

ソースコード

C++

1#include "pch.h" 2#include <iostream> 3#include <stdio.h> 4#include <fstream> 5#include <chrono> 6#include <time.h> 7 8using namespace std; 9 10int main() 11{ 12 13 std::chrono::system_clock::time_point start, end; 14 double elapsed = 0; 15 int counter = 0; 16 17 18 HANDLE hFile = ::CreateFile( 19 "COM3" 20 , GENERIC_WRITE 21 , 0 22 , NULL 23 , CREATE_ALWAYS 24 , FILE_ATTRIBUTE_NORMAL 25 , NULL 26 ); 27 28 while (1) { 29 DWORD dwNumberOfWritten = 0; 30 counter++; 31 sprintf_s(str, "%d\n", counter); 32 start = std::chrono::system_clock::now(); 33 WriteFile(hFile, str.c_str(), str.size(), &dwNumberOfWritten, NULL) 34 end = std::chrono::system_clock::now(); 35 elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count(); 36 cout << "elapsed" << elapsed << endl; 37 38 } 39 40 return 0; 41}

試したこと

送信時のタイムアウトの設定をいかに変更してみましたが,特に変化はありませんでした.
WriteTotalTimeoutMultiplier = 10;
WriteTotalTimeoutConstant = 10;

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2020/07/11 02:09

実は、WriteFile() APIの実行が失敗しているということはありませんか。(書き込み完了待ちになっているとか)WriteFile()の返り値(BOOL)とdwNumberOfWrittenの値、エラーならGetLastError()の値を確認してみてください。
ikadzuchi

2020/07/11 04:57

30~400[ms]とはだいぶ幅がありますが、これはランダムに変わるのですか? 出力の例を出していただけると分かりやすいかと思います。 また、文字数を多く(1000文字とか)した場合時間はどうなりますか?
guest

回答3

0

シリアル通信の通信速度、ってのは考慮されてますか?
ボーレートから、1バイトあたりに係る通信時間というのを算出できるので、それで計算してみましょう。

当然のことながら、この通信時間より早くは実行できません。
OSの中で、ある程度のバッファは持っているので、数キロバイトの程度なら一瞬で実行は終了します、が、それでも通信時間というのはかわりません。

投稿2020/07/10 22:59

y_waiwai

総合スコア87749

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keni

2020/07/12 16:31

回答ありがとうございます. 受信側の処理が遅かったため待ちが発生していたようで,受信側プログラムを変更することで解決できました. ご教授頂きありがとうございました.
guest

0

そもそも質問のコードはコンパイルを通りません。
とりあえず見込みで修正してコンパイルを通し、実行してみましたが症状が出ませんでした。(elapsed0が延々表示される。シリアルにはArduino UNOを繋いで、RXのLEDが点灯することでシリアル出力がされていることは確認)
あなたが実行したものとの違いが原因になっているのかも知れません。

こちらで試したものは以下になります。

C++

1#include <stdio.h> 2#include <time.h> 3 4#include <chrono> 5#include <fstream> 6#include <iostream> 7 8//#include "pch.h" 9#include <windows.h> 10using namespace std; 11 12int main() { 13 std::chrono::system_clock::time_point start, end; 14 double elapsed = 0; 15 int counter = 0; 16 17 HANDLE hFile = ::CreateFile("COM3", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 18 FILE_ATTRIBUTE_NORMAL, NULL); 19 20 while (1) { 21 char str[128]; 22 DWORD dwNumberOfWritten = 0; 23 counter++; 24 sprintf_s(str, "%d\n", counter); 25 start = std::chrono::system_clock::now(); 26//Sleep(100); //これを入れるとちゃんと100とか101になる 27 WriteFile(hFile, str, strlen(str), &dwNumberOfWritten, NULL); 28 end = std::chrono::system_clock::now(); 29 elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start) 30 .count(); 31 cout << "elapsed" << elapsed << endl; 32 } 33 34 return 0; 35}

投稿2020/07/11 02:02

thkana

総合スコア7629

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keni

2020/07/12 16:33

回答ありがとうございます. 受信側の処理が遅かったため待ちが発生していたようです.なので受信側のプログラムを変更することで解決しました. わざわざ実行までしていただきまして,ありがとうございました.
guest

0

ベストアンサー

相手側のデバイスが何なのかに依るとも思いますが、真っ先に思いつくのは通信速度の設定が双方合っていないとか。
双方のボーレートを上げてみましょう。115200bpsとか。
また、相手側の受信処理が遅いと(送信バッファがいっぱいなので)WriteFile処理に待ち時間が発生しているかもしれません。
これは相手側機器の都合なのでどうしようもないとは思います。

なお、仮想COMポートで上記コードを(わりと手直しして)実行してみましたが、elapsedはずっと0でした。
ご参考までに。

投稿2020/07/10 16:24

hope_mucci

総合スコア4447

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

keni

2020/07/10 17:32

回答ありがとうございます. ボーレートは双方とも115200bpsなのでそこは問題ないのかと思います. 受信側についてのプログラムを見返してみます.機器的な問題もあるのかもしれませんね. 実行して確認もしていただきありがとうございます. よければどういったところ手直ししたところを教えていただけないでしょうか? よろしくお願いいたします.
hope_mucci

2020/07/11 04:48

コンパイルが通らないので最低限コンパイルが通るよう手直しをしただけです。
keni

2020/07/12 16:29

ご返信ありがとうございます. 受信側の処理が遅かったため待ちが発生していたようです. 受信側を変更することにより時間がかからずに通信を行えました. ご教授頂きありがとうございました.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問