简体   繁体   English

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

[英]C++ reading data from external device - connection: OPTO-USB

I was looking for some information about connecting a dial gauge (I'm not sure if it is called like that) made by Sylvac with program written in C++. 我一直在寻找有关将Sylvac制作的千分表与用C ++编写的程序连接的一些信息(我不确定是否这样称呼)。 The connection is by OPTO-USB cable (number 926.6621.10). 通过OPTO-USB电缆(编号926.6621.10)进行连接。 Data format: X.XX (in millimeters). 数据格式:X.XX(以毫米为单位)。

I tried to use MSDN functions: CreateFile , ReadFile . 我尝试使用MSDN函数: CreateFileReadFile There is no error, neither any value. 没有错误,也没有任何值。 Transmission settings should be correct (I found them on CD attached to the cable). 传输设置应该正确(我在电缆附带的CD上找到了它们)。

Does someone have any idea how to read data from dial gauge? 有人知道如何从百分表读取数据吗? I tried to convert data in a few ways. 我试图以几种方式转换数据。 "cout" under each function was used to find the place, where program stops. 每个功能下的“ cout”用于查找程序停止的位置。 I wrote this code using some on the Internet. 我是使用Internet上的一些代码编写的。

Edit on 2014-01-10 编辑于2014-01-10

There is still problem with my program. 我的程序仍然有问题。 The dial gauge shows "0,04" on the display, so I expect the same value in my program in "buffor" variable, but there is nothing. 千分表在显示屏上显示“ 0,04”,因此我希望程序中的“ buffor”变量具有相同的值,但没有任何作用。 Even "read" is zero. 甚至“读取”也为零。

My code: 我的代码:

#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;
}

I put here the result in console: console 我将结果放在控制台中: console

Variables expected: buffor -> 0,04; 预期变量:buffor-> 0,04; read -> number of read bytes 读取->读取字节数

Output variables: buffor ???? 输出变量:buffor ???? Nothing?; 没有?; read = 0 读取= 0

With the additional information provided in the comments, we can start to diagnose this. 借助注释中提供的其他信息,我们可以开始对此进行诊断。 The actual problem for you is that junk is getting printed after the word "odczytane". 对您来说,实际的问题是,在“ odczytane”一词后会打印垃圾。 This information should have been in the first post, by the way. 顺便说一句,这些信息应该在第一篇文章中。

First of all, you need to ensure that your program is set up to do blocking reads. 首先,您需要确保将程序设置为执行阻止读取。 You have set some very short reading timeouts, which means that whenever you try to read data from the file your program will give up very quickly. 您已经设置了一些非常短的读取超时,这意味着每当您尝试从文件中读取数据时,程序都将很快放弃。 Your program is probably giving up before any data is ready. 您的程序可能在准备好任何数据之前就放弃了。 Try increasing each of those to 1000 ms by doing something similar to he following code: 尝试通过执行类似于以下代码的操作,将每个时间增加到1000 ms:

    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;
}

You might need to make those even longer depending on the details of your device. 您可能需要根据设备的详细信息来延长这些时间。

Another basic problem here is that you are not thinking carefully about the format of the data returned by ReadFile. 这里的另一个基本问题是您没有仔细考虑ReadFile返回的数据格式。

ReadFile is a generally useful function for reading any kind of data (ie binary). ReadFile是用于读取任何类型的数据(即二进制)的通用函数。 It does not append a null termination character at the end of the data as far as I know. 据我所知,它不会在数据末尾附加一个空终止符。 (It shouldn't, because you might want to read some 0 bytes.) You need to look at the value of read after calling ReadFile to know how many bytes were read. (不应该这样,因为您可能希望读取0个字节。)您需要在调用ReadFile之后查看read的值,以了解读取了多少字节。

Things like printf and cout need to be passed a null-terminated string. 诸如printf和cout之类的东西需要传递一个以空值结尾的字符串。

Printing sizeof(read) will always give you a 4 because read is just defined to be a 32-bit integer ( DWORD ). 打印sizeof(read)总是给您4,因为read仅被定义为32位整数( DWORD )。

Putting all this knowledge together, here is a reasonable way we could call ReadFile and print the results. 综合所有这些知识,这是我们可以调用ReadFile并打印结果的一种合理方法。 I don't know if the returned data is ASCII or binary so I will just print the numeric value of each byte: 我不知道返回的数据是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;
}

I haven't looked carefully at how this particular serial device works, so there might be a problem with how you set it up that would cause it to not send data. 我尚未仔细研究此特定串行设备的工作方式,因此,如何设置它可能会导致其不发送数据。

If you continue to have trouble, please simplify your program to a single file less than 100 lines long and provide the entire code, along with the output and the expected output. 如果仍然遇到问题,请将程序简化为少于100行的单个文件,并提供完整的代码以及输出和预期输出。 http://www.sscce.org/ http://www.sscce.org/

I was looking long time for the solution until I found. 我一直在寻找解决方案很长时间,直到找到为止。 The answer is very simple! 答案很简单! There are two ways to transfer data from this dial gauge to the computer: 有两种方法可以将数据从该千分表传输到计算机:

  1. You can set event-mask using function SetCommMask and then wait for event that you declared using function WaitCommEvent . 您可以使用函数SetCommMask设置事件掩码,然后等待使用函数WaitCommEvent声明的事件。

  2. You can send some character to the dial gauge using WriteFile and then just read with: ReadFile . 您可以使用WriteFile将某些字符发送到千分表,然后使用ReadFile读取。

My code: 我的代码:

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

buffer is LPBYTE so I have to convert it: 缓冲区是LPBYTE所以我必须对其进行转换:

char buf[4];

for (int i = 0; i < 4; i++)
    buf[i] = buffer[i];

double buff = 0;
buff = atof(buf);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM