Arduino 和 Windows 串行通信问题?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8190782/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 18:30:03  来源:igfitidea点击:

Arduino and Windows serial communications issue?

cwindowsvisual-studio-2010serial-portarduino

提问by richie za

I am working on a project that involves some 'c' serial communication implemented in Visual Studio 2010 Proffesional on a Windows 7 32-bit platform connected to an Arduino Mega device (to control some hardware **not relevant to problem). The code for this works 100%; the ONLY problem I'm having is that something very funny is going on with my serial communication.

我正在从事一个项目,该项目涉及在连接到 Arduino Mega 设备的 Windows 7 32 位平台上的 Visual Studio 2010 Proffesional 中实现的一些“c”串行通信(以控制一些与问题无关的硬件)。此代码 100% 有效;我遇到的唯一问题是我的串行通信发生了一些非常有趣的事情。

The Visual C program is as follows.

Visual C 程序如下。

HANDLE hDevice = CreateFile(L"COM5",
                            GENERIC_READ | GENERIC_WRITE,
                            FILE_SHARE_READ | FILE_SHARE_WRITE,
                            NULL,
                            OPEN_EXISTING,
                            0,
                            0); //Open COM handle (create file)
if (hDevice !=INVALID_HANDLE_VALUE) //If COM3 connected
{
    printf("Com port opened\n");
    DCB lpTest;
    GetCommState(hDevice,&lpTest);
    lpTest.BaudRate = CBR_9600;
    lpTest.ByteSize = 8;
    lpTest.Parity = NOPARITY;
    lpTest.StopBits = ONESTOPBIT;
    SetCommState(hDevice,&lpTest);
    DWORD btsIO;
    WriteFile(hDevice,c1,strlen(c1),&btsIO,NULL);
    CloseHandle(hDevice);
}

The output of this program is a text string, and I'm 100% happy with it (should end in Null, have x characters, etc.).

这个程序的输出是一个文本字符串,我对它 100% 满意(应该以 Null 结尾,有 x 个字符等)。

Typing the result obtained from this program in Serial Communicator, it does not seem to work! Using a COM spy program, I am able to obtain the "handshaking" protocols from the terminal application.

在Serial Communicator中输入这个程序得到的结果,好像不行!使用 COM 间谍程序,我能够从终端应用程序获取“握手”协议。

However, it seems that communication with the Arduino board works on HyperTerminal and not on Serial Communicator or any other serial applications (no handshaking, etc. is done on the Arduino board **not relevant).

然而,似乎与 Arduino 板的通信在超级终端上工作,而不是在串行通信器或任何其他串行应用程序上(在 Arduino 板上不进行握手等**不相关)。

The following "handshaking" was obtained from HyperTerminal (THIS WORKS!!)

以下“握手”是从超级终端获得的(这个工作!!)

*
COM port is opened
In/out queue size 8192/8192
Baud rate 9600
DTR on
Data bits=8, Stop bits=1, Parity=None
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(DTR_CONTROL, CTS_HANDSHAKE, ERROR_ABORT), FlowReplace=    (TRANSMIT_TOGGLE, RTS_HANDSHAKE, XOFF_CONTINUE), XonLimit=80, XoffLimit=200
Set timeouts: ReadInterval=10, ReadTotalTimeoutMultiplier=0, ReadTotalTimeoutConstant=0,     WriteTotalTimeoutMultiplier=0,     WriteTotalTimeoutConstant=5000
*

And this is from Serial Communicator (it does not work; incorrect and inconsistent numbers):

这是来自 Serial Communicator(它不起作用;不正确和不一致的数字):

*
COM port is opened
In/out queue size 2048/2048
Baud rate 9600
RTS off
DTR off
Data bits=8, Stop bits=1, Parity=None
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(), FlowReplace=(), XonLimit=80, XoffLimit=200
Set timeouts: ReadInterval=0, ReadTotalTimeoutMultiplier=0, ReadTotalTimeoutConstant=0,     WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=0
*

