473,408 Members | 2,535 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,408 software developers and data experts.

Read Write serial port

hi

we use linux and c language
under bash i do
echo -e \\000\\000\\000\\000\000\\001Z00\\002AA LINUX \\004 >/dev/ttyS2

that send command to a led display (alpha sign communication)

i need to do convert this code to a c programm under linux

i tried this code:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <stdio.h>

/* File descriptors for the ports */
int fd1, fd2;
char *buff,*buffer,*bufptr;

/* Opening port one for read and write */
int open_port1(void)
{
fd1 = open("/dev/ttyS2", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd1 == -1)
{
perror("open_port: Unable to open /dev/ttyS0 - ");
}
else
{
fcntl(fd1, F_SETFL, 0);
printf(" Port 1 has been sucessfully opened and %d is the file
descriptor\n",fd1);
}
return (fd1);
}

int open_port2(void)
{
fd2 = open("/dev/ttyS2", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd2 == -1)
{
perror("open_port: Unable to open /dev/ttyS0 - ");
}
else
{
fcntl(fd2, F_SETFL,FNDELAY);
printf(" Port 2 has been sucessfully opened and %d is the file
descriptor\n",fd2);
}
return (fd2);
}

int main()
{
int wr,rd;
open_port1();
open_port2();

char msg[]="\\000\\000\\000\\000\\000\\001Z00\\002AA LINUX \\004";

wr=write(fd1,msg,100);

printf(" Bytes sent are %d \n",wr);
if (wr < 0)
fputs("write() of 4 bytes failed!\n", stderr);
else
printf(" Stuff has been written into port 1\n");
sleep(1);

fcntl(fd2, F_SETFL,FNDELAY);
rd=read(fd2,buff,100);
printf(" Bytes recieved are %d \n",rd);
printf("%s",buff);

close(fd1);
close(fd2);
return 1;
}

but nothing happen on the led display

any idea?

Nov 14 '05 #1
8 14727
collinm wrote:
we use linux and c language
<irony> but you don't use shift keys</irony>
echo -e \\000\\000\\000\\000\000\\001Z00\\002AA LINUX \\004 >/dev/ttyS2

that send command to a led display (alpha sign communication)

i need to do convert this code to a c programm under linux int fd1, fd2;
int open_port1(void)
{
fd1 = open("/dev/ttyS2", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd1 == -1)
{
perror("open_port: Unable to open /dev/ttyS0 - ");
}
else
{
fcntl(fd1, F_SETFL, 0);
printf(" Port 1 has been sucessfully opened and %d is the file
descriptor\n",fd1);
}
return (fd1);
}
Bad idea: returning a value and storing it in a global at the same time.
Later on ignoring the returnvalue and using the global. Time for
refactoring.
char msg[]="\\000\\000\\000\\000\\000\\001Z00\\002AA LINUX \\004";

wr=write(fd1,msg,100);


Your mistake is that you don't know what gets sent through the serial port.
Seriously, the 'echo -e ..' is something you type at a sh prompt (I assume
you use sh or some similar shell). This line is subject to having certain
characters (in particular the backslash) interpreted specially before
invoking 'echo'. 'echo' in turn interprets another set of characters
specially before sending anything to its stdout. Now, the same scheme
applies to C sourcecode, which interprets the content of string literals
to generate binary strings.

IOW, you have to read manuals to first find out what gets sent to the
serial port and can then start redoing the same under C.

Uli

Nov 14 '05 #2
In article <11**********************@z14g2000cwz.googlegroups .com>,
collinm <co*****@laboiteaprog.com> wrote:
:we use linux and c language

;under bash i do
;echo -e \\000\\000\\000\\000\000\\001Z00\\002AA LINUX \\004 >/dev/ttyS2

:that send command to a led display (alpha sign communication)

:i need to do convert this code to a c programm under linux

:i tried this code:

:/* Opening port one for read and write */
:int open_port1(void)

Your code for open_port1() is the same as your code for
open_port2() except for the message about which port was opened.
In particular, it is bug-for-bug identical in claiming to open S0 but
really opening S2.

: fd1 = open("/dev/ttyS2", O_RDWR | O_NOCTTY | O_NDELAY);

Why are you setting a global variable with the fd number, and
then ignorning the fd value returned by the routine? Don't mix
metaphors.

: char msg[]="\\000\\000\\000\\000\\000\\001Z00\\002AA LINUX \\004";

That doesn't correspond to what you are doing in bash. The correspondance
would be

char msg[] = {'\0', '\0', '\0', '\0', '0', '0', '\1', '0', '0',
'\2', 'A', 'A', ' ', 'L', 'I', 'N', 'U', 'X', '\4' };

a) in your bash version you have a \000 in one place instead of a \\000
b) in your bash version the characters after the Z are literal, not
numeric;
c) using char[] with an initialized string is going to result in a trailing
'\0' being put on that is not present in your original. As you are already
dealing with null characters, this could be significant.

