LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
LinkBack Search this Thread
Old 04-14-2005, 01:24 PM   #1
prems
LQ Newbie
 
Registered: Mar 2005
Posts: 9

Rep: Reputation: 0
gtk serial port communication


Hi,
I know how to do a basic serial communication prgram. I am trying to make the interface graphical.
For starters I have my serial program serial.c and serial.h

I have created a gtk interface. when I press my button I need to initialise and send a string. I tried to include the serial.h header in this file and made a function for the gtk_signal_connect call. here i tried to initialise and send my command. It does not seem to work. I tried to look up simliar stuff on the net but am unable to understand the gtkterm project. Can someone please help me with this.
If this works I am sure I can have an input and output side text box. But for now am stuck. Can someone help!!
Thanks
Prem
 
Old 04-14-2005, 11:44 PM   #2
alred
Member
 
Registered: Mar 2005
Location: singapore
Distribution: puppy and Ubuntu and ... erh ... redhat(sort of) :( ... + the venerable bsd and solaris ^_^
Posts: 658
Blog Entries: 8

Rep: Reputation: 30
does your serial.c and serial.h works without a gui ?
how you code your button pressed "events" ?
if possible show them the gtk_signal_connect code .....
they might need some code inorder to help you ...........
 
Old 04-28-2005, 03:22 PM   #3
prems
LQ Newbie
 
Registered: Mar 2005
Posts: 9

Original Poster
Rep: Reputation: 0
This is my basic code

include<stdio.h>
#include<string.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include "serial.h"
/*
file-scope variable to save terminal settings
*/
struct termios oldtermios; /* to save original settings */
/*
Function implementations:
serial_open () takes the port number and the baud and returns
an open file descriptor, or -1 = failed, -3 = other error.
*/
int
serial_open (int port_no, int baud)
{
int fd; /* file descriptor of the port */

char *name = "/dev/ttyS0";
int b_baud;
struct termios t; /* struct for port settings */

/* convert to port and baud input */
switch (port_no)
{
case 2:
name = "/dev/ttyS1";
break;
case 3:
name = "/dev/ttyS2";
break;
case 4:
name = "/dev/ttyS3";
break;
default:
name = "/dev/ttyS0";
break;
}
switch (baud)
{
case 4800:
b_baud = B4800;
break;
case 9600:
b_baud = B9600;
break;
case 19200:
b_baud = B19200;
break;
case 38400:
b_baud = B38400;
break;
case 57600:
b_baud = B57600;
break;
case 115200:
b_baud = B115200;
break;
default:
b_baud = B9600;
break;
}

fd = open (name, O_RDWR | O_NOCTTY );
if (fd < 0)
return -1; /* open failed */

if (tcgetattr (fd, &t) != 0) {
return (-3);
}
/*
save old settings
*/
oldtermios = t;
/*
do settings
*/
t.c_cc[VMIN] = 32;
t.c_cc[VTIME] = 1;

/* &= ~ disables bits, |= enables bits */
t.c_iflag &= ~(BRKINT
| IGNPAR | PARMRK |
INPCK | ISTRIP | INLCR | IGNCR |
ICRNL | IXON);
t.c_oflag &= ~(OPOST);
/* non-canonical */
t.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL | ICANON
| ISIG | NOFLSH | TOSTOP);
t.c_cflag &= ~(CSIZE | CSTOPB | HUPCL | PARENB);

t.c_cflag |= CLOCAL | CREAD | CS8;
/* copy data rates into termios struct */
if (cfsetispeed (&t, b_baud) == -1)
{
return (-3);
}
if (cfsetospeed (&t, b_baud) == -1)
{
return (-3);
}
/* throw away any input data / noise */
if (tcflush (fd, TCIFLUSH) == -1)
{
return (-3);
}
/* Now, set the terminal attributes */
if (tcsetattr (fd, TCSANOW, &t) == -1)
{
return (-3);
}
return fd;
}
/*
serial_close () resets then closes port of file descriptor fd.
*/
int
serial_close (int fd)
{
/* reset port to old settings and return */
tcsetattr (fd, TCSANOW, &oldtermios);
close (fd);
return 0;
}
/*
serial_bytes_waiting () returns the number of bytes waiting to be read
at the port described by fd.
*/
int
serial_bytes_waiting (int fd)
{
int bytes;
ioctl (fd, FIONREAD, &bytes); /*read number of bytes in input buffer*/
return bytes;
}
/*
The serial_read () and serial_write () are simple wrappers.
serial_write () writes the string pointed to by buf, up to n chars.
serial_read () reads up to n chars and puts it into buf.
*/