I can obviously see the differences but need to know how to make the Arduino board independent of these "handshaking" protocols. (DTR, timing, etc.)

我显然可以看到差异,但需要知道如何使 Arduino 板独立于这些“握手”协议。(DTR、时序等)

And this is from my Visual Studio program (does not work; incorrect and inconsistent numbers)

这是来自我的 Visual Studio 程序(不起作用;不正确且不一致的数字)

*
COM port is opened
Baud rate 9600
RTS off
DTR off
Data bits=8, Stop bits=1, Parity=None
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(), FlowReplace=(), XonLimit=80, XoffLimit=200
*

Thus I would like to get the Arduino board away from DTR and all handshaking, as I want the final implementation to "speak" directly from Visual Studio to the Arduino board.

因此,我想让 Arduino 板远离 DTR 和所有握手,因为我希望最终实现能够直接从 Visual Studio 与 Arduino 板“对话”。

*****UPDATE*******

** ***更新*** ****

Thanks for the advice, the thing is I do not understand is why an open source piece of hardware would require so much handshaking.. That is, why does only the worst serial terminal program work where Serial Communicator, advance serial monitor, terterm, terminal, etc. don't seem to work?

感谢您的建议,问题是我不明白为什么开源硬件需要这么多握手。也就是说,为什么只有最糟糕的串行终端程序才能在串行通信器、高级串行监视器、terterm、终端中工作等似乎不起作用?

I have updated my code to mirror HyperTerminal exactly (complete all handshaking), but it does not seem to work!

我已经更新了我的代码以准确地反映超级终端(完成所有握手),但它似乎不起作用!

Heres the updated code fragement:

这是更新后的代码片段:

HANDLE hDevice = CreateFile(L"COM5",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ |     FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,0); //Open COM handle (create file)
if (hDevice !=INVALID_HANDLE_VALUE) //If COM3 connected
{
    printf("Com port opened\n"); //Show it's open
    DCB lpTest;
    // Initialize the DCBlength member.
    lpTest.DCBlength = sizeof (DCB);
    GetCommState(hDevice,&lpTest); //com state
    lpTest.BaudRate = CBR_9600;//load baud
    lpTest.ByteSize = 8;// load no. bits
    lpTest.Parity = NOPARITY;//parity
    lpTest.StopBits = ONESTOPBIT;//stop bits

    lpTest.fBinary = FALSE;            // Binary mode; no EOF check
    lpTest.fOutxCtsFlow = TRUE;         // No CTS output flow control
    lpTest.fOutxDsrFlow = FALSE;         // No DSR output flow control
    lpTest.fDtrControl = DTR_CONTROL_ENABLE;  // DTR flow control type
    lpTest.fDsrSensitivity = FALSE;      // DSR sensitivity
    lpTest.fTXContinueOnXoff = TRUE;     // XOFF continues Tx
    lpTest.fOutX = FALSE;                // No XON/XOFF out flow control
    lpTest.fInX = FALSE;                 // No XON/XOFF in flow control
    lpTest.fErrorChar = FALSE;           // Disable error replacement
    lpTest.fNull = FALSE;                // Disable null stripping
    //lpTest.fRtsControl = RTS_CONTROL_ENABLE; //// RTS flow control
    lpTest.fAbortOnError = TRUE;        // Do not abort reads/writes on error
    SetCommState(hDevice,&lpTest);
    DWORD btsIO;
    //ETC
}

The result is exactly the same as the working result from HyperTerminalexcept there is no timing conditions. However, I have used a 1 second delay after this code before closing the port.

其结果是完全一样从超级终端工作结果除了没有定时条件。但是,在关闭端口之前,我在此代码之后使用了 1 秒延迟。

Is the issue with my write statement?

是我的 write 语句有问题吗?

WriteFile(hDevice,c1,strlen(c1),&btsIO,NULL); //Write string to serial