: wr=write(fd1,msg,100);

Why are you writing 100 characters out of a string that is only 19
characters long? You should write(fd1, msg, sizeof(msg))

: printf(" Bytes sent are %d \n",wr);
: if (wr < 0)
: fputs("write() of 4 bytes failed!\n", stderr);

But it isn't 4 bytes you would have written!

: fcntl(fd2, F_SETFL,FNDELAY);
: rd=read(fd2,buff,100);
: printf(" Bytes recieved are %d \n",rd);

If you are reading from the same file as you are writting to, and
both fd's are RW, why not just use the same descriptor? Just make
sure you switch properly into reading mode by doing the appropriate
lseek().

: printf("%s",buff);

You are sending binary characters to the device, so why should we
expect that we will get null-terminated printable text back?
My expectation would be that there might be a null in the input,
and that would cause the %s format to stop printing.

Also, you said that the C program was to be the equivilent of the
bash, but in the bash you never read from the device.

One has to wonder whether the device is properly initialized to the
correct speed, parity, and so on, since there is no 'stty' shown,
nor tcsetattr() nor termio call.
--
"Who Leads?" / "The men who must... driven men, compelled men."
"Freak men."
"You're all freaks, sir. But you always have been freaks.
Life is a freak. That's its hope and glory." -- Alfred Bester, TSMD
Nov 14 '05 #3

Walter Roberson wrote:

: char msg[]="\\000\\000\\000\\000\\000\\001Z00\\002AA LINUX \\004";
That doesn't correspond to what you are doing in bash. The correspondance would be

char msg[] = {'\0', '\0', '\0', '\0', '0', '0', '\1', '0', '0',
'\2', 'A', 'A', ' ', 'L', 'I', 'N', 'U', 'X', '\4' };
a) in your bash version you have a \000 in one place instead of a \\000

why some characters have \ in front of them and some not?

where is the Z?

they surely miss a '\0', because in the msg array, there a 5 null

b) in your bash version the characters after the Z are literal, not
numeric; ya i know, in bash i can mix octal characters with literal...

i need to do the same thing with the C program

c) using char[] with an initialized string is going to result in a trailing '\0' being put on that is not present in your original. As you are already dealing with null characters, this could be significant.


what i need to do to resolve that?

char *msg?

Nov 14 '05 #4
collinm <co*****@laboiteaprog.com> wrote:
Walter Roberson wrote:

: char msg[]="\\000\\000\\000\\000\\000\\001Z00\\002AA LINUX \\004";

That doesn't correspond to what you are doing in bash. The

correspondance
would be

char msg[] = {'\0', '\0', '\0', '\0', '0', '0', '\1', '0', '0',
'\2', 'A', 'A', ' ', 'L', 'I', 'N', 'U', 'X', '\4'

};

a) in your bash version you have a \000 in one place instead of a

\\000

why some characters have \ in front of them and some not?
Because '\0' and '0' are two different characters. The first one ('\0')
is the character with the numerical value 0, while the second is the
character that will be printed as the character 0 but will have the
numerical value 48 if your machines uses the ASCII character encoding.
Same for the difference between '\1' and '1' etc. Or do you mean the
difference in bash? That's a question for comp.unix.shell or maybe
comp.unix.programmer since it's nothing related to C.
where is the Z?
Walter forgot it, just put it in where it's missing (i.e. after the
'\1' character).
they surely miss a '\0', because in the msg array, there a 5 null
Then put it in. The corrected version would be

char msg[ ] = { '\0', '\0', '\0', '\0', '\0', '\1', 'Z', '0', '0',
'\2', 'A', 'A', ' ', 'L', 'I', 'N', 'U', 'X', '\4' };
b) in your bash version the characters after the Z are literal, not
numeric;


ya i know, in bash i can mix octal characters with literal...
i need to do the same thing with the C program


What is "the same thing"? Octal, decimal, hexadecimal or whatever
way a value is represented in the program is irrelevant.
c) using char[] with an initialized string is going to result in a

trailing
'\0' being put on that is not present in your original. As you are

already
dealing with null characters, this could be significant.

what i need to do to resolve that?


Take care that you don't use functions that expect strings (i.e. char
arrays that are terminated by a '\0' character) with that array and
to pass the correct length of the array to functions that operate on
simple arrays. You can determine the length by using e.g. 'sizeof msg'.

Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@physik.fu-berlin.de
\__________________________ http://www.toerring.de
Nov 14 '05 #5
In article <11**********************@z14g2000cwz.googlegroups .com>,
collinm <co*****@laboiteaprog.com> wrote:

