前提・実現したいこと
RS485通信を用いてインバータの制御を行うプログラムを開発しております。
発生している問題・エラーメッセージ
エラーではないのですが、18行目CreateFileにてhComに値を入力しますと、
hCom=0xffffffff でINVALID_HANDLE_VALUEとなります。
20行目のIf文以降に進めません。
該当のソースコード
Visual C++(Visual Studio 2019)
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <windows.h> #include <tchar.h> using namespace std; int main(int) { HANDLE hCom; // 通信ハンドル DCB hDcb; // 通信設定用の構造体 COMMTIMEOUTS hTim; // タイムアウト設定用の構造体 char szTx[0x10]; // 送信バッファ char szRx[0x10]; // 受信バッファ char szCommand[0x10];// コマンド DWORD nTx, nRx; // バッファサイズ格納用 int nSum; // サムコード計算用 BOOL bRet; int nRet; unsigned int i; //?????COM4ポートをオープンする ???? hCom = CreateFile(L"\\.\COM4", (GENERIC_READ | GENERIC_WRITE), 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); void error_dialog(HWND hWnd) { DWORD errorcode = GetLastError(); LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER // テキストのメモリ割り当てを要求する | FORMAT_MESSAGE_FROM_SYSTEM // エラーメッセージはWindowsが用意しているものを使用 | FORMAT_MESSAGE_IGNORE_INSERTS,// 次の引数を無視してエラーコードに対するエラーメッセージを作成する NULL, errorcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),// 言語を指定 (LPTSTR)&lpMsgBuf, // メッセージテキストが保存されるバッファへのポインタ 0, NULL); MessageBox(hWnd, (LPCTSTR)lpMsgBuf, _TEXT("エラー"), MB_OK | MB_ICONINFORMATION); LocalFree(lpMsgBuf); }; if (hCom != INVALID_HANDLE_VALUE) { //???? COM4ポートの通信設定をする ???? GetCommState(hCom, &hDcb); // 現在の通信情報を取得 hDcb.DCBlength = sizeof(DCB); // 構造体サイズ設定 hDcb.BaudRate = 19200; // 通信速度=19200bps hDcb.ByteSize = 8; // データ長=8bit hDcb.Parity = 2; // 偶数パリティ hDcb.StopBits = 2; // ストップビット=2bit bRet = SetCommState(hCom, &hDcb); // 変更した通信情報の設定 if (bRet == TRUE) { //???? COM1ポートのタイムアウト設定をする ???? GetCommTimeouts(hCom, &hTim); // 現状のタイムアウト値取得 hTim.WriteTotalTimeoutConstant = 1000; // 書込みタイムアウト1秒 hTim.ReadTotalTimeoutConstant = 1000; // 読込みタイムアウト1秒 SetCommTimeouts(hCom, &hTim); // 変更したタイムアウト値設定 //???? 局番1のインバータをネットワーク運転モードに切り換えるコマンドを設定 ???? sprintf(szCommand, "00FB10000"); // 送信データ(NET運転書込み) nTx = strlen(szCommand); // 送信データサイズ //???? サムコードを生成する ???? nSum = 0; // サムデータ初期化 for (i = 0; i < nTx; i++) { nSum += szCommand[i]; // サムコードを計算 nSum &= (0xff); // データをマスク } //???? 送信データを生成する ???? memset(szTx, 0, sizeof(szTx)); // 送信バッファ初期化 memset(szRx, 0, sizeof(szRx)); // 受信バッファ初期化 sprintf(szTx, "\5%s%02X", szCommand, nSum);// ENQコード+送信データ+サムコード nTx = 1 + nTx + 2; // ENQコード数+送信データ数+サムコード数 nRet = WriteFile(hCom, szTx, nTx, &nTx, NULL); //???? 送信 ???? if (nRet != 0) { nRet = ReadFile(hCom, szRx, sizeof(szRx), &nRx, NULL); //???? 受信 ???? if (nRet != 0) { //???? 受信データを表示する ???? for (i = 0; i < nRx; i++) { printf("%02X ", (BYTE)szRx[i]);// 受信データをコンソール出力 // アスキーコードを16進数で表示します。'0'の場合30と表示します。 } printf("\n\r"); } } } CloseHandle(hCom); // 通信ポートを閉じる } }
試したこと
https://stackoverrun.com/ja/q/3960970 を参照して
「COM4」を「.\COM4」という表記にしてみました。
エスケープシーケンスとして正しく認識されませんでした。
おわかりの方がいらっしゃいましたらお教えください。
まずはCOM4ってちゃんとあるのかを確認しよう
CreateFile() 実行直後、GetLastError()APIでエラーコードを確認してください。ほとんどはそれで原因が分かります。
こういう場合はまず、APIリファレンスを確認しましょう。
CreateFile https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
> if the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.
y_waiwai様
早速の回答を頂きましてありがとうございます。COM4はデバイスマネージャにて確認をしております。
dodox86様 回答を頂きましてありがとうございました。void error_dialog(HWND hWnd)を追加してcodeを変更しましたが、「'error_dialog': ローカル関数の定義が正しくありません。」というエラーが発生しております。下記のサイトを参考にしました。
http://yamatyuu.net/computer/program/sdk/base/errmsg1/index.html
>yasu2711 さん
C言語にまだ不慣れでしたでしょうか。「ローカル関数の定義が...」というコンパイルエラーは定義の仕方が間違っていたのだと思います。error_dialog関数を自作するまでもなく、例えばDWORD err = GetLastError(); としてerrの値を確認すればよい、というお話でした。問題は解決されたようなのでもうよいと思います。
C++始めたばかりです。今後のためにもGetLastError()についてマスターをしたいと思います。ありがとうございます。
回答2件
あなたの回答
tips
プレビュー