Find the answer to your Linux question:
Results 1 to 5 of 5
First post... done a ton of googling to try and figure out my problem, to no avail. Hopefully this is the right forum. I'm talking over an RS232 to a ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Mar 2011
    Posts
    2

    Question serial port communication woes


    First post... done a ton of googling to try and figure out my problem, to no avail. Hopefully this is the right forum.

    I'm talking over an RS232 to a motion control board. I've got a windows library that I ported to Linux to make it talk serial to said board. Commands to the board work great... I can move motors and do all kinds of fun stuff. However, getting data back through the board is not working so great.

    What happens is the high bit of every byte is 0, regardless of if it should be or not. The problem manifested itself when trying to get the position of the motor back... if it is at 127, it is fine, but when it should return 128, it send back 0.

    After opening, the code to configure looks like this:

    Code:
    tcgetattr(hPeriph->handle, &options);
    
    //Set up baud rates
    cfsetispeed(&options, baudList[baud]);
    cfsetospeed(&options, baudList[baud]);
    
    //Enable the receiver and set local mode...
    options.c_cflag |= (CLOCAL | CREAD);
    
    options.c_cflag &= ~(PARENB| PARODD);
    
    //Set up stop bits
    options.c_cflag &= ~CSTOPB;
    
    //Disable HW flow control
    options.c_cflag &= ~CRTSCTS;
    
    //Setup input parity processing
    options.c_iflag &= ~(IGNBRK | BRKINT | ICRNL |
    	                    INLCR | PARMRK | INPCK | ISTRIP | IXON);
    
    options.c_oflag = 0;
    options.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
    
    tcsetattr(hPeriph->handle, TCSANOW, &options);
    I've tried dozens of combinations with the various parameters, to no avail. The baud rate is correct (57600), and it is 8N1.

    The windows code from the vendorworks fine, here is the config for that:
    Code:
        dcb.DCBlength         = sizeof(DCB);
        dcb.BaudRate          = baudList[baud];
        dcb.fBinary           = 1;
        dcb.fParity           = TRUE;
        dcb.fOutxCtsFlow      = 0;
        dcb.fOutxDsrFlow      = 0;
        dcb.fDtrControl       = DTR_CONTROL_DISABLE;
        dcb.fDsrSensitivity   = 0;
        dcb.fTXContinueOnXoff = 0;
        dcb.fOutX             = 0;
        dcb.fInX              = 0;
        dcb.fErrorChar        = 0;
        dcb.fNull             = 0;
        dcb.fRtsControl       = RTS_CONTROL_DISABLE;
        dcb.fAbortOnError     = 0;
        dcb.XonLim            = 0;
        dcb.XoffLim           = 0;
        dcb.ByteSize          = 8;
        dcb.Parity            = parList[parity];
        dcb.StopBits          = stopList[stopbits];
        dcb.XonChar           = 0;
        dcb.XoffChar          = 0;
        dcb.ErrorChar         = 0;
        dcb.EofChar           = 0;
        dcb.EvtChar           = 0;
    
        if( !SetCommState( hPeriph->handle, &dcb ) )
            return FALSE;
        return TRUE;

    Thoughts? I know that the data coming back from the board is the same regardless of windows/linux is talking to it (scoped the line), so I've got to think it is my setup or some weird driver issue.

  2. #2
    Just Joined!
    Join Date
    Mar 2011
    Location
    Portland, Oregon
    Posts
    14
    Quote Originally Posted by medvedm View Post
    Thoughts? I know that the data coming back from the board is the same regardless of windows/linux is talking to it (scoped the line), so I've got to think it is my setup or some weird driver issue.
    Well, my only experience with Motion Control (which is an art all it's own) is with Siemens MM4 drives and Siemens Sinumerik CNC equipment, and as best as I can tell, the words "Siemens" and "Weird Driver issue" are synonymous. Not sure if all motion controls are weird or just Siemens.

    This may be a stupid question, but are you POSITIVE you're actually looking at the high bit and not running into a Big Endian/Little Endian and/or padding issue? Just in the Siemens world, I've seen the most god-awful things. And for whatever reason they did it based on nibbles rather than bytes.

    I've seen nibble order reversed within bytes: Bit4,Bit3,Bit2,Bit1,Bit8,Bit7,Bit6,Bit5.

    I've seen every other nibble reversed: Bit1,Bit2,Bit3,Bit4,Bit8,Bit7,Bit6,Bit5.

    I've seen nibbles padded into bytes: Bit1,Bit2,Bit3,Bit4,nul,nul,nul,nul,Bit5,Bit6,Bit7 ,Bit8.

  3. #3
    Just Joined!
    Join Date
    Jan 2011
    Location
    Fairfax, Virginia, USA
    Posts
    94

    serial port communication woes

    Hi Medvedm,

    I'm not an expert with serial line things and tend to fight to get them working to be honest. It sure sounds like a stop bit problem but your stop bits look good for 8N1.

    Would you mind trying this?:

    Code:
    tcgetattr(hPeriph->handle, &options);
    
    // Set terminal to raw mode
    cfmakeraw( &options );  // <-- New line
    
    //Set up baud rates
    cfsetispeed(&options, baudList[baud]);
    cfsetospeed(&options, baudList[baud]);
    
    #ifdef  DISABLED
    XXX/Enable the receiver and set local mode...
    XXXoptions.c_cflag |= (CLOCAL | CREAD);
    #endif
    
    options.c_cflag &= ~(PARENB| PARODD);
    
    //Set up stop bits
    options.c_cflag &= ~CSTOPB;
    
    #ifdef DISABLED
    XX//Disable HW flow control
    XXoptions.c_cflag &= ~CRTSCTS;
    XX
    XX/Setup input parity processing
    XXoptions.c_iflag &= ~(IGNBRK | BRKINT | ICRNL |
    XX	                    INLCR | PARMRK | INPCK | ISTRIP | IXON);
    XX
    XXoptions.c_oflag = 0;
    XXoptions.c_lflag &= ~(ECHO | ECHONL | ICANON | IEXTEN | ISIG);
    #endif
    
    tcsetattr(hPeriph->handle, TCSANOW, &options);

  4. #4
    Just Joined!
    Join Date
    Oct 2008
    Posts
    1
    To me this has the feel of a programing problem. You said that you converted a
    window library to Linux. Here is my guess.

    binary representation of 127 0x0111 1111
    binary representation of 128 0x1000 0000

    I am wondering if the byte you receive is being treated as a signed byte and
    not as a unsigned byte. Therefore 0x0111 1111 is 127 and 0x1000 0000 is -0 or 0.
    Make sure in your window library source code all your bytes are declared as
    unsigned bytes and recompile. Again just a educated guess.

  5. #5
    Just Joined!
    Join Date
    Mar 2011
    Posts
    2

    sheepish grin

    Ouch... just figured out my problem. Turns out none of my changes were making it into the code because I was pointing my compiler to a version of the library (where the serial comm resides) that was a week old. Any time I recompiled the library, the changes weren't getting taken.

    Thanks for you help though, turns out if I had ACTUALLY been getting my changes i would've probably saved 4 days of work. Sheesh. I guess I know serial ports better than I ever wanted to! BTW, the cfmakeraw() function is sweet. I haven't seen that until here, so I guess that is a bonus!

    Well the universe is sane again and I can go about actual coding buisness!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •