• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:シリアル通信がすっきり終れない)

シリアル通信がすっきり終れない

このQ&Aのポイント
  • vb2010expressの初心者です。コンテックのサイトからのプログラムを借用してシリアルの受信をしております。
  • このアプリを終了させようとするといつもグダグダしてしまい、すきっと終了してくれません。
  • どう書いたらいいんでしょうかおしえてください。

質問者が選んだベストアンサー

  • ベストアンサー
  • parsley59
  • ベストアンサー率100% (1/1)
回答No.1

一般的なシリアル通信のケースで回答します。 シリアル通信は双方向からデータの送受信が可能です。 状況から察するに、相手からの送信中に、受信側がCloseしているだと思います。 VBではたしか、メソッドが終了するまでマウスクリックなどのイベントが処理されません。 そのプログラムの受信処理は、受信データがある限り継続処理するようになっているのではないですか。 送信側が送信を止めれば、受信側プログラムも終了できるのではないでしょうか。 受信メソッドでにDoEventsを追加するだけで解決するかも。 通信を制御するには、通信プロトコルを決めてそれに従って双方の送受信をコントロールします。 例えば、受信側が送信要求した場合のみに相手が送信するとか、 または、送信要求で送信開始して、送信終了の指示で送信終了するとかします。 借用元のプログラムには、そのような通信プロトコルがあるはずです。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • VB2010で、シリアル通信をするには

    VB2010で、シリアル通信をするには シリアルポートをopenしようとすると、エラーで弾かれてしまいます。 どのように対処したら良いですか? 使っているソースコードは、下記の通り。 Private Sub ButtonRsStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonRsStart.Click Try '例外処理のはじまり If SerialPort1.IsOpen = True Then 'ポートはオープン済み MessageBox.Show("すでに" & SerialPort1.PortName & "は接続されています。", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) Exit Sub End If SerialPort1.PortName = "COM1" 'オープンするポート名を格納 SerialPort1.Open() 'ポートオープン PORT_STATE.Text = "OPEN" Catch ex As Exception '例外処理 MessageBox.Show(ex.Message, "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error) End Try End Sub --------------- エラーが発生する場所は、「Catch 」になります。 エラーメッセージは、「ポート 'COM1' へのアクセスが拒否されました。」です。 何が原因なのか、さっぱり分かりません。 ヒントになりそうな解答を頂けないでしょうか?

  • キーエンス製シーケンサとのシリアル通信

    いつも御世話になっております。 早速ですが、現在VB2010Exでキーエンス製シーケンサとシリアル通信のプログラムを作成しています。 接続方法は上位リンクモードで設定しています。 パソコン(VB2010)からの送受信は出来ています。 ただ現在困っているのが、シーケンサの接点の監視です。 ためしに、 PortOpen ↓ コマンド送信(SerialPort1.Write()にて) ↓ レスポンス受信(SerialPort1.DataReceivedにて) ↓ PortClose この工程をループさせてみました。 問題なく、接点の監視は出来たのですが、通信を常時行うプログラムが本当に良いのか疑問に思い質問させていただきました。 シーケンサの接点の監視を常時行うにはどのようなプログラムが一般的なのでしょうか? よろしく御願い致します。

  • VB.netで、シリアル通信のタイムアウト処理について

    VB.netで、シリアル通信のタイムアウト処理について http://msdn.microsoft.com/ja-jp/library/7ya7y41k.aspx このサイトのコードを、参考にしています。 ------------------------------------ここから Dim com1 As IO.Ports.SerialPort = Nothing Try com1 = My.Computer.Ports.OpenSerialPort("COM1") com1.ReadTimeout = 10000 Catch ex As TimeoutException returnStr = "Error: Serial Port read timed out." Finally If com1 IsNot Nothing Then com1.Close() End Try ------------------------------------ここまで この方法ですと、タイムアウトが発生したらポートを閉じるようですが、これを、送信したシリアルのデータを再度、送信させたいと思います。 そして、何度かリトライを掛けた後に、やっぱり駄目だったときに ポートを閉じたいと思います。 どんな方法がありますか? 参考になりそうなサイトなどがありましたら、教えていただけませんか。 以上、よろしくお願いします。

  • VB.Net シリアル通信

    VB.Net 2010/W.7でシリアル通信のプログラムを作成しました。 デバック状態では正常に動作しました。又、Debugフォルダー内に出来た.exeファイルでも正常に動作しました。 この.exeをVB.Netの外にコピーして実行させようとした所、"アプリケーションのコンポーネントで、ハンドルされていない例外が発生しました。「続行」をクリックすると、アプリケーションはこのエラーを無視し、続行しようとします。「終了」をクリックすると、アプリケーションは直ちに終了します。 ポート'Com1'は存在しません。 とのメッセージが出てしまいました。 RS-232cの部分を外して実行させると正常に動作する様です。 これは無料版を使用している為の制限なのでしょうか、それとも何かをインクルードする必要があるのでしょうか。 同様に System.IO.Directory.CreateDirectory(sCurDir & "Log") でディレクトリーを作成出来ない様です。Debugフォルダーの中ではディレクトリーは作成されて居ました。 手動でディレクトリーを作成すると、その中にファイルは書けるみたいです。 お分かりに成る方が居られましたらお教え下さい。 宜しくお願い致します。

  • (VC++)シリアル通信について

    OS:Windows7 開発環境:VisualStudio2010 言語:C++ 機器:カードリーダ 接続:RS-232C VisualStudio2010にて、シリアル通信を行うプログラムを作成しています。 VisualStudioのヘルプや、いくつかのWebページを参考に、送信を行うところまではできています。 しかし、受信ができているのか、もしくは受信した内容が表示できていないのか分かりませんが、受信が確認できません。 送信はカードリーダが動くので分かりやすいのですが、受信は表示できないと確認できないためこのような状態です。 カードリーダの仕様は、あるASCIIコードを送るとカードが送られ、エラーステイタスコードが返ってきます。正常にカードが送られた場合は、またASCIIコードを送ると、読み取ったカードの情報がでてきます。(シリアル通信をテストするプログラムでは送信受信共に成功しています。) (送信)は、こちらが送ったもので、それ以外は受信した結果です。 ---------------以下その時の結果--------------- 3f 0d (送信) 30 10 45 30 31 32 30 30 38 0d (送信) 32 0d 33 59 0d 30 0d 31 59 0d 32 59 0d 33 0d 30 0d 31 0d ---------------------------------------------- C++のプログラムは以下の様になっています。 上記の結果でいうと、3f、0dを送り30を受け取るというところです。3f、0dでカードが送られ、30(正常終了)という結果を受け取ります。この結果をテキストボックスに表示したいと考えています。現在は、カードは送られるものの、30(もしくは他のエラーステイタスコード)という結果を表示することができません。 private: System::Void button_start_Click(System::Object^ sender, System::EventArgs^ e) {  serialPort1->Open();  serialPort1->Write(x3f); //defineにて定義(中身は?[0x3f])  serialPort1->Write(x0d); //defineにて定義(中身はCR[0x0d])  serialPort1->Close(); } delegate void SerialDataRecievedDelegate(String^ recvData); private: void SerialDataRecieved(String^ recvData) {  textBox1->Text = recvData; //確認するためにtextBox1に結果を表示 } private: System::Void serialPort1_DataReceived(System::Object^ sender, System::IO::Ports::SerialDataReceivedEventArgs^ e) {  SerialDataRecievedDelegate^ dlgte = gcnew SerialDataRecievedDelegate( this, &CardReader::Form1::SerialDataRecieved );  String^ RecievedData = serialPort1->ReadExisting();  //1バイトずつ受信  if(serialPort1->IsOpen == true) //シリアルポートが開いているか確認  {   COMRevieveBuffer = COMRevieveBuffer + RecievedData; //受信バッファに追加   if(RecievedData == "\r" ) //改行コード検出   {    RecievedData = RecievedData + "\n";    COMRevieveBuffer = COMRevieveBuffer + RecievedData;    //受信した一行をテキストボックスに転送    this->Invoke(dlgte, COMRevieveBuffer);    COMRevieveBuffer = "";   }   //エコーを返す   serialPort1->Write(RecievedData);  } } C言語でのプログラム作成はしていたのですが、VisualStudioやC++でのプログラム作成は初めてです。 ソースに変な点が多々あるとは思います。 ご教授お願いします。

  • 2進数でのシリアル通信

    シリアルを用いてデータを伝送するプログラムを作りたいのですが、よく分かりません。 10進数では出来たのですが2進数に変換する際に上手く行きません。 シリアル通信のプログラムとして以下を使用しています。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <termios.h> #include <fcntl.h> #include <errno.h> #define BAUDRATE B9600 //hentyou-kaisu per second #define BSIZE 64 //byte size #define CR 0x0D // carriage return int fd; //file descriptor 0:H-nyuryoku,1:H-syuturyoku,2;error struct termios otio; int open_serial_port(char *modem_dev) //modem_dev = serial_dev { struct termios ntio; if ((fd = open(modem_dev, O_RDWR | O_NOCTTY)) < 0) { // O_RDWR=read&write O_NOCTTY= perror(modem_dev); exit (1); } tcgetattr(fd, &otio); //tanmatsu-no-now-settei-syutoku memset(&ntio, 0, sizeof(ntio)); ntio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD; ntio.c_cc[VTIME] = 0; //burst-de-datadenso-wo-timeout-surutameno-timer ntio.c_cc[VMIN] = 1; //jyusin-moji-no-min tcflush(fd, TCIFLUSH); // not read data-wo flash tcsetattr(fd, TCSANOW, &ntio); //new-tanmatsu-settei-watasu return (0); } void close_serial_port(void) { tcsetattr(fd, TCSANOW, &otio); //motono-settei-ni-modosu close(fd); } int main(int argc, char **argv) { char *serial_dev; // char buf[BSIZE]; //data-wo-kakikomu-buffa-no-top-address char *buf = (char *)malloc(sizeof(char)*64); char msg[BSIZE]; int i,j; j=0; if (argc != 2) { fprintf(stderr, "usage : %s serial_dev\n", argv[0]); exit (1); } serial_dev = argv[1]; //device to write e.g. /dev/ttyUSB0 memset(buf, '\0', BSIZE); //m byte memory block no set \0=char-gatano-0 memset(msg, '\0', BSIZE); //syokika open_serial_port(serial_dev); i = 0; while (1) { //infinite loop sprintf(buf, "%d,", i); //printf-wo-buf-ni j = strlen(buf); write(fd, buf, j); //write to modem-device printf("%s\n", buf); sleep (2); //read(fd, msg, BSIZE); //printf("%s\n", msg); i++; if (i >= 10) i = 0; } close_serial_port(); free(buf); exit (0); } 2進数変換プログラムは、 #include <stdio.h> #include <stdlib.h> int main(void) { int i, n; int bits[1024]; int digit, amari; printf("10進数: "); scanf("%d", &digit); n=0; while(digit>=1){ amari = digit % 2; /* 配列変数に順番に代入して */ bits[n++] = amari; digit = digit / 2; } /* 逆順に表示している */ for(i=n-1; i>=0; i--){ printf("%d", bits[i]); } printf("\n"); return 0; } この両者をつなぎ合わせたいのですが、どうすればよろしいでしょうか。

  • StatusStripの表示が更新されない?

    いつもココにはお世話になっております。 またよろしくお願いします。 VB.net(Visual Studio Express)を使用しています。 OSはWin7 64Bitです。 Form1にStatusStrip(名前:stsStrip1)を配置してその中にStatusLabel(名前:stsbarLabel1)がある普通のステータスバーがあります。 以下の様な処理をしているのですが、存在しないシリアルポートを設定するとWrite(sndData)で8秒間止まりますが、その間”処理中”が表示されないことが有ります。(1~2秒経って表示されることもある) どうも、IO処理で待ちの状態になるとステータスバーの表示がうまく更新されないようなのです。 (UDP通信の時も同じ現象でした) StatusStripの表示を即座に更新させるようなことは出来ないものでしょうか? よろしくご享受願います。 '======================================================= stsbarLabel1.Text="処理中" Try    SerialPort1.PortName = "COM6"    '存在しないポートを設定    SerialPort1.WriteTimeout = 8000    'タイムアウト8秒    SerialPort1.Open()    SerialPort1.Write(sndData)        '送信    SerialPort1.Close() Catch ex As Exception    エラー処理 End Try     stsbarLabel1.Text="" '=======================================================

  • VB2010Eで作成したプログラムの終了コード

    こんばんは、VB2010Eを使ってプログラミングをしています。 私のプログラミングのスキルは初心者(上・中・下で言うなら、下の中くらい;)です。 なのでお手柔らかにお願いします<(_ _)> 作っているプログラムに終了ボタンを作ったのですが、クリックイベントのコードに 『Close()』と『Application.Exit()』のどちらを書くべきでしょうか? 用途は、自作のプログラムを普通に終了させたいです。 (ウィンドウの右上角の[×]ボタンの様に普通に…) 出来れば、『Close()』と『Application.Exit()』の違い等も教えて下さい。

  • シリアルポートから送られてくる文字の指定方法

    現在VB2010で作成中のアプリと測定器のデーターをシリアル通信で記録採取したと考えています。 測定機からの通信が下記の通りにPCに送られてきますが、必要な部分の採取す方法が分かりませんので教えてください。 ハイパーターミナルでの測定器からの文字受信は12文字送られてきます。 VBで作成中のアプリでは5文字目から9文字目のみをテキストに表示したいと思いますが、分かる方教えてください。現在制作中のソースも一部表示しますので、よろしくお願いします。今年から勉強してる、初心者です。 Delegate Sub AddDataDelegate(ByVal str As String) Private Sub AddData(ByVal str As String) '受信データー表示' If SerialPort1.IsOpen = False Then 'シリアルポートをオープンしていないときは、処理しない Return End If '受信データー読み込み Dim data As String data = SerialPort1.ReadExisting()    上記のソースが受信するようにしていますが、受信データーは1s毎に更新されておりますその都度テキストへ表示するようにしたいと思います。データーが更新されても、数値は残るようにしたいと思います。

  • 'Button1を押したらポートオープン

    'Button1を押したらポートオープン Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 'シリアルポートを設定。 SerialPort1.PortName = SerialPortComboBox.Text SerialPort1.BaudRate = SerialBpsComboBox.Text Select Case SerialParityComboBox.Text Form3.SerialPort1.Parity = IO.Ports.Parity.None 'データ長 SerialPort1.DataBits = SerialDataBitsComboBox.Text 'RTSラインを有効にする SerialPort1.RtsEnable = True '送信タイムアウト SerialPort1.WriteTimeout = 3000 Try 'ポートをオープン SerialPort1.Open() 'いざ送信 'SerialPort1.Write(Chr(&HC)) 'ケーブルが外れた場合などのタイムアウトエラーなら、 Catch ex As Exception MsgBox(ex.Message, MsgBoxStyle.Critical, "シリアル通信エラー") SerialPort1.Close() Exit Sub End Try '送信バッファが空になるまで待って、 While SerialPort1.BytesToWrite > 0 My.Application.DoEvents() End While ''''''''''''文字送信 'シリアルポート送信データをSJISに指定 SerialPort1.Encoding = System.Text.Encoding.GetEncoding(932) Dim Settei As String '送信文字代入 Settei = "A.1=" & vbCrLf 'いざ送信 SerialPort1.Write(Settei) '送信バッファが空になるまで待って、 While SerialPort1.BytesToWrite > 0 My.Application.DoEvents() End While End Sub '文字受信 Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived Dim strDataReceived As String Dim add As New AddDataDelegate(AddressOf AddData) Try strDataReceived = SerialPort1.ReadLine Catch ex As Exception strDataReceived = ex.Message End Try TextBox1.Invoke(add, strDataReceived) End Sub ///////// 文字を送信した後に相手から帰ってきます。 送信した後の受信の部分ですが、これで正しいか教えて頂きたいです。