:Walter Roberson wrote:
:> char msg[] = {'\0', '\0', '\0', '\0', '0', '0', '\1', '0', '0',
:> '\2', 'A', 'A', ' ', 'L', 'I', 'N', 'U', 'X', '\4'
:};

:> a) in your bash version you have a \000 in one place instead of a
:\\000

:where is the Z?

As Jens indicated in his follow-up, I forgot that one when I was
typing it.
:they surely miss a '\0', because in the msg array, there a 5 null

Yes, in the msg array, but that original bash we were given as the
original value had \\000\\000\\000\\000\000 at the beginning. The
\\ introduces an octal character in that bash context, but notice that
before the fifth group there is only a single \ instead of a double \\ .
The single \ and the following 0 will be consumed by the shell at a
level before octal conversion is attempted, so in the bash version
there were four nulls followed by a silently-eaten \0 pair followed
by two literal characters 0 as strings.

:ya i know, in bash i can mix octal characters with literal...

:i need to do the same thing with the C program

You can generally do so in a double-quoted initializer, but there
are a couple of restrictions.

a) The double-quoted initializer wants
to tack a null on the end of the string, and it is not clear from
what you wrote before that that is acceptable; if not, then you cannot
use a double-quoted string (not unless you use it as a convenient
initializer but take a copy of it and strip off the trailing null
before actual use.)

b) A sequence starting with \ extends as far as possible, so
the sequence \00000 wants to consume the five 0's, whereas the
bash you presented wants to consume 3 0's and then have two
literal 0's. There are two ways around this:

1) Keep using \ escapes as far as necessary to reach something
that is not part of any possible escape sequence. For example,

"\0\x30\x30Z"

ends the first null byte because it sees the second one start;
then the \0x30 is one of the representations of the character 0
(as opposed to the -number- 0). You need another escape
after that to end the \x30 because the next character, 0, would
otherwise be eaten as part of the first \x30 too. But then
after that, the Z cannot possibly be part of any octal or
hex or decimal escape sequence, so it is "self-delimiting",
not needing anything to indicate that the previous escape
sequence has ended.

2) Sometimes it's easiest to break the double-quoted string
into two parts, and rely upon the fact that standard C will merge
adjacent double-quoted strings. For example,

"\0\0\0\0" "00Z"

The first four escapes are processed, but the first closing quote
ends the scope of the active escape sequence, so when the second
opening quote starts one is not in escape mode anymore and it is
the literal characters 0 0 Z that would be there.

:> c) using char[] with an initialized string is going to result in a
:trailing
:> '\0' being put on that is not present in your original. As you are
:already
:> dealing with null characters, this could be significant.

:what i need to do to resolve that?

If you need to work with "strings" with embedded nulls, you end up
needing to pass the size all over the place, one way or another
(because otherwise the code won't know where to leave off.) You can
initialize a char [] with a "" string and then pass around the length
-excluding- the trailing null you know to be there. Or you can do as I
demonstrated earlier, in which you use an aggregate initializer of byte
by byte. Or you can bother to create a new string that has the null
stripped out, except you don't gain much by doing so since you
still need to pass the sizes around.
--
Ceci, ce n'est pas une idée.
Nov 14 '05 #6

Walter Roberson wrote:

a) The double-quoted initializer wants
to tack a null on the end of the string, and it is not clear from
what you wrote before that that is acceptable; if not, then you cannot use a double-quoted string (not unless you use it as a convenient
initializer but take a copy of it and strip off the trailing null
before actual use.)

b) A sequence starting with \ extends as far as possible, so
the sequence \00000 wants to consume the five 0's, whereas the
bash you presented wants to consume 3 0's and then have two
literal 0's. There are two ways around this:

1) Keep using \ escapes as far as necessary to reach something
that is not part of any possible escape sequence. For example,

"\0\x30\x30Z"

ends the first null byte because it sees the second one start;
then the \0x30 is one of the representations of the character 0
(as opposed to the -number- 0). You need another escape
after that to end the \x30 because the next character, 0, would
otherwise be eaten as part of the first \x30 too. But then
after that, the Z cannot possibly be part of any octal or
hex or decimal escape sequence, so it is "self-delimiting",
not needing anything to indicate that the previous escape
sequence has ended.


about hex code i have with bash

CMD_INIT="\x00\x00\x00\x00\x00\x01Z00\x02"
CMD_END="\x04"
echo -e "${CMD_INIT}E$AAU0030FFFF${CMD_END}" >/dev/ttyS2

in C, i wrote

char msg1[]={"\x00\x00\x00\x00\x00\x01Z00\x02E$AAU0030FFFF\x0 4"};

that don't seem to be ok

with your information that could maybe transform to

