Thread: Getting a string from the UART/COM port

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    7

    Getting a string from the UART/COM port

    I cannot get the string that's sent to the com port. I know that it's sent there because I checked using a Serial Port Monitor.

    Here is the function that I use for reading the string from the COM port.

    Code:
    BOOL ReadString(void *outstring, int *length)
    {
        BYTE data;
        BYTE dataout[4096]={0};
        int index = 0;
        while(ReadByte(data)== TRUE)
        {
            dataout[index++] = data;
        }
        memcpy(outstring, dataout, index);
        *length = index;
        return TRUE;
    }
    Here is its in instance in the main function.

    Code:
        ReadString(str,&i);
    Can you please help me on this?
    When I try to display the contents of str, what I get is an empty string.

  2. #2
    Banned
    Join Date
    Jan 2009
    Posts
    30
    Would it be possible to post your code you are using to open the COM port for reading? Perhaps you are making a mistake at that point in your program. Also, how does ReadByte() work?

  3. #3
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    some questions before jumping into this - BYTE is a typedef for what? what is data initialized to? in a nutshell explain the code in more detail.

  4. #4
    Registered User
    Join Date
    Jan 2009
    Posts
    7
    Here is ReadByte.

    Code:
    BOOL ReadByte(BYTE  *res)
    {
        BOOL bReturn = TRUE;
        BYTE rx;
        DWORD dwBytesTransferred=0;
    
        if (ReadFile (hPort, &rx, 1, &dwBytesTransferred, 0)> 0)
        {
            if (dwBytesTransferred == 1)
            {
                res=rx;
                bReturn  = TRUE;
            }
            else bReturn = FALSE;
        }
        else    bReturn = FALSE;
        return bReturn;
    }
    Here is an overview of my setup. A ZigBee module (equipped with an Atmel microcontroller) sends data to my PC, specifically to a GUI I made using Glade/GTK.

    My experimentation has led me to the conclusion that although the module is able to send the string (the data), the GUI program is unable to save the string in the variable str.

    I use a serial port monitor to see what is sent and received at the COM port.

    Code:
    void
    on_BT_COLLECT_clicked                  (GtkButton       *button,
                                            gpointer         user_data)
    {
                                            
        gchar x;
        gchar str[100];
        gchar str2[100];
        //gchar *p_str;
        int i,j=0;
        
        GtkWidget *dialog, *label, *okay_button; // These will be used for the dialog   
       
        
        hPort = ConfigureSerialPort("COM5");
        if(hPort == NULL)
        {
            printf("Com port configuration failed\n");
           // return -1;
        }
        // Call your ReadString and WriteString functions here
    
        WriteString("C\n",1);
        sleep(50);
        ReadByte(&x);
        sleep(50);
        
        WriteString("~",1);
        sleep(50);
        //ReadByte(&x);
        //sleep(50); 
        
        //sprintf(str,"tsktsk\n");
        //sleep(50);
        ReadString(str,&i);
        sprintf(str2,"%c%c\n",x,x);
        //sleep(50);
        /*
        while (1)
        {
            ReadByte(x);
            //sleep(5);
            //if (x=='~')
             //  break;
            str[j]=x;
        }
        */
        //sleep(2000);
        
        
        dialog = gtk_dialog_new();
        label = gtk_label_new(str2); // Create the widgets of the dialog box
        okay_button = gtk_button_new_with_label("OK");
        gtk_signal_connect_object(GTK_OBJECT (okay_button), "clicked", gtk_widget_destroy, GTK_OBJECT(dialog));
        gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->action_area),
        okay_button);
        // Add the Okay Button to the dialog
        gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label); // Add the label
        gtk_widget_show_all (dialog); // Show everything the dialog.
        
        //gtk_entry_set_text(GTK_OBJECT("entry1"),str);  
        ClosePort();
    
    }

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by thatchergrey View Post
    Here is ReadByte.

    Code:
    BOOL ReadByte(BYTE  *res)
    {
        BOOL bReturn = TRUE;
        BYTE rx;
        DWORD dwBytesTransferred=0;
    
        if (ReadFile (hPort, &rx, 1, &dwBytesTransferred, 0)> 0)
        {
            if (dwBytesTransferred == 1)
            {
                res=rx;  /* oops */
                bReturn  = TRUE;
            }
            else bReturn = FALSE;
        }
        else    bReturn = FALSE;
        return bReturn;
    }
    I would have expected a warning on the red line there.

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > while(ReadByte(data)== TRUE)
    So this doesn't generate an error message?
    It should, it's expecting a pointer.
    Without a pointer, it's not going to change.

    > ReadString(str,&i);
    You should also pass the size of this buffer, to prevent buffer overflow.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Jan 2009
    Posts
    7
    Yes, there's a warning. Is this the reason why I'm unable to read the complete string? So how can I address this?

    Quote Originally Posted by tabstop View Post
    I would have expected a warning on the red line there.

  8. #8
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by thatchergrey View Post
    Yes, there's a warning. Is this the reason why I'm unable to read the complete string? So how can I address this?
    If you want to assign to *res, then do so. Note also Salem's note that the function call is wrong too.

  9. #9
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    My experimentation has led me to the conclusion that although the module is able to send the string (the data), the GUI program is unable to save the string in the variable str.
    My conclusion is that you set out to write the complete program -- including GUI -- without first having written something simple to make sure that you could actually read a string from the com port into a variable (which does not require a GUI). Of course, if you were already competent at gtk, communicating with comports, and C generally, that might be okay, but since you are obviously new to all three of them, why don't you try what anyone but a complete fool would try -- make sure your idea works before you add a graphical front end to it, or you will have more potential red herring to chase than anyone but a complete fool could possibly want.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #10
    Registered User
    Join Date
    Jan 2009
    Posts
    7
    Thank you everyone for all your insights! Thank you tabstop!

    Code:
    BOOL ReadByte(BYTE  *res)
    {
        BOOL bReturn = TRUE;
        BYTE rx;
        DWORD dwBytesTransferred=0;
    
        if (ReadFile (hPort, &rx, 1, &dwBytesTransferred, 0)> 0)
        {
            if (dwBytesTransferred == 1)
            {
                *res=(char)rx;
                bReturn  = TRUE;
            }
            else bReturn = FALSE;
        }
        else    bReturn = FALSE;
        return bReturn;
    }
    
    BOOL ReadString(char *outstring, int *length)
    {
        char data;
        char dataout[4096]={0};
        int index = 0;
        while(ReadByte(&data)== TRUE)
        {
            dataout[index++] = data;
        }
        memcpy(outstring, dataout, index);
        *length = index;
        return TRUE;
    }
    I was finally able to retrieve the string and display it in a dialog box. Thanks again!

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
                *res=(char)rx;
    Why the cast - res is a pointer to BYTE, rx is a BYTE - no point in casting this, is there?

    You should also pay attention to iMalc's comment about passing the max length to the ReadString function, as you may find yourself overwriting the end of the input buffer. And you should at the very least check that index never reaches sizeof(dataout).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. FTP program
    By jakemott in forum Linux Programming
    Replies: 14
    Last Post: 10-06-2008, 01:58 PM
  2. String Class
    By BKurosawa in forum C++ Programming
    Replies: 117
    Last Post: 08-09-2007, 01:02 AM
  3. Calculator + LinkedList
    By maro009 in forum C++ Programming
    Replies: 20
    Last Post: 05-17-2005, 12:56 PM
  4. Classes inheretance problem...
    By NANO in forum C++ Programming
    Replies: 12
    Last Post: 12-09-2002, 03:23 PM
  5. Warnings, warnings, warnings?
    By spentdome in forum C Programming
    Replies: 25
    Last Post: 05-27-2002, 06:49 PM

Tags for this Thread