Visual C++ 6.0(MFC)でプログラミングを行っています.

VB 6.0でPCから値を入力し,PICへRS232Cケーブルを用いて値を送り,モータコントロールするプログラムは既に存在しており,現在はVBで書かれていた部分(インターフェイス部)をVC++に書き換えようとしています.

サンプルプログラムを参考にシリアル通信に関するVC++のプログラムは完成し,PCからモータの制御を行おうと思ったのですが,うまくいきません.

こういった際,どこに問題があるのかを検証したいのですがどうすればいいでしょうか?

現状,
1,シリアル通信ができていない
2,シリアル通信はできているが,PICへ値がうまく格納されていない
3,それ以外

問題があるのは分かるのですが,プログラマーのほうに原因がフィードバックされないため困っています.

明確な答えでなくても,アドバイスのようなものがいただけたら幸いです.

このQ&Aに関連する最新のQ&A

A 回答 (5件)

まず、シリアル通信が正しく動作しているかどうか確認してみましょう。


動作を確認するには次のような方法があります。

○ループバックテスト
 まずはPC側のプログラムが正しく動作しているか確認します。
1.PIC側のRS-232Cケーブルを抜いて、TXDとRXDを短絡します。
2.続いてPC側のプログラムから適当なデータを送信します。
3.送信したものと同じデータを受信できれば、PC側のシリアル通信が正しく動作していると言えます。
(参考)http://whzat.dyns.net/shoko3/USB-Serial_Bridge/i …
 上記URLにある「自己診断プラグ」を作っておくと便利です。

○エコーバックテスト
 続いて、PIC側のプログラムがデータを正しく受信できているか確認します。
1.PIC側では、シリアル通信で受信したデータをそのまま送信するプログラムを用意し、PCとPICを通信ケーブルで接続します。
2.ループバックテストをクリアしたPC側プログラムから適当なデータを送信します。
3.送信したものと同じデータを受信できれば、PIC側で正しくデータを受信できていることが確認できます。

> 1,シリアル通信ができていない
> 2,シリアル通信はできているが,PICへ値がうまく格納されていない
> 3,それ以外

ループバックテストとエコーバックテストで、上記の1、2まで確認できますが、3については非常に高い確率でPIC側のプログラムに問題でしょう。

ところで、モータと言っているのはDCモータですか、それともRC用サーボモータ?

この回答への補足

DCモータです.モータコントロールに関するプログラム及び回路は業者によるものなので問題はありません.

補足日時:2009/05/29 10:57
    • good
    • 0
この回答へのお礼

ありがとうございます.検証方法が全く思いつかなかったため,ループバックテスト,エコーバックテストを行い検証していこうと思います.他の皆さんもありがとうございました.

お礼日時:2009/05/29 12:29

 オシロでTXD端子に何かしらの波形が出る事を確認する。


 TXDは出力とは限らない。モデムのTXDは入力になります。
 それは電話回線に出て行く方向がTXDだからです。
 そのため、ケーブルにはストレートとクロスが有ります。
 それで、相手装置と電気的な入出力を確認します。

 RTS,CTS信号も確認します。これらを使わない方法も有りますが、使っているときはイネーブルにしないとハード的に通信できません。

 次に他のパソコンのハイパーターミナルで受信します。
 文字でないデータを見るには、次の方法を使います。
 ハイパーターミナルの「テキストのキャプチャ」を使えばファイルに書き込んでくれます。そのファイルをバイナリデータとしてエディタで見ます。

 ハイパーターミナルで、モータを制御してみます。長い命令だったら、「テキストファイルの送信」を使います。
この方法で動かなかったら、プログラムでいくら頑張っても動きません。
    • good
    • 0

No.2さんのようにプロトコル・アナライザーで解析するのが


常道であると考えます。
しかし、プロトコル・アナライザーが用意できない場合もあるでしょう。
そんな場合、
ハイパーターミナル等の端末で確認されることを
考えてみてはいかがでしょうか?
Vistaではハイパーターミナルがありませんので、
オンライン・ソフトで探されては如何でしょうか?

端末かモーターを操作できれば、VCアプリ側の問題ですし、
端末でも操作できなければ、(ケーブル等も含め)
ハード側の問題となります。

当然のことですが、
PCとPIC側でボーレート、パリティ等の設定が合致している必要があります。
念のため、確認なさってはいかがでしょうか?
    • good
    • 0

