Click here to Skip to main content
15,896,111 members
Articles / Desktop Programming / MFC

How to use serial port to communicate between two computers

Rate me:
Please Sign up or sign in to vote.
4.65/5 (16 votes)
30 Sep 20056 min read 232.1K   9K   67  
Using the serial port and cable to send a file from one computer to another.
/* sertrans.c */
/* Transmits a file to another computer over a serial cable */
/* Last modified: September 20, 2005 */
/* http://www.gomorgan89.com */

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Function to set up the serial port settings with the specified baud rate,
   no parity, and one stop bit */
void set_up_serial_port(HANDLE h, long baud);

/* Function to print out usage */
void usage(void);

/* Function to get size of file */
unsigned long get_file_size(char *file_name);

/* Function to write the file to the serial port */
void write_file_to_serial_port(HANDLE h, char *file_name, unsigned long file_size);

int main(int argc, char **argv)
{
	HANDLE serial_port;				/* Handle to the serial port */
	long baud_rate = 9600;			/* Specified baud rate */
	char port_name[] = "COM1:";		/* Name of the serial port */
	unsigned long file_size;		/* File size to transmit in bytes */
	unsigned long bytes_written;	/* Bytes written to serial port */
	unsigned long file_name_size;	/* Size of file name */

	/* Check command line arguments */
	if (argc == 4)
	{
		/* Read in baud rate */
		if (argv[2][1] != 'b' || sscanf(argv[3], "%ld", &baud_rate) != 1)
		{
			usage();
			exit(0);
		}
	}
	else if (argc != 2)
	{
		usage();
		exit(0);
	}
	
	/* Open up a handle to the serial port */
	serial_port = CreateFile(port_name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);

	/* Make sure port was opened */
	if (serial_port == INVALID_HANDLE_VALUE)
	{
		fprintf(stderr, "Error opening port\n");
		CloseHandle(serial_port);
		exit(0);
	}

	/* Set up the serial port */
	set_up_serial_port(serial_port, baud_rate);

	/* Get the file size */
	file_size = get_file_size(argv[1]);

	/* Print out information */
	printf("Preparing to transmit file %s: %lu bytes\n", argv[1], file_size);

	/* Write file name size to serial port */
	file_name_size = (unsigned long)strlen(argv[1]);
	WriteFile(serial_port, (void *)&file_name_size, sizeof(unsigned long), &bytes_written, NULL);
	if (bytes_written != sizeof(unsigned long))
	{
		fprintf(stderr, "Error writing file name size.\n");
		CloseHandle(serial_port);
		exit(0);
	}

	/* Write file name to serial port */
	WriteFile(serial_port, (void *)argv[1], file_name_size, &bytes_written, NULL);
	if (bytes_written != file_name_size)
	{
		fprintf(stderr, "Error writing file name.\n");
		CloseHandle(serial_port);
		exit(0);
	}


	/* Write file size to serial port */
	WriteFile(serial_port, (void *)&file_size, sizeof(unsigned long), &bytes_written, NULL);
	if (bytes_written != sizeof(unsigned long))
	{
		fprintf(stderr, "Error writing file size.\n");
		CloseHandle(serial_port);
		exit(0);
	}

	/* Write file to serial port */
	write_file_to_serial_port(serial_port, argv[1], file_size);

	printf("\n%lu bytes successfully transmitted.\n", file_size);

	/* Close the handle */
	CloseHandle(serial_port);

	return 0;
}

void set_up_serial_port(HANDLE h, long baud)
{
	DCB properties;			/* Properties of serial port */

	/* Get the properties */
	GetCommState(h, &properties);

	/* Set the baud rate */
	switch(baud)
	{
	case 1200:
		properties.BaudRate = CBR_1200;
		break;
	case 2400:
		properties.BaudRate = CBR_2400;
		break;
	case 4800:
		properties.BaudRate = CBR_4800;
		break;
	case 9600:
		properties.BaudRate = CBR_9600;
		break;
	case 14400:
		properties.BaudRate = CBR_14400;
		break;
	case 19200:
		properties.BaudRate = CBR_19200;
		break;
	case 38400:
		properties.BaudRate = CBR_38400;
		break;
	default:
		fprintf(stderr, "Invalid baud rate: %ld", baud);
		usage();
		exit(0);
		break;
	}
	
	/* Set the other properties */
	properties.Parity = NOPARITY;
	properties.ByteSize = 8;
	properties.StopBits = ONESTOPBIT;

	SetCommState(h, &properties);

	return;
}

void usage(void)
{
	fprintf(stderr, "Usage:\n");
	fprintf(stderr, "\tsertrans file [-b baud_rate]\n");
	fprintf(stderr, "\tDefault baud rate is 9600\n");
	fprintf(stderr, "\tSupported baud rates: 1200, 2400, 4800, 9600, 14400, 19200, 38400\n");
	return;
}

unsigned long get_file_size(char *file_name)
{
	FILE *data_file;
	unsigned long size = 0;
	size_t bytes_read;
	char byte_read;

	/* Open the file */
	data_file = fopen(file_name, "rb");

	/* Quit if file couldn't be opened */
	if (data_file == NULL)
	{
		fprintf(stderr, "Could not open file %s\n", file_name);
		exit(0);
	}

	/* Read in data one byte at a time until we reach the end */
	while (1)
	{
		bytes_read = fread((void *)&byte_read, 1, 1, data_file);
		if (bytes_read <= 0)
		{
			break;
		}
		++size;
	}

	/* Close file */
	fclose(data_file);

	return size;
}

void write_file_to_serial_port(HANDLE h, char *file_name, unsigned long file_size)
{
	FILE *data_file;
	unsigned long bytes_left = file_size;
	unsigned long bytes_sent;
	unsigned long bytes_read;
	unsigned long total_bytes_sent = 0;
	size_t bytes_to_send;
	char buffer[200];

	/* Open the file */
	data_file = fopen(file_name, "rb");

	/* Quit if file couldn't be opened */
	if (data_file == NULL)
	{
		fprintf(stderr, "Could not open file %s\n", file_name);
		exit(0);
	}

	while (1)
	{
		/* Determine how many bytes to send */
		if (bytes_left == 0)
		{
			break;
		}
		else if (bytes_left < 200)
		{
			bytes_to_send = bytes_left;
		}
		else
		{
			bytes_to_send = 200;
		}

		/* Read in specified number of bytes */
		bytes_read = (unsigned long)fread((void *)buffer, 1, bytes_to_send, data_file);

		/* Send data over serial cable */
		WriteFile(h, (void *)buffer, bytes_read, &bytes_sent, NULL);
		if (bytes_sent != bytes_read)
		{
			fprintf(stderr, "Error writing file.\n");
			CloseHandle(h);
			exit(0);
		}
		
		/* Decrement number of bytes left */
		bytes_left -= bytes_sent;

		/* Increment number of bytes sent */
		total_bytes_sent += bytes_sent;

		/* Print out progress */
		printf("\r%5lu bytes transmitted.", total_bytes_sent);
	}

	fclose(data_file);

	return;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions