GIDForums  

Go Back   GIDForums > Computer Programming Forums > C Programming Language
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 22-Mar-2005, 10:05
collinm collinm is offline
New Member
 
Join Date: Mar 2005
Posts: 20
collinm is on a distinguished road

Problem with string and serial port


hi

in c programming (linux), i search a way to read the setting of the serial port (speed, parity...) and change it.

i need also to write to a led display (alpha sign communications protocole)

with bash i do:

Code:
echo -e \\000\\000\\000\\000\\000\\001Z00\\002AA Triplex\\004 >/dev/ttyS2

my source code

CPP / C++ / C Code:
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>                     /*atoi, system, getenv */
#include <unistd.h>                     /*sleep, close */
#include <dirent.h>                     /*opendir, readdir, closedir */
#include <string.h>
#include <fcntl.h>                      /*open */
#include <sys/stat.h>
#include <sys/errno.h>  

char *ledisplay;

/* Opening port one for read and write */
int writeopen(char msg[])
{
    int fd1;
    int wr;
    fd1 = open(ledisplay, O_RDWR | O_NOCTTY | O_NDELAY );
    if (fd1 == -1)
    {
        fprintf(stderr, " %s open_port: Unable to open %s\n", strerror(errno), ledisplay);
    }
    else
    {
        fcntl(fd1, F_SETFL, 0);
        printf(" Port 1 has been sucessfully opened and %d is the file descriptor\n",fd1);
        
        printf("sizeof %d\n", sizeof(msg));
        
        wr=write(fd1, msg, sizeof(msg));
        printf(" Bytes sent are %d \n",wr);
        if (wr < 0)
            fputs("write() of n bytes failed!\n", stderr);
        else
            printf(" Stuff has been written into port 1\n");
        close(fd1);
    }
    return (fd1);
} 

int readopen()
{
    int fd1;
    int rd;
    char *buff=NULL;
    fd1 = open(ledisplay, O_RDONLY | O_NOCTTY | O_NDELAY );
    if (fd1 == -1)
    {
        fprintf(stderr, "%s open_port: Unable to open %s\n", strerror(errno), ledisplay); 
    }
    else
    {
        fcntl(fd1, F_SETFL, 0);
        printf(" Port 1 has been sucessfully opened and %d is the file descriptor\n",fd1);
        rd=read(fd1, buff, 100);
        printf(" Bytes recieved are %d \n",rd);
        printf("%s\n",buff);
        close(fd1);
    }
    return (fd1);
} 

int main()
{
    int result;
    
    //echo -e \\000\\000\\000\\000\000\\001Z00\\002AA TRIPLEX \\004 >/dev/ttyS2
    char msg[] = {'\0', '\0', '\0', '\0', '\0', '\1', 'Z', '0', '0', '\2', 'A', 'A', ' ', 'T', 'R', 'I', 'P', 'L', 'E', 'X', ' ', '\4' };
  
    if((result=(readRtuConfig()))!=-1)
    {
    
        printf("port série utilisé: %s\n", ledisplay);
        printf("msg = %s\n",msg);

         if((result=(writeopen(msg)))!=-1)
         {
            printf("ok\n");
         }
    }
    return 1;
}

when i run this program i get

Code:
Port 1 has been sucessfully opened and 3 is the file descriptor Bytes sent are 4 Stuff has been written into port 1 ok

that seem ok but on the led display, i see nothing...

surely,
char msg[] = {'\0', '\0', '\0', '\0', '\0', '\1', 'Z', '0', '0', '\2', 'A', 'A', ' ', 'T', 'R', 'I', 'P', 'L', 'E', 'X', '\4' };

is not equivalent to this bash command

echo -e \\000\\000\\000\\000\\000\\001Z00\\002AA Triplex\\004 >/dev/ttyS2

any idea?
Last edited by LuciWiz : 22-Mar-2005 at 10:32. Reason: Please insert your C code between [c] & [/c] tags
  #2  
