LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Serial Programming (https://www.linuxquestions.org/questions/programming-9/serial-programming-492735/)

g4j31a5 10-15-2006 10:24 PM

Serial Programming
 
Hi, I'm trying to create a program that can access serial port as I/O. I've created a null modem device which can be attached to serial port as I/O. The device's input is in a form of buttons while the output is in LEDs. When I tried it in minicom, it worked. So I started to write the application in C++. I've looked at the Serial Programming How-To and tried copy-pasted the canonical input into my application. It didn't work. I tried the asynchronous and still it didn't work. Even when I pressed the button, it didn't throw SIGIO at all. But in minicom, it worked. If i pressed a button, it sends a message (like "Test", etc). Can anybody help me?

Hko 10-16-2006 04:58 AM

Not sure, but it sounds like you non-canonical I/O.

Here's some document that has some more information:
http://www.easysw.com/~mike/serial/serial.html

Hop this helps a bit.

g4j31a5 10-17-2006 01:27 AM

Well, I can understand if it's the input from serial. But the output is also somewhat didn't work. You see in the serial device controller, there's a program that will detect I/O from / to the serial. If I send (write) eg. "fls 1 1 1", it will cause the first LED to blink with 1 second on and 1 off. In minicom, it worked. But when I tried it in my program (with: write(fd,"fls 1 1 1",9);), it didn't work. Can anybody help me?

Wim Sturkenboom 10-17-2006 04:59 AM

In minicom, you probably hit <enter> before it works. So you must do the same thing in your program
Code:

write(fd,"fls 1 1 1\n",10)
or similar.
I don't know what your device reacts on, it might need '\r\n' instead of '\n'. But that's trial-and-error or consulting the documentation.

g4j31a5 10-17-2006 08:57 PM

Quote:

Originally Posted by Wim Sturkenboom
In minicom, you probably hit <enter> before it works. So you must do the same thing in your program
Code:

write(fd,"fls 1 1 1\n",10)
or similar.
I don't know what your device reacts on, it might need '\r\n' instead of '\n'. But that's trial-and-error or consulting the documentation.

Yeah, I've tried using \r and it worked, occasionally. I mean I added SDL as a event handler so every time I clicked a mouse, it will blink if it was turned off before or vice versa. The funny thing was I have to click numerous time until the mode toggle itself. For example:

Quote:

State 1: LED turned off
> Mouse click --> mode = 1, sent "fls 1 1 1\r" to device, still in state 1
> Mouse click --> mode = 0, sent "turnoff 1\r" to device, still in state 1
> Mouse click --> mode = 1, sent "fls 1 1 1\r" to device, change to state 2
State 2: LED blinked
> Mouse click --> mode = 0, sent "turnoff 1\r" to device, still in state 2
> Mouse click --> mode = 1, sent "fls 1 1 1\r" to device, still in state 2
> Mouse click --> mode = 0, sent "turnoff 1\r" to device, still in state 2
> Mouse click --> mode = 1, sent "fls 1 1 1\r" to device, still in state 2
> Mouse click --> mode = 0, sent "turnoff 1\r" to device, change to state 1
State 1: LED turned off
...
The behaviour is not always like that. Sometimes I have to click multiple times to change the state, but sometimes one click is just what it needed. Why is this happening? BTW, my initialization step is:

Code:


    #define STOPBITS        0
    #define PARITY        0
    #define PARITYON        0

    int fd,c, res;
    struct termios oldtio,newtio;
    struct sigaction saio;          /* definition of signal action */
    char buf[255];

    fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK | O_NDELAY );
    if (fd <0)
    {
        perror(MODEMDEVICE);
        exit(-1);
    }
       

    saio.sa_handler = signal_handler_IO;
    sigemptyset(&saio.sa_mask);  //saio.sa_mask = 0;
    saio.sa_flags = 0;
    saio.sa_restorer = NULL;
    sigaction(SIGIO,&saio,NULL);

    fcntl(fd, F_SETOWN, getpid());

    fcntl(fd, F_SETFL, FASYNC);

    tcgetattr(fd,&oldtio); /* save current serial port settings */
    bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */
   
    newtio.c_cflag = BAUDRATE | CS8 | STOPBITS| PARITY |PARITYON | CLOCAL | CREAD ;

    newtio.c_iflag = IGNPAR | ICRNL;
       
    //newtio.c_oflag = 0;
    newtio.c_oflag = OPOST|ONLCR;

    newtio.c_lflag = ICANON;// | ECHO | ECHOE;
       
    tcflush(fd, TCIFLUSH);
    tcsetattr(fd,TCSANOW,&newtio);


Wim Sturkenboom 10-17-2006 11:01 PM

I don't know.

You use something that I've never used (sigaction) so I can not really comment on your code. A possible error might be that your program does not send the complete string. You can check how many bytes were written.

In this thread I've posted my init routine. Maybe it helps.

g4j31a5 10-17-2006 11:39 PM

Quote:

Originally Posted by Wim Sturkenboom
I don't know.

You use something that I've never used (sigaction) so I can not really comment on your code. A possible error might be that your program does not send the complete string. You can check how many bytes were written.

In this thread I've posted my init routine. Maybe it helps.

Well, I've checked the return value of the "write" calls and it returned the number of characters which indicate that the string was successfully sent. As for the sigaction, I copy-pasted it from the Serial Programming Howto with asynchronous communication. It's only purpose was to hanlde whether a SIGIO was thrown.

BTW, I've looked at your thread and I see that it is pretty much the same as my code (beside the signal handler). Thanks anyway.

g4j31a5 10-18-2006 11:42 PM

BTW, another question. What is the difference between using minicom and coding serial port in C / C++? Is it only the flags's initialization values or there was something else? If it's only the flags's, how do I know the minicom's flags in C that can be used in a raw C code?

BTW here's the minicom's config that actually worked:
Quote:

Serial Device : /dev/ttyS0
Lock Location : /var/lock
Callin Program :
Callout Program :
Bps / Par / Bits : 4800 8N1
Hardware Flow Control : No
Software Flow Control : No


All times are GMT -5. The time now is 09:24 PM.