Sunday, February 8, 2009

Serial Port Programming : Sender and Receiver

The required equipment required consists of :
1. DB-9 null modem. The null modem that you need to use is loop type null modem.
2. USB to serial port converter.

Now we are going to write a program that act as a data sender. Data is sent through the serial port. Basically program consists of several activities :
1.turning on a null modem.
2.setting up program's action on incoming package.
3.setting up program's output mode.
4.setting up program's connection control flag :
1.Baudrate is 4800 BPS (B4800) .
2.Enable RTS/CTS (hardware) flow control (CRTSCTS) .
3.Ignore modem control lines (CLOCAL) .
4.Character size mask is 8 (CS8).
5.flushing the modem line.
6.initiating the modem.
7.sending data through the modem line. the data is system's time.

Of course you need to have a receiver. wich is also a program. What makes the receiver different from the sender is the loop that reads data input :
for(;;)
{
read(fd,&c,1); /* reads the null modem */
write(1, &c,1); /* prints input to the screen */
}

before running any program you really need to alter the status of your null modem device (after you plug in it)), so that it can be read and written on. REMEMBER ALL SERIAL COMMUNICATION DEVICES IS TREATED AS FILE. You have to make it readable and writable. Beside that you need to have a null modem :
1. For changing the permission of ttyS0 you need to execute : #sudo chmod 777 /dev/ttyS0
2. For changing the permission of ttyUSB0 you need to execute : #sudo chmod 777 /dev/ttyUSB0

Now first we have a sender's source code. We assume program below uses Serial Port 0.

#include "termios.h" /*this file contains declaration of required functions and types*/
#include "stdio.h" /*you know what this is*/
#include "fcntl.h" /*this file constains declaration for O_RDWR and O_NOCTTY)*/
#include "time.h" /*this file contains time's operatives*/


int main(void)
{
int i, j, s;
char t[9];
time_t ttrs;
struct tm *ti;
int fd; /*variable of type integer used as descriptor to a serial port*/
char c;
struct termios termiosA; /*declaring a variable of type termios*/
/* Turn on the null modem */
fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY); /* I have done : sudo chmod 777 /dev/ttyS0 */


/* We don't care about incoming bytes with parity on data input */
termiosA.c_iflag = IGNPAR;

/*
Raw output.
*/
termiosA.c_oflag = CR0; /* output modes */

/*
we are going to set a connection with serial port to the receiver (this computer is a sender)
1. Baudrate is 4800 BPS (B9600)
2. Enable RTS/CTS (hardware) flow control (CRTSCTS)
3. Ignore modem control lines (CLOCAL)
4. Character size mask is 8 (CS8)
*/
termiosA.c_cflag = B4800 | CRTSCTS | CLOCAL | CS8; /* control flags */


/* flush the modem line */
tcflush(fd, TCIFLUSH);

/* initiate the modem */
tcsetattr(fd,TCSANOW,&termiosA);

/* Now its time to send something. */
i = 0;
for (;;)
{
time(&ttrs);
ti=localtime(&ttrs);
if (s != ti->tm_sec)
{
printf("Sending time data : %s", t);
sprintf(t, "%d:%d:%d\n", ti->tm_hour, ti->tm_min, ti->tm_sec);
s = ti->tm_sec;
for (j = 0; j < 9;j++)
{
write(fd, t[j], 1);
}
return 0;
}

Next we have a receiver program. The receiver uses USB port 0. :

#include "termios.h" /*this file contains declaration of required functions and types*/
#include "stdio.h" /*you know what this is*/
#include "fcntl.h" /*this file constains declaration for O_RDWR and O_NOCTTY)*/

int main()
{
int fd; /*variable of type integer used as descriptor to a serial port*/
char c;
struct termios termiosA; /*declaring a variable of type termios*/
/* Turn on the null modem */
fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY); /* I have done : sudo chmod 777 /dev/ttyUSB0 */


/* We don't care about incoming bytes with parity on data input */
termiosA.c_iflag = IGNPAR;

/*
Raw output.
*/
termiosA.c_oflag = CR0; /* output modes */

/*
we are going to set a connection with serial port to the sender (this computer is a receiver)
1. Baudrate is 4800 BPS (B4800)
2. Enable RTS/CTS (hardware) flow control (CRTSCTS)
3. Ignore modem control lines (CLOCAL)
4. Character size mask is 8 (CS8)
*/

termiosA.c_cflag = B4800 | CRTSCTS | CLOCAL | CS8; /* control flags */

/*The change to the line's state takes effect straight away*/
/* flush the modem line and initiate the modem */
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&termiosA);
/* input is handled by the loop below */

for(;;)
{
read(fd,&c,1); /* reads the null modem */
write(1, &c,1); /* prints input to the screen */
}

}

Now what you need to do is to compile and run each program and see the result. Good luck