Sunday 17 July 2011

Serial Port Manipulation in C

          Serial communications is the most popular and cheaper way of communicating between two devices. The obvious advantage is lesser number of conductors used. There are lots of information available in internet, so we'll focus on our experiment without discussing the in-depth details.

Serial Interface
         For communication between two or more devices there should be some well defined interface. In the world of Serial Communication it is specified by RS232. RS232 is defined by Electronic Industries Association (EIA). It defines the conventions to be followed for serial communication. At first, it is used for connecting telephone lines to the computer.  RS232-standard specifies the voltage levels for MARK (HIGH) and SPACE (LOW).

 Value            Voltage-range
 MARK         < -3V 
 SPACE        > +3V

Voltages between -3V and +3V is neither MARK nor SPACE
Female DB-9 RS232 Connector

Male DB-9 RS232 Connector


            In this experiment we are going to use only two pins namely TXD and SGND. We connect the TXD pin to Anode of LED and the Cathode of LED is connected to SGND through a Resistor. Thats all about the circuit. The DB-9 RS232 male connector is used to connect the circuit to the PC.

Pin
Symbol
I/O
Active HIGH/LOW
Description
Used/Not
1
DCD
Input
LOW
Data Carrier Detect
Not Used
2
RXD
Input
DATA
Receive
Not Used
3
TXD
Output
DATA
Transmit
Used
4
DTR
Output
LOW
Data Terminal Ready
Not Used
5
SGND
-
GND
Signal Ground
Used
6
DSR
Output
LOW
Data Set Ready
Not Used
7
RTS
Input
LOW
Request To Send
Not Used
8
CTS
Input
LOW
Clear To Send
Not Used
9
RI
Output
-
Ring Indicator
Not Used


Asynchronous Communication

               For the computer to understand the serial data coming into it, it needs some way to determine where one character ends and the next begins. This guide deals exclusively with asynchronous serial data.




              In asynchronous mode the serial data line stays in the MARK (HIGH) state until a character is transmitted. A start bit preceeds each character and is followed immediately by each bit in the character, an optional parity bit, and one or more stop bits. The start bit is always a SPACE (LOW) and tells the computer that new serial data is available. Data can be sent or received at any time, thus the name asynchronous.

             With these hardware background now we are going to dive into software part. I'm using Ubuntu Linux-10.10 ( Maverick Meerkat ). Linux already has serial port drivers. For now we'll see how to use those drivers. I'll discuss how serial drivers works in a separate article.

             In Unix/Linux everything is file. Yes, the serial port is also treated as file. So we can write and read the data to/from serial port just like a file.

The file names are as follows:
System Port-1 Port-2
Digital UNIX /dev/tty01 /dev/tty02
HP-UX /dev/tty1p0 /dev/tty2p0
IRIX /dev/ttyf1 /dev/ttyf2
Linux /dev/ttyS0 /dev/ttyS1
Solaris /dev/ttya /devttyb


Coding:

#include <stdio.h>     // Standard input/output definitions
#include <string.h>    // String function definitions
#include <unistd.h>   // UNIX standard function definitions
#include <fcntl.h>      // File control definitions
#include <errno.h>     // Error number definitions
#include <termios.h>  // POSIX terminal control definitions

// function to open the port
int open_port(void)
{
          int port;
          //open the port and store the file descriptor in 'port'
          port = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
          if (port == -1){
                 // Could not open the port
                perror("open_port: Unable to open /dev/ttyS0 - ");
          }else{
                fcntl(port, F_SETFL, 0); //leave this
          }
          return (port);
}


int main()
{
          int port,n;
          char str[30];
          
          //termios - structure contains options for port manipulation
          struct termios specs; // for setting baud rate

          //setup part
          port = open_port();
          tcgetattr(port, &specs);

          //now the specs points to the opened port's specifications
          specs.c_cflag = (CLOCAL | CREAD ); //control flags


          //output flags
          //CR3 - delay of 150ms after transmitting every line
          specs.c_oflag = (OPOST | CR3);


         //set Baud Rate to 50bps
         cfsetospeed(&specs,B50);


         //our custom specifications set to the port
         //TCSANOW - constant that prompts the system to set
         //specifications immediately.
          tcsetattr(port,TCSANOW,&specs);
         
          //execution part
         printf("\nEnter the data:\t");
         scanf("%s",str);
         n = write(port,str,11); // n = no of bytes written
         if (n<0) {
              printf("\nError");
         }


         //close the port
         close(port);
         return(0);



Here is mine. It is no a good practice to solder individual wore. Set of six wire sleeves are available in shops. Use them.










Connect the  the Serial Cable to your PC and execute the program. Happy Blinking!!!

8 comments:

Thats fantastic man!!!!!!
Very helpful indeed............

thts very clear and detailed ..appreciate it.
I am looking for a serial port communication protocol which lets me transfer files and also send management commands and is also very light weight as it has to go embedded . any ideas???

pradeep
pradeepdeeps@gmail.com

@pradeep

Now I'm working on that only. I was just planned to use to send commands to uC from PC. If u giv me some more specific details. I'll be able to do that soon. I'll add these on my next post may within 10 days.!!! :-)

Thank you very much. Your program is perfect for my
purpose of controlling analog circuit through the serial
port. I need a very bright LED to light up, so I cannot use the serial power supply.

I there fore made a circuit consisting of an inverting comparator to a sample & hold to another comparator to a transistor which turns on the power from a battery.

can anyone plz convert the same program codefor matlab i m not familiar with c ? plz help

Hello, thanks for your post. I am using Ubuntu 13.04, but I can't open the port "/dev/ttyS0" or "/dev/ttyS1"! and always the output is -1. What should I do? :(

Thanks... it helped a lot.


I m having problem in receiving data with read() function can you plz help me.

Not sure for Ubuntu, but in Debian you have to become member of the group dialout in order to be able to use the serial ports. As root, invoke the command: useradd -a -G dialout yourusername.

To check which group you have add on your distribution, use the command: ls -l /dev/ttyS0 and read which group name is mentioned.


In order be sure that your LED won't burn, you will need a resistor of 680 Ohm or more for a 2 volt 20 mA LED. I succesfully used a common 1 kOhm resistor.



In the execution part, I changed "11" to "strlen(str)" in order to only send the relevant information in stead of sending 11 bytes statically.



Nice tutorial!

Post a Comment

தங்களது கருத்துக்களை இங்கே வெளியிடவும்...

Share

Twitter Delicious Facebook Digg Stumbleupon Favorites More