int
serial_write (int fd, char *buf, int n)
{
int bytes_written = write (fd, buf, n);
return bytes_written;
}
int
serial_read (int fd, char *buf, int n)
{
int bytes_read = read (fd, buf, n);
return bytes_read;
}
/*
end of serial.c
*/

int main ()

{
int st1,st2,st3,st4,st5;
char out_buffer[100];
char *op;
int size;
char *ip[26];

op = (char *)memset(out_buffer, '\0', 100);

st1=serial_open(1,9600);
st2=serial_open(2,9600);
printf("File descirptor for port 1 %d\n",st1);
printf("File descriptor for port 2 %d\n",st2);



ip[0]="123SMD990bbbbb\r";


size=strlen(ip);
printf(" String: %s\n",ip);
printf("Its length is %d\n",size);

st4=serial_write (st1,ip,size);
sleep(1);
st3=serial_bytes_wait

printf("number of bytes in com2 buffer is %d and com1 buffer is %d\n",
st3,st4);

op = (char *)memset(out_buffer, '\0', 100);

st5=serial_read (st2, op,size);
printf("\nnumber of bytes in reader buffer %d ",st5);
printf("\nRecieved word is %s\n",op);
serial_close (st1);
serial_close (st2);

}

and I am able to both send and recive data without any problem.
In the same directory I have created my graphics program.
sergra.c
#include<gtk/gtk.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include "serial.h"


int st1;


void destroy_func(GtkWidget *widget, gpointer data);
void button_func(GtkWidget *widget, gpointer pdata);

int main( int argc, char *argv[])

{

/* Define objects */
GtkWidget *window,*button;


gtk_init(&argc,&argv);


/* Define frame */
window= gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_usize(GTK_WIDGET(window),180,120);
gtk_window_set_title(GTK_WINDOW(window),"WRAPTOR SERIAL PORT PROGRAM");

gtk_signal_connect(GTK_OBJECT(window),"destroy",GTK_SIGNAL_FUNC(destroy_func),NULL);
gtk_container_set_border_width(GTK_CONTAINER(window),20);


/* DEFINE TEXTBOX*/




/* button 1*/
button=gtk_button_new_with_label("Send serial data");
gtk_signal_connect(GTK_OBJECT(button),"clicked",GTK_SIGNAL_FUNC(button_func),NULL);
gtk_container_add(GTK_CONTAINER(window),button);




/* Make All visible. */


gtk_widget_show_all(window);


gtk_main();

g_print("about to clear the place.\n");
return 0;

}



void destroy_func(GtkWidget *widget,gpointer data)

{
g_print("getting out cause you asked for it .\n");
gtk_main_quit();
}


void button_func(GtkWidget *widget,gpointer pdata)
{

g_print("CLICK\n");
st1=serial_open(1,9600);

}
I amn not even able to open the port!! Shouldnt I be simply ablt to include my header serial.h ( where I have defined my function ) and directly be able to use it in the gtk program. I will really appreciate it if someone responds . Unfortunately I have had a look at the gtkterm project but could not make out head or tail.am hence trying to take this one step at a time
prem
 
Old 04-29-2005, 12:40 AM   #4
alred
Member
 
