
こんにちは、VC++初心者です。
現在、下記サイトのプログラムをもとにシリアル通信用プログラムを作成しています。
http://www.takebay.net/~daigo-ao/paddlewiki.pl/t …
例えば、editboxに02 31 32 33 03と入力したら、0x02 0x31 0x32 0x33 0x03として送信するところまではできました。
ただし、00と入力したとき、0x00として送信することができません。
どうすれば0x00を送信できるか、ご教授お願いいたします。
m_editSend.GetWindowText()にて入手したstrSendのデータから、SPACEを除いて、
0xをつけてhexにしてから、Send()にて送信しています。
void CSerial2Dlg::OnBnClickedButtonSend()
{
CString strSend;
CString strSendCMD;
CString bw;
int i, n, i2;
unsigned int hex;
m_editSend.GetWindowText(strSend); // ポート名を取得
char *buff = new char[strSend.GetLength()+1];
if(strSend.GetLength() == 0 || strSend == " "){ //送るものが無ければ終了
AfxMessageBox("送信するコマンドがありません。");
}
else{
strcpy(buff, strSend); //editboxのデータをbuff[]へコピー
i = 0;
n = 0;
bw = "\0";
while (buff[i] != '\n'){
if( buff[i] == ' ' || buff[i] == ':' || buff[i] == ',')//SPEACEorコロンorカンマをSKIPして送信する。
else{
bw += buff[i];//2文字ためる
n++;
}
if(n == 2){
sscanf(bw, "%x", &hex); //bwに2文字溜まったら、hexに変換
strSendCMD += hex;
bw = "\0"; //変換が終わったらClear
n = 0; //カウントもリセット
}
i++;
}
m_serial->Send(strSendCMD, strlen(strSendCMD));
}
delete [] buff ; //bufferの開放
}
下記のプログラムで、 WriteFileにて送信しています。
void CSerialCommunication::Send(LPCSTR str, DWORD strLength)
{
if (m_hComm == NULL) {
AfxMessageBox("COMポートが開かれていません");
return;
}
// ** 送信! **
DWORD dwWrite; // COMポートに送ったバイト数
WriteFile(m_hComm, str, strLength, &dwWrite, NULL);
}
No.3ベストアンサー
- 回答日時:
>普通、皆さんはシリアル通信の際、どのように変数使用していらっしゃるのでしょうか。
すでに回答にありますが、「文字列」が「NULL(0x00)終端」であることが問題の為、CString型は使えません。
char型配列のように内容に限らず(バイナリー)データとして扱える型を使用します。
質問のソースでは、
・2桁の文字列を数値(バイナリー値)に変化する処理(sprinfのあたり)
・Send()の引数の型の変更
を行えば対処可能です。
No.4
- 回答日時:
>普通、皆さんはシリアル通信の際、どのように変数使用していらっしゃるのでしょうか。
通常は固定電文を仕様化した上で通信を行うので、大概は構造体をごそっと送る方が多いですね。
ただ、質問されたようなケースでは(もちろん動的なエリア確保をする手もありますが…)、手っ取り早く全文字コードを送信する為には、変数「hex」(sscanfにて取得したデータ)を1文字ずつ送る手もありますね。
例:
---------------
char send[2]={0,0}; // 変数追加
// 中略
if(n == 2){
sscanf(bw, "%x", &hex); //bwに2文字溜まったら、hexに変換
send[0] = (char) hex;
m_serial->Send(send,1); // ここで1バイト送ってしまう
bw = "\0"; //変換が終わったらClear
n = 0; //カウントもリセット
}
// 後略
---------------
ご丁寧な説明ありがとうございます。
固定電文を仕様化してプログラムを作成したいところですが、
汎用性を持たせるために、あえてeditboxにいちいち電文を入れる様式でやっております。
char型でないと0x00は送信できないということも理解できました。
ご教示いただいた方法で挑戦してみます。
アドバイスありがとうございました。
No.2
- 回答日時:
「CSerialCommunication::Send」はご自分で作られた関数ですので、このままでOKだと思います。
それよりも問題はCStringを使用している事にあります。
0x00(NULL)は文字列の終端として扱われますので、いくらCStringに追加しても文字数としては増えません。
例:
---------------
CString strText;
strText += '1';
strText += '2';
strText += '3';
strText += (char)0x00;
strText += (char)0x00;
strText += (char)0x00;
ASSERT(strText.GetLength() == 3); // 3が返る
---------------
文字コードを全て送りたい場合にはCString以外の変数を使う事をお勧めします。
ご回答ありがとうございます。
普通、皆さんはシリアル通信の際、どのように変数使用していらっしゃるのでしょうか。
データ通信をするのに、0x00が遅れないんでは制御すらできないので、なんとかプログラムを作り上げたいのですが。
お知恵を拝借できれば幸いです。
No.1
- 回答日時:
「CSerialCommunication::Send()」は文字列を送信する関数です。
0x00は文字ではない為,送信できません。
送信するデータに0x00が含まれている場合はその時点で文字列終端(\0)と同じ意味になります。
どうしても文字ではない,0x00を送信するのであればバイナリデータを送信する関数をクラスに追加するか,別途バイナリ送信に対応したシリアル通信用プログラムを用意するしかありません。また,メインソースのstrSendCMDもバイナリデータが扱える配列に変更する必要があります。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
文字コードによる表記
-
アルファベットの出て来た回数
-
sprintf関数での文字列変換につ...
-
%dなどの違い
-
WSH(VBS)でJSONの文字列を読み...
-
TCL言語で文字列検索方法を教え...
-
シリアル通信で0x00を送信した...
-
int型での文字列の扱いについて
-
配列を使わずに、変数名を動的...
-
C# DataGridView のヘッダーセ...
-
Integer変数をカラにしたいので...
-
Excelですべての組合せ(重複組...
-
ExcelVBAでのkernel32(64bit)
-
isalpha()関数について
-
Run-Time Check Failure #3とい...
-
allocってなんですか?
-
define で 配列
-
CStringからchar*への型変換に...
-
C言語 配列の長さの上限
-
「#undef」と「#define」の使い...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
nullと""、\\0とEOFの違いにつ...
-
C#でstringをポインタとして渡す
-
TCL言語で文字列検索方法を教え...
-
シリアル通信で0x00を送信した...
-
C++で入力した文字列から数字を...
-
16進数を2文字ずつ配列に格納し...
-
プログラムによく出てくるst...
-
WSH(VBS)でJSONの文字列を読み...
-
_tcscpy_s(wcscpy_s)の第二引数...
-
%dなどの違い
-
VBA-DLLの引数受け渡しについて
-
C言語の問題です。
-
c#で他のアプリの文字入力フォ...
-
構造体→文字列→構造体 をする方法
-
int型での文字列の扱いについて
-
[C++]WCHARの1文字目しか表示で...
-
char a[]="thank you for comin...
-
VB6.0でのバイナリデータの扱い...
-
Excelシートを固定長のテキスト...
-
C#のGUIからサーバー側のPHPへ...
おすすめ情報