从 C 读取串行数据 (OSX /dev/tty)

发布于 2024-08-26 07:07:15 字数 1155 浏览 3 评论 0原文

我正在尝试使用 C 从蓝牙条形码扫描仪(KDC300)读取数据。这是我到目前为止的代码,并且该程序成功建立了与扫描仪的蓝牙连接,但是当扫描条形码时,没有输入显示在屏幕(最终将用数据完成更多工作,但我们必须首先让它工作,对吧)。

程序如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/ioctl.h>

int main (int argc, const char * argv[]) {

    // define vars
    int STOP = 0;
    //char buf[255];

    if(argv[1])
    {
        int fd = open("/dev/tty.KDC1", O_RDONLY);
        if(fd == -1)
        {
            printf("%s", strcat("Unable to open /dev/tty.", argv[1]));
        }

        int res;
        while(STOP == 0)
        {
            while((res = read(fd,buf,255)) == 0);
            {
                if(res > 0)
                {
                    buf[res]=0;
                    printf("%s:%d\n", buf, res);
                    if(buf[sizeof(buf)]=='\n') break;   
                }
            }
        }
    }

    return 0;
}

如果有人有任何想法,到目前为止我对此一无所知。如果有任何帮助,我可以运行 screen /dev/tty.KDC1 并且扫描仪上扫描的任何条形码都会出现在终端中,我只是无法对数据执行任何操作。

贾德

I am trying to read data from a bluetooth barcode scanner (KDC300) using C. Here is the code I have so far, and the program successfully establishes a bluetooth connection to the scanner, but when a barcode is scanned, no input is displayed on the screen (Eventually more will be done with the data, but we have to get it working first, right).

Here is the program:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <sys/ioctl.h>

int main (int argc, const char * argv[]) {

    // define vars
    int STOP = 0;
    //char buf[255];

    if(argv[1])
    {
        int fd = open("/dev/tty.KDC1", O_RDONLY);
        if(fd == -1)
        {
            printf("%s", strcat("Unable to open /dev/tty.", argv[1]));
        }

        int res;
        while(STOP == 0)
        {
            while((res = read(fd,buf,255)) == 0);
            {
                if(res > 0)
                {
                    buf[res]=0;
                    printf("%s:%d\n", buf, res);
                    if(buf[sizeof(buf)]=='\n') break;   
                }
            }
        }
    }

    return 0;
}

If anyone has any ideas, I am at a loss on this so far. If it is any help, I can run screen /dev/tty.KDC1 and any barcodes scanned on the scanner appear in the terminal, I just can't do anything with the data.

Jud

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

凉城凉梦凉人心 2024-09-02 07:07:15

这行:

        while((res = read(fd,buf,255)) == 0);

不做你认为它做的事。这是一个带有空主体的 while 循环。

This line:

        while((res = read(fd,buf,255)) == 0);

Does not do what you think it does. That's a while loop with an empty body.

野味少女 2024-09-02 07:07:15

@tommieb75,
strcat 语句来自程序的第一个“go”,我从 argv[1] 中获取一个变量并将其附加到 /dev/tty.*,以便您可以选择要监视的设备。

我不知道为什么我注释掉了 buf,可能是因为看代码太多/尝试不同的方法而忘记了我在哪里(不是一个 C 程序员,这就是我如何得到在 30 LOC 内丢失)。

@caf,很好地捕获了 while 循环后的额外分号,不幸的是,即使在更正它之后,程序也无法正确运行。

我正在进一步研究这个问题。我可以验证(使用 osx packetlogger)计算机正在获取数据,但是缓冲区中从未放置任何数据。

-Jud

---------------编辑--------------

经过一番尝试和错误后我解决了这个问题。添加以下代码来设置串行连接解决了一切:

struct termios theTermios;

memset(&theTermios, 0, sizeof(struct termios));
cfmakeraw(&theTermios);
cfsetspeed(&theTermios, 115200);

theTermios.c_cflag = CREAD | CLOCAL;     // turn on READ
theTermios.c_cflag |= CS8;
theTermios.c_cc[VMIN] = 0;
theTermios.c_cc[VTIME] = 10;     // 1 sec timeout
ioctl(fileDescriptor, TIOCSETA, &theTermios);

感谢其他答案让我走到这一步。

@tommieb75,
the strcat statement was from the first "go" at the program, I took a variable from argv[1] and appended it to the /dev/tty.* so you could select which device you wanted to monitor.

I am not sure why I had commented out buf, probably stems from looking at the code too much / trying different approaches and forgetting where I was (not much of a C programmer, which is how I can get lost in 30 LOC).

@caf, Good catch on the extra semi-colon after the while loop, unfortunately, even after correcting it, the program doesn't behave correctly.

I am researching the problem further. I can verify (with osx packetlogger) that the computer is getting the data, but the but the buffer never has any data placed in it.

-Jud

---------------Edit--------------

I solved the problem after a little trial and error. Adding the following code to setup the serial connection solved everything:

struct termios theTermios;

memset(&theTermios, 0, sizeof(struct termios));
cfmakeraw(&theTermios);
cfsetspeed(&theTermios, 115200);

theTermios.c_cflag = CREAD | CLOCAL;     // turn on READ
theTermios.c_cflag |= CS8;
theTermios.c_cc[VMIN] = 0;
theTermios.c_cc[VTIME] = 10;     // 1 sec timeout
ioctl(fileDescriptor, TIOCSETA, &theTermios);

Thanks to the other answers for getting me to this point.

尴尬癌患者 2024-09-02 07:07:15

这里是我找到的最好的信息。

使用 termios 的 C 程序只需添加

#include<string.h>

并更改波特率以满足我的需求即可工作。

Here is the best info I've found.

The C program on there using termios worked just by adding

#include<string.h>

And changing the baudrate to match my needs.

爱给你人给你 2024-09-02 07:07:15

在你的代码中

printf("%s", strcat("Unable to open /dev/tty.", argv[1]));

你为什么这么做?这样做会更容易:

printf("%s: Unable to open /dev/tty.KDC1", argv[0]); 

为什么参数引用命令行?

res = read(fd,buf,255)

为什么上面的 buf 声明被注释掉了?

In your code

printf("%s", strcat("Unable to open /dev/tty.", argv[1]));

Why did you do that? It would be easier to do it this way:

printf("%s: Unable to open /dev/tty.KDC1", argv[0]); 

Why the parameter referencing to the command line?

res = read(fd,buf,255)

Why did you have buf declaration commented out above?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文