>プログラマーのほうに原因がフィードバックされないため困っています.


やることはNo.1氏の書いている通り、問題点の切り分けです。

可能であれば、PCとPICの間にプロトコルアナライザーを入れて通信データを確認します。
これで、「通信しているかどうか」「通信内容が正しいかどうか」は確認できます。
通信していなかったり、内容が間違っていればプログラムのほうが疑えますので、それぞれ使用しているモジュールのI/Fやデータやプロトコルの設定などが正しいか確認することになります。
    • good
    • 0

まったく動いてないのに完成したというのが不思議なんですけど、、、



デバッグのやり方って話なら、
1.原因の切り分け (インターフェース部分を観測し、どちらが間違っているか判定する)
2.原因になっているモジュールをデバッグする

しかないです。
ファンクションコールしている部分を担当してるなら、検証はハードウェアレベルでやるなり、リダイレクト出来るならリダイレクトするなりですね。

元々動いてるソフトがあるなら、それと全く同じ出力が得られていればいいわけですよね?
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qシリアル通信でのデータ受信

シリアル通信にてデータを連続的に受信するプログラムを
つくりたいと思っています.

以下のプログラムを作成して,
main関数のcountを増やして,繰り返しreadを行おうとすると,

出力結果として,
時,分,秒,ID,値B,値C,値Dというフォーマットで

0, 9,30, 1,514,708,542,290

0, 9,30, 2,515,707,542,288

0, 9,30, 3,514,709,542,287

0, 9,30, 4,514,707,543,289

0, 9,30, 5,514,708,542,289

0, 9,30, 6,514,708,542,292

0, 9,30, 7,514,708,542,291

0, 9,30, 8,514,708,542,289

0, 9,30, 9,514,708,543, 0, 9,39,35,514,708,542,289

(この後フが連続)
フフフフフフフフフフフフフフフ ク 0, 9,39,36,514,708,542,290

0, 9,39,37,515,709,541,291

0, 9,39,38,514,707,542,286

0, 9,39,39,514,708,542,281

0, 9,39,40,514,708,542,284

0, 9,39,41,514,707,542,286

0, 9,39,42,514,707,542,290

0, 9,39,43,514,709,542,290

0, 9,30, 9,514,708,543, 0, 9,39,35,514,708,542,289

フフフフフフフフフ・・・再びフ

となってしまいます.
問題としては

・フがたくさんでてきてしまう.
・1サイクルの最後で改行ができていない
・1サイクルが終わって次のサイクルに入る時までの
間にデータが失われている.
・2サイクル目になぜか1サイクル目の値が残っている?

などがあります.

どなたか解決方法を教えていただけると大変助かります.
よろしくお願いします.
-------------------------------
#include "stdafx.h"
#include <stdlib.h>
#include <windows.h>
#include <string.h>
#include <stdio.h>

#define COM_PORT_NAME"COM2"
#define BAUD_RATE57600
#define BYTE_SIZE5000 //250
#define PARITYNOPARITY //EVENPARITY
#define STOP_BITTRUE
#define F_PARITYONESTOPBIT

HANDLE hComm;// シリアルポートとの通信ハンドル

bool ComInit()
{
// シリアルポートを開ける
hComm = CreateFile(
COM_PORT_NAME,/* シリアルポートの文字列 */
GENERIC_READ | GENERIC_WRITE,
/* アクセスモード:読み書き */
0,/* 共有モード:他からはアクセス不可 */
NULL,/* セキュリティ属性:ハンドル継承せず */
OPEN_EXISTING,/* 作成フラグ: */
FILE_ATTRIBUTE_NORMAL,/* 属性: */
NULL/* テンプレートのハンドル: */
);

if (hComm == INVALID_HANDLE_VALUE) {
printf("シリアルポートを開くことが出来ませんでした。\n");
return false;
}

// 通信属性を設定する
DCB dcb;
GetCommState(hComm, &dcb); /* DCB を取得 */
dcb.BaudRate = BAUD_RATE;
dcb.ByteSize = BYTE_SIZE;
dcb.Parity = PARITY;
dcb.fParity = STOP_BIT;
dcb.StopBits = F_PARITY;
SetCommState(hComm, &dcb); /* DCB を設定 */

return true;
}

void ComEnd()
{
// ハンドルを閉じる
CloseHandle(hComm);
}


