C ++从外部设备读取数据 - 连接:OPTO-USB

时间:2014-01-02 11:44:10

标签: c++ serial-port usb

我正在寻找一些关于连接拨号仪的信息(我不确定它是否被称为是这样的),由Sylvac制作,用C ++编写的程序。连接采用OPTO-USB电缆(编号926.6621.10)。数据格式:X.XX(以毫米为单位)。

我尝试使用MSDN功能:CreateFileReadFile。没有错误,也没有任何价值。传输设置应该是正确的(我发现它们连接在电缆上的CD上。)

有人知道如何从千分表读取数据吗?我试图通过几种方式转换数据。每个函数下的“cout”用于查找程序停止的地方。我在互联网上用一些代码编写了这段代码。

在2014-01-10编辑

我的程序仍有问题。千分表在显示屏上显示“0,04”,所以我期望在“buffor”变量中我的程序中的值相同,但没有任何内容。甚至“读”都是零。

我的代码:

#include <iostream>
#include <windows.h>

using namespace std;

int main()
{
    LPBYTE buffor = new BYTE[64];
    *buffor = 1;
    HANDLE file;
    COMMTIMEOUTS timeouts;
    DWORD read;
    DCB port;
    char port_name[128] = "\\\\.\\COM3";
    cout << "pierwszy: " << endl;

    // open the comm port.
    file = CreateFile((port_name), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if ( file == INVALID_HANDLE_VALUE ) {
        cout << "1 1";
        return 1;
    }
    else
    {
        // get the current DCB, and adjust a few bits to our liking.
        memset(&port, 0, sizeof(port));
        port.DCBlength = sizeof(port);
        if ( !GetCommState(file, &port))
            cout << " 2 ";
        if (!BuildCommDCB(("baud=4800 parity=e data=7 stop=2"), &port))
            cout << " 3 ";
        if (!SetCommState(file, &port))
            cout << " 4 ";

        port.fDtrControl = DTR_CONTROL_ENABLE;
        port.fRtsControl = RTS_CONTROL_ENABLE;

        BOOL success;
        success = GetCommTimeouts(file, &timeouts);
        if (!success)
        {
            cout << "error";
            CloseHandle(file);
            return 1;//INVALID_HANDLE_VALUE;
        }
        timeouts.ReadIntervalTimeout = 1000;
        timeouts.ReadTotalTimeoutConstant = 1000;
        timeouts.ReadTotalTimeoutMultiplier = 0;
        timeouts.WriteTotalTimeoutConstant = 1000;
        timeouts.WriteTotalTimeoutMultiplier = 0;
        success = SetCommTimeouts(file, &timeouts);
        if (!success)
        {
            cout << "error";
            CloseHandle(file);
            return 1;//INVALID_HANDLE_VALUE;
        }

        if (!EscapeCommFunction(file, CLRDTR))
           cout << " 7 ";
        Sleep(200);
        if (!EscapeCommFunction(file, SETDTR))
           cout << " 8 ";

        // check for data on port and display it on screen.
        if(ReadFile(file, &buffor, sizeof(buffor), &read, NULL))
        {
            cout << "buffor: " << buffor << endl;
            cout << "read = " << read << endl;
            for (int i = 0; i < read; i++ )
                cout << i+1 << ". " << buffor[i] << endl;

            cout << "." << endl;
        }
        else
            cout << "error read";

        delete buffor;
        CloseHandle(file);
    }

    system("pause");
    return 0;
}

我把结果放在控制台中:console

预期的变量: buffor - &gt; 0,04; 阅读 - &gt;读取字节数

输出变量: buffor ????没有?; 读= 0

2 个答案:

答案 0 :(得分:0)

通过评论中提供的其他信息,我们可以开始诊断这一点。对你来说,实际的问题是在“odczytane”之后印刷垃圾。顺便提一下,这些信息应该在第一篇文章中。

首先,您需要确保您的程序设置为执行阻止读取。您设置了一些非常短的读取超时,这意味着每当您尝试从文件中读取数据时,您的程序将很快放弃。您的程序可能在任何数据准备好之前放弃。尝试通过执行与以下代码类似的操作将每个增加到1000毫秒:

    BOOL success;
    success = GetCommTimeouts(port, &timeouts);
if (!success)
{
    fprintf(stderr, "Error: Unable to get comm timeouts.  Error code 0x%x.\n", GetLastError());
    CloseHandle(port);
    return INVALID_HANDLE_VALUE;
}
timeouts.ReadIntervalTimeout = 1000;
timeouts.ReadTotalTimeoutConstant = 1000;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 1000;
timeouts.WriteTotalTimeoutMultiplier = 0;
success = SetCommTimeouts(port, &timeouts);
if (!success)
{
    fprintf(stderr, "Error: Unable to set comm timeouts.  Error code 0x%x.\n", GetLastError());
    CloseHandle(port);
    return INVALID_HANDLE_VALUE;
}

根据设备的详细信息,您可能需要更长时间。

这里的另一个基本问题是你没有仔细考虑ReadFile返回的数据格式。

ReadFile是读取任何类型数据(即二进制)的通用函数。据我所知,它不会在数据末尾追加空终止字符。 (它不应该,因为您可能希望读取0个字节。)在调用read之后,您需要查看ReadFile的值以了解读取了多少字节。

printf和cout这样的东西需要传递一个以空字符结尾的字符串。

打印sizeof(read)将始终为您提供4,因为read只是定义为32位整数(DWORD)。

将所有这些知识放在一起,这是我们可以调用ReadFile并打印结果的合理方法。我不知道返回的数据是ASCII还是二进制,所以我只打印每个字节的数值:

if(ReadFile(file, buffor, sizeof(buffor), &read, NULL))
{
  cout << "bytes read:" << read << endl;
  for (int i = 0; i < read; i++)
  {
    cout << buffor[i] << " " << endl;
  }
}
else
{
  cout << "ReadFile failed" << endl;
}

我没有仔细研究过这个特定的串行设备是如何工作的,因此设置它可能会导致它无法发送数据。

如果您仍然遇到问题,请将程序简化为少于100行的单个文件,并提供整个代码,以及输出和预期输出。 http://www.sscce.org/

答案 1 :(得分:0)

我找到了解决方案的时间很长。答案很简单! 有两种方法可以将数据从此千分表传输到计算机:

  1. 您可以使用函数SetCommMask设置事件掩码,然后等待使用函数WaitCommEvent声明的事件。

  2. 您可以使用WriteFile向刻度盘发送一些字符,然后阅读:ReadFile

  3. 我的代码:

    if(WriteFile(Sensor, " ", 1, &read, NULL))
        ReadFile(Sensor, buffer, sizeof(buffer), &read, NULL);
    

    缓冲区为LPBYTE所以我必须转换它:

    char buf[4];
    
    for (int i = 0; i < 4; i++)
        buf[i] = buffer[i];
    
    double buff = 0;
    buff = atof(buf);