Old 22-Mar-2005, 10:34
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,720
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold
Quote:
Originally Posted by collinm
hi


any idea?

First of all, when you have a function like this
CPP / C++ / C Code:
int writeopen(char msg[])

The argument is a pointer to char. There is no way (no way) that the function can know the size of the array unless you tell it.

Note that in your main() function, msg[] is an array of char whose initialization defines the number of chars, so sizeof(msg) in main() gives the number of chars in the message.

However, inside your writeopen() function the following code shows the size of a pointer to char (which is apparently four bytes in your system, as it is in mine).

CPP / C++ / C Code:
int writeopen(char msg[])
{
  printf("sizeof %d\n", sizeof(msg));

Furthermore when you use any standard library string functions, including printf with "%s" format specifier, they always assume that a "string" is a null-terminated sequence of chars. You do know that there is no "string" data type in C, right?

So, since your message has some byte values that are zero, you can't use strlen(), strcpy(), printf("%s"), etc., to do anything useful with the message.

Bottom line: you must pass information about the message length to your function.

If you want to, you can try the following to see some of the points I have tried to make:

CPP / C++ / C Code:
#include <stdio.h>

int main()
{
  void printit(char []);

  char msg[] = {'\0', '\0', '\0', '\0', '\0', '\1', 
                'Z', '0', '0', '\2', 'A', 'A', ' ',
                'T', 'R', 'I', 'P', 'L', 'E', 'X', '\4' };

  int i;
  int length;

  length = sizeof(msg);
  printf("sizeof(msg) = %d\n\n", length);

  printf("Here are the bytes of msg:\n");

  for (i = 0; i < length; i++) {
    printf("msg[%2d] = 0x%02x\n", i, msg[i]);
  }

  printf("Here's msg, printed with %%s:\n");
  printf("msg: <%s>\n", msg);

  printit(msg);

  return 0;
}

void printit(char x[])
{
  printf("in printit(): sizeof(x) = %d\n", sizeof(x));

}

Regards,

Dave
  #3  
Old 22-Mar-2005, 11:48
collinm collinm is offline
New Member
 
Join Date: Mar 2005
Posts: 20
collinm is on a distinguished road
thanks a lot for the information you writed

i tried to correct some part of the code with you information

now, i have
CPP / C++ / C Code:
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>                     /*atoi, system, getenv */
#include <unistd.h>                     /*sleep, close */
#include <dirent.h>                     /*opendir, readdir, closedir */
#include <string.h>
#include <fcntl.h>                      /*open */
#include <sys/stat.h>
#include <sys/errno.h>  


char *ledisplay;
struct termios oldtio, newtio;


/* Opening port one for read and write */
int writeopen(char msg[], int size)
{
    int fd1;
    int wr;
    fd1 = open(ledisplay, O_RDWR | O_NOCTTY | O_NDELAY );
    if (fd1 == -1)
    {
        fprintf(stderr, " %s open_port: Unable to open %s\n", strerror(errno), ledisplay);
    }
    else
    {
        fcntl(fd1, F_SETFL, 0);
        printf(" Port 1 has been sucessfully opened and %d is the file descriptor\n",fd1);
        
        printf("sizeof %d\n", size);
        
        wr=write(fd1, msg, size);
        printf(" Bytes sent are %d \n",wr);
        if (wr < 0)
            fputs("write() of n bytes failed!\n", stderr);
        else
            printf(" Stuff has been written into port 1\n");
        close(fd1);
    }
    return (fd1);
} 

int readRtuConfig()
{
    /* LED_DISPLAY port */
    if(!(ledisplay = getenv("LED_DISPLAY")))
    {
        fprintf(stderr, "%s - Unable to read variable: LED_DISPLAY\n", strerror(errno));
        return -1;
    }
    return 0;
}

int main()
{
    int result;
    
    //echo -e \\000\\000\\000\\000\000\\001Z00\\002AA TRIPLEX \\004 >/dev/ttyS2
    char msg[] = {'\0', '\0', '\0', '\0', '\0', '\1', 'Z', '0', '0', '\2', 'A', 'A', ' ', 'T', 'R', 'I', 'P', 'L', 'E', 'X', '\4' };
        
    if((result=(readRtuConfig()))!=-1)
    {
        printf("port série utilisé: %s\n", ledisplay);
        int i;
        int length =sizeof(msg); 
        for (i = 0; i < length; i++) 
        {
            printf("msg[%2d] = 0x%02x\n", i, msg[i]);
        }
        
        for(i=0;i<5;i++)
        {
            if((result=(writeopen(msg, length)))!=-1)
            {
                sleep(3); 
            }
        }  
    }
    return 1;
}


that display me:

Code:
/opt/gyear/bin # ./com port série utilisé: /dev/ttyS2 msg[ 0] = 0x00 msg[ 1] = 0x00 msg[ 2] = 0x00 msg[ 3] = 0x00 msg[ 4] = 0x00 msg[ 5] = 0x01 msg[ 6] = 0x5a msg[ 7] = 0x30 msg[ 8] = 0x30 msg[ 9] = 0x02 msg[10] = 0x41 msg[11] = 0x41 msg[12] = 0x20 msg[13] = 0x54 msg[14] = 0x52 msg[15] = 0x49 msg[16] = 0x50 msg[17] = 0x4c msg[18] = 0x45 msg[19] = 0x58 msg[20] = 0x04 Port 1 has been sucessfully opened and 3 is the file descriptor sizeof 21 Bytes sent are 21 Stuff has been written into port 1 Port 1 has been sucessfully opened and 3 is the file descriptor sizeof 21 Bytes sent are 21 Stuff has been written into port 1 Port 1 has been sucessfully opened and 3 is the file descriptor sizeof 21 Bytes sent are 21 Stuff has been written into port 1 Port 1 has been sucessfully opened and 3 is the file descriptor sizeof 21

but i see nothing on the led display...
Last edited by LuciWiz : 22-Mar-2005 at 11:59. Reason: Please insert your C code between [c] & [/c] tags
  #4  
Old 22-Mar-2005, 12:54
Dr. Evil Dr. Evil is offline
Member
 
Join Date: Oct 2004
Location: Netherlands
Posts: 120
Dr. Evil will become famous soon enough
I could be way off here, but if the character combination '\0' means NULL, then this:
Code:
\\000\\000\\000\\000\\000\\001Z00\\002AA Triplex\\004
to me, would be
Code:
{'\\', 0, '0', '0', '\\', 0, '0', '0', '\\', 0, '0', '0', '\\', 0, '0', '0', '\\', 0, '0', '0', '\\', 0, '0', '1', 'Z', '0', '0', '\\', 0, '0', '2', 'A', 'A', ' ', 'T', 'r', 'i', 'p', 'l', 'e', 'x', '\\', 0, '0', '4'};
  #5  
Old 22-Mar-2005, 13:19
collinm collinm is offline
New Member
 
Join Date: Mar 2005
Posts: 20
collinm is on a distinguished road
Quote:
Originally Posted by Dr. Evil
I could be way off here, but if the character combination '\0' means NULL, then this:
Code:
\\000\\000\\000\\000\\000\\001Z00\\002AA Triplex\\004
to me, would be
Code:
{'\\', 0, '0', '0', '\\', 0, '0', '0', '\\', 0, '0', '0', '\\', 0, '0', '0', '\\', 0, '0', '0', '\\', 0, '0', '1', 'Z', '0', '0', '\\', 0, '0', '2', 'A', 'A', ' ', 'T', 'r', 'i', 'p', 'l', 'e', 'x', '\\', 0, '0', '4'};

\\000\\000\\000\\000\\000
are NULL, not other 0
  #6  
Old 22-Mar-2005, 13:50
Dr. Evil Dr. Evil is offline
Member
 
Join Date: Oct 2004
Location: Netherlands
Posts: 120
Dr. Evil will become famous soon enough
Oh, then would that not be:
Code:
{0, 0, 0, 0, 0, 1, 'Z', '0', '0', 2, 'A', 'A', ' ', 'T', 'r', 'i', 'p', 'l', 'e', 'x', 4};
? For I don't know of any escape character such as \1, \2 or \4.
  #7  
Old 22-Mar-2005, 13:54
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,720
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold
Quote:
Originally Posted by collinm
thanks a lot for the information
but i see nothing on the led display...

There's no way that I can debug your hardware from here. I modified your function to verify that the bytes are getting there OK:

CPP / C++ / C Code:
#include <stdio.h>
#include <stdlib.h>                     /*atoi, system, getenv */

char *ledisplay;
/* Opening port one for read and write */
int writeopen(char msg[], int size)
{
  int i;
  printf("in writeopen(): size =  %d\n", size);
  printf("The message bytes are:\n");
  for (i = 0; i < size; i++) {
    printf("0x%02x  ", msg[i]);
    if ((i % 8) == 7) {
      printf("\n");
    }
  }
  printf("\n");
  return 1;
} 


int main()
{
    int result;
    ledisplay="TEST LED DISPLAY";
    
    char msg[] = {'\0', '\0', '\0', '\0', '\0', '\1', 
                  'Z', '0', '0', '\2', 'A', 'A', ' ', 
                  'T', 'R', 'I', 'P', 'L', 'E', 'X', '\4' };
        
        printf("port série utilisé: %s\n", ledisplay);
        int i;
        int length =sizeof(msg); 
        printf("In main(): the message bytes are:\n");
        for (i = 0; i < length; i++) 
        {
            printf("0x%02x  ", msg[i]);
            if ((i % 8) == 7) {
              printf("\n");
            }
        }
        printf("\n");
        
        for(i=0;i<5;i++)
        {
          printf("In main(), i = %d\n", i);
            if((result=(writeopen(msg, length)))!=-1)
            {
                sleep(3); 
            }
        }  
    return 1;
}

Since the message is getting to the function OK, then if you're absolutely sure that the bytes are correct, then there must be some hardware functionality not operating properly.

(By the way, your program has TRIPLEX and your most recent command line example has Triplex, if it matters.)

You can capture the command line in a file by doing something like this:

Quote:
echo -e \\000\\000\\000\\000\\000\\001Z00\\002AA TRIPLEX\\004 >test.txt

Then compare the bytes of the file with your message from the program. (Does your message need a newline at the end? The command line that you echo to your output device always has a newline at the end. Just thought I'd mention it.)


Regards,

Dave
  #8  
Old 23-Mar-2005, 07:37
collinm collinm is offline
New Member
 
Join Date: Mar 2005
Posts: 20
collinm is on a distinguished road
Quote:
Originally Posted by davekw7x
Since the message is getting to the function OK, then if you're absolutely sure that the bytes are correct, then there must be some hardware functionality not operating properly.

Then compare the bytes of the file with your message from the program. (Does your message need a newline at the end? The command line that you echo to your output device always has a newline at the end. Just thought I'd mention it.)

Regards,

Dave

before displaying my message, i display this string before my msg...

char init[] = {'\0', '\0', '\0', '\0', '\0', '\1', 'Z', '0', '0', '\2', 'E', '$','\4' };

my message is displayed correctely

my init and mss array have some octal code... what i need to do to use hexadecimal code?

i would like to read a file and display the text file to led display
how can i read the file and put the text correctly to msg array?
surely there are a better way?
  #9  
Old 23-Mar-2005, 10:26
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,720
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold
Quote:
Originally Posted by collinm
before displaying my message, i display this string before my msg...

char init[] = {'\0', '\0', '\0', '\0', '\0', '\1', 'Z', '0', '0', '\2', 'E', '$','\4' };

my message is displayed correctely

my init and mss array have some octal code... what i need to do to use hexadecimal code?

Are you saying that following this preamble (from the init[] array) then any sequence of bytes will be displayed? Are the bytes ascii chars or what?


As for hex codes: If you have an integral type (int, char, short, etc.) and you want to express it in hex, use something like this:

CPP / C++ / C Code:
  int v;
  char w;
  v = 0x10;
  w = 0x21;

If you have a string literal and you want to give a hex value for an element, then you can use something like this:

CPP / C++ / C Code:
  char msg[] = "\x10\x21";

Here is an example that shows two ways to initialize an array of char:

(Be sure to pay attention to the size of the first array. An extra byte is used for the terminating null character.)

CPP / C++ / C Code:
#include <stdio.h>
#include <ctype.h>

int main()
{
  unsigned char m1[] = "text""\x12\x00\x56""more";
  unsigned char m2[] = {'t', 'e', 'x', 't', 0x12, 0x00, 0x56, 
                        'm', 'o', 'r', 'e'};


  int i;

  int length;

  length = sizeof(m1);
  printf("length of m1 = %d\n", length);
  printf("Here are the bytes of m1\n");

  for (i = 0; i < length; i++) {
    printf ("m1[%2d] = 0x%02x", i, m1[i]);
    if (isprint(m1[i])) {
      printf("(%c)", m1[i]);
    }
    printf("\n");
        
  }

  printf("\n\n");

  length = sizeof(m2);
  printf("Length of m2 = %d\n", length);
  printf("Here are the bytes of m2\n");

  for (i = 0; i < length; i++) {
    printf ("m2[%2d] = 0x%02x", i, m2[i]);
    if (isprint(m2[i])) {
      printf("(%c)", m2[i]);
    }
    printf("\n");
        
  }

  return 0;
}

Regards,

Dave
  #10  
Old 23-Mar-2005, 10:53
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 4,720
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold
Quote:
Originally Posted by collinm
i would like to read a file and display the text file to led display
how can i read the file and put the text correctly to msg array?
surely there are a better way?

Just open the file and read the chars, I guess:

CPP / C++ / C Code:
#include <stdio.h>

int main()
{
  FILE *infile;
  char *inname = "test.txt";
  int i;
  int charcount;

  unsigned char msg[10];

  int maxchars = sizeof(msg);

  int inchar;
  
  if ((infile = fopen(inname, "rb")) == NULL) {
    printf("Can't open input file <%s> for reading.\n", inname);
    return 0;
  }

  charcount = 0;
  while ((inchar = getc(infile)) != EOF) {
    if (charcount >= maxchars) {
      printf("Maximum character count (%d) reached\n", maxchars);
      break;
    }
    msg[charcount++] = inchar;
  }
  printf("Number of characters read = %d\n", charcount);

  printf("Here are the bytes in msg:\n");
  for (i = 0; i < charcount; i++) {
    printf("%02x ", msg[i]);
    if ((i % 16) == 15) {
      printf("\n");
    }
  }
  printf("\n");

  return 0;
}

Notes:
1. If the file is created by a Windows-type text editor, it will have \r\n characters at the end of each line (usually even if it has only one line).

2. If the file is created by a UNIX/Linux-type text editor, it will have \n characters at the end of the lines.

3. If the file contains non-ascii bytes, and if, in particular, it may contain '\0', you can't use strcpy(), strcat(), etc. since these will quit when the zero byte is encountered. You can simply copy byte-by-byte using pointer or array notation to put the file's bytes together with whatever control sequences are required to display the stuff.

Regards,

Dave
 
 

Recent GIDBlogDeveloping GUIs with wxPython (Part 2) by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

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

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 17:55.


vBulletin, Copyright © 2000 - 2008, Jelsoft Enterprises Ltd.