bool ReadData(char *buff, unsigned int max_size)
{
DWORD dwErrors; /* エラー情報 */
COMSTAT ComStat; /* デバイスの状態 */
DWORD dwCount; /* 受信データのバイト数 */
DWORD dwRead; /* ポートから読み出したバイト数 */

ClearCommError(hComm, &dwErrors, &ComStat);
dwCount = ComStat.cbInQue;

FILE *fid;
fid=fopen("test.txt", "w");

printf("%d %d\n", dwCount, max_size);
fprintf(fid,"%d %d\n", dwCount, max_size);

fclose(fid);
if (dwCount > max_size) {
printf("バッファサイズが足りません。\n");
return false;
}

if(hComm != NULL){
ReadFile(hComm, buff, dwCount, &dwRead, NULL);

if (dwCount != dwRead) {
printf("データの受け取りに失敗しました。\n");
return false;
}
}

return dwRead;
}

int main(int argc, char* argv[])
{

char buff[BYTE_SIZE];
int count = 0;
int data_length;
FILE *fid2;
fid2=fopen("test2.txt","w");

ComInit();

while(1){
if(count == 2) break;
count++;

data_length=ReadData(buff, strlen(buff));
printf("%s ",buff);
fprintf(fid2, "%s ",buff);


}
fclose(fid2);
ComEnd();

return 0;
}

シリアル通信にてデータを連続的に受信するプログラムを
つくりたいと思っています.

以下のプログラムを作成して,
main関数のcountを増やして,繰り返しreadを行おうとすると,

出力結果として,
時,分,秒,ID,値B,値C,値Dというフォーマットで

0, 9,30, 1,514,708,542,290

0, 9,30, 2,515,707,542,288

0, 9,30, 3,514,709,542,287

0, 9,30, 4,514,707,543,289

0, 9,30, 5,514,708,542,289

0, 9,30, 6,514,708,542,292

0, 9,30, 7,514,708,542,291

0, 9,30, 8,51...続きを読む

Aベストアンサー

先ほどの訂正と追加です。
3.dcb.Bytesizeを8にして、while文を無限ループにし
(countのif~break文を削除し), strlen(buff)のところを
BYTE_SIZEにしてみてください。データが取りこぼしなく
表示されませんか。
#通信が終わらないという問題は、受信ができない問題
とは別問題なので、今は考えていません
4.3.でデータの取りこぼしがあれば、送信側・受信側とも、
BaudRateを低く(9600bpsとか)してみて改善されるかどうか、
確認してください。

データの取りこぼしが通信速度によるものなら、フロー制御など
も考えないといけませんね。ところで、今頃聞くのもなんなんですが、
送信側・受信側は、どのような環境をお使いなんでしょう?

QC# シリアル通信でデータ受信時の欠損について

Visualstudio 2013 を使用して C# で開発を行っています。

SerialPort Classを使用してデータの送受信をするプログラムを作成しているのですが、
非同期でデータを受信する際にどうしてもうまくデータを取得出来ません。

5Byteのデータは正常に取得できるのですが、
その直後にくる40Byteのデータは、真ん中あたりの10数Byteや最後の10数Byteしか取れません。


serialPort.DataReceived に登録したイベント関数の中身です。

--------------------------------------------------------------------------------------
private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
bytesRead = 0;
// Initialize a buffer to hold the received data
byte[] buffer = new byte[this.serialPort.ReadBufferSize];

try
{
bytesRead = this.serialPort.Read(buffer, 0, buffer.Length);
if (true == serialPort.IsOpen)
{
serialPort.DiscardInBuffer();//受信バッファをクリアする
}

}
catch (Exception ex)
{
DataLog.Exception(ex);
}

//派生クラス用の処理
DeviceClassEventArgs _DeviceClassEventArgs = new DeviceClassEventArgs(buffer, bytesRead);
DeviceClassEvent(this, _DeviceClassEventArgs);
}
--------------------------------------------------------------------------------------

ネットの情報を参考に、
ReceivedBytesThreshold の値を期待するデータ量に逐一変えることで
とりあえず正常に取ることが出来たのですが、これでいいのでしょうか?
期待するデータ量がわからなかった場合は使えないのかなとも思います。

データが欠損してしまう理由、
上記の対処法以外の一般的な対処法など有りましたら教えて下さい。

その他参考になるページ等ありましたら教えていただけると大変助かります。