Registered: Mar 2005
Location: singapore
Distribution: puppy and Ubuntu and ... erh ... redhat(sort of) :( ... + the venerable bsd and solaris ^_^
Posts: 658
Blog Entries: 8

Rep: Reputation: 30
although i never do gtk before and since there's full code
so i try to compile it and have some fun out of it
it's seem to be able to compile for me or maybe i'm doing it the wrong way or some other , these are the results without gui and with gtk :

result without gui :
Code:
File descirptor for port 1 3
File descriptor for port 2 -3
File descriptor for port 3 -3
File descriptor for port 4 -3
 String: 123SMD990bbbbb
Its length is 15
number of bytes in com1 buffer is 15
result with gtk :
Code:
File descirptor for port 1 6
File descriptor for port 2 -3
File descriptor for port 3 -3
File descriptor for port 4 -3
 String: 123SMD990bbbbb
Its length is 15
number of bytes in com1 buffer is 15
am i doing the right thing ?

Last edited by alred; 04-29-2005 at 01:15 AM.
 
Old 04-29-2005, 01:16 PM   #5
prems
LQ Newbie
 
Registered: Mar 2005
Posts: 9

Original Poster
Rep: Reputation: 0
alred,
How did you compile the code. My guess is that you just compiled serial.c two times. Basically what am doing is defining open port etc etc in serial .h. The gtk porgram is sergra.c where I have defined a button this is the file that needs to be complied . If I click this button I am hoping that I can call my intit port function since I am including serial.h header in sergra.c. Anyways I just hope someone who know these thing can help me out!
 
Old 04-30-2005, 05:00 AM   #6
alred
Member
 
Registered: Mar 2005
Location: singapore
Distribution: puppy and Ubuntu and ... erh ... redhat(sort of) :( ... + the venerable bsd and solaris ^_^
Posts: 658
Blog Entries: 8

Rep: Reputation: 30
this is how i like to organise and complie files :

gcc -c serial.c
gcc -shared -o libserial.so serial.o
gcc -L. -lserial -o ser ser.c
gcc `pkg-config --cflags --libs gtk+-2.0` -L. -lserial serGTK.c -o serGTK

by these the gtk app works for me

your method might be different though
 
Old 05-09-2005, 11:40 AM   #7
prems
LQ Newbie
 
Registered: Mar 2005
Posts: 9

Original Poster
Rep: Reputation: 0
Alred,
Thanks a lot, your file organisation seems to right. But I am still stuck . I tried mimicking exactly what you did. However I seem to have a few problems.


this is what I did
gcc -c serial.c
gcc -shared -o libserial.so serial.o
gcc -L. -lserial -o ser ser.c
gcc `pkg-config --cflags --libs gtk+-2.0` -L. -lserial serGTK.c -o serGTK

where serial.c is the function definitions,
ser.c is my main program
and serGTK is the graphics program.
I do not get any errors for any of them
.
But when i try to execute them
./ser or
./sergra i get an error:
error while loading shared libraries: libserial.so : cannot open shared object file: No such file or directory exists. However this file very much exists . All files are in the same directory. Hope you help me cause I seem totally stuck !!!

PS: my gtk version is the same. checked that !
 
Old 05-09-2005, 05:35 PM   #8
michaelk
Moderator
 
Registered: Aug 2002
Posts: 9,920

Rep: Reputation: 338Reputation: 338Reputation: 338Reputation: 338
FYI
http://gcomm.sourceforge.net/
 
Old 05-10-2005, 02:08 AM   #9
alred
Member
 
Registered: Mar 2005
Location: singapore
Distribution: puppy and Ubuntu and ... erh ... redhat(sort of) :( ... + the venerable bsd and solaris ^_^
Posts: 658
Blog Entries: 8

Rep: Reputation: 30
copy or link your libserial.so to "/usr/lib" or "/usr/local/lib"
then just for extra precaution run the command "ldconfig" in your Xterminal

Last edited by alred; 05-10-2005 at 02:11 AM.
 
Old 05-10-2005, 11:30 AM   #10
prems
LQ Newbie
 
Registered: Mar 2005
Posts: 9

Original Poster
Rep: Reputation: 0
Works!. Thanks a lot alred. Just one more point.( its more out of academic interest really) why do I need to share it in this way. For normal library functions I created All I need to do is to include the header, whereas here am creating a dynamic share.
 
Old 05-10-2005, 03:51 PM   #11
alred
Member
 
Registered: Mar 2005
Location: singapore
Distribution: puppy and Ubuntu and ... erh ... redhat(sort of) :( ... + the venerable bsd and solaris ^_^
Posts: 658
Blog Entries: 8

Rep: Reputation: 30
its still possible to just include headers in the main app but it just make your source more readable by breaking large source file into multiple sources especially you have a lot of global declations of #define or variables

with dynamic shared lib we have app which is more re-usable . That mean we need just to "upgrade" that particular library source and re-complie as shared and redistribute that particular shared library only , no need to touch and redistribute the main app and source . This works fine if we can break down our app into many manageble "components" as shared libraries , with this method the main source actually functions as a glueing board for our components/shared libraries.
Furthermore if programmers using languages other the C need your serial library functions in their own app , then they only need to port your headers file to their language of choice , compile it with their language compiler , then they can call your serial functions in their own program .

i'm using only Kylix/Pascal when comes to programming and there are lots of well known headers files in linux which have been ported to Pascal headers like xine.h , smpeg and sdl.h , therefor Kylix/Pascal programmers can still call XINE , SMPEG and SDL functions in their app . infact i had tried porting your serial.h to serial.pas , compile it with Kylix and i'm able to call your serial functions in Kylix/Pascal program for testings .

this is how i understand C shared libraries , hopes that i'm not too wrong with this .
as for the actual answer , i believe those real-world C programmers are in a better position to give you a better answer .
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
serial port communication prems Linux - Newbie 1 04-17-2005 02:31 AM
serial port communication vidyaraj Linux - Software 2 03-14-2004 11:32 PM
communication with serial port vidyaraj Linux - Hardware 0 03-09-2004 08:32 PM
serial port communication vidyaraj Linux - Software 6 03-02-2004 06:46 PM
communication via serial port perdesiz Linux - Software 0 11-13-2003 06:23 AM


All times are GMT -5. The time now is 04:55 AM.

Main Menu
 
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: @linuxquestions
Open Source Consulting | Domain Registration