SerialSend

Graphical icon download link for SerialSend.exeSerialSend is a little command line application I created to send text strings via a serial port. I mainly use it to send information to microcontroller circuits via a USB-to-serial converter, so it’s designed to work well in that context.

SerialSend lets you:

  • Send an arbitrary text string to a device via serial port using one simple command.
  • Send text from simple console applications to hardware devices via serial port using the “system” function.
  • Specify baud rate.
  • Specify serial port number.
  • Automatically find and use the highest available serial port number (very useful for USB-to-serial converters).

The reason I included the last feature in the above list is that Windows seems to assign different serial port numbers to the same USB-to-serial converter on different occasions, especially when different USB sockets are used. In my experience, the assigned port number is usually a high number (e.g. my USB-to-serial adapter is currently appearing as COM22), so by automatically finding and using the highest available serial port, SerialSend makes it easy to send text via a USB adapter without needing to check the precise port number that has been assigned to it.

The full C source code for SerialSend is provided below. I compiled SerialSend with MinGW (gcc) using the command shown in the opening comments of the code, but it should be straightforward to compile it using Visual C++ or another Windows C/C++ compiler. Alternatively, just download and use the executable file:

SerialSend.exe (54 KB, date: 8-4-2015)

Example commands:

Note: If the text to be transmitted contains any space characters, it should be enclosed in inverted commas.

The following command sends the characters “abc 123” via the highest available serial port at the default baud rate (38400 baud).

SerialSend.exe "abc 123"

The following command sends the characters “Hello world!” via the highest available serial port at 9600 baud.

SerialSend.exe /baudrate 9600 "Hello world!"

The following command sends the characters “S120 E360” via COM10 at the default baud rate (38400 baud). If COM10 is not available, the next highest serial port that is available is used instead.

SerialSend.exe /devnum 10 "S120 E360"

Arbitrary bytes, including non-printable characters can be included in the string as hex values using the “/hex” command line option and the “\x” escape sequence in the specified text. For example, the following command sends the string “abc” followed by a line feed character (hex value 0x0A) – i.e. 4 bytes in total.

SerialSend.exe /hex "abc\x0A"

When the “/hex” commmand line option is specified, the escape sequences “\n” and “\r” may be used to insert line feed and carriage return characters respectively. For example, the following command sends the string “Hello” followed by a carriage return and a line feed (7 bytes in total).

SerialSend.exe /hex "Hello\r\n"

The “/closedelay” commmand line option allows a delay (in milliseconds) to be carried out after the specified text is transmitted, but before the serial port is closed. This seems to be necessary when sending data to certain devices in order to give them time to respond. For example, the following command transmits the characters ‘ABCD’ and a carriage return to COM5, then delays for 500 ms before closing the COM port.

SerialSend.exe /devnum 5 /closedelay 500 "ABCD\r"

This is a screen shot of SerialSend running in a console:

Screenshot of SerialSend.exe running in a console window

//
// SerialSend.c - This program sends text via serial port
// Written by Ted Burke - last updated 8-4-2015
//
// The text to send is specified as command line arguments.
// By default, the highest available serial port is used.
// The default baud rate is 38400 baud.
//
// To compile with MinGW:
//
//      gcc -o SerialSend.exe SerialSend.c
//
// To compile with cl, the Microsoft compiler:
//
//      cl SerialSend.c
//
// To run (this example sends the characters "S365 E120"):
//
//      SerialSend.exe "S356 E120"
//
   
#include <windows.h>
#include <stdio.h>
   
