Read from Serial Port -> Only zeroes - Linux

This is a discussion on Read from Serial Port -> Only zeroes - Linux ; Hi I am trying to read some data from a serial port. I tried to do so via gtkterm with 4800 baud, no parity, 8 bits, 1 stopbit, no flowcontrol - and it worked as intended. Then i tried to ...

+ Reply to Thread
Results 1 to 11 of 11

Thread: Read from Serial Port -> Only zeroes

  1. Read from Serial Port -> Only zeroes

    Hi

    I am trying to read some data from a serial port. I tried to do so via
    gtkterm with 4800 baud, no parity, 8 bits, 1 stopbit, no flowcontrol -
    and it worked as intended. Then i tried to write a program to do the
    same. I am using the following initialization (i have used the same
    code for another device and it worked perfectly there... just in this
    case it doesnt...):

    tcgetattr ( aFd,&tio );
    cfsetispeed ( &tio,B4800 ); // bitrate for input
    cfsetospeed ( &tio,B4800 ); // bitrate for outputMsg

    tio.c_cflag= ( tio.c_cflag & ~CSIZE ) | CS8; // data bits = 8bit

    tio.c_iflag&= ~ ( BRKINT | ICRNL | ISTRIP );
    tio.c_iflag&= ~ IXON; // no XON/XOFF
    tio.c_cflag&= ~PARENB; // no parity
    tio.c_cflag&= ~CRTSCTS; // no CTS/RTS
    tio.c_cflag&= ~CSTOPB; // stop bit = 1bit

    // Other
    tio.c_lflag &= ~ ( ISIG | ICANON | ECHO );

    // Commit
    tcsetattr ( aFd,TCSANOW,&tio ); // this succeeds

    Then I am trying to use the read() function to read some data from the
    port. read returns some positive number indicating that data could be
    read successfully, but the buffer that i passed is only filled with
    zeroes without any sign of an error.

    Any idea what I am doing wrong?

    Thanks alot

  2. Re: Read from Serial Port -> Only zeroes

    Frank Neuhaus writes:

    > Hi
    >
    > I am trying to read some data from a serial port. I tried to do so via
    > gtkterm with 4800 baud, no parity, 8 bits, 1 stopbit, no flowcontrol -
    > and it worked as intended. Then i tried to write a program to do the
    > same. I am using the following initialization (i have used the same
    > code for another device and it worked perfectly there... just in this
    > case it doesnt...):
    >
    > tcgetattr ( aFd,&tio );
    > cfsetispeed ( &tio,B4800 ); // bitrate for input
    > cfsetospeed ( &tio,B4800 ); // bitrate for outputMsg
    >
    > tio.c_cflag= ( tio.c_cflag & ~CSIZE ) | CS8; // data bits = 8bit
    >
    > tio.c_iflag&= ~ ( BRKINT | ICRNL | ISTRIP );
    > tio.c_iflag&= ~ IXON; // no XON/XOFF
    > tio.c_cflag&= ~PARENB; // no parity
    > tio.c_cflag&= ~CRTSCTS; // no CTS/RTS
    > tio.c_cflag&= ~CSTOPB; // stop bit = 1bit
    >
    > // Other
    > tio.c_lflag &= ~ ( ISIG | ICANON | ECHO );
    >
    > // Commit
    > tcsetattr ( aFd,TCSANOW,&tio ); // this succeeds
    >
    > Then I am trying to use the read() function to read some data from the
    > port. read returns some positive number indicating that data could be
    > read successfully, but the buffer that i passed is only filled with
    > zeroes without any sign of an error.
    >
    > Any idea what I am doing wrong?


    Not offhand. Can you post your complete code, if it isn't excessively long?

  3. Re: Read from Serial Port -> Only zeroes

    On 2008-10-31, Frank Neuhaus wrote:

    > Then I am trying to use the read() function to read some data from the
    > port. read returns some positive number indicating that data could be
    > read successfully, but the buffer that i passed is only filled with
    > zeroes without any sign of an error.


    I suspect it's the call to read();

    Bye.
    Jasen

  4. Re: Read from Serial Port -> Only zeroes

    > Not offhand. *Can you post your complete code, if it isn't excessively long?

    Ok here it is (even though I doubt it helps as its not much more than
    what I already posted):

    #include "MyReceiver.h"

    #include
    #include

    #include
    #include
    #include
    #include


    #define BAUD B4800

    namespace Devices
    {
    //-----------------------------------------------------------------------------
    MyReceiver::MyReceiver()
    {
    m_port=0;
    }
    //-----------------------------------------------------------------------------
    MyReceiver::~MyReceiver()
    {
    if (m_port)
    close(m_port);
    }
    //-----------------------------------------------------------------------------
    bool MyReceiver::init(const char* dev)
    {
    m_port = open ( dev, O_RDWR );
    if (!m_port)
    {
    LogError("Couldnt connect to Device!");
    return false;
    }
    if (!setupSerial(m_port,BAUD))
    {
    LogError("setupSerial failed!");
    return false;
    }
    return true;
    }
    //-----------------------------------------------------------------------------
    void MyReceiver::read()
    {
    char buffer[256];
    memset(buffer,0,256);
    int reada=::read((int)m_port,&buffer, 200);
    std::cout << reada << "X" << buffer << std::endl;
    for (int i=0;i printf("%02lX ",buffer[i]); // everything 00 here
    }
    //-----------------------------------------------------------------------------
    bool MyReceiver::setupSerial (int aFd, speed_t speed)
    {
    struct termios tio;

    tcgetattr ( aFd,&tio );
    cfsetispeed ( &tio,speed ); // bitrate for input
    cfsetospeed ( &tio,speed ); // bitrate for outputMsg

    tio.c_cflag= ( tio.c_cflag & ~CSIZE ) | CS8; // data bits = 8bit

    tio.c_iflag&= ~ ( BRKINT | ICRNL | ISTRIP );
    tio.c_iflag&= ~ IXON; // no XON/XOFF
    tio.c_cflag&= ~PARENB; // no parity
    tio.c_cflag&= ~CRTSCTS; // no CTS/RTS
    tio.c_cflag&= ~CSTOPB; // stop bit = 1bit

    // Other
    tio.c_lflag &= ~ ( ISIG | ICANON | ECHO );

    // Commit
    if ( tcsetattr ( aFd,/*TCSADRAIN*/TCSANOW,&tio ) ==0 ) return true;

    return false;
    }
    //-----------------------------------------------------------------------------
    //-----------------------------------------------------------------------------
    };


  5. Re: Read from Serial Port -> Only zeroes

    On 31 Okt., 06:49, Jasen Betts wrote:
    > On 2008-10-31, Frank Neuhaus wrote:
    >
    > > Then I am trying to use the read() function to read some data from the
    > > port. read returns some positive number indicating that data could be
    > > read successfully, but the buffer that i passed is only filled with
    > > zeroes without any sign of an error.

    >
    > I suspect it's the call to read();


    In what way? According to the man pages, read returns a positive
    integer when it succeeds... and thats what it does for me?

  6. Re: Read from Serial Port -> Only zeroes

    On 2008-10-31, Frank Neuhaus wrote:
    > On 31 Okt., 06:49, Jasen Betts wrote:
    >> On 2008-10-31, Frank Neuhaus wrote:
    >>
    >> > Then I am trying to use the read() function to read some data from the
    >> > port. read returns some positive number indicating that data could be
    >> > read successfully, but the buffer that i passed is only filled with
    >> > zeroes without any sign of an error.

    >>
    >> I suspect it's the call to read();

    >
    > In what way?


    wrong parameters? not having the source it's imposible to do other
    than guess.

    > According to the man pages, read returns a positive
    > integer when it succeeds... and thats what it does for me?


    means you gave it a valid file handle... but was it the right one
    (etc...)

    Bye.
    Jasen

  7. Re: Read from Serial Port -> Only zeroes

    On 2008-10-31, Frank Neuhaus wrote:
    >> Not offhand. *Can you post your complete code, if it isn't excessively long?



    > Ok here it is (even though I doubt it helps as its not much more than


    There was nothing obviously wrong with your discription of the code.

    > namespace Devices
    > {
    > //-----------------------------------------------------------------------------
    > MyReceiver::MyReceiver()
    > {
    > m_port=0;


    0 is a valid file handle, should probably use -1 for error value.

    > }
    > //-----------------------------------------------------------------------------
    > MyReceiver::~MyReceiver()
    > {
    > if (m_port)
    > close(m_port);


    as above.

    > }
    > //-----------------------------------------------------------------------------
    > bool MyReceiver::init(const char* dev)
    > {
    > m_port = open ( dev, O_RDWR );
    > if (!m_port)


    see above: you should definately use -1 (or <0) here.

    > {
    > LogError("Couldnt connect to Device!");


    perror, or strerror is useful at times like these.

    ....

    > void MyReceiver::read()
    > {
    > char buffer[256];
    > memset(buffer,0,256);
    > int reada=::read((int)m_port,&buffer, 200);

    -- ----- -
    what does the :: do?
    why the cast?
    does c++ need the address operator here?

    > std::cout << reada << "X" << buffer << std::endl;
    > for (int i=0;i > printf("%02lX ",buffer[i]); // everything 00 here
    > }
    > //-----------------------------------------------------------------------------


    ....

    > tio.c_iflag&= ~ IXON; // no XON/XOFF
    > tio.c_cflag&= ~PARENB; // no parity


    I'm assuming you've checked these lines (and their neighbours) and
    you're setting the correct flags in the structs members, and the
    correct baud rate... if your rate is 10 times or more higher than the
    devices rate all you'll read are zero bytes (actually break symbols but
    you're not checking for them).

    --

    Bye.
    Jasen

  8. Re: Read from Serial Port -> Only zeroes

    On Oct 30, 6:45*pm, Frank Neuhaus wrote:
    > Hi
    >
    > I am trying to read some data from a serial port. I tried to do so via
    > gtkterm with 4800 baud, no parity, 8 bits, 1 stopbit, no flowcontrol -
    > and it worked as intended. Then i tried to write a program to do the
    > same. I am using the following initialization (i have used the same
    > code for another device and it worked perfectly there... just in this
    > case it doesnt...):
    >
    > tcgetattr ( aFd,&tio );
    > cfsetispeed ( &tio,B4800 ); // bitrate for input
    > cfsetospeed ( &tio,B4800 ); // bitrate for outputMsg
    >
    > tio.c_cflag= ( tio.c_cflag & ~CSIZE ) | CS8; // data bits = 8bit
    >
    > tio.c_iflag&= ~ ( BRKINT | ICRNL | ISTRIP );
    > tio.c_iflag&= ~ IXON; * *// no XON/XOFF
    > tio.c_cflag&= ~PARENB; * // no parity
    > tio.c_cflag&= ~CRTSCTS; *// no CTS/RTS
    > tio.c_cflag&= ~CSTOPB; * // stop bit = 1bit
    >
    > // Other
    > tio.c_lflag &= ~ ( ISIG | ICANON | ECHO );
    >
    > // Commit
    > tcsetattr ( aFd,TCSANOW,&tio ); // this succeeds
    >
    > Then I am trying to use the read() function to read some data from the
    > port. read returns some positive number indicating that data could be
    > read successfully, but the buffer that i passed is only filled with
    > zeroes without any sign of an error.
    >
    > Any idea what I am doing wrong?


    The fact that characters are being returned but they are only zeroes
    seems to indicate a serial framing error. Either the baud rate,
    character width, or parity values are wrong.

  9. Re: Read from Serial Port -> Only zeroes

    On Oct 31, 12:26*pm, Jasen Betts wrote:
    > On 2008-10-31, Frank Neuhaus wrote:
    >
    > >> Not offhand. *Can you post your complete code, if it isn't excessively long?

    > > Ok here it is (even though I doubt it helps as its not much more than

    >
    > There was nothing obviously wrong with your discription of the code.
    >
    > > namespace Devices
    > > {
    > > //-----------------------------------------------------------------------------
    > > MyReceiver::MyReceiver()
    > > {
    > > * *m_port=0;

    >
    > 0 is a valid file handle, should probably use -1 for error value.
    >
    > > }
    > > //-----------------------------------------------------------------------------
    > > MyReceiver::~MyReceiver()
    > > {
    > > * *if (m_port)
    > > * * * * * *close(m_port);

    >
    > as above.
    >
    > > }
    > > //-----------------------------------------------------------------------------
    > > bool MyReceiver::init(const char* dev)
    > > {
    > > * *m_port = open ( dev, O_RDWR );
    > > * *if (!m_port)

    >
    > see above: you should definately use -1 (or <0) here.
    >
    > > * *{
    > > * * * * * *LogError("Couldnt connect to Device!");

    >
    > perror, or strerror is useful at times like these.
    >
    > ...
    >
    > > void MyReceiver::read()
    > > {
    > > * *char buffer[256];
    > > * *memset(buffer,0,256);
    > > * *int reada=::read((int)m_port,&buffer, 200);

    >
    > * * * * * * * * * -- * * ----- * * * -
    > what does the :: do?
    > why the cast?
    > does c++ need the address operator here?
    >
    > > * *std::cout << reada << "X" << buffer << std::endl;
    > > * *for (int i=0;i > > * * * * * *printf("%02lX ",buffer[i]); // everything 00 here
    > > }
    > > //-----------------------------------------------------------------------------

    >
    > ...
    >
    > > * *tio.c_iflag&= ~ IXON; * *// no XON/XOFF
    > > * *tio.c_cflag&= ~PARENB; * // no parity

    >
    > I'm assuming you've checked these lines (and their neighbours) and
    > you're setting the correct flags in the structs members, and the
    > correct baud rate... if your rate is 10 times or more higher than the
    > devices rate all you'll read are zero bytes (actually break symbols but
    > you're not checking for them).


    I have compared them with http://ulisse.elettra.trieste.it/ser...al/config.html
    and IMHO all my settings are correctly set (4800 Baud, 8 Databit, 1
    Stopbit, No Parity, No Flow control - these are also the settings that
    work in gtkterm!)
    I also tried various combinations of the settings and none of those
    worked, it always shows the exact same behavior. When I use incorrect
    settings inside gtkterm, it shows at least something - it never shows
    0 chars only.

  10. Re: Read from Serial Port -> Only zeroes

    On Oct 31, 1:56*pm, Frank Neuhaus wrote:
    > On Oct 31, 12:26*pm, Jasen Betts wrote:
    >
    >
    >
    > > On 2008-10-31, Frank Neuhaus wrote:

    >
    > > >> Not offhand. *Can you post your complete code, if it isn't excessively long?
    > > > Ok here it is (even though I doubt it helps as its not much more than

    >
    > > There was nothing obviously wrong with your discription of the code.

    >
    > > > namespace Devices
    > > > {
    > > > //-----------------------------------------------------------------------------
    > > > MyReceiver::MyReceiver()
    > > > {
    > > > * *m_port=0;

    >
    > > 0 is a valid file handle, should probably use -1 for error value.

    >
    > > > }
    > > > //-----------------------------------------------------------------------------
    > > > MyReceiver::~MyReceiver()
    > > > {
    > > > * *if (m_port)
    > > > * * * * * *close(m_port);

    >
    > > as above.

    >
    > > > }
    > > > //-----------------------------------------------------------------------------
    > > > bool MyReceiver::init(const char* dev)
    > > > {
    > > > * *m_port = open ( dev, O_RDWR );
    > > > * *if (!m_port)

    >
    > > see above: you should definately use -1 (or <0) here.

    >
    > > > * *{
    > > > * * * * * *LogError("Couldnt connect to Device!");

    >
    > > perror, or strerror is useful at times like these.

    >
    > > ...

    >
    > > > void MyReceiver::read()
    > > > {
    > > > * *char buffer[256];
    > > > * *memset(buffer,0,256);
    > > > * *int reada=::read((int)m_port,&buffer, 200);

    >
    > > * * * * * * * * * -- * * ----- * * * -
    > > what does the :: do?
    > > why the cast?
    > > does c++ need the address operator here?

    >
    > > > * *std::cout << reada << "X" << buffer << std::endl;
    > > > * *for (int i=0;i > > > * * * * * *printf("%02lX ",buffer[i]); // everything 00 here
    > > > }
    > > > //-----------------------------------------------------------------------------

    >
    > > ...

    >
    > > > * *tio.c_iflag&= ~ IXON; * *// no XON/XOFF
    > > > * *tio.c_cflag&= ~PARENB; * // no parity

    >
    > > I'm assuming you've checked these lines (and their neighbours) and
    > > you're setting the correct flags in the structs members, and the
    > > correct baud rate... if your rate is 10 times or more higher than the
    > > devices rate all you'll read are zero bytes (actually break symbols but
    > > you're not checking for them).

    >
    > I have compared them withhttp://ulisse.elettra.trieste.it/services/doc/serial/config.html
    > and IMHO all my settings are correctly set (4800 Baud, 8 Databit, 1
    > Stopbit, No Parity, No Flow control - these are also the settings that
    > work in gtkterm!)
    > I also tried various combinations of the settings and none of those
    > worked, it always shows the exact same behavior. When I use incorrect
    > settings inside gtkterm, it shows at least something - it never shows
    > 0 chars only.



    Ok thanks for your help everyone - I think i solved it... Obviously
    the device i was working with has some "timing issues" - i found some
    information on that on the web somewhere. After calling setattr, i am
    now doing a 200 ms sleep, then a tcflush, another 200 ms sleep, and
    another tcflush - then it all works great... weird device... (its a
    GPS receiver...)



  11. Re: Read from Serial Port -> Only zeroes

    Jasen Betts wrote:
    > On 2008-10-31, Frank Neuhaus wrote:
    >> void MyReceiver::read()
    >> {
    >> char buffer[256];
    >> memset(buffer,0,256);
    >> int reada=::read((int)m_port,&buffer, 200);

    > -- ----- -
    > what does the :: do?


    Lookup of 'read' would otherwise have found MyReceiver::read.

    > why the cast?


    It isn't necessary and using C-style casts are a damn bad idea anyway.

    > does c++ need the address operator here?


    No, but it actually shows quite clearly that you are passing the address of
    a buffer to read(), so why not. I'm not sure though why there is not a
    single case of 'sizeof buffer' in above code though...

    >> std::cout << reada << "X" << buffer << std::endl;
    >> for (int i=0;i >> printf("%02lX ",buffer[i]); // everything 00 here
    >> }


    Mixing IOStream with stdio is IMHO a bad idea. Further, the parameters don't
    match, 'lX' claims that you pass a long (unsigned long?), but you are
    passing a char. So, for a proper result, use a buffer of unsigned char,
    static_cast it to unsigned (Note: using unsigned arithmetic avoid sign
    extension) and then use '%02X' as format.

    BTW: there is no semicolon after every closing curly bracket. In particular,
    there must not be one after the closing ones of namespaces or function,
    though they are actually okay after the definition of a memberfunction
    inside a class definition.

    Uli


+ Reply to Thread