It seems like there is something fundamentally wrong that I am doing, and I can't find it!

似乎我在做的事情根本上是错误的,我找不到!

*************UPDATE2***********

** *** *** *****更新2 *** *** *** **

I have stumbled across something, how would I configure my program to send each character individually?

我偶然发现了一些东西,我将如何配置我的程序以单独发送每个字符?

Visual Studio does not allow me to remove the Null or send one character in the code:

Visual Studio 不允许我删除 Null 或在代码中发送一个字符:

 WriteFile(hDevice,c1,strlen(c1),&btsIO,NULL);//WRITE STRING TO SERIAL

How do I fix this problem? It seems like the Arduino board only accepts one character at a time.

我该如何解决这个问题?似乎 Arduino 板一次只接受一个字符。

I have edited the character variables to be one char, etc.!

我已将字符变量编辑为一个字符等!

*********UPDATE3********************

** *** **** UPDATE3 *** *** *** *** *** *** **

This are the results from monitoring the communication from Visual Studio 2010 (or serial communicator) and HyperTerminal. The issue is sending a bit at a time!

这是从 Visual Studio 2010(或串行通信器)和 HyperTerminal 监视通信的结果。问题是一次发送一点!

HyperTerminal:

超级终端:

Baud rate 9600
DTR on
Data bits=8, Stop bits=1, Parity=None
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(DTR_CONTROL, CTS_HANDSHAKE, ERROR_ABORT), FlowReplace=    (TRANSMIT_TOGGLE, RTS_HANDSHAKE, XOFF_CONTINUE), XonLimit=80, XoffLimit=200
Set timeouts: ReadInterval=10, ReadTotalTimeoutMultiplier=0,     ReadTotalTimeoutConstant=0, WriteTotalTimeoutMultiplier=0, WriteTotalTimeoutConstant=5000

and Program/serial communication:

和程序/串行通信:

Baud rate 9600
DTR on
Data bits=8, Stop bits=1, Parity=None
Set chars: Eof=0x00, Error=0x00, Break=0x00, Event=0x00, Xon=0x11, Xoff=0x13
Handflow: ControlHandShake=(DTR_CONTROL, CTS_HANDSHAKE, ERROR_ABORT), FlowReplace=    (TRANSMIT_TOGGLE, RTS_HANDSHAKE, XOFF_CONTINUE), XonLimit=80, XoffLimit=200

An X sec wait in program code.

程序代码中的 X 秒等待。

回答by sarnold

It's been a long time since I last did serial work -- but it was veryclear in those days that your software on the computer hadto be configured exactly as the hardware device required. Your non-working example doesn't have DTR or RTS raised, and that's exactly what the board appears to require.

自从我上次进行串行工作以来已经有很长一段时间了——但在那个时候清楚你的计算机上的软件必须完全按照硬件设备的要求进行配置。您的非工作示例没有提高 DTR 或 RTS,而这正是董事会所要求的。

Since software on a full-powered computer is usually far easier to modify than hardware on an embedded board, it'd make sense to look into the configuration options available in your serial software -- any tolerable piece of software will have those settings to fiddle with. If not, I liked both Qmodemand ProComm, though I had friends that were adamant that Telixwas the nicer tool. (I had some Trade Wars scripts for Telix that were amazing...)

由于全功率计算机上的软件通常比嵌入式板上的硬件更容易修改,因此查看串行软件中可用的配置选项是有意义的——任何可容忍的软件都需要摆弄这些设置和。如果不是,我喜欢QmodemProComm,尽管我有朋友坚持认为Telix是更好的工具。(我有一些 Telix 的贸易战脚本,非常棒……)

回答by ctasdemir

Just as a suggestion: If you learn some C# and use .net API's it can be so easy to access serial port...

就像一个建议:如果你学习了一些 C# 并使用了 .net API,它可以很容易地访问串行端口......