C++ 无法从串行端口接收数据

C++ 无法从串行端口接收数据,c++,serial-port,robotics,C++,Serial Port,Robotics,目前,我试图用VC++编写一个串口通信程序,通过XBee变送器从PC机和机器人传输数据。但是在我编写了一些命令来轮询robot的数据之后,我没有从robot收到任何东西(代码中filesize的输出为0)。因为我的MATLAB接口工作正常,所以问题应该发生在代码中,而不是硬件或通信。你能帮我一下吗 2014年3月1日更新:我已更新代码。它仍然无法从我的机器人接收任何数据(读取的输出为0)。当我使用“cout*>p4”时,strlen(“>*>p4”),&writed,NULL); //检查是否可

目前,我试图用VC++编写一个串口通信程序,通过XBee变送器从PC机和机器人传输数据。但是在我编写了一些命令来轮询robot的数据之后,我没有从robot收到任何东西(代码中filesize的输出为0)。因为我的MATLAB接口工作正常,所以问题应该发生在代码中,而不是硬件或通信。你能帮我一下吗

2014年3月1日更新:我已更新代码。它仍然无法从我的机器人接收任何数据(读取的输出为0)。当我使用“cout*>p4”时,strlen(“>*>p4”),&writed,NULL); //检查是否可以接收数据 字符缓冲区[103]; 做{ ReadFile(serialHandle,buffer,sizeof(buffer),&read,NULL);
coutGetFileSize在与串行端口句柄一起使用时被证明无效。请使用ReadFile函数接收串行端口数据。

您应该在此处使用
strlen
而不是
sizeof

WriteFile(serialHandle,init,strlen(init),&written,NULL)
您最好创建这样的函数:

function write_to_robot (const char * msg)
{
   DWORD written;
   BOOL ok = WriteFile(serialHandle, msg, strlen(msg), &written, NULL)
      && (written == strlen(msg));
   if (!ok) printf ("Could not send message '%s' to robot\n", msg);
}
但这只是开胃菜。主要的问题是,正如MDN所说:

不能将GetFileSize函数与非查找设备(如管道或通信设备)的句柄一起使用

如果要从端口读取,只需使用
ReadFile
,直到它返回零字节

如果您已经知道机器人响应的最大大小,请尝试读取那么多字符。 继续读取,直到读取报告实际读取的字节数低于缓冲区大小。例如:

#define MAX_ROBOT_ANSWER_LENGTH 1000 /* bytes */
const char * read_robot_response ()
{
    static char buffer[MAX_ROBOT_ANSWER_LENGTH];
    DWORD read;
    if (!ReadFile (serialHandle, buffer, sizeof(buffer), &read, NULL))
    {
        printf ("something wrong with the com port handle");
        exit (-1);
    }
    if (read == sizeof(buffer))
    {
        // the robot response is bigger than it should
        printf ("this robot is overly talkative. Flushing input\n");

        // read the rest of the input so that the next answer will not be
        // polluted by leftovers of the previous one.
        do {
           ReadFile (serialHandle, buffer,  sizeof(buffer), &read, NULL);
        } while (read != 0);

        // report error
        return "error: robot response exceeds maximal length";
    }
    else
    {
        // add a terminator to string in case Mr Robot forgot to provide one
        buffer[read] = '\0';

        printf ("Mr Robot said '%s'\n", buffer);
        return buffer;
    }
}
这个过于简单的函数返回一个静态变量,每次调用read\u robot\u response时都会覆盖该变量

当然,正确的做法是使用阻塞I/O,而不是等待一秒钟,祈祷机器人及时响应,但这需要付出更多的努力

如果您觉得有冒险精神,您可以使用重叠I/O,这一点已被深入探讨

编辑:查看代码后

// this reads at most 103 bytes of the answer, and does not display them

if (!ReadFile(serialHandle,buffer,sizeof(buffer),&read,NULL))
   {
  printf("Reading data to port has a problem.");
  return FALSE;
    }

// this could display the length of the remaining of the answer,
// provided it is more than 103 bytes long

   do {
  ReadFile (serialHandle,buffer,sizeof(buffer),&read,NULL);
      cout << read;
    }
while (read!=0);
//这最多读取103字节的答案,并且不显示它们
if(!ReadFile(serialHandle,buffer,sizeof(buffer),&read,NULL))
{
printf(“将数据读取到端口有问题”);
返回FALSE;
}
//这可以显示答案剩余部分的长度,
//前提是它的长度超过103字节
做{
ReadFile(serialHandle,buffer,sizeof(buffer),&read,NULL);

如果没有XBee,它就不能直接在串行上工作吗?如果包含NULL,sizeof(init)将为0或1将不发送数据。这是您遇到的问题吗?@Lokno感谢您的回复。目前我没有合适的电缆直接连接robot和PC串行…回答您的问题可能需要一点时间。@TimDave我的问题是,在发送轮询数据的命令后,我无法接收任何数据。即使我删除了第一个WriteFile,我仍然会无法接收任何数据。我已更新了帖子中的代码。感谢您的回复。您能告诉我如何设置使用ReadFile时接收的数据大小吗?例如,我可以编写ReadFile(serialHandle,output,sizeof(output),&read,NULL);但我不知道如何定义“output”的大小@Scotty您必须将输出缓冲区的大小传递给ReadFile。这是它提供给您的最大字节数。但您无法设置将接收的数据的大小。这取决于设备定时和您设置的读取超时。请检查&read参数以了解您实际获得的字节数。您好@Scott,我已在e post。它仍然无法工作。read的输出给我0。&read的输出给我“0041F01C1”。这是什么意思?如果ReadFile返回0,则调用GetLastError以找出失败的原因。嗨@Scott,当我使用DWORD err=GetLastError();err的输出总是0。但是当我使用error=ReadFile(serialHandle,LPVOID(缓冲区)时,255,&numberOfBytesRead,NULL);错误输出始终为1。Hi@kuroi,当我使用缓冲区[read]='\0'时,系统给我错误“interface_test.cpp(100):错误C2440:'=':无法从“const char[2]”转换为“char”。我已经更新了姿势中的代码。我想问题是我不知道我的机器人响应的最大大小。你能帮我吗?对不起,我忘了声明
read
变量。该代码是我头脑中的一般原理说明,不是一个完全工作的程序。
// this reads at most 103 bytes of the answer, and does not display them

if (!ReadFile(serialHandle,buffer,sizeof(buffer),&read,NULL))
   {
  printf("Reading data to port has a problem.");
  return FALSE;
    }

// this could display the length of the remaining of the answer,
// provided it is more than 103 bytes long

   do {
  ReadFile (serialHandle,buffer,sizeof(buffer),&read,NULL);
      cout << read;
    }
while (read!=0);
#define BUFFER_LEN 1000
DWORD read;
char buffer [BUFFER_LEN];
do {
    if (!ReadFile(
        serialHandle,  // handle
        buffer,        // where to put your characters
        sizeof(buffer) // max nr of chars to read
             -1,       // leave space for terminator character
        &read, // get the number of bytes actually read
        NULL)) // Yet another blody stupid Microsoft parameter
    {
        // die if something went wrong
        printf("Reading data to port has a problem.");
        return FALSE;
    }

    // add a terminator after last character read,
    // so as to have a null terminated C string to display
    buffer[read] = '\0';

    // display what you actually read
    cout << buffer;
}
while (read!=0);