RE: communicating with serial port



From: "Govinda Parida" <govinda parida gmail com>
To: gtkmm-list gnome org
Subject: communicating with serial port
Date: Wed, 7 Mar 2007 17:14:46 +0530

Hi
I am using gtkmm for GUI. My operating system is Obuntu.
In my application i need like this.
I have to open a window which contain a label "swipe the card", I have
magnetic swipe card reader which is connected to serial port after that it
reads data from serial port. if it will read correctly then new window will
be open.So please help me.
Thanks in advance.




Those are the functions I use to open serial ports ( I have almost copy&paste the functions so maybe there are some class functions not listed here , as for example the error printing functions ... ).


int libreria_serie::tty_open(char *line, int baudios, char *par, char *bits, int stop,int hw_flow, int sw_flow)
{
 int puerto; // Port descriptor
 char devname[100], error_mens[80];
 int modo;
 modo = (O_RDWR | O_NONBLOCK | O_EXCL);
 //modo = (O_RDWR);

 if ((puerto = open(line, modo)) <0) {
   sprintf(error_mens,"Cant open %s: %s", devname, strerror(puerto));
   this->tty_error(error_mens); // Error printing function
   return(-1);
 }

 if(isatty(puerto) == 0) {
   sprintf(error_mens,"%s not a tty\n", devname);
   this->tty_error(error_mens);
   return(-1);
 }
 // Save the port attributtes to save then during close
 if(tcgetattr(puerto, &this->termios_original) < 0)
   this->tty_error("Error while doing tcgetattr\n");

 // configure the serial port
 this->tty_m_setparms(puerto, baudios, par, bits, stop, hw_flow, sw_flow);

 return(puerto);
}

void libreria_serie::tty_m_setparms(int fd, int newbaud, char *par, char *bits, int stop,int hwf, int swf)
{
 int spd = -1;
 int bit = bits[0];

 struct termios tty;
 tcgetattr(fd, &tty);

 /* We generate mark and space parity ourself. */
 if (bit == '7' && (par[0] == 'M' || par[0] == 'S'))
	bit = '8';

 // Marcamos la velocidad
 newbaud=newbaud/100;
 switch(newbaud) {
 	case 0:
			spd = 0;	break;
 	case 3:		spd = B300;	break;
 	case 6:		spd = B600;	break;
 	case 12:	spd = B1200;	break;
 	case 24:	spd = B2400;	break;
 	case 48:	spd = B4800;	break;
 	case 96:	spd = B9600;	break;
 	case 192:	spd = B19200;	break;
 	case 384:	spd = B38400;	break;
	case 576:	spd = B57600;	break;
	case 1152:	spd = B115200;	break;
 }

 if (spd != -1) {
	cfsetospeed(&tty, (speed_t)spd);
	cfsetispeed(&tty, (speed_t)spd);
 }

 switch (bit) {
 	case '5':
 		tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS5;
 		break;
 	case '6':
 		tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS6;
 		break;
 	case '7':
 		tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS7;
 		break;
 	case '8':
	default:
 		tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;
 		break;
 }

 /* Set into raw, no echo mode */
 tty.c_iflag =  IGNBRK;
 tty.c_lflag = 0;
 tty.c_oflag = 0;
 tty.c_cflag |= CLOCAL | CREAD;

 // Para permitir poner 1 o 2 bits de stop
 if(stop==2) tty.c_cflag|=CSTOPB;

 tty.c_cc[VMIN] = 0;
 tty.c_cc[VTIME] = 10;

 if (swf)
	tty.c_iflag |= IXON | IXOFF;
 else
	tty.c_iflag &= ~(IXON|IXOFF|IXANY);

 tty.c_cflag &= ~(PARENB | PARODD);
 if (par[0] == 'E')
   {
	tty.c_cflag |= PARENB;
   }
 else if (par[0] == 'O')
   {
	tty.c_cflag |= PARENB;
	tty.c_cflag |= PARODD;
   }

 tcsetattr(fd, TCSANOW, &tty);

 //  m_setrts(fd);

 this->tty_m_sethwf(fd, hwf);
}


/************************************** m_sethwf *****************************/
/* Set hardware flow control. */
void libreria_serie::tty_m_sethwf(int fd, int on){
 struct termios tty;

 tcgetattr(fd, &tty);
 if (on)
   tty.c_cflag |= CRTSCTS;
 else
   tty.c_cflag &= ~CRTSCTS;
 tcsetattr(fd, TCSANOW, &tty);
}


Using those function we can open a serial port has follows :

int desc;
SigC::Connection conexion;

// Open /dev/ttyS0 at 9600baud 8N1 no hw/sw flow control
if(desc = tty_open("/dev/ttyS0",9600,'N','8',1,0,0)<0)
{
	// ERROR
}

// Now we have a valid descriptor for the port let start reading from it

if(conexion.connected())
  conexion.disconnect();

// Activate callback
conexion = Glib::signal_io().connect(SigC::slot(*this,&class_name::callback_funcion),
					     Glib::IOChannel::create_from_fd(desc),
					     Glib::IO_IN,Glib::PRIORITY_HIGH);
if(!conexion.connected())
{
	// ERROR
}


With this callback_funcion is called whenever is something to be read on the serial port.

bool class_name:callback_funcion(Glib::IOCondition io)
{

 // Reading buffer
 gchar c[TAM_BUFFER];
 // Recogemos todo lo que haya hasta ese momento
 gint res = -1;
 res = read(c,TAM_BUFFER);

 // Now res has the number of chars readed from the port
 if(res>0) // Todo bien
do_what_you_need_with_data(c,res); // Pass the chars to the needed function
 else if(res<0) // Error
 {
	// ERROR, something failed when reading the data
 }
 else // (res==0)
 {
	// ERROR or WARNING there where no data on the port
 }

 return true; // We continue active
}

If you need to write data to the port just use write(file_desc,char_buffer*,char_count);
Also remenber to close the port on exit :-)


Hope it helps, ( or at least dont confuse you even more ;-) )

_________________________________________________________________
Acepta el reto MSN Premium: Correos más divertidos con fotos y textos increíbles en MSN Premium. Descárgalo y pruébalo 2 meses gratis. http://join.msn.com?XAPID=1697&DI=1055&HL=Footer_mailsenviados_correosmasdivertidos




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]