int main(int argc, char *argv[])
{
    // Declare variables and structures
    int m, n;
    unsigned char buffer[MAX_PATH];
    unsigned char text_to_send[MAX_PATH];
    unsigned char digits[MAX_PATH];
    int baudrate = 38400;
    int dev_num = 50;
    int parse_hex_bytes = 0;
    int close_delay = 0;
    char dev_name[MAX_PATH];
    HANDLE hSerial;
    DCB dcbSerialParams = {0};
    COMMTIMEOUTS timeouts = {0};
    
    // Print welcome message
    fprintf(stderr, "SerialSend (last updated 8-4-2015)\n");
    fprintf(stderr, "See http://batchloaf.com for more information\n");
    
    // Parse command line arguments
    int argn = 1;
    strcpy(buffer, "");
    while(argn < argc)
    {
        if (strcmp(argv[argn], "/baudrate") == 0)
        {
            // Parse baud rate
            if (++argn < argc && ((baudrate = atoi(argv[argn])) > 0))
            {
                fprintf(stderr, "%d baud specified\n", baudrate);
            }
            else
            {
                fprintf(stderr, "Baud rate error\n");
                return 1;
            }
        }
        else if (strcmp(argv[argn], "/devnum") == 0)
        {
            // Parse device number. SerialSend actually just
            // begins searching at this number and continues
            // working down to zero.
            if (++argn < argc)
            {
                dev_num = atoi(argv[argn]);
                fprintf(stderr, "Device number %d specified\n", dev_num);
            }
            else
            {
                fprintf(stderr, "Device number error\n");
                return 1;
            }
        }      
        else if (strcmp(argv[argn], "/closedelay") == 0)
        {
            // Parse close delay duration. After transmitting
            // the specified text, SerialSend will delay by
            // this number of milliseconds before closing the
            // COM port. Some devices seem to require this.
            if (++argn < argc)
            {
                close_delay = atoi(argv[argn]);
                fprintf(stderr, "Delay of %d ms specified before closing COM port\n", close_delay);
            }
            else
            {
                fprintf(stderr, "Close delay error\n");
                return 1;
            }
        }      
        else if (strcmp(argv[argn], "/hex") == 0)
        {
            // Parse flag for hex byte parsing.
            // If this flag is set, then arbitrary byte values can be
            // included in the string to send using '\x' notation.
            // For example, the command "SerialSend /hex Hello\x0D"
            // sends six bytes in total, the last being the carriage
            // return character, '\r' which has hex value 0x0D.
            parse_hex_bytes = 1;
        }
        else
        {
            // This command line argument is the text to send
            strcpy(buffer, argv[argn]);
        }
          
        // Next command line argument
        argn++;
    }
      
    // Check that some text to send was provided
    if (strlen(buffer) == 0)
    {
        fprintf(stderr, "Usage:\n\n\tSerialSend [/baudrate BAUDRATE] ");
        fprintf(stderr, "[/devnum DEVICE_NUMBER] [/hex] \"TEXT_TO_SEND\"\n");
        return 1;
    }
      
    // If hex parsing is enabled, modify text to send
    n = 0; m = 0;
    while(n < strlen(buffer))
    {
        if (parse_hex_bytes && buffer[n] == '\\')
        {
            n++;
            if (buffer[n] == '\\') text_to_send[m] = '\\';
            else if (buffer[n] == 'n') text_to_send[m] = '\n';
            else if (buffer[n] == 'r') text_to_send[m] = '\r';
            else if (buffer[n] == 'x')
            {
                digits[0] = buffer[++n];
                digits[1] = buffer[++n];
                digits[2] = '\0';
                text_to_send[m] = strtol(digits, NULL, 16);
            }
        }
        else
        {
            text_to_send[m] = buffer[n];
        }
          
        m++; n++;
    }
    text_to_send[m] = '\0'; // Null character to terminate string
      
    // Open the highest available serial port number
    fprintf(stderr, "Searching serial ports...\n");
    while(dev_num >= 0)
    {
        fprintf(stderr, "\r                        ");
        fprintf(stderr, "\rTrying COM%d...", dev_num);
        sprintf(dev_name, "\\\\.\\COM%d", dev_num);
        hSerial = CreateFile(
        dev_name, GENERIC_READ|GENERIC_WRITE, 0, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
        if (hSerial == INVALID_HANDLE_VALUE) dev_num--;
        else break;
    }
  
    if (dev_num < 0)
    {
        fprintf(stderr, "No serial port available\n");
        return 1;
    }
  
    fprintf(stderr, "OK\n");
  
    // Set device parameters (38400 baud, 1 start bit,
    // 1 stop bit, no parity)
    dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
    if (GetCommState(hSerial, &dcbSerialParams) == 0)
    {
        fprintf(stderr, "Error getting device state\n");
        CloseHandle(hSerial);
        return 1;
    }
    //dcbSerialParams.BaudRate = CBR_38400;
    dcbSerialParams.BaudRate = baudrate;
    dcbSerialParams.ByteSize = 8;
    dcbSerialParams.StopBits = ONESTOPBIT;
    dcbSerialParams.Parity = NOPARITY;
    if(SetCommState(hSerial, &dcbSerialParams) == 0)
    {
        fprintf(stderr, "Error setting device parameters\n");
        CloseHandle(hSerial);
        return 1;
    }
  
    // Set COM port timeout settings
    timeouts.ReadIntervalTimeout = 50;
    timeouts.ReadTotalTimeoutConstant = 50;
    timeouts.ReadTotalTimeoutMultiplier = 10;
    timeouts.WriteTotalTimeoutConstant = 50;
    timeouts.WriteTotalTimeoutMultiplier = 10;
    if(SetCommTimeouts(hSerial, &timeouts) == 0)
    {
        fprintf(stderr, "Error setting timeouts\n");
        CloseHandle(hSerial);
        return 1;
    }
      
    // Send specified text
    DWORD bytes_written, total_bytes_written = 0;
    fprintf(stderr, "Sending text... ");
    while(total_bytes_written < m)
    {
        if(!WriteFile(hSerial, text_to_send + total_bytes_written,
            m - total_bytes_written, &bytes_written, NULL))
        {
            fprintf(stderr, "Error writing text to %s\n", dev_name);
            CloseHandle(hSerial);
            return 1;
        }
          
        total_bytes_written += bytes_written;
    }
    fprintf(stderr, "\n%d bytes written to %s\n", total_bytes_written, dev_name);
    
    // Flush transmit buffer before closing serial port
    FlushFileBuffers(hSerial);
    if (close_delay > 0)
    {
        fprintf(stderr, "Delaying for %d ms before closing COM port... ", close_delay);
        Sleep(close_delay);
        fprintf(stderr, "OK\n");
    }
    
    // Close serial port
    fprintf(stderr, "Closing serial port...");
    if (CloseHandle(hSerial) == 0)
    {
        fprintf(stderr, "Error\n", dev_name);
        return 1;
    }
    fprintf(stderr, "OK\n");
  
    // exit normally
    return 0;
}

230 Responses to SerialSend

  1. sam says:

    hi plz help me out to send bytes to comport in visual c , via rs 232 command. m stuck wd it ..i hope you will help me😦

  2. josh says:

    hi.

    how can i have a carage return be sent at the end of the text ive sent?

    josh

    • batchloaf says:

      Hi Josh,

      I’m sure there’s a way to do this using escape characters. You could try ending the SerialSend command with the carat character, ‘ ^ ‘, probably followed by one or two blank lines. The carat “escapes” the next character, in this case the carriage return, so that instead of being interpreted as the end of the SerialSend command, it is interpreted as part of the command line argument. The following blank line is required to add another carriage return that actually does end the command.

      Unfortunately, I don’t have my Windows laptop with me, so I can’t try this right now to confirm that it works. I’ll try it when I’m back in my office on Monday.

      Here’s an alternative: If you’re willing to recompile SerialSend, then all you need to do is insert the following two lines in between lines 160 and 161 in the code shown above:

      WriteFile(hSerial, "\n", 1, &bytes_written, NULL);
      total_bytes_written += bytes_written;
      

      That will add a new line character to every string you output with SerialSend.

      Ted

  3. josh says:

    hi.

    A friend of tried compileing with the additional lines for LF /CR, but it dosent seem to work. If there is any way you can find an oppertunity to add this capibility, I would be extreamly grateful.

    One way I was thinking this may be simple to impliment and also allow users with different needs to use could be to have a DEC or HEX string mode. I.E. /HEX would mean that everthing following would be parced as 2 digit hex values and sent out. Same for /DEC but with 3 digit values. Just a sugestion.

    Thanks much

    josh

    • batchloaf says:

      Hi Josh,

      Thanks for the update.

      I’m sorry to hear your friend didn’t have any luck with the carriage return version. I don’t have my Windows laptop here, so I can’t try compiling it myself right now, but I’ll try it when I’m back in the office next week. It will be Tuesday at least since tomorrow (Monday) is a bank holiday here in Ireland due to today being St Patrick’s Day.

      Your suggestion of the option to specify specific byte values in decimal or hex is a good idea, so I’ll try to add that in at the same time. It seems like it could provide a very flexible solution for lots of people’s specific problems.

      Ted

    • batchloaf says:

      Hi Josh,

      I’ve updated SerialSend to allow line feeds, carriage returns and arbitrary hex bytes to be included in the string that’s sent. Just include the “/hex” command line option to enable parsing of special characters prior to transmission. For example, to add a carriage return and line feed to the end of the transmitted string, do something like:

      SerialSend /hex "Hello\r\n"
      

      Sorry it took so long!

      Ted

  4. Alan says:

    Hi Ted, did the ability to send 2 character hex ever get done ?? I am trying to send hex code to a music controller that expects hex commands on it’s serial port. (like 0xEF to stop and 0xEB to play). I can do it from a terminal emulator but am trying to see how to issue the commands under a program.
    regards
    Alan

    • batchloaf says:

      Hi Alan,

      I’m afraid I didn’t get around to it yet. I’ve been flat out at work, so I just haven’t had time to update SerialSend in quite a while. However, I’d still like to add this feature when I do get around to it. It won’t take long to code it, but I just need to set up the USB-to-serial converter and a receiving device, etc.

      Hopefully soon!

      Ted

    • batchloaf says:

      Hello again Alan,

      I’ve just updated SerialSend to include the feature you requested. You can now specify arbitrary bytes to send in hex notation using the “/hex” command line option and the “\x” escape sequence. For example, to send the byte 0xEF to the highest available serial port, just use the following command:

      SerialSend /hex "\xEF"
      

      Let me know if that works for you.

      Ted

  5. Alan says:

    Hi Ted, thanks for effort. I tried the new program and it does seem to send a hex code but it seems that it is not correct.
    I assume in your instructions you meant “xEF” not \xEF as shown.
    When I send 0xEF I get response from my unit and it starts playing a file (number 5) however this is supposed to be a stop command. If I send 0xEB , which is supposed to be play, then it just replays the music file from the start. It does same thing with 0xEA which is supposed to be a pause command. It is as though the command 0x05 is always being sent which would be the command to play the file which keeps happening with Serialsend no matter what other HEX code I actually try to send
    Obviously Serialsend is outputting something in a HEX fashion but it seems not the code I expect.
    I have tried using “hterm” a terminal program over the same USB com3 port and my unit responds and functions as expected so I know the basic HEX comm is OK. When using hterm I can see my unit is returning the same command as sent and it all works correctly, but I don’t know how to check what return code is received when using Serialsend.
    Sorry, as you will gather I am complete ignorant working in command prompt and using HEX but maybe from above description you might have a clue to my problem in trying to use Serialsend.
    Thanks for your patience and help,
    regards
    Alan

    • batchloaf says:

      Hi Alan,

      I really did mean “\xEF” – i.e. include the backslash. This type of notation used to insert arbitrary byte values into strings in some programming languages such as Python. The exact command you should be typing is:

      SerialSend /hex "\xEF"
      

      That will send just a single byte (0xEF). If the “/hex” flag is specified, SerialSend slows down whenever it meets a backslash and checks the next character to see what it is. If it’s an “x” it knows that the next byte to transmit will be specified as a pair of hex digits immediately afterwards.

      Can you try the exact command above and see if it works? Just to be clear, I should probably add that if you need to specify a particular serial port device, you’ll need to add that to the command.

      Ted

      • Josh says:

        It might be helpful to connect a second computer to the output of the first (using a nul modem) and observe the output of the first computer.

        Josh

  6. Alan says:

    Thanks Ted for your interest and help.
    I tried the exact command you specify and now get different (but still wrong) result;

    Sending any of my E commands (i.e. EF, EA, EB) is now completely ignored by my box.
    Sending 01 (which should play file 01) actually plays file 06, sending 02 actually plays file 05 and sending 03 plays file 06. (yes it really does play same file)
    Sending 04, 05, 06, 07. 08 are ignored.

    Yet if I use a terminal, program sending HEX all is correct.
    Very strange.

    This is what I actually see in command prompt;
    C:\users\alan>SerialSend.exe /hex “\xEA”
    Searching serial ports…
    Trying com3…OK
    Sending text…
    1 byte written to \\.\com3
    Closing serial port…OK

    C:users\alan>

    My possible commands are;
    0x01 to 0x08 play file number 01 to 08
    0xEF stop
    0xEA pause
    0xE3 next
    0xE2 Previous
    0xEB play

    These all seem to work fine in a terminal program that sends HEX,so I’m completely lost why it doesn’t work with SerialSend. Why some commands are recognized but incorrect, and others ignored.
    I don’t want to waste your time but I hoped you might recognize what is wrong with what should be a simple task !.
    regards
    Alan

  7. Alan says:

    Ted, my problem is solved. My own lack of knowledge !!!!
    My box had default baudrate of 9600 but using SerialSend with just raw command then Serial Send runs at 38400. When I changed my box to run at 38400 everything worked with SerialSend .
    Thanks for your help and patience
    Alan

    • batchloaf says:

      Hi Alan,

      Great! Glad to hear you solved the problem.

      To be honest, I should have realised that might be what was going wrong. For future reference, you can also specify the baud rate with SerialSend. For example:

      SerialSend /baudrate 9600 /hex "\xEF"
      

      Best of luck getting the rest of your system working!

      Ted

  8. Dave B says:

    Nice.

    Your source also compiles without problems under Dev-C++ on WIndows. I’ll also have a play with it under Linux sometime.

    I’ve been looking for something like this as a “worked example” to play with for some time.
    Many thanks.

    It’s also useful to me as is, so even better! 🙂

    Best Regards.

    Dave B G0WBX.

  9. Johan Bruggen says:

    Could you compile me a new exe taht incorparates the new /baudrate switch since the version on the website is from last year ?

    Thanks,
    Johan Bruggen

    • batchloaf says:

      Hi Johan,

      Sorry for the delay in responding. I’ve been away for the last few days.

      I’m pretty sure the current exe download version includes the baudrate switch. That feature isn’t new. I can’t actually double check it right now because I’m working on a Linux laptop and my windows computer is out of action. Can you check it again please?

      Ted

  10. Meysam says:

    Hi Ted,
    I am working on a project to control speed of 4 DC motors with two motor controllers, I wrote the script for my motor controllers and now I need to send the start command (!r) to both of my motor controllers which are attached to the computer through two serial ports at the same time. I saw SeriaSend and I think it can work for my purpose, now I have two problems:
    1- when I run SerialSend on my computer, it is closed automatically and I don’t know why?
    2- how can I send run command (!r) to both of the motor controllers at the same time.
    thanks in advance,
    Meysam.

  11. meysam says:

    Hi Ted,
    I wanna send run command to two motor controller at the same time with (!r) command, can I do this with SerialSen?

    • batchloaf says:

      Hi Meysam,

      I saw your other message, but hadn’t gotten around to replying yet. When you say “at the same time” how exact does it need to be? SerialSend only opens one serial port at a time, so it won’t be able to send to two simultaneously. However, if it’s just that one simple command you want to send each time, I could probably give you a short example program that would do it. You’d need to tell me the serial port numbers and the baudrate, etc. The idea would be to open both serial ports, then write the two character command to each one, then close both serial ports.

      Ted

      • Meysam says:

        Hi Ted,
        Thanks for your quick reply, I’m trying to control speed of 4 brushed DC motors separately through 2 RoboteQ SDC2130 motor controller, I wrote appropriate script for each motor controller and uploaded it to motor controllers. because these 4 DC motors want to run my 4 wheel ground robot, I need to send just the run command (!r) at the same time to both of them, and I think your Idea will work for this purpose.
        for serial port numbers, I’m using a serial to USB converter which accept two serial input of my two motor controller and one USB output which is attached to the computer. the baud rate for my case should be 115K and I just want to send the run command (!r) through serial port. It would be appreciated If you could send me the sample example which works for this case.
        again thanks a lot for your help,
        Best Regards,
        Meysam.

  12. Stuart says:

    Hi Ted, if only I knew something about programming this code would be perfect. I think it solves my exact problem with Hyperterminal in having to re-select comm port each time.

    I have a number of macros running out of excel that basically takes data on the excel, converts it to text, opens hyperterminal and pastes the data – which triggers upload to the device. I have a config file for HT that sets baud at 19200 so this is the only change I see in your code.

    I tried using this in Visual Studio Express C#, but 34 line errors, most of which made no sense to me. I assume this is not coded for C# so will install minGW and try this.

    I justed wanted to see if you would change anything in your code to allow for simple copy and paste into the console? I think I do not want to use command line arguements, it should just be ready to send whatever is typed or pasted.

    Thanks

    Here is the back end of what I am doing. I have other VB code to convert excel data to text, copy this to clipboard (also saves a txt copy to disk). I then use the submacro below to open HT and paste the data.

    Sub Open_HP13()
    Shell ActiveWorkbook.Path & “/System/Legacy/Hypertrm.EXE ” & ActiveWorkbook.Path & “\System\Legacy\LXtraMU.ht”, 1
    Application.Wait (Now + TimeValue(“0:00:1”))
    SendKeys “%”, True
    DoEvents
    SendKeys “e”, True
    DoEvents
    SendKeys “p”, True
    End Sub

  13. Benjamin says:

    Hi Ted,

    I am searching for a way to communicate to an Arduino based circuit via USB. I want to send to Arduino 3 simple commands: turn ON LED1, 2 and 3. This commands I want to send from a C program that reads a value from a txt file. An exemple: I write 1 in the txt file-> Arduino should turn on Led 1.

    The problem is that I don’t know how to send the command from my C program via USB. I saw your SerialSend application but i don’t know if I can use it. And how if I can use it.

    Can you help me please?

    • batchloaf says:

      Hi Benjamin,

      It’s easy enough to do what you want provided you have a USB-to-serial converter, which is basically a kind of USB dongle – this is the one I use, but there are lots of other ones available:

      http://www.satistronics.com/usb-to-rs232-module-ttl-uart-converter-pl2303-pl2303hx_p2147.html

      Once you install the driver for the USB-to-serial converter, the device shows up as a regular serial port in Windows and you can open it and send data to whatever device is connected to it.

      If you only need this to work on your own computer, the easiest way to do it is to install the USB-to-serial converter, then check what number COM port it shows up as (on my computer they tend to appear with quite high numbers for some reasons, e.g. COM22). It’s best to keep plugging into the same USB socket – otherwise it might show up as a different number COM port.

      So then basically, in your C program you just use fopen (or whatever) to open the file “COM22” (you might need to use the full special file path fopen. It will look something like this:

      FILE *ser;
      ser = fopen("\\\\.\\COM22","w");
      fprintf(ser, "LED1ON");
      // blah blah
      fclose(ser);
      

      It will probably use the default baud rate. Sorry, which I’m not sure what that will be – you’ll need to do some detective work. Whatever it is, your arduino will need to be set to the same baud rate (that’s the speed of serial transmission used – i.e. how many bits per second).

      I hope the above code is close to what should work, but I’m on a Linux computer here, so I’m not able to try it out. Also, I’m heading away on holidays for the next week, so I probably won’t be able to answer any follow up questions until at least a week from now.

      You might find it useful to take a look at this post by the way:

      https://batchloaf.wordpress.com/2013/02/12/simple-trick-for-sending-characters-to-a-serial-port-in-windows/

      Best of luck getting it working!

      Ted

  14. Benjamin says:

    Thank you very much for your help. I hope this will work just fine.

    Have a great holiday!

  15. Bob says:

    Hi Ted,
    Found your site looking for a way to send some Hex through the windows serial port using the command interpreter. Your method: set /p x=abc\\.\COM1 seemed to be a good way by sending appropriate cntl codes for instance ^a to send out 0x01. Problem is I need to send out 0x00 which seems is interpreted as a nul and halts execution. Also needed to send 0x03 which is cntl c, an unfortunate break. Perhaps you have an idea around this? It appeared SerialSend might be the way to do it but I find the /baudrate switch isn’t working. I need to send at 9600 it seems to be stuck at 38400. Thanks for the help.

    Bob

    • batchloaf says:

      Hi Bob,

      Hmmm, that’s curious about the baudrate. Is it possible that the 9600 baudrate is not supported by the serial device you’re using? What kind of serial device is it? Is it a USB-to-serial adapter or something like that?

      Actually, now that I see you stated COM1 in your question, perhaps it’s a physical serial port built into the PC?

      Ted

  16. Bob says:

    Hi Ted,
    You infer correctly that it is a physical serial port in the PC. I know it supports the 9600 baudrate since I can set it via mode command and send successfully using the command interpreter set /p function. Also at this time I am just sending to a data line monitor so I can see what is going out. Once I have it working well I will be sending to a Modbus device. Observe below I have pasted the text from a test run. I check the com port settings then run SerialSend then check port settings again.

    C:\Documents and Settings mode com1

    Status for device COM1:
    ———————–
    Baud: 9600
    Parity: None
    Data Bits: 8
    Stop Bits: 1
    Timeout: ON
    XON/XOFF: OFF
    CTS handshaking: OFF
    DSR handshaking: OFF
    DSR sensitivity: OFF
    DTR circuit: ON
    RTS circuit: ON

    C:\Documents and Settings SerialSend.exe /baudrate 9600 /devnum 01 /hex “\x02”

    C:\Documents and Settings mode com1

    Status for device COM1:
    ———————–
    Baud: 38400
    Parity: None
    Data Bits: 8
    Stop Bits: 1
    Timeout: ON
    XON/XOFF: OFF
    CTS handshaking: OFF
    DSR handshaking: OFF
    DSR sensitivity: OFF
    DTR circuit: ON
    RTS circuit: ON

    Bob..

    • batchloaf says:

      Hi Bob,

      Interesting! I’ve actually never checked to see whether the baud rate selected by CommandCam remains in effect after it’s finished running. It’s possible that even if you select a different baudrate (using CommandCam) the baud rate reverts to whatever it was beforehand. I’ll have to check that myself to see.

      Anyway, let me ask you a couple more questions:

      1. Bearing in mind what I mentioned above, are you sure that CommandCam really isn’t transmitting at 9600 baud and that the baud rate isn’t just reverting to the original baudrate afterwards?

      2. Have you tried using the mode command to set the baudrate to 9600 just before calling CommandCam. If that worked, it would provide a workaround (albeit an inelegant one). Your command would then just be something like:

      mode COM1 BAUD=38400 PARITY=n DATA=8 ;SerialSend.exe /baudrate 9600 /devnum 01 /hex "\x02"

      Perhaps you could try that to see if it works?

      Ted

  17. Andrew Martin says:

    Thanx – it’s great, but the baudrate parameter is broken.
    I downloaded the code and fixed it – quite easy.

  18. Giuliano says:

    Thank you for this great code (SerialSend).

    Where could I find the latest program to download (2013 version)? I downloaded from this site but the file is from year 2012. Thanks again.

    • batchloaf says:

      Hi Giuliano,

      I don’t think I’ve updated it since 2012. Are you having any problem running the one you downloaded?

      Ted

      • batchloaf says:

        Ah, sorry, I see what you mean now! The code above says it was last updated in 2013. I’ll have to recompile that and upload the new version. I doubt there are any big changes though, so it probably won’t make much difference.

        I won’t recompile right now, because this laptop is running 64-bit Windows 8, so I’d be worried the compiled executable wouldn’t work on other people’s 32-bit Windows machines.

        Ted

  19. Rafa Kory says:

    Hi,
    I want to send this hexadecimal string: 100201000a0b1003100201063c001e00251003100201093c00341003
    I am using this command: SerialSend.exe /baudrate 4800 /devnum 05 “0x100201000a0b1003100201063c001e00251003100201093c00341003”
    I do not find anything wrong,
    Other thing is that the parity is Even.
    Regards
    Rafa K.

    • batchloaf says:

      Hi Rafa,

      If you want to specify the characters to send as hex bytes, you need to include the “/hex” option and you also need to mark each individual byte as hex by preceding it with “\x”. I think your command should be something like the following:

      SerialSend.exe /baudrate 4800 /devnum 5 /hex “\x10\x02\x01\x00\x0a\x0b\x10\x03\x10\x02\x01\x06\x3c\x00\x1e\x00\x25\x10\x03\x10\x02\x01\x09\x3c\x00\x34\x10\x03”

      Unfortunately, to set the parity to even you’ll need to recompile serialsend.exe. You just need to change line 164 to the following and recompile:

      dcbSerialParams.Parity = EVENPARITY;
      

      I’ve just recompiled it on my machine with the parity set to even. You can download the even parity version here:

      https://drive.google.com/file/d/0B3NaVR72FYQcRnI1bVA0SUgwQXc/edit?usp=sharing

      I’m running 64-bit Windows 8, so I’m not sure whether that version will run on 32-bit Windows or not. I’m still completely confused about 32-bit v 64-bit compatibility! Let me know if it won’t run for you and I’ll compile it on a 32-bit machine.

      Ted

      • Rafa Kory says:

        Ted,
        Thanks for your help. After a few changes of the code I could do what I want.
        Now I can control the tanning beds.

        Rafa K.

      • batchloaf says:

        Great – glad to hear you gt it working. I think this is probably the first time someone has used SerialSend to control tanning beds!

        Ted

    • Asif says:

      hi rafa
      i am doing a project where pc is connected to t-max manager G2
      and trying to send commands to start tanning beds,
      can you please help me how you managed to send command successfully with serialsend.exe

      many thanks

      asif

  20. Andrew Martin says:

    Ted, wrt the update to the source code to fix the baud rate, I see you have made this change:
    //dcbSerialParams.BaudRate = CBR_38400;
    dcbSerialParams.BaudRate = baudrate;
    However, that was not all – it may be compiler specific, but I had to change this:
    if (++argn 0))
    to
    if (++argn 0))
    as well, or it always reported the specified baud rate as ‘= 1’ and would not execute.
    BTW – thanx🙂

  21. Andrew Martin says:

    Try that again – change this:
    ” if (++argn 0)) ”
    to this
    ” if (++argn 0)) ”
    If that hides the code again, it is an extra set of brackets here: (baudrate = atoi(argv[argn]))

  22. Wim says:

    Hi Ted,
    Is there any chance that the functionality of serial send will be extended with “serial receive” ?
    I plan to use serial send to send very simple commands to a TCP/IP relais (ETH002), via a virtual com port,( HW-VSP3). The relays can send status information back i want to investigate. This will make implementation more robust.
    Regards,
    Wim

    • batchloaf says:

      Hi Wim,

      Thanks for your message. Yes, it has struck me a couple of times that it might be useful if SerialSend could capture a response to something it sends out. I wasn’t quite sure exactly how to go about it though. Should it just print the received characters in the console for the user to look at? Would that be adequate for what you’re trying to do? If so, how do you think SerialSend should decide when to close the serial port and exit? How long should it stay open waiting for characters to be received from the serial port? Should it be possible to specify a timeout or something like that?

      If you have a suggestion how it might work, I’ll give it some thought.

      By the way, have you looked at my other program ComPrinter which prints text coming in via a serial port to the console. Another possibility might be to add an option to ComPrinter which lets it send some output. I really should combine these two programs somehow.

      Ted

      • Wim says:

        Hi Ted,
        Thanks for your response.
        Let me explain a little bit more what I am trying to achieve.
        The challenge is to switch a device (230V) on and off a certain amount of time and that on arbitrary days in a month.
        You certainly can buy relay’s who can be programmed in this way but they are quite expensive and by that way over the top for my situation.
        After searching the web I found a relatively cheap TCP/IP relays (ETH002) which can, besides other functions, switched on and off by a simple command set, mostly three hex characters.
        Just what I needed!
        Furthermore I found a freeware serial to Ethernet converter utility (HW-VSP3) which makes it possible together with your “serial send” to construct a little Windows 7 command file (RelaysOn.bat) for sending just those three bytes. The command file will be activated by the Windows 7 task scheduler.

        About the receive part.
        The TCP/ IP relays will send a “0” when a command is executed correctly and a “1” when not.
        With other commands as for instance request MAC, the TCP/IP relays will send back his MAC address, etc, etc.
        So my thoughts are: “serial send” accepts information FROM the command file via the “serial send” parameters.
        If “serial send” can manage to set the value of a specific variable in the command file equal to the received data on the serial port, than the command file can act upon the content of this variable which is in fact the received data.
        In this way “serial send” presents information TO the command file.

        To avoid deadlock situations you definitely need a timeout on the receiver. I think this should be an extra parameter (receive timer), specifying the waiting time in Ms.
        Probably also an extra parameter (mode) will be handy to set the “serial send” application to send only or to send/receive.
        The port should stay open until the receive timer has expired or data is received, so one session is: open port – send data – wait/receive data – close port.

        Above are my thoughts.
        To me it looks lean and mean and will serve my needs and is hopefully generic enough so that others can use it also. However I cannot overlook if this proposal can be implemented software wise.
        It is of course also not a robust and full blown send/receive application.

        Best regards,
        Wim

  23. Terry Davis says:

    Maybe I’m missing something, but when I send the character “2” with SerialSend I getting 0xF5 at the receiving end. Both are setup with 19200 8n1 and working as expected when terminal programs are at each end.

    • batchloaf says:

      Hi Terry, Can you tell me the exact SerialSend command you’re using please?

      Ted

      • Terry Davis says:

        serialsend.exe /devnum 4 /baudrate 19200 “2”

        Note that echo 2 > com4 works as expected, but with an appended Cr and Lf

      • Terry Davis says:

        Actually, it seems like serialsend is not responding to the arguments properly – are there any requirements to run in Windows 7?

      • Terry Davis says:

        The PowerShell command,

        PowerShell “$port= new-Object System.IO.Ports.SerialPort COM4,19200,None,8,one; $port.open(); $port.WriteLine(“2″); $port.Close()”

        also works as expected. Sends a “2” with Lf appended.

      • batchloaf says:

        Hmmm, seems strange. Thanks for the extra details. I actually haven’t tested SerialSend in Windows 7, but I have that on the laptop I use in the office, so I should be able to test it during the week. On the face of it though, if it’s sending anything at all (even the wrong character), I’d be surprised if it’s the version of WIndows that’s the problem. If it didn’t run at all, that would point the finger of suspicion in that direction, but running and sending the wrong character sounds more like it’s a problem in SerialSend. Anyway, I’ll try running the exact same command myself and capture the output on the scope to verify what’s being sent.

        Ted

      • Terry Davis says:

        Ok, thanks.

    • batchloaf says:

      Hi Terry,

      There was a problem with the how the baud rate command line argument was being parsed (my stupid mistake – sorry!) which was setting the baud rate to 1 whenever you set it to something other than the default value. Another user just alerted me to it, so I’ve just fixed it and uploaded a new version of the exe. I think this might (partly?) explain the problem(s) you were having.

      Ted

  24. batchloaf says:

    Hi Wim,

    Thanks for all those extra details – I see just what you’re trying to do. Thanks for identifying that relay module too – I haven’t come across it before, but I’ve just looked it up and it seems really useful. I’ll have to keep it in mind for future projects.

    Anyway, back to your problem: I can see the kind of thing you have in mind for receiving the response with SerialSend, but I think it could be a bit messy returning values to the command file. Instead, I have a simple recommendation for you: Use Python. If you haven’t used Python before, that probably sounds complicated, but trust me it’s not really. For automating simple serial interaction it’s almost always the first thing I reach for. Furthermore, I teach a Robotics module at third level and students find Python by far the easiest way to get serial communication going between PC and external devices, even if they have never used it before.

    You’ll need to install two things in the following order (both are completely free and take 2 minutes to install):

    1. Python – I’m using version 2.7.6 and I recommend you do the same.
    2. The PySerial module, which lets you open serial ports and send and receive data. The version you want is pyserial-2.7.win32.exe.

    Once you’ve installed those, you can just write a simple program called something like “RelaysOn.py”. A basic version might contain something like the following (lines starting with a ‘#’ are comments in Python):

    # Import the PySerial module
    import serial
    
    # Open COM1 with 1 second timeout
    ser = serial.Serial(port='COM1', baudrate=38400, timeout=1)
    
    # Send three hex bytes to the serial port
    ser.write('\x20\x01\x00')
    
    # Receive 1 byte and check response
    reply = ser.read()
    if reply == '1':
        print 'OK'
    else:
        print 'Failed'
    
    # Close the serial port
    ser.close()
    

    Depending on which options you selected when you installed Python, you might be able to run your “RelaysOn.py” file just by double clicking it. Alternatively, you can run it at the command line by typing the following:

    C:\Python27\python.exe RelaysOn.py
    

    Hopefully, you can follow how the code works? If not let me know and I’ll try to explain it.

    Using Python will give you bags of flexibility and you can even tack on a GUI if you like without much difficulty (see example). I strongly recommend considering this option rather than tying yourself in knots trying to glue together batch files etc. You can also run other programs really easily from inside a Python script, so you can basically do anything you could do in a batch file, but a lot more besides.

    Ted

    • wim says:

      Hi Ted,

      Thanks for the valuable information. I never have heard of Phyton (my fault of course🙂 ) but my first impression is that it will serve my needs. Is there also a Phyton module available to communicate directly to the TCP/IP stack? In this way I also can avoid the virtual com port (HW-VSP3). I let you know when i have reached results.

      • batchloaf says:

        Hi Wim,

        Yes, it should be very straightforward to communicate directly via TCP/IP from Python – in fact, that would be a very typical thing people would use Python for. It’s a while since I’ve done it, but it won’t take you long to work it out. Here’s a simple socket example:

        https://wiki.python.org/moin/TcpCommunication

        Let me know how you’re project works out. Sounds interesting.

        Ted

  25. Thank you for posting exe and the code, This is a very useful utility.

  26. Philip Almond says:

    Hi,

    The /baudrate parameter does not work.

    If I specify /baudrate 9600 it still sends at its default of 38400. I verified this by attaching a terminal to the COM port at 9600 (frame error) and 38400 (I see what I sent).

    Philip

    • batchloaf says:

      Hi Philip,

      I’ve just rebuilt SerialSend.exe and uploaded the new version. Could you please try downloading and running it again to see if the problem’s fixed? I’m working from home, and I don’t even have my USB-to-serial converter here, so I have no way of testing it myself right now unfortunately.

      Thanks,
      Ted

    • batchloaf says:

      Hi Philip,

      Another user spotted a stupid bug in the SerialSend source code (see discussion below) that explains the problem you were having with the baud rate. I’ve applied his fix, recompiled and uploaded the new version. In case you’re still using SerialSend, you should probably download the new version, which should now actually use whatever baud rate you specify. Sorry about that – I hope it didn’t waste too much of your time!

      Ted

  27. Wim says:

    Hi Ted,
    Just to let you know about the progress.
    Today I received the ETH002 relays. I implemented the attached Phyton code on Windows 7. Everything works fine and fully to my satisfaction.
    Any remarks on my code? It is my first phyton code so maybe some things could be coded in a better way.

    Thanks again for your help.

    Code:
    =====================================================================
    import socket
    import time

    TCP_IP = ‘192.168.2.115’
    TCP_PORT = 17494
    BUFFER_SIZE = 80
    MESSAGE = ‘\x21\x01\x00’ #Relais 1 permanent off

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((TCP_IP, TCP_PORT))
    s.send(MESSAGE)
    data = s.recv(BUFFER_SIZE)
    s.close()

    def SendMailMessage ( Mtext ):
    import smtplib

    sender = ‘wim.bruyn@hetnet.nl’
    receivers = [‘wim.bruyn@hetnet.nl’]
    message = Mtext

    smtpObj = smtplib.SMTP(‘mailhost.hetnet.nl’, 25)
    smtpObj.sendmail(sender, receivers, message)
    smtpObj.quit()

    if data == ‘\x00’:
    msg = ‘USB disk is powered off on date: ‘ + time.strftime(“%c”)
    SendMailMessage ( msg )
    else:
    msg = ‘Error: USB disk is not powered off on date: ‘+ time.strftime(“%c”)
    SendMailMessage ( msg )

    • batchloaf says:

      Hi Wim,

      Reallly, my only comment is that your code is extremely clear and would probably be a very useful example for others! If you don’t already have a blog, I think you should consider starting one to make a note of useful code snippets like this, so that others can learn from them. If you tag your posts with the right keywords (e.g. “ETH002, Python, TCP, SMTP, email”, etc) Google will very quickly start sending you readers who are looking to solve the same problem.

      Thanks for sharing this interesting example – I learned a lot just by reading through it.

      Ted

  28. Wim says:

    Hi Ted,
    I finalized my project. I migrated to the latest Python release (3.3.3) and revised the code to be compatible, incorporate command line arguments and made it usable fort the ETH008 too.
    Attached the final code for your archive.
    I do not have a blog and unfortunately i will not make one since i am not the kind of person who has enough discipline to maintain a blog, sorry.
    The final code:
    ========================================================================
    #python33, Windows 7

    #Purpose:
    #Switching ETH002 or ETH008 TCP/IP relays on and off and send an e-mail when done
    #Command line arguments required for: Relays number (1-8), Mode (on/off) and e-mail report ID (free format text)
    #Use Windows task scheduler to activate the relays (optional).
    #
    #Example: c:\python33\python.exe SwitchETH002.py 2 off “External WD USB disk”

    import socket
    import time
    import argparse
    import smtplib

    def SendCommandToRelays (MESSAGE): #Value of MESSAGE is command to be send to relays
    TCP_IP = ‘192.168.2.115’ #IP address of the relays
    TCP_PORT = 17494 #Port number of the relays
    BUFFER_SIZE = 80

    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((TCP_IP, TCP_PORT))
    s.send(MESSAGE)
    data = s.recv(BUFFER_SIZE) #Response from Relays
    s.close()

    if data == b’\x00′:
    SendMailMessage ( (args.Device + ‘ is powered ‘ + args.Function + ‘, on date: ‘ + time.strftime(“%c”) ) )
    else:
    SendMailMessage ( (‘Error:’ + args.Device + ‘ is not powered ‘ + args.Function + ‘, on date: ‘ + time.strftime(“%c”)) )

    def SendMailMessage (Mtext): #Value of Mtext is action report send to mail recipient
    sender = ‘wim.bruyn@****.nl’ #mail address of the sender
    receivers = [‘wim.bruyn@****.nl’] #mail address of the receiver

    smtpObj = smtplib.SMTP(‘mailhost.****.nl’, 25)
    smtpObj.sendmail(sender, receivers, Mtext)
    smtpObj.quit()

    parser = argparse.ArgumentParser()
    parser.add_argument (“Number”, help = “Relays number 1 – 8”, type=int, choices = [1, 2, 3, 4, 5, 6, 7, 8])
    parser.add_argument (“Function”, help = “on is relays on, off is relays off”, choices = [“on”, “off”])
    parser.add_argument (“Device”, help = “Device id for e-mail message”)

    args = parser.parse_args()

    if args.Number == 1 :
    if args.Function == ‘on’ :
    print (‘Relays 1 on’),
    SendCommandToRelays ( b’\x21\x01\x00′ ) #Relays 1 permanent on
    elif args.Function == ‘off’ :
    print (‘Relays 1 off’),
    SendCommandToRelays ( b’\x20\x01\x00′ ) #Relays 1 permanent off

    if args.Number == 2 :
    if args.Function == ‘on’ :
    print (‘Relays 2 on’),
    SendCommandToRelays ( b’\x21\x02\x00′ ) #Relays 2 permanent on
    elif args.Function == ‘off’ :
    print (‘Relays 2 off’),
    SendCommandToRelays ( b’\x20\x02\x00′ ) #Relays 2 permanent off

    if args.Number == 3 :
    if args.Function == ‘on’ :
    print (‘Relays 3 on’),
    SendCommandToRelays ( b’\x21\x03\x00′ ) #Relays 3 permanent on
    elif args.Function == ‘off’ :
    print (‘Relays 3 off’),
    SendCommandToRelays ( b’\x20\x03\x00′ ) #Relays 3 permanent off

    if args.Number == 4 :
    if args.Function == ‘on’ :
    print (‘Relays 4 on’),
    SendCommandToRelays ( b’\x21\x04\x00′ ) #Relays 4 permanent on
    elif args.Function == ‘off’ :
    print (‘Relays 4 off’),
    SendCommandToRelays ( b’\x20\x04\x00′ ) #Relays 4 permanent off

    if args.Number == 5 :
    if args.Function == ‘on’ :
    print (‘Relays 5 on’),
    SendCommandToRelays ( b’\x21\x05\x00′ ) #Relays 5 permanent on
    elif args.Function == ‘off’ :
    print (‘Relays 5 off’),
    SendCommandToRelays ( b’\x20\x05\x00′ ) #Relays 5 permanent off

    if args.Number == 6 :
    if args.Function == ‘on’ :
    print (‘Relays 6 on’),
    SendCommandToRelays ( b’\x21\x06\x00′ ) #Relays 6 permanent on
    elif args.Function == ‘off’ :
    print (‘Relays 6 off’),
    SendCommandToRelays ( b’\x20\x06\x00′ ) #Relays 6 permanent off

    if args.Number == 7 :
    if args.Function == ‘on’ :
    print (‘Relays 7 on’),
    SendCommandToRelays ( b’\x21\x07\x00′ ) #Relays 7 permanent on
    elif args.Function == ‘off’ :
    print (‘Relays 7 off’),
    SendCommandToRelays ( b’\x20\x07\x00′ ) #Relays 7 permanent off

    if args.Number == 8 :
    if args.Function == ‘on’ :
    print (‘Relays 8 on’),
    SendCommandToRelays ( b’\x21\x08\x00′ ) #Relays 8 permanent on
    elif args.Function == ‘off’ :
    print (‘Relays 8 off’),
    SendCommandToRelays ( b’\x20\x08\x00′ ) #Relays 8 permanent off

    • batchloaf says:

      Hi Wim,

      Ha ha, ok I understand! Thanks for the updated version. I think this is a great example program, so if you’re not going to publish it yourself (apart from here in these comments), how would you feel about me putting it up as a new post on this blog? I’ll attach a short explanation and, of course, I’ll give you full credit. I just think this could be useful for others to learn from. Plus, the only way I can ever find anything when I need it in a hurry is if I add it my blog. If you’d rather not, of course that’s no problem at all.

      Ted

  29. Wim says:

    Hi Ted,

    That’s why i send the code to you🙂.
    Feel free to publish it so that others can benefit/learn from it.
    And thanks again for your advices.

    Mary Christmas and a happy new year from Holland.

    Regards
    Wim

  30. Brad says:

    Hi Ted,
    Thank you for posting your work.

    I have two questions.

    1. Should SerialSend work on Windows 7 64 bit? I got a BSOD when trying it.
    2. If I want to send several hex characters, what would be the syntax?

    Thanks again…Brad

    • batchloaf says:

      Hi Brad,

      Wow, you definitely should not be seeing a BSOD due to SerialSend!!! If there’s any way that it could be directly responsible, I would be extremely alarmed. I have had no other reports of this happening. What kind of serial port is it you’re opening? Is it possible that a serial port driver issue is responsible?

      SerialSend doesn’t do anything very unusual with the serial port – it’s basically just using the normal Win32 serial port functions in exactly the normal way, apart from one slightly unusual thing which is that if you don’t specify a serial port, it looks for the highest available serial port number by trying them one by one counting down from device number 50. However, even in that case, all it does is try to open each port the normal way, so that’s not really very unusual.

      To answer your questions:

      1. Actually, I don’t know – I haven’t had a chance to try it yet on a Windows 7 64 bit machine. I will once I get a chance, but I’m not aware of a specific reason why it wouldn’t work. As stated above, you definitely should not be seeing BSOD.

      2. To send several hex characters, you need to precede each hex byte value with “\x”. For example, to send the three hex bytes A1,00,FF you would use the following command:

      SerialSend.exe /hex "\xA1\x00\xFF"
      

      Since each hex byte is escaped individually using “\x” you can mix hex bytes and normal text characters. However, the “\x” flag is only recognised if you specify the “/hex” switch at the start.

      Hope that helps.

      Ted

  31. Brad says:

    Thank You for your reply Ted and sorry for my delay getting back to you.

    I am sending to a virtual serial port. The port gets setup when I setup my NetCom IP to serial device. The virtual serial port sends info via UDP to the NetCom device that is then connected to my Hitachi Projector. It requires a string of hex bytes for control. I am hoping to use a CLI program to enable me to turn off the projector when the computer is turned off.

    I only tried using SerialSend once so far and have not had time to make further attempts. The computer is running Win 7 Home Premium 64 bit so I cannot try it in compatibility mode. (not supported on home version)

    Any thoughts would be appreciated.

    Brad

  32. Jon says:

    Ted, thank you very much for writing, publishing, and sharing the source code of this software.

    I’m getting “No serial port available.” Here is what I’m seeing:
    C:\…> SerialSend.exe /devnum 05 /baudrate 9600 /hex “\xFF\xFF etc.”
    Device number 5 specified
    1 baud specified
    Searching serial ports…
    Trying COM0…No serial port available

    To verify that COM5 exists, I did:
    PS C:\…> [System.IO.Ports.SerialPort]::getportnames()
    COM5

    When trying to open COM5:
    PS C:\…>$port= newObject System.IO.Ports.SerialPort COM5,9600,None,8,one
    PS C:\…>$port.close()
    PS C:\…>$port.open()
    Exception calling “Open” with “0” argument(s): “Access to the port ‘COM5’ is denied.”
    At line:1 char:11
    + $port.open <<<< ()
    + CategoryInfo: NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorID: DotNetMethodExcedption

    • batchloaf says:

      Hi Jon,

      I’m struggling to bring the exact details to mind, but as far as I recall, the device numbering start at device 0, where as the COM port numbering starts at COM1. Therefore,

      device 0 = COM1
      device 1 = COM2
      device 2 = COM3
      device 3 = COM4
      device 4 = COM5
      device 5 = COM6
      etc etc

      So, I think you actually want to open “/devnum 4”. Could you try that and see if it fixes it?

      Ted

    • batchloaf says:

      Actually, sorry Jon, I had that totally wrong. The /devnum number is actually the same as the COM port number in SerialSend.

      One weird thing is that (for some reason) the baudrate command line argument is being parsed wrong. Your output indicates that the baudrate is 1, but that should say 9600.

      However, even if the baudrate is invalid (which “1” would be), SerialSend would still be able to open the port, even if the requested parameters (such as baudrate) were not going to be supported. In your case, the port doesn’t even open, so there must be something even more fundamental going wrong.

      The part of the program that opens the serial port is shown below. When you specify a device number, the variable dev_num will start with that value. In your case, dev_num starts off equal to 5. The code inside the while loop tries different device numbers in decreasing order, starting with the initial value (5 in your case). Each device it tries, it prints out “Trying COMx…” (where x is the current device number), but the message keeps printing on the same line, overwriting the previous message, so in your case, it prints “Trying COM5…”, then overwrites it with “Trying COM4…”, then overwrites that with “Trying COM3”, and so on until it gets to 0. Obviously, if it succeeds in opening a COM port, it stops at that point. Alternatively, if none of them open, it prints the message you’re seeing: “No serial port available”.

      // Open the highest available serial port number
      fprintf(stderr, "Searching serial ports...\n");
      while(dev_num >= 0)
      {
          fprintf(stderr, "\r                        ");
          fprintf(stderr, "\rTrying COM%d...", dev_num);
          sprintf(dev_name, "\\\\.\\COM%d", dev_num);
          hSerial = CreateFile(
          dev_name, GENERIC_READ|GENERIC_WRITE, 0, NULL,
          OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
          if (hSerial == INVALID_HANDLE_VALUE) dev_num--;
          else break;
      }
      

      So it looks like it just couldn’t open COM5 for some reason. Is there anything special about this serial device? Is it a regular COM port? Is it some other kind of hardware device? SerialSend tries to open the device as a read/write device – is that likely to be a problem with the device you’re opening?

      Ted

      • Andrew Martin says:

        That Buadrate = 1 is a missing bracket bug in the source code.

        I have tried to paste the fix a couple of times, but WordPress eats my code statements.
        I’ll try again, with a smaller fragment – in the parsing of the baud rate parameter, replace this fragment:
        (baudrate = atoi(argv[argn]) > 0)
        with this:
        ((baudrate = atoi(argv[argn])) > 0)

      • batchloaf says:

        Well spotted Andrew!! Of course you’re absolutely correct!

        Actually, that explains a few problems people have been having. I’ll fix that now.

        Thanks so much for that Andrew – it’s much appreciated.

        Ted

      • batchloaf says:

        Ok, I’ve added those brackets, recompiled and uploaded the new version. Unfortunately, I don’t have anything to check the new exe with here, so if either of you (Jon, Andrew) have something to try the new version on, I’d really appreciate knowing if it’s running ok.

        Thanks,
        Ted

  33. Andrew Martin says:

    Ted, tried the new exe – works fine with the baud rate parameter.
    Thanx again for the code🙂

    • batchloaf says:

      Excellent! Sincere thanks for your help with this. I’m embarrassed that it took me so long to spot this, despite your persistent efforts to alert me! I can only imagine how much frustration this has probably caused to other users. Anyway, well done for spotting the cause and sharing the fix. I’m sure others will appreciate your efforts too.

      Ted

  34. Aaron says:

    Hi Ted, wondering if you’ve run across this issue with SerialSend before. I have two presumably identical HP DC7900 desktops running Win7 Professional 32bit. One runs SerialSend just fine and successfully sends serial text commands to my Broadcast Tools SS4.1 Plus audio router. The other just won’t do it. Guess which one I need to deploy? 🙂 More seriously, regardless of the commands I enter, I get an error “could not be opened” For example:

    C:\serial>serialsend.exe “*001”
    Error: serial port *001 could not be opened
    C:\serial

    Any suggestions? So far no luck no matter where I beat my head on the keyboard…

  35. Stef says:

    Hi
    Thank you for this app.
    I use it in a .bat file to get interaction from my presentation software (impress in libreOffice), .
    This way I could get an Arduino to close some relay depending on the answer (button) the user click. The button use the “interaction option” to start a external program.

    I create a .BAT files with notepad:

    ECHO OFF
    C:\yourdirectory\SerialSend /baudrate 9600 “f”

    In batch file be careful with space and accent (if your not in english version) for the directory.

    Hope it’s could help other
    Thank again

    Stef

  36. giancarlo says:

    Is it possible to include a little routine to catch the response from the serial devices within a limited timout and print to stdout the read chars?
    Thanks for you great work and for sharing it!

  37. ionut says:

    baudrate can have any value?

    • batchloaf says:

      Hi ionut,

      SerialSend allows you to specify the baudrate using the “/baudrate” command line switch. For example,

      SerialSend.exe /baudrate 9600 "Hello world!"
      

      However, each serial device only supports a certain number of baudrates, so whether you actually get the baudrate you ask for will depend on whether your device supports that rate or not.

      Ted

  38. mangalgishreyas says:

    can you tell me how can I send NDEF URI to Arduino via serial communication ?

  39. San San Lim says:

    THANK YOU, Arigatao, Danke Schoen, Terima Kasih, Gamza hamida, Merci

  40. altonmazin says:

    Command Set Command Command Converted
    (Charset) (Hexadecimal)
    1. Power (ka)
    Power Off ka 01 00(CR) 6B 61 20 30 31 20 30 30 0D

    Power On ka 01 01(CR) 6B 61 20 30 31 20 30 31 0D

    Power Status (On) ka 01 ff(CR) 6B 61 20 30 31 20 66 66 0D

  41. altonmazin says:

    please see owners manual on this page. I don’t know how to upload pdf here
    http://www.lg.com/us/support-product/lg-42LN5300#

  42. John Mundy says:

    Hi Ted, I am looking to use your SerialSend program to send a SMS from the command line. When I use Putty on COM2 I can enter the following commands to get a test message sent:

    at+cmgf=1
    at+cmgs=”+61419xxxxxx”
    Test Message Text
    [Ctrl+z] (this is the key combination on the keyboard I press after the message text)

    How would you suggest I do the same thing with SerialSend? Something like this (line by line) does not seem to work.

    SerialSend /baudrate 9600 /devnum 2 “at+cmgf=1”
    SerialSend /baudrate 9600 /devnum 2 “at+cmgs=””+61419xxxxxx””
    SerialSend /baudrate 9600 /devnum 2 “TEST Message text”
    SerialSend /baudrate 9600 /devnum 2 /hex “\x1a”

    Note I put the Phone number in double quotes, perhaps this is incorrect syntax?

    Your advice would be appreciated.

    Cheers,

    John (Australia)

    • batchloaf says:

      Hi John,

      My guess is that the problem (well, maybe not the only problem) is to do with the inverted commas around the phone number of the second line. Perhaps you could try inserting the quote characters as hex values to ensure that the windows command line doesn’t split the whole message text into two separate string arguments. Try this for the second line:

      SerialSend /baudrate 9600 /devnum 2 /hex "at+cmgs=\x22+61419xxxxxx\x22"
      

      Also, depending on your Putty settings, I suppose it could also be sending line feed and/or carriage returns at the end of each line. As far as I recall (and I’ve just glanced back at my code) serial send won’t send a carriage return at the end of each piece of text you send unless you explicitly include it. I don’t know whether a carriage return is required by your receiving device, but if so you can include it in each command using a “\n” inside the quotes. For example,

      SerialSend /baudrate 9600 /devnum 2 "at+cmgf=1\n"
      

      Hopefully that helps. If it still doesn’t work, please let me know. However, I’m going away for a few days tomorrow, so don’t be offended if you don’t hear back immediately!

      Ted

  43. John Mundy says:

    Thanks Ted, I reckon I am close with your advice. I have tested sending a simple set Echo ON or OFF using the following:

    SerialSend /baudrate 9600 /devnum 2 “ate1\n”

    Then checked in Putty that the change was made. It worked.

    So now, with your advice on using stopping the quotes I also need to send the carriage return \n at the end. I tried this but it does not seem to do anything:

    SerialSend /baudrate 9600 /devnum 2 /hex “at+cmgs=\x22+61419828109\x22\n”

    Note the \n on the end. Somehow I think I have this wrong.

    Cheers for any more advice offered.

    John

    • batchloaf says:

      Hi John,

      I think that the default termination character for AT commands is a “carriage return” rather than a newline / line feed. It might therefore be worth trying replacing the “\n” character at the end of each of your commands with “\r”. Alternatively, you could even specify the terminating carriage return using its raw hex value “\x0D”. For example,

      SerialSend /baudrate 9600 /devnum 2 "ate1\r"
      

      and

      SerialSend /baudrate 9600 /devnum 2 /hex "at+cmgs=\x22+61419828109\x22\r"
      

      If those don’t work, you could try something like…

      SerialSend /baudrate 9600 /devnum 2 /hex "at+cmgs=\x22+61419828109\x22\x0D"
      

      If none of the above works, maybe you could try experimenting with combinations of terminating characters, e.g. “\r\n” or “\x0D\x0A”.

      Hopefully something like that will work!

      Ted

  44. John Mundy says:

    Hey Ted, you be the man alright. Thankyou for your excellent advice. I have been able to get this up and running with SerialSend to communicate with my SGSM Modem and send SMS messages.

    My goal was to make alerts triggers from servers send me and SMS. So I use the Windows Event Log to trigger a batch file.

    A sample of the batch file is here:

    SerialSend /baudrate 9600 /devnum 2 /hex “at+cmgf=1\x0D\x0A”
    timeout /t 2
    SerialSend /baudrate 9600 /devnum 2 /hex “at+cmgs=\x22+61419xxxxxx\x22\x0D\x0A”
    timeout /t 2
    SerialSend /baudrate 9600 /devnum 2 “Test message text here”
    timeout /t 2
    SerialSend /baudrate 9600 /devnum 2 /hex “\x1a”

    So in summary the GSM modem is a: ETM9300 GSM Modem connected via a serial port on COM2. I use the “timeout /t 2” in between the SerialSend commands to just wait a couple of seconds before the next command is sent.

    It works well. And I am sincerely grateful for your help.

    Take care, and if you are ever in Adelaide Australia I will buy you a beer.

    John

  45. Rakesh Bute says:

    Hi Ted,
    I just want to thank you. Your work saved me money.
    I wanted to make speech processing based control. I used Simon in computer for speech recognition, and I had Arduino in the other side. I used your program and little scripting to get it done. It saved from buying Bitvoicer License.
    Thanks again

  46. Basil says:

    very useful utility, thank you very much.
    Basil from Iraq.

  47. Maribel says:

    the batch file for sms is not working for me, any suggestion, debug please.

  48. Maribel says:

    Sorry I didnt explain, yes about SMS GSM modem, same thing, commands are running over Putty but not the batch file, I installed SerialSend, my COM port is 22 and running the .bat file everythings looks ok, but the SMS didnt came to the cellphone, this is the result after the last line:
    C:\>SerialSend /baudrate 9600 /devnum 22 /hex “\x1a”
    9600 baud specified
    Device number 22 specified
    Searching serial ports…
    Trying COM22…OK
    Sending text…
    3 bytes written to \\.\COM22
    Closing serial port…OK
    C:\>
    Thanks

    • John Mundy says:

      Did you try my batchfile above (specifying a different COM port and phone number). What commands do you send from Putty which work?

  49. Maribel says:

    With Putty:

    AT+CMGF=1
    AT+CMGS="77745999"
    >Message to send 
    Ctrl Z
    

    It works, I can get the sms on the phone

    I already had a batch file sms1.bat with the following code:

    echo AT+CMGF=1>com22
    echo AT+CMGS="77745999" >com22
    echo Message to send >com22
    copy c:\ctrlz.txt \\.\COM1 /b
    

    ctrlz.txt contains \x1a, and this way doesnt work.

    Another batch file sms2.bat contains:

    SerialSend /baudrate 9600 /devnum 22 /hex "at+cmgf=1\x0D\x0A"
    timeout /t 2
    SerialSend /baudrate 9600 /devnum 22 /hex "at+cmgs=\x2277745999\x22\x0D\x0A"
    timeout /t 2
    SerialSend /baudrate 9600 /devnum 22 "Message to send"
    timeout /t 2
    SerialSend /baudrate 9600 /devnum 22 /hex "\x1a"
    

    Still not working

    • batchloaf says:

      Hi Maribel,

      I notice that you’re explicitly including carriage return (‘\r’ = 0x0D) and line feed (‘\n’ = 0x0A) characters at the end of the first two lines you send. However, you do not send them at the end of the message to send or after the 0x1A.

      I’m not sure how your PuTTY line endings are configured, but presumably it’s sending the same thing at the end of at least the first three lines (I suppose there’s probably nothing after the Ctrl-Z?), so since the PuTTY approach is working I suggest trying to replicate the exact same transmission using SerialSend.

      So basically,

      • Check what characters PuTTY is sending at the end of each line. Maybe it’s ‘0x0D0A’ or maybe it’s something slightly different, such as just 0x0A or just 0x0D.
      • Whatever PuTTY is sending, place the exact same characters at the end of every line that SerialSend transmits.

      Ted

    • batchloaf says:

      By the way, in your file “sms1.bat” you’re sending the final Ctrl-Z to COM1 rather than COM22.

      Ted

  50. Maribel says:

    I did your advice and finally thic code is working:

    SerialSend /baudrate 9600 /devnum 22 /hex "at+cmgf=1\x0d\x0a"
    timeout /t 2
    SerialSend /baudrate 9600 /devnum 22 /hex "at+cmgs=\x2273590999\x22\x0d\x0a"
    timeout /t 2
    SerialSend /baudrate 9600 /devnum 22 /hex "Test message text here\x1a\x0d\x0a" 
    

    What the ….! everything has a solution in this life, its only material, physics our spirit is the boss!
    Thanks Ted and John
    Thanks

  51. Elder Soares says:

    Hi Ted!
    First of all, thank you and congratulations for your work and for publishing with the source code. I ended up in your website because I was looking for some information about sending data to an usb hid device. I’m working in a Adobe AIR app that should send binary signals to a microcontroller via USB-to-Parallel adapter, just like this one (http://www.netmak.com.ar/index.php?page=shop.product_details&flypage=&product_id=111&category_id=11&option=com_virtuemart&Itemid=71).

    On the Adobe AIR side, I will try to use Native Process class to communicate with an external process that sends the data to the USB port where this cable is connected to. I don’t understand very much about electronics or parallel communication. This adapter is recognized by Windows like “IEEE 1284 controller”. There is no COM port assigned to the adapter because it is USB connected, identified as “USB printer compatibility”. Do you have an idea if I can use SerialSend to send some information to this adapter? If not, do you know about any other option? A command-line program like yours would be a good solution.

    Thank you very much! Saludos!

    • batchloaf says:

      Hi Elder,

      This is an interesting problem. I should preface what I’m about to say by clarifying that I don’t know a lot about parallel port interfacing, so I could have this completely wrong, but I think this might end up being easier than you think!

      Back when PCs ran DOS, printer ports (i.e. parallel ports) appeared as special device files with names like LPT1 and LPT2. These device files were equivalent to the likes of COM1, COM2, etc for serial ports. Anyway, you could use these device filenames to interact with a parallel port at the command line, and I think it’s possible that it might still work in Windows today. Serial ports can still be accessed this way, so my hope is that your USB parallel port adapter may also appear as LPT1 and that you can send text or other data to it directly from the command line.

      To send the string “hello” to your parallel port, open a command window and try something like this…

      echo "hello" > LPT1
      

      If you want, you could store some bytes in a file and send the file to LPT1 as follows…

      copy /b mybytes.txt LPT1
      

      …or maybe this…

      type mybytes.txt > LPT1
      

      Can you try the commands above and see if anything happens?
      Also, what exactly do you need to send to the microcontroller? Is it a stream of data, or are you just trying to set some lines high and some lines low in the parallel port? If it’s the latter, then you may only need to write one character at a time to LPT1.

      Ted

      • Elder Soares says:

        Great, Ted…thank you very much. I tried your solution and it worked! Actually, what I need is just setting high and low lines, but also GETTING lines from the machine on the other side. With your idea, I was able to send data, now I have to figure out how to receive… Any idea?

        Thank you again!

  52. maria says:

    Hello Ted!
    Thank you very much for your codes, they are very helpful!! I want to send serial commands like “#5 P1600 S750 ” to an SSC32 Board so i can move an AL5D robotic arm, but i don’t want to do this in the command prompt, I want to write a programme with these commands so i can send many commands when an event occurs. Is that possible? Can you help me pls?? Thank you very much!!

    • batchloaf says:

      Hi Maria,

      That should be possible, but can you describe what you’re trying to do in a bit more detail. When you say “send many commands when an event occurs”, what kind of event are you talking about? And how is the event detected?

      Ted

      • maria says:

        I have to make a project where I will connect a kinect with a robotic arm, and when I move my hand, the robot will make the same move. So i want to take the coordinates from the kinect, transform them into commands like “#5 P1600 S750 ” and send it to the robotic arm by the serial send. I want to make a program with three steps, 1. take the coordinates from my hand with the kinect, 2. transform them to robotic arm commands, 3. send the commands to the robotic arm. I have problem with the 3rd step! It will be a big help if you can help me!! Thank you very much!

      • batchloaf says:

        Hi Maria,

        What programming language are you using to read the coordinates from the Kinect? The best way to run SerialSend (or send the serial command another way) will depend on what programming language you’re already working in for the Kinect part.

        Ted

  53. maria says:

    Hi Ted,

    Thanks for the reply! The code to read the coordinates from the kinect is also written in c++ programming language. I want to make this project only with c++, the kinect part and the translation of the coordinates to robotic arm commands are ready, the only problem I have is with the serial send. I just want a code (commands) for the serial send that I can use in an IF statement or a FOR loop to tell to the robot what it should do.

    Thank you!

    • batchloaf says:

      Hi Maria,

      I should say up front that what I’m about to suggest is not very elegant, but if you’re just looking for a quick way to send some text via serial from your C++ program, you could do worse than use the C Standard Library’s “system” function (#include ) to run SerialSend.

      For example,

      #include 
      
      if (WHATEVER)
      {
          system("SerialSend \"#5 P1600 S750\"");
      }
      

      If you’re using C++ rather than C, then maybe you should “#include ” rather than “#include “, but I’m just guessing about that.

      Would that solve your problem?

      Ted

  54. Burak says:

    Hi Ted , It’s me once again .
    BTW thanks once more for helping me with comprinter app .. Now I need to ask you sth ..
    I wanna send data to one of my serial ports eg.com3 using batch commands … But when I use such a command snippet like ;

    set /p x=3 \\.\COM3
    It sends ascii 3 to my MCU , but I want it to send decimal 3 ..
    How I can sort this problem out ?

    • batchloaf says:

      Hi Burak,

      I’m assuming you mean that you want to send a single byte with the value 3 to the serial device? If so, I can’t remember exactly how to do it with built-in command line commands (such as “set”). However, you can certainly do this using SerialSend, which allows you to send arbitrary bytes (specified as hex values) to whatever serial device you want.

      Just do something like this:

      SerialSend.exe /hex "\x03"
      

      Hope that helps!

      Ted

      • batchloaf says:

        Another thought…

        Have a look at my conversation with Elder above. He was able to send some bytes to a printer port (parallel port) using only built-in commands. He stored the bytes he wanted to send in a file and then used either the “copy” or “type” commands to pipe the bytes to the printer port. Surely the same approach could work for the serial port?

        That would definitely be worth a try if you want to do it with built-in commands and you only want to send the same byte value each time.

        Ted

  55. Viva Foxpro says:

    Hello Sir!

    Your program SerialSend will prove useful in a hobby project of mine where I will control an arduino via USB virtual port.

    Thank you and more power !

  56. Jason says:

    Ted,
    Thank you so kindly for writing this excellent software.
    I am having a HUGE problem though… a problem actually obtaining the .exe file and most recent source code. You have hosted the software on a Google drive dropbox, and I am attempting to download it with a number of Apple handheld devices (iPhone, 2 iPads, and an iPod)… using 4 different browser software packages. COMPLETE fail… Google just doesn’t want to talk to Apple devices for the download!
    Any chance you could give a simple DIRECT download link, or emsil me the files? This utility is EXACTLY what I’m looking for – but I fear I may never have the chance to try it if I can’t download it.
    Very grateful,
    Jason

    • batchloaf says:

      Hi Jason,

      I’ve uploaded a copy of the current version of the exe file to a webserver where you should hopefully be able to download it without problems:

      http://signalswim.com/SerialSend/SerialSend.exe

      The current version of the C code is exactly what’s shown on the page above, so you can just cut and paste that into a plain text file and save it (which is exactly what I do – I’m not very disciplined on source control, I’m afraid!)

      A quick word of warning: You mentioned that you’re using several Mac devices (iPhone, iPad, iPod). Please be aware that SerialSend is a Windows program and although I understand Mac OS can run some Windows software now, I’ve never tried running SerialSend on a Mac. Although it may be possible, I’m not sure how to do it and I’m not sure if anyone has done it either. No harm trying though!

      Best of luck.

      Ted

  57. jed says:

    Thanks for the great little utility – it works perfectly! Only change I would make is to add a /? or /help switch so I don’t have to keep referring back to the website🙂

  58. Naomi says:

    Hi Ted,
    I’m using a slightly modified version of your code to send data to a microcontroller over bluetooth. The first time I run it, everything works fine, but if I try to run the code again, it has an error opening the COM port (I don’t bother searching for ports; my bluetooth dongle always connects on COM6). I’m guessing the call to CloseHandle doesn’t actually close the port correctly for virtual bluetooth ports (even after I unplug the bluetooth, there’s a problem on the PC side — I have to re-login to connect to the serial port again). Any idea how to fix this?
    Thanks for posting the code!
    -Naomi

    • batchloaf says:

      Hi Naomi,

      Hmmm, interesting problem. Since I don’t know what you’ve changed in the code, I’m just going to speculate based on what’s in the original SerialSend code.

      Does it print any error? Specifically, I’m wondering whether the CloseHandle call returns a value indicating that it failed to close the COM port. I’m guessing it doesn’t print an error, since you’d probably have mentioned it. However, if it is printing an error, I would suggest trying something like the following:

          // Try to close serial port, repeatedly if necessary
          fprintf(stderr, "Closing serial port...");
          while (CloseHandle(hSerial) == 0)
          {
              // CloseHandle returns zero when it fails
              fprintf(stderr, "."); // Print a full stop each time
              Sleep(500);           // 500ms delay
          }
          fprintf(stderr, "OK\n");
      

      Speaking of which, here’s another idea you could try. This is just speculation (I’m literally making this up as I’m typing it), based on the fact that you’re transmitting via Bluetooth rather than a regular wired serial connection. What if the closing the COM port doesn’t work properly while there’s still data waiting to be transmitted? Your program might have written it to the serial port, but it’s actually still sitting in a buffer waiting to be processed by the Bluetooth stack. In case something like this is happening, maybe you could try just inserting a couple of seconds delay into the program just before you call CloseHandle.

          // Close serial port
          fprintf(stderr, "Short delay before closing COM port, just in case...\n");
          Sleep(2000);
          fprintf(stderr, "Closing serial port...");
          if (CloseHandle(hSerial) == 0)
          {
              fprintf(stderr, "Error\n", dev_name);
              return 1;
          }
          fprintf(stderr, "OK\n");
      

      I’m kind of clutching at straws here, so I’ll have to give it a bit more thought and see if there’s something else I can suggest. Please let me know if you make any progress!

      Ted

  59. Naomi says:

    Thanks for the quick reply!

    Well, I haven’t tested it extensively yet, but everything is working fine now and I think you were on to something with the delay. I haven’t been as thorough as I probably should be in testing this project, but in any case I needed to add a delay to the send loop (which delays before closing the port as well) and the com port now closes and reopens just fine!

    // Keep generating new boards until a ‘q’ is received
    while (myKey[0] != ‘q’) {

    initRules(rules);

    // Send “Rules” array to Arduino
    DWORD bytes_written;
    fprintf(stderr, “Sending rules… “);
    if(!WriteFile(hSerial, rules, 21, &bytes_written, NULL))
    {
    fprintf(stderr, “Error writing text.\n”);
    CloseHandle(hSerial);
    return 1;
    }
    fprintf(stderr, “Ok.\n”);
    fprintf(stderr, “Rank the board 0-9, or q to quit: “);

    scanf(“%s”, myKey);

    // Tell the Arduino to stop when myKey is received
    if(!WriteFile(hSerial, myKey, 1, &bytes_written, NULL))
    {
    fprintf(stderr, “Error sending key.\n”);
    CloseHandle(hSerial);
    return 1;
    }
    fprintf(stderr, “\n%c sent successfully.”, myKey[0]);
    Sleep(500); // Give Arduino time to reset
    }

    • batchloaf says:

      Well, that’s interesting! I’ll have to do some experiments with SerialSend to see whether I observe the same problem with Bluetooth COM ports. If so, maybe I can incorporate something similar to your solution to fix it.

      A couple of questions:

      1. What Bluetooth adapter (or chipset?) and version of Windows are you using? I’m just wondering in case I have difficulty replicating your original issue.

      2. What are all these boards you’re ranking? Sounds like you’re working on something interesting!

      Ted

      • Naomi says:

        1. It looks like I may have jumped the gun a little in assuming it was the code–I’m running Windows 7 x64 in a virtual box on my Mac and now it’s abruptly having issues accessing the USB COM port. The joys of hardware debugging! I’m connecting to a HC-06 bluetooth chip.

        2. Right now the project is almost entirely in hardware stage, but the end goal is using combination user input/genetic algorithm to evolve LED displays. Right now I send simple sets of rules over the bluetooth connection for the Arduino to use in driving a 16×16 LED matrix. (A grid of 4 of these obscenely bright neoMatrices: http://www.adafruit.com/product/1487)

        Thanks again!
        Naomi

      • batchloaf says:

        Hi Naomi,

        Gosh, it sounds as if you’re growing some biomorphs! If so, I hope it goes well. When I read about those in Dawkins’ The Blind Watchmaker a few years ago, it blew my mind, but I never got around to trying it for myself.

        I love that NeoMatrix.

        In case you’d like to speed up your selection iterations a tiny bit, you could swap that scanf() call for something like _getch() or _getche() which allow you to receive a keystroke without the user pressing return (at least, they do in Windows). The two versions of the function are with and without echo to screen respectively. Something like this should do it:

        //scanf(“%s”, myKey);
        mykey[0] = _getche();
        

        You might need to…

        #include <conio.h>
        

        VirtualBox is an amazing piece of technology, but it does seem to kind of stretch the limits of interfacing to hardware, so I’m not too surprised that you’re hitting a few glitches opening and closing ports. Anyway, I hope you get it all sorted out. It sounds like a fascinating project – best of luck getting it all working.

        Ted

      • batchloaf says:

        PS Following our previous exchange, and especially what I said about _getch(), I decided to spend a little time yesterday playing around with Python/Tkinter to make a really simple GUI for sending keystrokes via serial. It’s only about 30 lines of code. Just in case it could be useful for your project, perhaps it might be worth taking a quick look:

        https://batchloaf.wordpress.com/2015/03/10/very-simple-python-tkinter-gui-to-send-selected-keystrokes-via-serial-port/

        Ted

  60. Pradyumna Vasudevan says:

    Hey Ted,
    I’m a newbie to batch files. I’ve a weird glitch that i’m encountering off late. I’ve to send a value to PIC controller through a batch file. The code is as follows:

    mode COM3 BAUD=9600 PARITY=n DATA=8
    set x=2500
    echo %x%>COM3
    pause

    I’ve programmed my PIC to turn on
    LED 0 for value between 0 to 1000
    LED 1 for value between 1001 to 2000 and so on till LED3

    I’ve performed ASCII to integer conversion(32 bit as value exceeds 255) in my CCS compiler for PIC

    I sent the values over several iterations through hyperterminal and it works perfectly.
    The trouble arises when i call my batch file.
    1)When i call the batch file the first time(value being 2500), the desired LED 2 glows.
    But the next time i call it, it automatically makes LED 0 glow though there’s no change in the code.
    The LED does not change after the first attempt.
    2)However, when i press hardware RESET in PIC, the batch file works perfectly once and then reverts to LED 0 again.
    3)Also, When i sent the value that’s being sent to COM into a text file using
    COPY COM1 a.txt
    I noticed something weird

    For first call,
    2500

    For further calls
    250
    0

    Its indeed puzzling as it works perfectly in hyperterminal. But only for the first time in batch file.

    I was puzzled over
    1. echo command sending CR or NULL character, but then as i said, it works perfectly the first time.
    2. Buffer register of PIC getting full. (but it works perfectly via hyperterminal)

    I even used interrupt handlers from PIC side. I’m running out of ideas. I would be obliged if you could help me out of this.

    Thanks Ted🙂

    • batchloaf says:

      Hi Pradyumna,

      Interesting problem. I’ve struggled with similar seemingly straightforward tasks in the past. I’ll try to remember some of the things I did to solve it.

      I have some questions:

      1. Which PIC exactly are you using?

      2. What programmer are you using – is it a PICkit 2?

      3. What compiler are you using? Is “CCS” Code Composer Studio?

      4. What’s the C code you’re using to receive the number at the PIC end? To me, this seems like the most likely source of the problem. For example, the line ending character(s) may not be parsed correctly. Normally, I read the characters one by one and write the code to parse the character myself rather than using a library function. That way, I can keep reading characters until I get something that’s not a digit.

      5. Did you try changing the following line…
      echo %x%>COM3
      …to something like this…
      echo %x%
      …to verify that the echo command is definitely sending the text you think it’s sending?

      6. Since the batch file seems to work the first time you run it, did you try changing it so that it sends a value other than 2500 the first time? It would be interesting to know if it works correctly the first time for every value. Is it possible that it’s just a coincidence that LED2 comes on the first time?

      7. When you say “COPY COM1 a.txt”, does that mean that you have a 2-way serial connection, but the return connection is on COM1 rather than COM3?

      It’s suspicious that you get back the numbers “2500” followed by “250” and then “0” over and over. As I recall, most of the PICs I’ve used in recent years have had a 4 character serial receive buffer, so if you send a 4-digit number followed by a line ending character (or two), then depending on how the library function handles it, you could be right about the buffer filling up. If so, I could suggest some code to catch the digits one by one as they arrive and parse the number yourself.

      Sorry for all the questions, but I’m just trying to get a handle on the problem.

      Ted

      • Pradyumna Vasudevan says:

        Hey there Ted,
        Thanks a lot for your prompt response and your time to patiently read through my problem!🙂

        My apologies for not being clear on certain details. I’d gladly answer your questions as per your order of questions along with slight modifications to my previous comment.

        1. I’m using a PIC16F877A in a PIC development board

        2. I’m currently using a PICkit 3 programmer

        3. “CCS” Code Composer Studio

        4. Here’s my code(btw, using MPLAB IDE v 8.92)

        #include
        #include
        #include
        #fuses HS,WDT, NOPROTECT, NOLVP
        #use delay(clock=20000000)
        #use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
        #priority INT_RDA
        int1 g_bSendRequest;

        void SendChar(int8 value)
        {
        g_bSendRequest = true;
        putc(value);
        }
        #INT_RDA
        void SerialDataReceive()
        {
        int8 rxData;

        rxData = getchar();

        if (g_bSendRequest)
        {
        g_bSendRequest = false;
        return;
        }

        SendChar(0xFF – rxData);
        } //tried without interrupt handling, encountering the same problem
        void main()
        {
        set_tris_b(0);
        output_b(0);
        char data[4],c; //tried increasing the data size to data[11] in vain
        //data[4]=”; // also tried terminating using null charater in vain
        int i;
        int32 a; // as it started giving negative values over the value of 255
        enable_interrupts(INT_RDA);
        while(1)
        {
        delay_ms(100);
        fgets(data);
        data[4]=”; //as i believe it should receive only first four digits, tried commenting this line as well
        a=atoi32(data);
        delay_ms(100);
        //printf(“%ld”,a); //surprisingly, no error was encountered in hyperterminal
        if((a>=0)&&(a=1000)&&(a=2000)&&(a=3000)&&(aCOM3 as its working fine in hyperterminal and PIC responds perfectly without any overflow.🙂

        6. Yes, I did just that. I tried sending different values over varied ranges.
        When I give a value of 500, it turns ON the LED 0 for the first time(and the it does remain to the same LED 0 as there for this value there should be no change)
        When I give a value of 1500, it turns ON the LED 1 for the first time(and then it reverts to LED 0 from next call, but again only when running batch files)
        When I give different ranges one after the other, it works perfectly for first call n whatever the next value is, LED 0 turns ON

        7. One of the modifications is that it should be COM3 rather than COM1. I erred while posting it over here. My apologies.
        Another modification is that

        For first call,
        2500

        For further calls
        250
        0

        the above modifiers were removed when i posted it earlier.

        Hope u’ve got a better grip over the situation. Thanks for your time.
        Would be obliged if you could solve the mystery behind it!
        Thanks Ted.🙂

      • Pradyumna Vasudevan says:

        Hey Ted,
        The wordpress deletes the modifiers that I used.
        Here’s the actual output into the text file.

        For first call,
        2500

        For further calls
        250(spAce)(eNter)
        (sPace)(TaB)0

        Also, I tried receiving the digits one by one using for loop instead of fgets

        for(i=0;i<4;i++)
        {
        data[i]=getc();
        }
        a=atoi32(data);

        //This code reacted the same way as well.I just had a hunch that it might be the spaces and tabs which are creating the problem through batch file but not via hyperterminal where these modifiers never appear.

        Thanks again, Ted.🙂

      • batchloaf says:

        Hi Pradyumna,

        This won’t solve all of the problems, but you definitely do need to increase the size of that character buffer called “data”:

        char data[4],c;
        

        …should be something like this…

        char data[10],c;
        

        …in order to leave plenty of room for line ending character(s) and null terminating character. The end of each normal C string is marked by a so-called null terminating character (a zero byte) which is just after the last ascii character in the string. When you allocate a char buffer to store a string, you need to leave at least one extra char to store the null terminator – otherwise string processing functions like fgets and atoi etc will not behave correctly. In this case, there may also be one or more line ending characters such as ‘\n’ and/or ‘\r’ sent after each set of four digits.

        I’m confused by this line:

        SendChar(0xFF - rxData);
        

        It seems like before you echo the byte back to the PC, you’re inverting every bit, but I’m not sure why you would need to do this.

        Anyway, what I’m most concerned about is that your SerialDataReceive interrupt service routine (ISR) and your main function look like they’re effectively competing to receive the incoming data (and the ISR will probably always win that fight). The main function therefore may not be receiving data at all. As an experiment, I would suggest removing the ISR and just letting the main function receive all the characters. Something like this…

        #include 
        #include <?????????.h>
        #include <?????????.h>
        #fuses HS,WDT, NOPROTECT, NOLVP
        #use delay(clock=20000000)
        #use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)
        #priority INT_RDA
        
        int1 g_bSendRequest;
        
        void SendChar(int8 value)
        {
            g_bSendRequest = true;
            putc(value);
        }
        
        void main()
        {
            set_tris_b(0);
            output_b(0);
            
            char c;        // used to store each received character
            int32 digit;   // used to store numerical value of each received digit
            int32 number;  // used to construct the final value of a string of digits
            
            // This main loop should iterate once for each number received.
            // (It may also iterate if a non-digit character is received
            //  before any digits have been received - i.e. not a number.)
            while(1)
            {
                // Receive and parse a number comprising several digits
                number = 0;                             // this will store the final number
                while(1)
                {
                    c = getchar();                      // receive a character
                    if (c >= '0' && c <= '9')           // if the character is a digit
                    {
                        digit = c - '0';                // convert digit character to number
                        number = (10 * number) + digit; // shift existing digits up one and add new digit
                    }
                    else break;                         // if not a digit, exit this loop
                }
                
                // For debugging, send the number back to the PC
                printf("%ld",number);
                
                if (number == 0)
                {
                    // This just means that a non-digit character was received
                    // before any digits. This could happen if the PC sends
                    // more than one line terminating characters at the end
                    // of a number that it has sent. The number will get parsed
                    // as soon as the first non-digit char is received, so any
                    // further characters that arrive before the next set of
                    // digits should be ignored. i.e. DO NOTHING HERE!
                }
                else if (number > 0 && number < 1000)
                {
                    // Light LED 0
                }
                else if (number >= 1000 && number < 2000)
                {
                    // Light LED 1
                }
                else if (number >= 2000 && number < 3000)
                {
                    // Light LED 2
                }
                else if (number >= 3000 && number < 4000)
                {
                    // Light LED 3
                }
            }
        }
        

        I know it already seems to be working in hyperterminal, but the problem may relate to the line ending characters that are being sent, so my intention with the above code is to robustly filter out any non-digit characters.

        Ted

  61. Pradyumna Vasudevan says:

    Hey Ted,
    Thanks a lot. That seemed to have solved the problem.:)🙂
    I do have one small question.
    I also send the value 0 to PIC and in that case(according to the program), it does nothing.
    Am puzzled as to where to use a flag variable in this program.

    Thanks a lot Ted. Just loved the way you approached this problem!🙂

    • batchloaf says:

      Hi Pradyumna,

      Wow, I’m glad (and pleasantly surprised) that solved it!

      I didn’t realise that you needed to send zero as a value also, but it’s no big deal. Just replace the original main function with the one below. I added a variable called digit_count that counts up the number of digits received in each number. There’s no problem receiving zero now because it uses digit_count to check if whatever was received wasn’t a number at all.

      Everything other than the main function is the same as before. Ok, here’s the updated version…

      void main()
      {
          set_tris_b(0);
          output_b(0);
          
          char c;          // used to store each received character
          int digit_count; // used to count how many digits were received in each number
          int32 digit;     // used to store numerical value of each received digit
          int32 number;    // used to construct the final value of a string of digits
          
          // This main loop should iterate once for each number received.
          // (It may also iterate if a non-digit character is received
          //  before any digits have been received - i.e. not a number.)
          while(1)
          {
              // Receive and parse a number comprising several digits
              number = 0;                             // this will store the final number
              digit_count = 0;                        // reset digit counter
              while(1)
              {
                  c = getchar();                      // receive a character
                  if (c >= '0' && c <= '9')           // if the character is a digit
                  {
                      digit_count = digit_count + 1;  // count this digit
                      digit = c - '0';                // convert digit character to number
                      number = (10 * number) + digit; // shift existing digits up one and add new digit
                  }
                  else break;                         // if not a digit, exit this loop
              }
              
              // For debugging, send the number back to the PC
              printf("%ld",number);
              
              if (digit_count == 0)
              {
                  // This just means that a non-digit character was received
                  // before any digits. This could happen if the PC sends
                  // more than one line terminating characters at the end
                  // of a number that it has sent. The number will get parsed
                  // as soon as the first non-digit char is received, so any
                  // further characters that arrive before the next set of
                  // digits should be ignored. i.e. DO NOTHING HERE!
              }
              else if (number >= 0 && number < 1000)
              {
                  // Light LED 0
              }
              else if (number >= 1000 && number < 2000)
              {
                  // Light LED 1
              }
              else if (number >= 2000 && number < 3000)
              {
                  // Light LED 2
              }
              else if (number >= 3000 && number < 4000)
              {
                  // Light LED 3
              }
          }
      }
      

      I hope that works for you.

      Ted

      • Pradyumna Vasudevan says:

        Ted!!!
        Typing out thanks would never suffice. We were trying with a flag variable with same logic and it didn’t work initially.
        Finally, we modified the batch file value from 0 to 000 and VOILA, it worked.
        My friend Siva too is elated and conveyed his thanks to you!!!🙂 🙂 🙂
        We thought we were at a deadlock and found a way through you!🙂
        Thanks a ton once again Ted!!🙂🙂🙂
        Finally, can u elaborate on why it worked perfectly with hyperterminal and not with Batch file earlier(which made me refrain from changing PIC code)
        I’d really like to know about it.
        Thanks Ted!!🙂🙂🙂

      • batchloaf says:

        Hi Pradyumna (and Siva),

        To be honest, I’m not 100% sure why it worked in HyperTerminal but not with your batch file, but I suspect it’s to do with the line ending characters. When you “echo” something to a COM port, I’m pretty sure one or two line ending characters get sent along after the text you send. For example, it might append ‘\n’ (newline) or ‘\r\n’ (carriage return, newline) or something like that. Your microcontroller receives that character (or characters) and you need to process them too so that they don’t disrupt the parsing of the incoming digits. It’s possible that HyperTerminal was configured to send a different type of line ending character, or even none at all if you set it to send the characters one at a time as you typed them.

        So basically, I think the problem was the extra (non-printable) line ending character(s) that the “echo” command is attaching to your text when you send it.

        Personally, I find newline characters really confusing and I’m never sure exactly what bytes are being transmitted. If you want to read more about how confusing it is, check this out:

        http://en.wikipedia.org/wiki/Newline

        Anyway, I’m delighted you got it working. I hope you get the rest of your system up and running!

        Ted

      • Pradyumna Vasudevan says:

        Hey there Ted,
        Oh, I came across the echo command behaving this way in your earlier blogs but couldn’t find a way to handle it.
        Yeah, sure, I’ll look into the wiki link about newline!🙂
        I’m just amazed at your patience and thanks to you, I’ll follow your blogs and get to know more about interesting electronics and coding!🙂
        With your guidance, we’ll definitely get the system up and running!🙂🙂
        Inspired and motivated thanks to you!🙂
        Keep blogging Ted!🙂🙂🙂

      • Pradyumna Vasudevan says:

        Hey there Ted!!!
        I need another help from you…
        Can you tell me a way to receive a serial character from PIC (reflection of printf from PIC)
        I need the batch file to receive serial character and send the same to an excel cell.
        I tried copying it to a text file using “copy COM1 data.txt” command. I’m not sure of the path file directory of the text file. (Both the batch file and text file are in the same location i.e. desktop) I’m not able to get the value in that text file.
        The text file was used to help me understand the syntax of the code but I was unsuccessful with that.
        I’d be delighted if you could help me with sending over the data to an excel file.
        Thanks Ted.

  62. Jon says:

    Hi Ted,
    Great little program, but I’m having trouble communicating to one device.
    Have you ever had issues talking to a Silicon Labs USB to serial adaptor using CP210x?
    It seems to work fine with FTDI adaptors.
    The trouble is the Silicon Labs device is embedded so I cant use anything else. The product that it is fitted to works with other terminal programs, just not this one.
    I know I’m sending the correct command, baud and COM port etc.
    Using serial send and termite together, I can send a command from Serial Send to Termite and then get Termite to forward the command to the device I’m trying to control and it works. I can see the command I send displayed in Termite and its correct. Obviously Serial Send, in this scenario is not controlling the device, but proves I’m sending the correct info. Any ideas??

    Best regards
    Jon

    • batchloaf says:

      Hi Jon,

      That’s a strange problem! As far as I’m aware, I haven’t ever connected to a CP210x device. However, SerialSend simply opens the serial port via Windows’ normal API functions, so it doesn’t really treat different manufacturers’ devices differently. Is it possible that it’s just something to do with the exact serial port configuration that’s being used by default in Termite?

      Can you list the exact settings of the serial connection between Termite and the CP210x? (baudrate, parity, bits per byte, etc.)

      Ted

  63. Jon says:

    Hi Ted,
    Termite is setup using COM5 57600 baud 8N1 no handshake
    Serial Send, I’m sending this: serialsend.exe /devnum 5 /baudrate 57600 /hex “*NVM SETVOL 30\r”
    Jon

    • batchloaf says:

      Hi Jon,

      Is it possible that Termite is modifying the line ending character(s) at the end of the message? Perhaps you could try each of the following…

      serialsend.exe /devnum 5 /baudrate 57600 /hex "*NVM SETVOL 30\n"
      

      or this…

      serialsend.exe /devnum 5 /baudrate 57600 /hex "*NVM SETVOL 30\r\n"
      

      or this…

      serialsend.exe /devnum 5 /baudrate 57600 /hex "*NVM SETVOL 30\n\r"
      

      Ted

  64. Jon says:

    Hi Ted,
    I think I tried all those but will do it again and report back

    Jon

  65. Jon says:

    Hi Ted,
    Tried all those combos and none of them work.
    Termite is using CR by the way, but also works with LF and CR-LF.
    I’m running windows 7 64 bit, if that helps any more.

    Jon

  66. Jon says:

    Hi Ted,
    This is what I get if I use command prompt.
    C:\Users\test-engineering\Desktop>serialsend.exe /devnum 5 /baudrate 57600 /hex
    “*NVM TESTSCREEN ON\r”
    Device number 5 specified
    57600 baud specified
    Searching serial ports…
    Trying COM5…OK
    Sending text…
    19 bytes written to \\.\COM5
    Closing serial port…OK

    Jon

  67. Jon says:

    Hi Ted,
    Thanks for helping with this issue, but I’m sorry to say it’s the same.

    C:\Users\test-engineering\Desktop>serialsend.exe /devnum 5 /baudrate 57600 /hex
    “*NVM TESTSCREEN ON\r”
    SerialSend (last updated 8-4-2015)
    See http://batchloaf.com for more information
    Device number 5 specified
    57600 baud specified
    Searching serial ports…
    Trying COM5…OK
    Sending text…
    19 bytes written to \\.\COM5
    Closing serial port…OK

    Jon

  68. Jon says:

    Hi Ted,
    You have cracked it!!! Works a treat now.
    So the Silicon Labs device is a bit slow at responding then??
    Is the delay time adjustable?

    Jon

    • batchloaf says:

      Hi Jon,

      Phew, that’s a relief! As it stands, I just hard-coded the two 500ms delays into the program before and after the command to flush the buffer, but I suppose it would be better to add an option which allows the user to tailor the delay to their requirements.

      If you don’t mind helping me out with this one more time, I’ll make the change quickly now and then ask you to test it with your device to see that it still works. Initially, I’ll try getting rid of the first delay and making the second one configurable. Hopefully, that will be sufficient.

      Oh, and I’m not sure why the Silicon Labs device responds this way, but since it does it’s probably not the only device that works that way, so there’s no harm updating SerialSend to cope with this requirement.

      Ted

      • batchloaf says:

        Ok, I’ve updated the program again and replaced the main download with the new version. I added a “/closedelay” command line option that allows you to specify a delay in milliseconds after the text is transmitted, but before the serial port is closed. Please try downloading the new exe file from the main download link at the top of the page and then run it using a command something like this:

        SerialSend.exe /devnum 5 /baudrate 57600 /closedelay 500 /hex"*NVM TESTSCREEN ON\r"
        

        Hopefully that will work, and should let you pare back the delay until you find how long it actually needs to be.

        Ted

  69. Jon says:

    Thanks Ted,
    No worries, send the new version as soon as you are ready and I will test it out.

    Jon

  70. Jon says:

    Hi Ted,
    Sorry, do I download from the old link above or have you forgotten to post the link?

    Jon

  71. Jon says:

    Hi Ted,
    Sorry my post crossed with yours and then I did not read properly.
    That seems to work I find that I need about 20ms of delay to make it work reliably🙂

    Thanks for all your help with fixing this issue.
    Best regards
    Jon

    • batchloaf says:

      Great!! Thanks for testing all those versions. Hopefully other users will benefit from the update too.

      Best of luck getting whatever your building working.

      Ted

  72. Jon says:

    Thanks Ted,
    This is all for RS232 control of various devices using Audio Precision audio analysers to control them using external program calls with arguments.

    Thanks again for providing a very useful tool.

    Jon

  73. maria says:

    Hi Ted,
    i am new in serial communications and i need some help! I am trying to send some data to an arduino Uno board via a c++ code on visual studio. I just want to send some integers like 1800 but i don’t know how to do this. Some examples i try didn’t work. I download your code but i don’t know what I have to change to make it work like i want. Can you help me pls? I just want a simple serial send code that while open the COM port 23 with baud rate 9600 and send integer data like 1800,1700,2000 etc. Pls help me!
    Thank you!

    • batchloaf says:

      Hi Maria,

      Sorry I didn’t get a chance to repond to this message when you posted it. I was snowed under last semester and I’m only clearing the backlog now. Hopefully you got your problem sorted in the meantime!

      Ted

  74. Michael Schrøder says:

    Is it possible to send to a specific address, have some displays have different address.

    maybe send “Hallo” to address 1 and “World” to address 2, only as a test.

    • batchloaf says:

      Hi Michael,

      I’m a bit confused by your question. The kind of serial connection that SerialSend works over (basically RS232) is normally point-to-point (one device at either end of the link) so there isn’t normally any need for addressing. Each device just sends whatever it’s sending down the line and it arrives at the other device.

      Are you sending to more than one device on the same COM port, or do you mean that you’re sending to multiple devices but each has its own COM port. If it’s the latter then you just need to know which COM port number each device is on.

      Ted

  75. siva says:

    Hi Ted,
    I am sorry if i miss the whole number of threads.
    I am trying to communicate with an FPGA from my PC through USB to UART cable.
    I use teraterm to enter the characters and read the output on the screen.
    I want to use your program to do the same.
    I am able to send characters using : SerialSend.exe /baudrate 9600 “c\r”
    How to I read the UART output from FPGA in my PC? If it is a teraterm I enter the characters and read the output on the same console. How do I do the same using SerialSend

    • batchloaf says:

      Hi Siva,

      Unfortunately, SerialSend doesn’t really do what you want. It’s really just intended for sending simple byte sequences to a device. It’s not designed to handle two way interaction at all.

      What I use when I need to automate some two-way interaction is Python with the PySerial module. It’s free and simple to download and install and it provides brilliant flexibility if you need to chatter away to a device over a 2-way serial link.

      I think there are some Python examples further up the comments on this page that I suggested to other people who wanted to do something similar to you.

      Ted

  76. Jon says:

    Hi Ted,
    Been using this GREAT program since our last chat in April and it has bee working fine.
    Today however using one bit of equipment, I have found the need for a delay between commands.
    Is this possible?? Example below of what I’m sending.
    /hex “COMMAND 1″\r/hex “COMMAND 2″\r/hex “COMMAND 3″\r
    I need an adjustable delay after each CR or LF or both should the need arise.
    Can you help me out with this request please?

    Best regards
    Jon

  77. Sam says:

    Do you know any free Virtual serial ports programs-
    I have a old program that can only accept information via serial I want to create a virtual serial port and us “serialsend” to sen it info…

    The one I found are geared to network serials but I want to leave it all local.

    Thansk

  78. hossam zayed says:

    Hi Ted,
    Thanks a lot for your effort , I’m not an expert in programming but could you please help us with this.
    we are a team of 4 engineers from Egypt working on a Flight Simulation Rig that rotates 360 degrees on 2 axis. We managed to build the simulation Rig and test it with a game (HAWX). it performs pretty well but after a few min of playing a time shift between the simulation and the rig appears.
    So we decided that we need feedback from the game it self with the plane exact angle of rotation on both x an y axis so we can compare it with the cabin orientation using the gyro on it , and the best way to do that is build a simple flight sim game using Cry engine and take the needed readings from it.
    So here is the question :
    How can we integrate your code with cry-engine to make it send the plane information of rotation on both x.y axis over serial to our micro-controller (Arduino Leonardo).
    we just need to send a simple string like (sx180y090e)
    Where s is the start character x 180 degrees y 90 degrees and e is the end character.
    we would really appreciate your feedback, and thanks again

    • batchloaf says:

      Hi Hossam,

      Sorry for the long delay in responding, I was inundated with correspondence at the end of term and I didn’t get a chance to reply. Then I was away on holidays. Are you still trying to solve the problem or is it all done now?

      Ted

  79. R Boopathi says:

    hi
    I want to receive data from serial port.
    I want that the character received to be displayed afthier command prompt
    can anyone reply to ” bimmtechnologies@gmail.com” or a reply here
    thanks
    R Boopat

  80. Shimon Dahan says:

    Hi Ted
    I’m using your SerialSend.c code for sending to my target HW a reboot command. i.e. sending the text: “reboot\r” at baudrate of 11520 to com43. –> It does not work.
    When I try this in Tera Terminal it works OK.
    Can you help solve this, sind I preffer using the SerialSecnd option.

    Thanks
    Shimon

    • batchloaf says:

      Hi Shimon,

      Can you post the exact command you’re using to run SerialSend please? It’s possible that you might need to do something different to send that carriage return character. Are you already including the “\hex” command line option? That’s necessary to send the ‘\r’ character.

      This would be my initial guess at the command you need:

      SerialSend.exe /baudrate 115200 /devnum 43 /hex "reboot\r"
      

      Also, is it possible that when you send it from Tera Terminal that one or more additional endline characters (such as ‘\n’ or ‘\r\n’) are being appended automatically? If so, you may need to add them explicitly to the string you send with SerialSend.

      Ted

      • Shimon Dahan says:

        Hi Ted

        Thanks for the response.
        I actually use the following command line:
        SerialSend.exe /baudrate 115200 /devnum 43 /hex “reboot\r”

        I get the following report:
        SerialSend (last updated 8-4-2015)
        See http://batchloaf.com for more information
        115200 baud specified
        Device number 43 specified
        Searching serial ports…
        Trying COM43…OK
        Sending text…
        7 bytes written to \\.\COM43
        Closing serial port…OK

        I actually try also to send “reboot\r\n” but no change, the target didn’t get the command.
        do you have any Idea why?

        Thanks again
        Shimon

      • batchloaf says:

        Hi Shimon,

        That’s strange! It looks as though SerialSend is successfully sending the characters. A couple of questions:
        1.) Is the serial device connected to your target device definitely COM43?

        2.) When you use Tera Terminal, what exact serial port settings do you use? You mentioned the baud rate (115200) but nothing about start bit, stop bit, parity, etc. SerialSend opens the serial connection for 8-bit bytes, 1 start bit, 1 stop bit, no parity bits. Is that definitely the same as you’re using in Tera Terminal?

        3.) What exactly do you type into Tera Terminal once the serial interface is up and running?

        4.) How do you have line endings configured in Tera Terminal? Does it send ‘\n’ or ‘\r’ or ‘\r\n’ at the end of each line?

        Sorry for all the questions, but I’m struggling to work out what the problem could be!

        Ted

  81. Shimon Dahan says:

    Hi Ted
    Regarding your questions:
    1. I verify that the serial device is COM43. (also in Tera Terminal the port is COM43)
    2. The serial port setting in Tera Terminal is the same as in serial send. –> Same parameters.
    3. I type the word reboot and then the Enter key.
    4. I did not add any line ending in the Tera Terminal (just type the word reboot and press the Enter key). I don’t know if the Tera Terminal add automatically a line ending.

    Thanks
    Shimon

    • batchloaf says:

      Hi Shimon,

      Regarding number 4 above, I think Tera Term does provide a way of configuring the type of line ending transmitted when you press Enter. I did a google image search and came up with this dialog box, which seems to allow line endings to be configure:

      Can you see if you can find that dialog under the menus somewhere and check what New-line / Transmit is set to.

      Ted

      • Shimon Dahan says:

        Hi Ted

        The configuration of my Tera Terminal is exactly like yours except for the New-Line->Reciever which is CR.

        Thanks
        Shimon

      • batchloaf says:

        Hmm, I’m afraid I’m running out of ideas then!

        What’s the target hardware, by the way?

        Ted

  82. Shimon Dahan says:

    It’s a cellular phone

    • Jon says:

      Hi Shimon,
      I had a similar issue back in May.
      Ted added a close delay option into the code, thus fixed the issue for me.
      (SerialSend.exe /devnum 5 /closedelay 500 “ABCD\r”)

      Jon

  83. Shimon Dahan says:

    Hi Ted and Jon
    I try your suggestion adding the option /closedelay 500, but it didn’t work.
    I think the problematic issue here is the end of line character that for some reason it didn’t send.
    I actually download other programs from the net that working through the same serial port and same setting and found that the problem occur also in some of them, but some are worked OK.

    I’ll keep update when I’ll found any news.

    Thanks
    Shimon

    • batchloaf says:

      Ok. thanks for the update Shimon. If I think of anything else, I’ll post it here.

      Ted

      • Barry McMahon says:

        COO-EEE Ted, I am a first time user of the serialsend.exe app downloaded from this site which reads as though it should be the bees knees for what I am trying to do. However I cannot get the /hex parameter to work .For example the command serialsend /baudrate 300/hex “abc/x0A” sends 7 bytes with the /x0A being interpreted as separate text characters (ie., 4 bytes}. I assume the \x are normalseparate keystrokes and not some non printing sequence.. I have looked at the source code above and although I don’t profess to be competent, it makes sense to me. I have also tried a couple of keyboards in case there is a hardware/ compatability issue.Another problem
        is that I can’t send DEL as a keyboard character, but I expect that I could get around this if the hex problem can be solved. Any chance the .exe file does not line up with the above source code?
        Best Regards, BAZ

  84. Barry McMahon says:

    PS Ted, I’ve just realized there is a typo in my comment. The command I am sending is serialsend /baudrate 300/hex “abc\x0A”.
    I am driving a plotter via a USB to serial adapter and the normal printing ascii chars sent are correctly received and plotted. Therefore I have put aside the possibility of communication problems.
    Regards, BAZ

    • batchloaf says:

      Hi Baz,

      Maybe this is just another typo in your comment (both of your comments actually), but it looks like there’s no space between “300” and “/hex”. There should be one between them for them to be read correctly. i.e. The command should be:

      serialsend /baudrate 300 /hex "abc\x0A"
      

      Could you give that a try please?

      All of the characters in the serialsend command are all normal typeable keyboard characters, including the “\x0A” which is just four normal keystrokes: backslash, x, 0 (as in zero) and A.

      Ted

      • batchloaf says:

        Oh, and to send a DEL character, I think you just send the hex byte 7F, for example using the following command:

        serialsend /baudrate 300 /hex "\x7F"
        

        Ted

  85. twister5800 says:

    Thanks for a great utility – exactly what I needed😉

  86. Raulp says:

    hi,
    Referring to “how can i have a carage return be sent at the end of the text ive sent?” , the second Qs of the blog by Josh, I wanted to try out the modification you suggested for the SerialSend source code.But unfortunately the source code given above seems different from what the SerialSend.exe is made up of.I tried building it (release mode X64,x86 platform) but the size is different form the one attached in this blog.Moreover the result of compiled one is not same as the one here.(i mean compiled one didnt work)
    My Target is to send the line read from a text file on a serial port, but unfortunately along with the null terminated(character)some junk values are also getting appended to the line and the receiver portion is not able to figure out the end of the line sequence and hence some mess at the receiver side.
    Thansk in advance !
    Rgds,
    Rp

    • batchloaf says:

      Hi Raulp,

      Did you compile it with GCC? I compiled it for 32-bit windows using GCC. I can’t tell you the exact gcc version I used because I don’t have my Windows laptop here, but it was probably a version from a couple of years ago because that’s when I installed MinGW, which contains gcc.

      If you’re trying to do something more complicated that just sending a simple one line command or something like that, then I would suggest looking at using something more flexible than SerialSend. Are you familiar with Python. When I need to set up a little serial chit-chat with a hardware device, I normally reach for Python (with the PySerial module installed). It’s really easy to set up more complicated dialogs over serial that way and you will have the full string handling power of Python behind you.

      Ted

  87. Raulp says:

    Hi Batcloaf,
    Can you provide the sources to the attached serial send.exe.Teh one you provided on compiling doesn’t provide the any result as compared to the attached one.
    Something may be missing.
    Thanks in advance !
    Rgds,
    Rp

    • batchloaf says:

      Hi Raulp,

      I’m pretty sure the version of the C code shown above is precisely the same one I compiled to produce the provided downloadable executable file. Is there something in particular that seems different? I’m working on my Linux laptop right now so I can’t check it myself, but normally whenever I make a change I update the code listing and the executable file at the same time to keep them consistent. I don’t keep a separate copy of the C code myself, so whenever I update it I always start with the C code on this page.

      Ted

      • Raul says:

        HI Ted,
        OK I understood! I will try to compile it with gcc and test it.Just wondering what is the max length of the line we can send.I am having trouble sending line of length > 256.Is it dependent on MAX_PATH.What is the value for this?256?Have you experimented it with size > 256?
        Thanks in advance.
        Rgds
        Rp

      • batchloaf says:

        Hi Raul,
        The text you send is limited by the size of two char arrays: buffer and text_to_send. The length of both of these arrays is currently set equal to MAX_PATH, which is defined by the operating system (I think you’re correct that it’s equal to 256). However, I just chose to use this value completely arbitrarily and there should be no problem at all making them much longer if you wish. I suppose that doing so will increase the memory footprint of the program a bit, but that won’t be a problem.

        For example, you could change the following lines:

            unsigned char buffer[MAX_PATH];
            unsigned char text_to_send[MAX_PATH];
        

        to something like this…

            unsigned char buffer[10000];
            unsigned char text_to_send[10000];
        

        Then recompile and you should be able to send much longer messages.

        Ted

  88. John C says:

    Hello Ted!
    I found your website and SerialSend while trying to figure out a way to test long, existing, serial communication cables inside of parking garages. Basically, I’m trying to make a poorman’s Bit Error Rate Tester. Here’s my proposed hardware setup: On the local end, I have my laptop USB going to a USB-to-Serial adapter. That plugs into a RS232-to-RS422 adapter which connects to the 4-wire communications cable. At the distant end of the cable, I do a hardwired loopback by connecting R+ to T+ and R- to T-. That’s the hardware. So, with that, in a terminal program I can type a character on the keyboard and hit enter. Then I get that character back so the hardware is working, but to fully test the cable I want to run a large number of characters for several hours and then have the software on the laptop somehow look at what was sent, compare to what was received and keep track of how many times the two were not the same. Can I use SerialSend to do that somehow or do you know of a very cheap program like it to perform this task? Thanks in advance for your help.

    • batchloaf says:

      Hi John,

      Sorry for the delay getting back to you. SerialSend is only designed for sending text, so it’s probably not quite what you’re looking for. It can certainly send the text you want, but the problem is in receiving the reply back from the remote end.

      What I would suggest is writing a short Python program using the PySerial module to send and receive text. Have you used Python before? Even if you haven’t, I promise you this will be a flexible way of doing it and you won’t need to become a Python expert by any stretch of the imagination. If you haven’t used Python before, I can try to sketch out a 10-line example program that would get you started.

      Ted

      • John C. says:

        Thank you, Ted, for getting back to me. I saw earlier where you recommended Python. My son is a Web front-end developer for a well respected company. I asked him what he knew about Python. It was his feeling that Python runs better in a Linux environment. He looked up JavaScript and feels he can do what I need in that language. I thank you for your getting back to me. If you don’t mind; I will let my son try with JavaScript and I’ll get back to you with the code he comes up with, if it works. Otherwise, I will get Python and the PYserial library you talked about earlier in this thread with the other gentleman. It seems to be an easy language to learn. I am familiar with Basic and Visual Basic so I am not too put off learning a new language. Thanks again for your help. Kind Regards,
        John

      • batchloaf says:

        Hi John,

        Ok, sounds like an interesting way to do it. Accessing the serial port directly from javascript running in a browser probably isn’t possible, but I presume there are plugins for node.js that give you serial port access so hopefully your son will get it sorted. Best of luck getting everything working!

        Ted

    • Mata Big says:

      John, if you really need it, I can programme a code snippet in C++ to add to Ted’s original SerialSend to make it send and receive to/from the serial port using Overlapped I/O, that just works!. It might be helpful for many applications as well.

  89. Preethi says:

    Hey Ted,
    Iam new to batch file programming. I’ve to send a value to Arduino UNO board through a batch file. The code is as follows:

    mode COM4:BAUD=9600 PARITY=n DATA=8
    set x=1
    echo %x%>COM4

    So whenever my arduino code receives the serial input as 1, the LED should glow else not. My arduino code is as follows,

    int thisPin=4; int h;
    void setup()
    {
    Serial.begin(9600);
    }
    void loop()
    {
    if (Serial.available()>0)
    {
    h=SerialLook();
    if (h==1)
    {
    digitalWrite(thisPin,HIGH);
    }
    else
    {
    digitalWrite(thisPin,LOW);
    }
    }
    }

    int SerialLook()
    {
    char c;
    int a;
    int number =0 ;
    c = Serial.read();
    if (c==’1′)
    {
    number= 10*number+int(c-‘0’); //Converting to integer
    }
    return number;
    }

    The above code works perfectly, when I use serial monitor of Arduino IDE. But when I use my Batch file to send data (1 is my data) to COM port, the value is received by the arduino code but the data is not 1, it receives something else. So the LED is not glowing.
    I would be obliged if u help me out of this.

    ThanksTed.

  90. preethimanoharan says:

    Hi Ted,
    I’m a newbie to batch files.. I’ve to send a value to Arduino UNO board through a batch file. The code is as follows:

    mode COM4 BAUD=9600 PARITY=n DATA=8
    set x=1
    echo %x%>COM4
    pause

    So whenever my arduino code receives 1 as an input the LED should glow else not. My arduino code is as follows
    int thisPin=4; // To store incoming data from computer
    int h;

    void setup()
    {
    Serial.begin(9600);
    }

    void loop()
    {
    if (Serial.available()>0)
    {
    h=SerialLook();
    if (h==1)
    {
    digitalWrite(thisPin,HIGH);
    }
    }
    }
    int SerialLook()
    {
    char c;
    int a;
    int number =0 ;
    c = Serial.read();
    if (c==’1′)
    {
    number= 10*number+int(c-‘0’);
    }
    return number;
    }

    When I use my serial monitor of the Arduino IDE it works perfectly. But when I use my batch file to send the value i.e, 1, the arduino code reads the value, but the value is not 1, it is something else I couldn’t figure out. so the LED is not glowing.
    I would be obliged if you could help me out of this.
    Thanks Ted

  91. Hi Ted,

    Cool looking utility, haven’t tried it yet, but it looks like it is exactly what I need, can’t wait to try it out after work. Could you just clarify for me the usage of this as I have very little command line experience. To execute this if I am in a cmd window: I would navigate to where on my comp the .eve flie is; then type out:

    SerialSend.exe /an_argument a_value /a_different_argument a_different_value “text I want to send”

    where an_argument would be something like devnum?

    So, if I were to just try running this without navigating to the folder the .exe is in could I just put the rest of the file path before the line shown above?

    Also, kind of a separate question based on my lack of serial knowledge, if this is opening and closing a com port each time, would I run into issues doing that over and over again? I am looking to use this to send commands to an arduino that controls some things in my room and I am hoping to use different calls to your program to initiate each action. And I actually am going to use unified remote to send each command to initiate your program, this is where I think I need a way to initiate your program with all the necessary arguments without actually navigating to the folder where the .exe is.

    I realize that is a hectic description, but any help/info you could give would be appreciated.

    • batchloaf says:

      Hi Timothy,

      Sorry for the delay responding to your query. You should be able to use SerialSend to transmit commands or data to an arduino – in fact that’s something I do regularly.

      SerialSend should close the serial port after it transmits the data, so you should be able to call it multiple times without problems. Serial ports can be funny though, so I wouldn’t absolutely rely on that working smoothly in every case.

      Ted

  92. Bob says:

    Very nice little App.

    I have been trying to solve a issue with my Terminal Node Controller (TNC) for Packet Radio over ham radio. I have a Email program that sets up the TNC for its use and leaved the TNC in a mode that is not useful for keyboard conversation on Packet Radio. I tried several different ways with batch files to reset the TNC with strings of commands without success. I came across SerialSend, set it up in a batch file, runs my commands to the TNC and then start PUTTY from batch. One command and I am back in the keyboard mode.

    I will write this application of SerialSend up on my website.
    Thanks,
    Bob – N4RFC
    http://www.n4rfc.com

  93. Pingback: N4RFC.COM » RMS Express and the PK232

  94. Markus says:

    Hi Ted,

    I am trying to send a struct from a microcontroller(uC) to a lte module from Telit via Uart.
    I have devided it to simulate first the communication of the uC with the laptop. (i am using code composer Studio and Halcogen for setting up the uC).
    I can do already send via uart when i press a button on the uC some string like “hello world” to teraterm and put this in the terminal. So writing to the com port is done.
    Now i dont know how to simulate the receiving part. That i can send some hello world from the laptop to the uC and show this somewhere that the uC received it.
    Can you maybe help me?

    (just in case i am using the TMS570LC43x and the CP2102 converter usb-ttl)

    i am kind of new (again) to programming and i am really glad for every kind of help how to achieve this Problem!

    regards
    Markus

    • batchloaf says:

      Hi Markus,

      Sorry, but I have no experience with the TMS microcontrollers and it sounds like what you’re asking is all about programming the UART on the microcontroller. All I can suggest is to google “TMS570LC43x UART example” and hope for the best!

      Ted

  95. Markus says:

    Hi bob,
    i am trying to test the uart communication of my microcontroller (TMS570LC43x of texas instruments). so i am using Halcogen and code composer studio (IDE).
    i need the communication to read and send bytes over this serial interface.
    what i already achieved is that i can send via “sciSendByte” function by pressing a button on the board “hello world” to Teraterm. So basically the sending part is kind of done.
    But now i want to test the reading funcitonality of the uC. For this i think i need to write hello world or anything to the interface from my laptop.
    But i am not sure how to implement this (like showing it into a terminal or console that the uC has read something)
    And i post it here because i imagine that i need somehow this serialsend from you.

    I am new to programming and i really need help so it would be nice if you can help me.

    regards
    Markus

  96. Simone says:

    Hi,
    nice program.

    Can I use it for send string to an Aten Matrix HDMI VM5808H product?

    i need to send this command:

    profile f 01 load

    it has:
    Baudrate: 19200
    Data bits: 8
    Parity: none
    Stop bits: 1
    Flow control: none

    Thank you,
    Simone

  97. Diego says:

    Hi:
    In first place, I must to say congratulations for your work. I’m from Argentina and sorry for my bad english. I have tested SerialSend and aparently work. But, how can I see the response?. I trial to comunicate to Markem Printer. This printer need some commands to send and she send a response. I tested your program and apparently send data, but I need to receive the data from printer. Is possible that?. Sorry, again, for my english and I hope to understand me.

  98. hi am very happy to find such program, am asking how can i make android phone connected to pc that have sim card in it start calling a number that i send over this tool.
    what command i must send with it to acomplish what i have described.

    • batchloaf says:

      Hi Mustapha,

      I’m sorry, but I don’t know how to do this. I suspect SerialSend is not the appropriate tool for this though because I don’t think an Android phone normally shows up as a serial port device when you plug it into a Windows PC. SerialSend is only designed to transmit bytes of data over a serial port connection (i.e. also known as a COM port in Windows). Some devices do appear as a serial/COM port when you plug them into the USB socket of a Windows PC, but I don’t think that’s typically the case for an Android phone.

      Ted

  99. RichardS says:

    Cool, I do a lot with ESP8266’s and this will come in handy, nice work. When I am not too tired from running ESP8266.com, I play with them🙂

  100. RequiredMyLeftToeSir says:

    You’re nice to do this thoughtful work for others. I’m trying to get to the “good part” of my hobby by skipping creating this myself- I’ll do it later😉 but it wants my gmail login.. sigh.

    not your doing I’m sure.. you shared, and someone else figured out how to gain from it. I’m sad now.. but once I finish all my projects I’ll be on my way to mars, so I won’t be sad as soon as I gain ground on that.. haha

    I’m not downloading it.. but I still think it’s great.

    • batchloaf says:

      Hi Required,

      You don’t need to provide your gmail login or anything else to download and use SerialSend. You can just click on the link above and download the exe file. You don’t need to provide anything or register in any way.

      Ted

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s