C ++ serial port question

Problem : I have a handheld device that scans these graphic color barcodes on all packaging. There is a track device that I can use and it will move the device automatically. This track device works by taking ascii code over the serial port. I need to get this to work in FileMaker on a Mac. So no terminal programs, etc.

What I have so far : I bought a Keyspan USB / Serial adapter. Using the ZTerm program, I was able to send commands to the device. Example: "C, 7 ^ M ^ J"

I was also able to do the same in Terminal with this command: screen / dev / tty.KeySerial1 57600 and then enter the same command above (but when I typed I just pressed Control-M and Control-J for carriage return and feed lines)

Now I am writing a plugin for FileMaker (in C ++ of course). I want what I did above to happen in C ++, so when I install this plugin in FileMaker, I can just call one of those functions and walk the whole process there.

I can connect to the device, but I cannot talk to it. He doesn't answer.

I tried to connect to the device (successfully) using the following:

FILE *comport;
if ((comport = fopen("/dev/tty.KeySerial1", "w")) == NULL){...}

      

and

int fd;
fd = open("/dev/tty.KeySerial1", O_RDWR | O_NOCTTY | O_NDELAY);

      

This is what I have tried so far to speak to the device:

fputs ("C,7^M^J",comport);

      

or

fprintf(comport,"C,7^M^J");

      

or

char buffer[] = { 'C' , ',' , '7' , '^' , 'M' , '^' , 'J' };
fwrite (buffer , 1 , sizeof(buffer) , comport );

      

or

fwrite('C,7^M^J', 1, 1, comport);

      

Questions : When I connected to the device from the terminal and using ZTerm, I was able to set the baud rate to 57600. I think that may be why it is not responding here. But I don't know how to do this ... Does anyone know how to do this? I tried this but it didn't work:

comport->BaudRate = 57600;

      

There are many cool solutions out there, but they all name files like termios.h and stdio.h. I don't have them and for some reason I can't find them to download. I have uploaded some examples, but they have 20 files and they all name other files that I cannot find (like the ones listed above). Do I need to find them, and if so, where? I just don't know enough about C ++ Is there a site where I can download libraries?

Another solution might be to put these terminal commands in C ++. Is there a way to do this?

So it was driving me crazy. I'm not a C ++ guy, I only know basic programming concepts. Anyone have a C ++ expert? Ideally, I would like this to just work using functions that I already have, such as fwrite, fputs. Thank!

+2


source to share


5 answers


Sending a and then M does not send control-M, this is how you write it, to send a check character the easiest way is to just use ascii control .

ps. ^ M - carriage return, i.e. "\ R" and ^ J is the string "\ n"



edit: Probably more than you will (hopefully) ever need to know - but read the How Serial Port Howto before moving on.

+5


source


This is not a C ++ question. You are asking how to interact with the TTY driver to set the baud rate. The fact that you open the file in / dev tells me that you are using a unix derivative, so the corresponding man page for reading on a Linux system is "man 3 termios".



Basically, you use the open () variant above and pass the file descriptor to tcsetattr / tcgetattr.

+1


source


Are you sure you have configured all the compiler tools correctly? On my OS X 10.5.8 Mac, termios.h and stdio.h are right under / usr / include as expected. the code you already found for programming the serial port on other flavors of Unix should only need minor changes (if any) to work on a Mac. Could you tell us a little more about what you tried and what went wrong?

mgb also has a good understanding of how control characters should be displayed.

0


source


You can set the baud rate using ioctl . Here's a link to an example .

0


source


You don't specify which Unix you are using, so below I am posting some Linux code that I am using.

Note that the code below is a class method, so ignore any external (i.e. undeclared) references.

The steps are as follows:

Set up your termio structure where you set any flags you need, etc. (i.e. the step you took with zterm. The termio settings below set the port to 8 db, 1 stop bit and no parity (8-n-1). Also the port will be in "raw" mode (as opposed to cooked), so its a stream of characters, no text wrapped in strings, etc. The baud constants correspond to the actual value, so for 56700 baud you use "57600".

Synchronization options mean that characters are returned from the device as soon as they are available.

Once you've set the termainal options, you open the device (using POSIX open ()) and then you can use tcgetattr / tcsetattr to configure the device via fd.

At this point, you can read / write to the device using the read () / write () system calls.

Note that in the example below, read () will block if no data is available, so you might want to consider using select () / poll () if blocking is not desired.

Hope it helps.

termios termio    
tcflag_t baud_specifier;

    //reset device state...
    memset (&termio, 0, sizeof (termios));
    read_buffer.clear();

    //get our boad rate...
    if (!(baud_specifier = baud_constant (baud))) {
        ostringstream txt;
        txt << "invalid baud - " << baud;
        device_status_msg = txt.str();
        status = false;

        return (true);
    }


    //configure device state...
    termio.c_cflag = baud_specifier | CS8 | CLOCAL | CREAD;

    //do we want handshaking?
    if (rtscts) {
        termio.c_cflag |= CRTSCTS;
    }

    termio.c_iflag = IGNPAR;
    termio.c_oflag = 0;
    termio.c_lflag = 0;

    //com port timing, no wait between characters and read unblocks as soon as there is a character
    termio.c_cc[VTIME]    = 0;
    termio.c_cc[VMIN]     = 0;

    //open device...
    if ((fd = open (device.c_str(), O_RDWR | O_NOCTTY)) == -1) {

        ostringstream txt;
        txt << "open(\"" << device << "\") failed with " << errno << " - "
            << std_error_msg (errno);
        device_status_msg = txt.str();
        status = false;

        return (true);
    }

    //keep a copy of curret device state...
    if (tcgetattr (fd, &old_termio) == -1) {

        ostringstream txt;
        txt << "tcgetattr() failed with " << errno << " - " << std_error_msg (errno);
        device_status_msg = txt.str();
        status = false;

        return (true);
    }

    //flush any unwanted bytes
    if (tcflush (fd, TCIOFLUSH) == -1) {

        ostringstream txt;
        txt << "tcflush() failed with " << errno << " - " << std_error_msg (errno);
        device_status_msg = txt.str();
        status = false;

        return (true);
    }

    //apply our device config...
    if (tcsetattr (fd, TCSANOW, &termio) == -1) {

        ostringstream txt;
        txt << "tcsetattr() failed with " << errno << " - " << std_error_msg (errno);
        device_status_msg = txt.str();
        status = false;

        return (true);
    }

    node_log_f ("successfully initialised device %s at %i baud", "open_device()",
                device.c_str(), baud);

    status = true;
    return (true);
} 

      

0


source







All Articles