Visualstudio 2013 を使用して C# で開発を行っています。

SerialPort Classを使用してデータの送受信をするプログラムを作成しているのですが、
非同期でデータを受信する際にどうしてもうまくデータを取得出来ません。

5Byteのデータは正常に取得できるのですが、
その直後にくる40Byteのデータは、真ん中あたりの10数Byteや最後の10数Byteしか取れません。


serialPort.DataReceived に登録したイベント関数の中身です。

-------------------------------------------------------------------------------...続きを読む

Aベストアンサー

DataReceivedイベントが発生したときでも、
シリアルポートへの受信はまだ継続している可能性があるので
不用意にバッファクリアしてはいけない。
非同期の受信処理は、何かと難しいのです。

private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
  bytesRead = 0;
  // Initialize a buffer to hold the received data
  byte[] buffer = new byte[this.serialPort.ReadBufferSize];

  try
  {
    //bytesRead = this.serialPort.Read(buffer, 0, buffer.Length);
    //if (true == serialPort.IsOpen)
    //{
    // serialPort.DiscardInBuffer();//受信バッファをクリアする
    //}

    // 受信バッファにデータがなくなるまで繰り返し読込む
    while (true)
    {
      if (0 == serialPort.BytesToRead)
      {
        break;
      }
      buffer[bytesRead] = (byte)serialPort.ReadByte();
      bytesRead++;
      System.Threading.Thread.Sleep(0);

      // シリアルポートの受信バッファには、
      // ・必要なブロックの途中から受信している。
      // ・次のブロックの先頭部分も受信されている。
      // 可能性があるので、ここで必要なブロックだけRead()できたことを確認する。
      if (必要なブロックが正常に読めたか確認する関数())
      {
        break;
      }
    }
  }
  catch (Exception ex)
  {
    DataLog.Exception(ex);
  }

  //派生クラス用の処理
  DeviceClassEventArgs _DeviceClassEventArgs = new DeviceClassEventArgs(buffer, bytesRead);
  DeviceClassEvent(this, _DeviceClassEventArgs);
}

DataReceivedイベントが発生したときでも、
シリアルポートへの受信はまだ継続している可能性があるので
不用意にバッファクリアしてはいけない。
非同期の受信処理は、何かと難しいのです。