char msg1[]={"\x00\x00\x00\x00\x00\x01\Z00\x02\E$AAU0030FFFF\ x04"};

?

Nov 14 '05 #7
In article <11********************@l41g2000cwc.googlegroups.c om>,
collinm <co*****@laboiteaprog.com> wrote:
about hex code i have with bash CMD_INIT="\x00\x00\x00\x00\x00\x01Z00\x02"
CMD_END="\x04"
echo -e "${CMD_INIT}E$AAU0030FFFF${CMD_END}" >/dev/ttyS2 in C, i wrote char msg1[]={"\x00\x00\x00\x00\x00\x01Z00\x02E$AAU0030FFFF\x0 4"}; that don't seem to be ok with your information that could maybe transform to char msg1[]={"\x00\x00\x00\x00\x00\x01\Z00\x02\E$AAU0030FFFF\ x04"};


Close; you recognized correctly that the problem was the run-on
of the x02 towards the E, but \E is not the way to correct it.

The simplest correction would likely be:

char msg1[]={"\x00\x00\x00\x00\x00\x01\Z00\02E$AAU0030FFFF\x0 4"};

Notice the lack of the 'x' before the 02. Without the x it's
an octal escape instead of a hex escape. E is not a valid octal
character so the parser would end the escape at the 2 and treat the
E as a plain text character.
--
"This was a Golden Age, a time of high adventure, rich living and
hard dying... but nobody thought so." -- Alfred Bester, TSMD
Nov 14 '05 #8
On 22 Mar 2005 18:22:48 GMT, ro******@ibd.nrc-cnrc.gc.ca (Walter
Roberson) wrote:
In article <11**********************@z14g2000cwz.googlegroups .com>,
collinm <co*****@laboiteaprog.com> wrote: <snip> :i need to do the same [string value] with the C program

You can generally do so in a double-quoted initializer, but there
are a couple of restrictions.

a) The double-quoted initializer wants
to tack a null on the end of the string, and it is not clear from
what you wrote before that that is acceptable; if not, then you cannot
use a double-quoted string (not unless you use it as a convenient
initializer but take a copy of it and strip off the trailing null
before actual use.)
Unless you declare a char array with an explicit bound which just fits
the contents of a string-literal initializer with no added null; in
this specific case no null is added, but this is error-prone
especially if you need (later) to change the string and its length.

Or, as you say later, initialize char[] with "string" which adds the
null, and then adjust the size, but you don't need to copy to do this.
Just e.g. write (fd1, msg, sizeof msg -1).
b) A sequence starting with \ extends as far as possible, so
the sequence \00000 wants to consume the five 0's, whereas the


No, \octal only takes up to three digits. And of course \b \r etc. do
exactly one letter. _Only_ \xhex takes as much as possible.

- David.Thompson1 at worldnet.att.net
Nov 14 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Daniel Åberg | last post by:
I can't find how I can, in c#, open a serial port and read and write to it. Anyone that knows if there is any namespace with methods or code example.
3
by: collinm | last post by:
hi i send a command to a led display, the led display is suppose to return me some character i write a string on a serial port void ledDisplayExist() { char msg={'\0', '\0', '\0', '\0',...
6
by: Casey Bralla | last post by:
I'd like to read ASCII data from a serial port, but (once again) I'm having trouble getting started. (Can't seem to find the basic level of docs to get going <sigh>) I'd like to use only...
7
by: alexandre_irrthum | last post by:
Hi there, I am trying to use pyserial to read data from a temperature logger device (T-logger). T-logger is based on the DS1615 temperature recorder chip (Dallas Semiconductor). According to the...
4
by: chenatcr | last post by:
Hello, I added a serial-USB converter to my laptop, it appear as USB serial port COM4, and I wrote an application to read 78k data from this port. In my VC++ express code, I defined...
4
by: rowan | last post by:
I'm writing a driver in Python for an old fashioned piece of serial equipment. Currently I'm using the USPP serial module. From what I can see all the serial modules seem to set the timeout when...
3
by: Charlotte1 | last post by:
How can I read and write a radio connected to the computer with a serial port with python, the same way a hyperterminal does ? I wrote this: from Tkinter import * import serial se =...
0
by: ghjk | last post by:
I want to read sms from GSM modem using C# in serial communication. I wrote the code. But i want to do it automatically. I put my code here and please tell me how can i do it automatically. ...
1
by: ghjk | last post by:
I'm write code to read data from GSM modem. but it couldn't read modem response. Could you please help me? I'll post my code. using System; using System.Collections.Generic; using...
1
by: rfarley | last post by:
Hi, I am using the pyserial module and am trying to read the serial port from an accelerometer (LIS302DL). It has an option in which you write "*debug\r\n" and then you read the data (three...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.