Thread: Commands to send and receive data via USB port

  1. #1
    Registered User
    Join Date
    Mar 2013
    Posts
    5

    Commands to send and receive data via USB port

    Hallo

    I have a USB to TTL converter (FT232RL) that allows me me to send serial commands from my PC to an Arduino microcontroller. I am currently using Hyperterminal with manual key presses to send and receive serial data for example I send "A" to the microcontroller and the microcontroller responds by sending back "B"

    I want to expand this to be automated on my PC i.e. I would like to write a C program that automatically sends an "A" character and scans the USB for any data delivered to my PC from the Arduino microcontroller.

    Can someone help me get started by understanding if there are a set of functions that allow me to send an "A" character and check for received character "B" via USB?


    Thanks

  2. #2
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    Since you mentioned Hyperterminal you may want to start with this link: Windows Serial Port programming.


    Jim

  3. #3
    Registered User
    Join Date
    Mar 2013
    Posts
    5
    Hi jimblumberg

    Thanks. I tried to access the website www.robbayer.com and it appears to no longer be there. Let me start studying the document as this will be the seed of knowledge that will help me grow and understand it better.

    I also found another forum link which refers to the www.robbayer.com website:
    Command Line Interface (CLI) using C
    If I understand correctly,since I am learning C for the first time, the snippet of code at this forum gets COMM 1 to communicate to COM3 and COM4
    It makes no mention whether the serial port is a USB one. I am trying to figure out what it is doing?

  4. #4
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    Did you read the link I provided?

    It makes no mention whether the serial port is a USB one.
    What "port" is Hyperterminal using? You'll probably need to use the same port.

    Jim

  5. #5
    Registered User
    Join Date
    Mar 2013
    Posts
    5
    Hi Jim

    Thanks...yes I read the link that you provided and it has expanded my understanding on this subject. With my basic understanding of C I kind of understand what’s going on but I am by no means an expert. I correlated the notes to the snippet of code found at Command Line Interface (CLI) using C

    Here is the code:

    Code:
    #include <stdlib.h>
    #include <windows.h>
    
    HANDLE GetSerialPort(char *);
    
    int main(void)
    {
    HANDLE h1, h2;
    char h1_buffer[] = ("Hello from Com1:");
    char h2_buffer[24];
    DWORD byteswritten = 0, bytesread = 0;
    char c1[] = {"COM3"};
    char c2[] = {"COM4"};
    h1 = GetSerialPort(c1);
    h2 = GetSerialPort(c2);
    
    WriteFile(h1, h1_buffer, 17, &byteswritten, NULL);
    ReadFile(h2, h2_buffer, strlen(h1_buffer) + 1, &bytesread, NULL);
    
    if (bytesread)
    printf("%s\n", h2_buffer);
    else
    printf("Nothing read\n"); 
    
    CloseHandle(h1);
    CloseHandle(h2);
    
    getch(); 
    }
    
    HANDLE GetSerialPort(char *p)
    {
    HANDLE hSerial;
    hSerial = CreateFile(p,
    GENERIC_READ | GENERIC_WRITE,
    0,
    0,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    0);
    
    DCB dcbSerialParams = {0};
    dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
    dcbSerialParams.BaudRate=CBR_19200;
    dcbSerialParams.ByteSize=8;
    dcbSerialParams.StopBits=ONESTOPBIT;
    dcbSerialParams.Parity=NOPARITY;
    SetCommState(hSerial, &dcbSerialParams);
    return hSerial;
    }

    OK. So from the above code I understand the following. The string "Hallo from COM1:" is transmitted to the serial TX of COM3 and COM 4 is listening on the RX line to check for the string being received. I also understand that when communicating serially you have to use "handles" i.e. the way I understand it is that when a handle is given to a port, all other ports cannot communicate otherwise there will be a clash of data.

    To get the code to compile on my PC I did some minor changes as shown below

    Code:
    #include <windows.h>
    #include<conio.h>
    #include <stdio.h>
    #include <io.h>
    #include <stdlib.h>
    HANDLE GetSerialPort(char *);
    void delay();
    int main(void)
    {
     do
     {
        HANDLE h1, h2;
        char h1_buffer[] = ("Hello World:");
        char h2_buffer[24];
        DWORD byteswritten = 0, bytesread = 0;
        char c1[] = {"COM14"};
        char c2[] = {"COM14"};
        h1 = GetSerialPort(c1);
        h2 = GetSerialPort(c2);
       
        WriteFile(h1, h1_buffer, 17, &byteswritten, NULL);
        ReadFile(h2, h2_buffer, strlen(h1_buffer) + 1, &bytesread, NULL);
       
        if (bytesread)
        {
           printf("%s\n", h2_buffer);
        }
        else
        {    printf("Nothing read\n");  
        }
        CloseHandle(h1);
        CloseHandle(h2);
        delay();
        //getch();
      }while(1);     
    }
    HANDLE GetSerialPort(char *p)
    {
        HANDLE hSerial;
        hSerial = CreateFile(p,
                             GENERIC_READ | GENERIC_WRITE,
                             0,
                             0,
                             OPEN_EXISTING,
                             FILE_ATTRIBUTE_NORMAL,
                             0);
        DCB dcbSerialParams = {0};
        dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
        dcbSerialParams.BaudRate=CBR_19200;
        dcbSerialParams.ByteSize=8;
        dcbSerialParams.StopBits=ONESTOPBIT;
        dcbSerialParams.Parity=NOPARITY;
        SetCommState(hSerial, &dcbSerialParams);
        return hSerial;
    }
    void delay ()
    {
       int i = 1000000000;
       printf("In delay\n");
       while(i>0)
       {
          i--;
       }
    }

    An explanation of why I did this is as follows. First, I got my USB to TTL converter (FT232RL) and hooked it up to my PC. I opened Hyperterminal and noted that it came up with COM14. I did this to see what COM port value the TTL converter was assigned.

    I then decided to take the TX of the USB to TTL converter (FT232RL) and loop it to the RX pin with a wire. I modified the code to make "COM14" the transmitting port and "COM14" the receiving port. So the logic behind this thought experiment is that the string "Hallo World:" could be sent to the TX pin of the USB to TTL converter (FT232RL) from COM14, get looped back to the RX pin and read back into "COM14".

    I also added a do while loop to keep on "listening" for the "Hallo World:" string...but it does not seem to read it. When I compile and run it always prints the message "Nothing read In delay"

    Can you advise how I can loop back the “Hallo World:” string? Have I missed out something obvious?
    Last edited by Jetsetter; 04-17-2013 at 09:40 AM.

  6. #6
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    I then decided to take the TX of the USB to TTL converter (FT232RL) and loop it to the RX pin with a wire. I modified the code to make "COM14" the transmitting port and "COM14" the receiving port. So the logic behind this thought experiment is that the string "Hallo World:" could be sent to the TX pin of the USB to TTL converter (FT232RL) from COM14, get looped back to the RX pin and read back into "COM14".
    Did you first try your hardware setup with Hyperterm to see if it works? You'll need to make sure the port is set not to echo the commands sent to the receiver.

    Also most of your code should be outside your loop. The only thing you should need in the loop is the read and it's associated if statements. Also you probably should be using the value returned from the function instead of the parameter. You shouldn't use the parameter until the read operation returns true. See this link for ReadFile().


    Jim

  7. #7
    Registered User
    Join Date
    Mar 2013
    Posts
    5
    Hallo Jim

    I made some interesting progress. I conducted an experiment as shown in the attached picture i.e. I used COM6 in my code to transmit the “Hallo World:” string and to receive any other data from another USB to TTL board that was connected to COM 8. To achieve the two way communication I had to modify the code as follows (more info follows after the code)

    Code:
    #include <windows.h>
    #include<conio.h>
    #include <stdio.h>
    #include <io.h>
    #include <stdlib.h>
    
    HANDLE GetSerialPort(char *);
    void delay();
    int main(void)
    {
    do
    {
     HANDLE h1, h2;
     char h1_buffer[] = ("Hello World:");
     char h2_buffer[24];
     DWORD byteswritten = 0, bytesread = 0;
     char c1[] = {"COM6"};
     char c2[] = {"COM6"};
     h1 = GetSerialPort(c1);
    // h2 = GetSerialPort(c2);
    
     WriteFile(h1, h1_buffer, 17, &byteswritten, NULL);
     CloseHandle(h1);
    
     h2 = GetSerialPort(c2);
     ReadFile(h2, h2_buffer, strlen(h1_buffer) + 1, &bytesread, NULL);
     if(bytesread)
     {
        printf("%s\n", h2_buffer);
     }
     else
     {    printf("Nothing read\n");
          printf("This is what is in h2_buffer %s\n", h2_buffer);   
     }
    // CloseHandle(h1);
     CloseHandle(h2); 
     delay();
     //getch();
    }while(1);     
    
    }
    
    HANDLE GetSerialPort(char *p)
    {
     HANDLE hSerial;
     hSerial = CreateFile(p,
                          GENERIC_READ | GENERIC_WRITE,
                          0,
                          0,
                          OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL,
                          0);
    
     DCB dcbSerialParams = {0};
     dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
     dcbSerialParams.BaudRate=CBR_19200;
     dcbSerialParams.ByteSize=8;
     dcbSerialParams.StopBits=ONESTOPBIT;
     dcbSerialParams.Parity=NOPARITY;
     SetCommState(hSerial, &dcbSerialParams);
     return hSerial;
    }
    
    void delay ()
    {
    int i = 1000000000;
    printf("In delay\n");
    while(i>0)
    {
       i--;
    }
    
    }
    OK…so what I notice is that the handles h1 and h2 cannot be open at the same time. So, during the transmission phase the following is conducted:

    Open handle h1 (h1 = GetSerialPort; )
    Send the “Hallo World:” string (WriteFile(h1, h1_buffer, 17, &byteswritten, NULL)
    Close handle h1 (CloseHandle(h1);)



    The “Hallo World:” string gets sent to the other USB to TTL module that is connected on COM8. I view the “Hallo World:” string on the Hyperterminal. On Hyperterminal window, I type the letters h, k, l and d in succession. The SW code, in the mean time, has activated COM6 to be in listening mode i.e.:

    Open handle h2 (h2 = GetSerialPort(c2);)
    Read the data in (ReadFile(h2, h2_buffer, strlen(h1_buffer) + 1, &bytesread, NULL)
    Print the data received (printf("%s\n", h2_buffer);)
    Close handle h2 (CloseHandle(h2); )

    So far….I am getting somewhere…..let me play some more and see if I can improve on it because when I receive the characters that I typed , they have a trail of ASCII garbage after them. I would like to extend my thanks to you for having guided me in the beginning.Commands to send and receive data via USB port-serial-usb-command-jpg
    Last edited by Jetsetter; 04-17-2013 at 03:16 PM.

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    As I said in my earlier post most of your serial port code should be outside the loop. For example:
    Code:
     HANDLE h1, h2;
     char h1_buffer[] = ("Hello World:");
     char h2_buffer[24];
     DWORD byteswritten = 0, bytesread = 0;
     char c1[] = {"COM6"};
     char c2[] = {"COM6"};
     h1 = GetSerialPort(c1);
    // h2 = GetSerialPort(c2);
    All of this code should happen before the loop, you don't need to re-initialize the port every time you loop. Also you are opening your port in both read and write mode so you can read and write to the port at the same time.

    This about all you need in your while loop:
    Code:
     WriteFile(h1, h1_buffer, 17, &byteswritten, NULL);
    
     ReadFile(h2, h2_buffer, strlen(h1_buffer) + 1, &bytesread, NULL);
     if(bytesread)
     {
        printf("%s\n", h2_buffer);
     }
     else
     {    
          char stop;
          printf("Nothing read\n");
          printf("Do you want to exit? ");
          scanf(" %c", stop);
          if(stop == 'N' || stop == 'n')
             break;
      
     }
    Jim

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to receive data from serial port?
    By coolrox86 in forum C++ Programming
    Replies: 1
    Last Post: 04-23-2010, 03:04 PM
  2. Send/Receive
    By C_ntua in forum Networking/Device Communication
    Replies: 1
    Last Post: 01-19-2010, 12:17 PM
  3. How to Receive data from serial/USB port ?
    By sunit in forum C Programming
    Replies: 3
    Last Post: 06-19-2009, 12:16 PM
  4. Sockets: send/receive continuous stream of data?
    By diddy02 in forum Networking/Device Communication
    Replies: 1
    Last Post: 08-09-2008, 12:52 AM
  5. Send and receive through serial Port
    By overspray in forum C++ Programming
    Replies: 1
    Last Post: 07-21-2004, 04:15 PM