private void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
  bytesRead = 0;
  // Initialize a buffer to hold the received data
  byte[] buffer = new byte[this.serialPort.ReadBufferSize];

  try
  {
    //bytesRead = this.serialPort.Read(buffer, 0, buffer.Le...続きを読む

Qシリアル通信プログラム(受信)について

現在、シリアル通信をする(受信のみ)プログラムを作成しています。
接続先は1秒ごとに10バイトのデータを自動で送信してきます。
現段階でPC側でデータを受信できることは確認できました。
しかし、受信データが文字化け(出力結果が{や■などがでています)しており、その原因がわかりません。
どこが問題なのか教えていただけないでしょうか?

また、接続先からは10バイトのうち最初の2バイトは固定の値(0x2b,0x22)がでてくるはずなのですが、それもでてきていません。これも文字化けで見えていないだけでしょうか?
文字化けしても周期的に固定の値に対応した文字がでてくるものだと思ったのですが、でてきていません。
(ソースで50バイトまでみているのはこの周期性を確認するためです)

シリアル通信を初めてさわるので、考え方自体間違っているかもしれませんが
配列pszBufに1つずつ、受信された1バイトのデータが格納されていると思っています。
個人的にはprintfでの表記(%cがいけない?)に間違いがあるかと疑っています。

ご回答よろしくお願いいたします。

(環境)
Visual C++ 2008 (C/C++)

(シリアルポート設定)
ボーレート 9600bps
パリティ   なし
ストップビット 1
データビット 8

(ソース) ※ポートの設定は省略。受信部のみ記述
HANDLE hComm;
DWORD dwErrors;
COMSTAT ComStat;
char pszBuf[1024];
DWORD dwRead;

ClearCommError(hComm, &dwErrors, &ComStat);
ReadFile(hComm, pszBuf, 50, &dwRead, NULL);  //50バイトまでデータを取得

for(int i=0;i<50;i++){
printf("%c\n",pszBuf[i]);
}

(参考URL)
http://www.geocities.jp/terukat/_geo_contents_/win/comm.html

現在、シリアル通信をする(受信のみ)プログラムを作成しています。
接続先は1秒ごとに10バイトのデータを自動で送信してきます。
現段階でPC側でデータを受信できることは確認できました。
しかし、受信データが文字化け(出力結果が{や■などがでています)しており、その原因がわかりません。
どこが問題なのか教えていただけないでしょうか?

また、接続先からは10バイトのうち最初の2バイトは固定の値(0x2b,0x22)がでてくるはずなのですが、それもでてきていません。これも文字化けで見えていない...続きを読む

Aベストアンサー

>一応、ReadFileをおわったあとにdwReadを確認したのですが、50になっていました。

であれば、ReadFile()が失敗したとかはなさそうですね。
# ReadFile()の戻り値を確認していないのであればdwReadはReadFile()コール前にクリアしておいた方がいいかと思いますが。

>なんらかの失敗といわれるとどういった失敗がありえるのでしょうか?

タイムアウトがないのであれば…基本的には失敗はない…でしょうね。
コネクタ類が接触不良でデータが化けるとか、XON/XOFFフロー制御している…とかでなければ。

>(ボーレートの設定がおかしければデータがかわることはあるでしょうが・・・)

ボーレート以外の設定が異なっていた場合も化けると思われます。

>接続先がデータを送らなくとも、ReadFileがデータを格納することがあるのでしょうか?

受信バッファに残っていた場合は読み出す…でしょうね。

CreateFile()でシリアルポートを開く処理、シリアルポートの設定を行っている部分も掲示された方がいいかも知れません。
# が、私自身はAPI叩いてシリアルポート操作したことは無かったりします。

WindowsAPIのパターンとして…構造体は0x00でクリアして必要な部分だけ設定する。
という方法を採らないと妙な挙動することもありますので、その辺りは確認された方がいいでしょう。
APIに構造体のアドレスを渡して、情報を取得(上書きされる)から…ということで、未初期化の構造体渡したらエラーで何も設定してくれなかった。
なんて場合もあります。
# 構造体のメンバに「構造体のサイズ」を格納する場合、その構造体のサイズで対応バージョンを判別する。
# なんて挙動をしている場合もありますので。

>一応、ReadFileをおわったあとにdwReadを確認したのですが、50になっていました。

であれば、ReadFile()が失敗したとかはなさそうですね。
# ReadFile()の戻り値を確認していないのであればdwReadはReadFile()コール前にクリアしておいた方がいいかと思いますが。

>なんらかの失敗といわれるとどういった失敗がありえるのでしょうか?

タイムアウトがないのであれば…基本的には失敗はない…でしょうね。
コネクタ類が接触不良でデータが化けるとか、XON/XOFFフロー制御している…とかでなければ。

>(ボーレ...続きを読む

Qteratrermを使ったデータの送信について

teratermで
16進数で下記の5バイトを送信したいのですが、どうすればいいでしょうか。

\x85\x02\x00\x01\x86

VTウィンドウにキーボードで直接打ち込むと、一文字ごとに送信されているようで、うまく行きませんでした。

Aベストアンサー

送信したい文字列を書いたファイルを作成してください。

teratrerm メニューの「ファイル(F)」-「ファイル送信(S)」を選び、作成したファイルを選択してください。
このとき作成したファイルの内容がバイナリーの場合送信ファイル選択画面のオプションで「バイナリー(B)」にチェック入れてください。

>16進数で下記の5バイトを送信したいのですが、どうすればいいでしょうか。
たぶんバイナリーだとおもいますのでファイルはバイナリーエディターで作成してください。

注)これは日本語化したteratermでの説明です

QCOMポート通信をモニターしたい

現在、PCと組み込み系の端末との間でRS-232C通信をさせています。このRS-232C通信のTXとRXのデータのタイミングなどをモニターできるソフトはありませんでしょうか?

現在RS-232C通信をさせているのですが、組み込み系の端末側にはTCP-RS232C通信変換のモジュールを取り付けていて、PC側もTCP-RS232C変換させるソフトを使用しています。


TCP-RS232C通信変換のモジュールはWIZNET社製のWIZ110SRというのを使用しています。

PC側ではTCP-RS232C通信変換ソフトでWIZNET社製のWIZ VSPというソフトを使用して、TCPで受けたデータをRS-232Cに変換して受信プログラムソフトに転送しています。


このPC側の受信ソフトとTCPへ変換する間のCOMポートの通信をモニターできるようなソフトというものはありませんでしょうか?

どうぞ、ご教授頂きますようお願い致します。

Aベストアンサー

PC自体のCOMポート(USB-Serial変換でも)なら、ソフトでどうにかできる場合もあるでしょうが……

ご使用の機器の場合、PCからはネットワーク端末に見える…のではないでしょうか?
ドライバでCOMポートとして見えるのですか?
# 後者ならソフトで何とかできる…かも知れません。

こちらの組み込み系開発ではラインアイ社の機器を使用しています。
http://www.lineeye.co.jp/html/product_le2500.html
http://www.lineeye.co.jp/html/product_le3500.html
などですね。
http://www.lineeye.co.jp/html/product_LE-200PS.html
http://www.lineeye.co.jp/html/product_LE-150PS.html
でも用途によっては十分かも知れません。
# 組み込み開発に使うのであれば1台あった方が何かと便利です。
# それなりに高機能なので…値段も結構しますけどね。

Qバイナリデータとテキストデータの違いについて

宜しくお願いします。

バイナリデータを用語辞典で調べると
「テキスト形式(文字データ)以外のデータ形式全般のこと。
実行可能形式のコンピュータプログラムや、画像や音声、
動画などのデータなどがバイナリデータにあたる。」
(http://e-words.jp/w/E38390E382A4E3838AE383AA.html)
とあります。

これでは、バイナリデータとテキストデータの違いが分かりません。

テキストデータはコードの集まりで、
さらに細かくすると0と1の集まり(?)だから・・・
と考えるとバイナリデータとテキストデータの
違いが分かりません。

Q1.私は何が分かっていないのでしょうか?
Q2.バイナリデータとテキストデータの違いを教えてください。

宜しくお願い致します。

Aベストアンサー

バイナリデータは01の集まりです。
テキストデータは文字としての意味が与えられて居ます。ただテキストデータの01としての表現方法はプラットフォーム(OSやアプリケーション)によって異なります。例えば英文字コードでもメインフレームで使われるEBCDICもあり、unixやPCで使われるASCIIもあります。また日本語など英語以外の文字をあらわすのには、さらに多くの種類があります。また改行を表す文字もいろいろです。
例えば telnet で他のコンピュータにログオンして通信する時の文字コードはASCIIで、改行はCRLFと決まっているので、そうでないコンピュータはtelnetプログラムが自分のコンピュータのコード体系と相互変換します。

ftpでテキストデータを転送する時も同じくASCIIとCRLFと決まっています。ただ日本語文字の時にどのコードを使うかは規格では決まっていないので、ftpクライアントで、相手コンピュータの日本語コード種類を指定して、自分と合わなければ転送時に相互変換します。

Cプログラムでもテキストの改行は'\n'と決まっているので、そうでないWindowsの場合はCプログラムとの間でCRLFと'\n'の相互変換が、ライブラリ中で自動的に行われます。

そういった変換を全く行わないのがバイナリデータです。画像ファイルなどはjpegと形式が決まればどのコンピュータでも同じフォーマットなので変換の必要はありません。逆にテキストとみなして変換するとデータが壊れてしまいます。

バイナリデータは01の集まりです。
テキストデータは文字としての意味が与えられて居ます。ただテキストデータの01としての表現方法はプラットフォーム(OSやアプリケーション)によって異なります。例えば英文字コードでもメインフレームで使われるEBCDICもあり、unixやPCで使われるASCIIもあります。また日本語など英語以外の文字をあらわすのには、さらに多くの種類があります。また改行を表す文字もいろいろです。
例えば telnet で他のコンピュータにログオンして通信する時の文字コードはASCIIで、改行はCRL...続きを読む

QDWORDの実際の型は何でしょうか

VC++.NETの環境です。
DOWRD dw1 = 1;
int i = 2; と定義し
ここで
if ( i > dw1 ){
何かの処理;
}
とコーディングすると
warning C4018: '>' : signed と unsigned の数値を比較しようとしました。
のワーニングがでます。
これは、DWORDがint型でなくunsigned int型のようにも見えます。
ある本によれば(VC++.V.NET逆引き大全500の極意)
DWORD はint型であると記述されています。
もし、int型ならこのワーニングはでないはずなのですが、
なぜでるのでしょうか。又、DWORDの実際の型は何なのでしょうか。ご存じのかたおりましたら、教えていただけませんでしょうか。

Aベストアンサー

型定義が知りたいのならば、宣言ファイルを見れば疑問を挟む余地もありません。
DWORD型はwindef.hで
"typedef unsigned long DWORD;"
と宣言されています。

Visual Studioを使っているのならば、知りたい型の上にマウスポインタを置いて右クリック、ポップアップメニューの「定義へ移動」または「宣言へ移動」で簡単に知ることが出来ます。

QC言語とシリアル通信の送受信データの概念

C言語とシリアル通信の送受信データの概念

今シリアル通信で基盤上のデータを読み書きするツールを作っています。
基盤はまだ手元にないので、先にプログラムと、基盤の動作を模したプログラムを作るつもりです。
基盤の説明にはデータはバイナリで送るようにと書かれていたので、
文字列で1バイトずつ割り当てようと考えました。
しかし、どうやって1234などの数値を1バイトずつ割り振るのか、
バイナリって何だっけと調べているうちにわけが分からなくなってきました。

たとえば1234という10進数の数値を送りたいとき、
現状ではchar型の文字列"1234"を渡しています。
もしかしてこれは間違っていて、本当は

char s[] = { 1, 2, 3, 4 };
16進数の場合はabcdなら
char s[] = { 0xa, 0xb, 0xc, 0xd };
として渡すのが正しいのでしょうか。
これでprintfを使うと文字化けして何だかバイナリっぽいぞと感じましたが。

また、バイナリ以外ならどんな送り方があるのでしょう?

Aベストアンサー

まあ、それは、データ形式の名前を気にするより、単に BCD でと言うことですね。

こんな感じで変換できますね。
(データを変換するだけなので、最初に送る 0xa1 はつけていません)

あと、BCD だと、(単純なバイナリ送信と違って) 'A' ~ 'F' に相当するコードは出てきません。
なので、0xa1 のように、「BCD としては存在しない」データがコマンドなどに割り当たっているわけです。

#include <stdio.h>

unsigned char toBCD2(int v)
{
return ( (v / 10) * 0x10 + v % 10);
}

void longToBCD(long src, char bcd[], int keta)
{
int i;
for(i = 0; i < keta; i++) // 桁は、BCD の配列の個数(安直ですが)
{
int work = src % 100;
bcd[i] = toBCD2(work);
src /= 100;
}
}

int main()
{
int i;

char result[5];
longToBCD(0x00201e90, result, 5);
for (i = 0; i < 5; i++)
{
printf("%02X ", result[i]);
}

return 0;
}

まあ、それは、データ形式の名前を気にするより、単に BCD でと言うことですね。

こんな感じで変換できますね。
(データを変換するだけなので、最初に送る 0xa1 はつけていません)

あと、BCD だと、(単純なバイナリ送信と違って) 'A' ~ 'F' に相当するコードは出てきません。
なので、0xa1 のように、「BCD としては存在しない」データがコマンドなどに割り当たっているわけです。

#include <stdio.h>

unsigned char toBCD2(int v)
{
return ( (v / 10) * 0x10 + v % 10);
}

void longToBCD(long src,...続きを読む

Qシリアル通信RS-232C(D-SUB9ピン)のハードウェア良否判定

PCとある外部機器とをRS-232C(D-SUB9ピン)クロスケーブルで接続して送受信するのですが、うまく動きません。同じセッティングで別PCにするとうまく送受信してくれました。
そのため、RS-232Cがあやしいとは思っていますが、RS-232Cが壊れているかどうかを、もう少し具体的に1台のパソコンしかない時でも調べるためにループバックテストを行えば分かるのではないか?と思っているのですが今一具体的にやり方が分かりませんでした。

とりあえず、ケーブルは送信と受信の2ピンと3ピンを短絡すればいいのかな、と思っています。ソフトはRs232c.exeやComloopなどVecterのダウンロード<Windows<ハードウェア<通信関係 とかをみると色々ありましたが具体的にそれらのソフトをどのように使えばいいのか、よく分かりませんでした。

申し訳ないですが、分からないので、具体的に、○○ソフトを使用して、設定はこうして、ケーブルはこうしておいて、こうならなければハードが壊れている可能性がある、などの説明をお願いしたいのですが、お手数ですがよろしくお願いいたします。

PCとある外部機器とをRS-232C(D-SUB9ピン)クロスケーブルで接続して送受信するのですが、うまく動きません。同じセッティングで別PCにするとうまく送受信してくれました。
そのため、RS-232Cがあやしいとは思っていますが、RS-232Cが壊れているかどうかを、もう少し具体的に1台のパソコンしかない時でも調べるためにループバックテストを行えば分かるのではないか?と思っているのですが今一具体的にやり方が分かりませんでした。

とりあえず、ケーブルは送信と受信の2ピンと3ピンを短絡すればいいの...続きを読む

Aベストアンサー

シリアルポートを積んでいるパソコンだと、ターミナルソフトウエアを使うとRS-232Cでの通信が可能です。ターミナルソフトでは、下記が有名だと思います。
http://easylabo.com/2014/08/tool/3294/

Tera Termで、シリアルを選択し、"シリアルポート 設定" でCOMポート番号とボーレートやその他の設定を行い、"端末の設定" でパソコンのコンソールの設定を行います。

ループバックテストを行う場合は、コンソールに打ち込んだ文字と同じ文字が表示されると思います。基本的には、ここに載っている設定で大丈夫だと思いますが、COM*は実際のポート番号を指定、"端末の設定" では、ローカルエコーをチェックすると入力した文字がそのままコンソールに反映されます。ループバックがあると同じ文字が2回表示されます。

ハードウエア的には、仰る通り、RxDとTxDの短絡だけでも良いと思います(ハードウエアでのフロー制御無し)が、下記のような商品もあります。
http://www.area-powers.jp/denki/supply/4580127698756/index.html ← ソフトウエアが添付されているようです。
http://amazon.co.jp/dp/B00FMQZBMO ← ¥1,400 これを買ってしまったほうが早い気がします(笑)。

ただ、自分でTera Termを使ったのはかなり昔で、しかも、手元にはそれを検証する環境がありません。記憶を掘り起こしての話なので、細かい部分は忘れてしまいました。自作の場合は、不明であっても、ご自分で試してもらわないとなりません。

まあ、それ程難しいことはなかったと思います。

シリアルポートを積んでいるパソコンだと、ターミナルソフトウエアを使うとRS-232Cでの通信が可能です。ターミナルソフトでは、下記が有名だと思います。
http://easylabo.com/2014/08/tool/3294/

Tera Termで、シリアルを選択し、"シリアルポート 設定" でCOMポート番号とボーレートやその他の設定を行い、"端末の設定" でパソコンのコンソールの設定を行います。

ループバックテストを行う場合は、コンソールに打ち込んだ文字と同じ文字が表示されると思います。基本的には、ここに載っている設定で大丈夫だと...続きを読む

Qソケット通信内 read関数について

現在C言語にソケット通信を作成しているのですが、read関数内の作成でつまずいています。
ご存知でしたら教えてください。

自分なりに調べた結果read関数の戻り値は受信した
バイト数、毎回指定サイズ受け取るとは限らないと
いうことでした。

そこでread関数を無限ループで回し
指定サイズ受信したら、ループを抜ける使用にしたのですが、受信バイトが0だった場合はどうすればよいのでしょか?
よくサンプルなどでは、0だったらエラーと判断し、すかさずbreakしているのですが、一度でも0バイトを受信すると、それ以降は1バイト以上受信出来ないものなのでしょうか?
もし出来ないのなら一度でも0を受信したら、breakしようと思っています。
出来るのでしたら、タイマー設定をし、指定受信バイトに満たなくても一定時間が過ぎたらループから抜ける使用にしたいと考えています。
そのほか良い方法があれば教えてください。

分かりずらい説明になってしまいましたが、宜しくお願い致します。

Aベストアンサー

selectの戻り値が1となったのならば一歩前進です。
あとは、FD_ISSET()して期待通りのソケット番号にデータきていれば受信できると思います。

ところで今回のソースでFD_SET()のところはどうなっていますか?
selectでいつも0となるのはFD_SETがちゃんとできていないような気がします。
前回と今回のソースで差分をチェックしてみてはどうでしょうか。

がんばってください!


あと、ほかに参考になりそうなページをのせてみます。
「selectを使う」の項目が役立ちそうです。fdという変数にaccept()した戻り値を入れるようにすればいけます。

参考URL:http://www.ops.dti.ne.jp/~allergy/socket/socket.html


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報