Program Hangs

I have two programs, DriverScale.c and scale9.c. DriverScale.c calls scale 9.c which sends a W and a carraige return to the scale which SHOULD return the weight to DriverScale. However scale 9 hangs for at least 10 min, and then finally returns the weight.

Compilation:

ethan@meow:/var/www$ gcc -g -Wall -o DriverScale DriverScale.c scale9.c  
scale9.c: In function �scale9':
scale9.c:53:2: warning: implicit declaration of function �cfsetispeed' [-Wimplicit-function-declaration]
  cfsetispeed(&options, B9600);
  ^
scale9.c:54:2: warning: implicit declaration of function �cfsetospeed' [-Wimplicit-function-declaration]
  cfsetospeed(&options, B9600);
  ^
scale9.c:65:2: warning: implicit declaration of function �tcflush' [-Wimplicit-function-declaration]
  tcflush(fp1, TCOFLUSH);
  ^
scale9.c:76:2: warning: implicit declaration of function �tcgetattr' [-Wimplicit-function-declaration]
  tcgetattr(fp1, &options); //The tcgetattr function fills the termios structure 
  ^
scale9.c:84:2: warning: implicit declaration of function �tcsetattr' [-Wimplicit-function-declaration]
  tcsetattr(fp1, TCSANOW, &options); /* apply the settings */
  ^
scale9.c:125:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

DriverScale.c

float scale9(void);

#include <stdio.h>

int main(void) 

{
    float wgt;
    
    printf ("%s", "weight from scale9\n");
    wgt = scale9();
    printf("%f", wgt);
    return 0;
}

scale9.c
Note: All comment lines are on one line in the code.

/*
*Scale9  Write data to Serial Port and Read it
*
*/ 

#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stropts.h>
#include <asm/termios.h>
#include <unistd.h>
#include <string.h>
//#include <termios.h>

#define MODEMDEVICE "/dev/ttyS0"
//void main(void)
float scale9(void) 
{
    char buf[8] = " ", buf2[8] = " ";
  
    FILE *fp1, *fp2; 
    float wgt;
    int i;

    struct termios options;

    fp1 = fopen(MODEMDEVICE, "w+");
    
    fp2 = fopen("/tmp/testfile.txt", "w+");

    if(fp2 == NULL)
    {
        printf("testfile error. \n");
    }

    
    if(fp1 == NULL)
    {
        printf("initiation error. \n");
    }

    printf("  hellow scale");


    cfsetispeed(&options, B9600);
    cfsetospeed(&options, B9600);




    options.c_cflag |= ~PARENB;  // Allow parity to be set

    options.c_cflag &= ~CSTOPB; // 1 stop bit 
    options.c_cflag &= ~CSIZE;  // Mask the character size bits 
    options.c_cflag |= CS7;     // 7 bits
    tcflush(fp1, TCOFLUSH);
    
    
    printf("  hellow scale2");

    
    tcgetattr(fp1, &options); //The tcgetattr function fills the termios structure 
    //you provide with the current serial port configuration. 
    //After we set the baud rates and enable local mode and serial data receipt, 
    //we select the new configuration using tcsetattr. The TCSANOW constant specifies 
    //that all changes should occur immediately without waiting for output data to finish 
    //sending or input data to finish receiving. There are other constants 
    //to wait for input and output to finish or to flush the input and output buffers.
    
    tcsetattr(fp1, TCSANOW, &options); /* apply the settings */
    
    
printf("scale7");
    fprintf(fp1, "%s","W\r\n");  //send the command to the scale
    fread(buf, 1, 7,fp1); strip the first character, which is a carriage return
    printf("buf\n");
printf("scale7#2");
    for (i= 1; i < 7; i++)
        buf2 = buf;
    printf("%s", buf2);
    
    for (i = 0; i<8; i++)
        printf("%c\n", buf);
        
printf("\n%s#3", buf);
    
    printf("buf2\n");

    
    for (i = 0; i<7; i++)
        printf("%c\n", buf2);
  printf("buf2\n");
printf("scale7#4");
    printf("%s", buf2);
    wgt = atof(buf2);
    printf("wgt\n");
     printf("%f", wgt);
    

printf("\n%s", buf2);
    fclose(fp1);
   fwrite(buf, 1, 7,fp2 );
   fwrite(buf2, 1, 7,fp2 );
    
    fclose(fp2);

}

TIA

You can't modify terminal characteristics until you have determined what your current terminal characteristics are; and getting the characteristics after you have initialized settings you want to put in place wipes out all of the initializations you performed... Try moving the line:

    tcgetattr(fp1, &options); //The tcgetattr function fills the termios structure 

so it comes before the line:

    cfsetispeed(&options, B9600);

Don -

Thank you.

Hangs and makes no progress.

A few more points to be added -

The program previously ran beautifully from the terminal. Now it eventually gives 0.00 as the result.

If I use minicom, I get the correct number.

You do not have two programs. You have one program that requires compiling two C source files and linking them together into one executable object file.

What is minicom? If it works with minicom what are you using when it fails?

What operating system are you using?

What compiler are you using? What command line are you using to compile and link the various pieces of this program.

So, why is the inclusion of termios.h commented out when you are clearly getting warnings because you haven't included that header? And, why are you including asm/termios.h ?

You declare that scale9() will return a floating point value, but there are no return statements in scale9() (so it can't possibly return a value).

There is clearly other code in what you have shown us that would generate compilation errors (not just warnings). ( strip the first character, which is a carriage return is not a valid C statement.) Please show us your real code; not code that has been modified to spread comments across multiple lines.

The way you are setting options.c_cflag is clearly wrong, but I'm not sure how to correct it since I'm not sure what you're trying to do. What terminal characteristics does the scale connected to /dev/ttyS0 expect?

Please show us the output you get from the command:

od -bc < /tmp/testfile.txt

after you run your program.

Don -

Thanks. Incisive answers that provide help are greatly appreciated.

So, why is the inclusion of termios.h commented out .. That is not where

termios.h

is. It is here ..

#include <asm/termios.h>

.

If it works with minicom what are you using when it fails? scale9

What operating system are you using? Debian testing.

There are no return statements in scale9() I noticed that and added one, no difference.

not code that has been modified to spread comments across multiple lines. As I said in my post.. Note: All comment lines are on one line in the code.

strip the first character, which is a carriage return is not a valid C statement.
It is a comment.

I do not get any errors in running the program, just warnings on compile.

What terminal characteristics does the scale connected to /dev/ttyS0 expect? 9600 7E1

Please show us the output you get from the command:

ethan@meow:/var/www$ od -bc < /tmp/testfile.txt
0000000

I hope this answers your questions.

TIA

No! The standard header is <termios.h> . I have no idea what is in <asm/termios.h> , but it clearly isn't what you need or you wouldn't be getting warnings about 5 functions being undeclared that should be declared in <termios.h> . Delete the line including <asm/termios.h> and uncomment the line including <termios.h> .

OK. So, you're saying that when you run some other code that you haven't shown us, it works. And, when you run the code you have shown us it doesn't work.

What return statement did you add and where did you add it?

No! In the code you showed us:

    fread(buf, 1, 7,fp1); strip the first character, which is a carriage return

the text shown in red is not a comment.

Then you have now shown us the code you compiled! The code you have shown us will not compile successfully!

That doesn't even come close to answering the question.

With the fopen() call you used, and the code:

   fwrite(buf, 1, 7,fp2 );
   fwrite(buf2, 1, 7,fp2 );

, you add 14 bytes to the end of that file every time you run your program. And, you're telling us that you have run your program several times and end up with absolutely no data written to your this file??? So, if your script is running for 10 minutes and then dies without printing anything, something is killing your program before it successfully reads anything from your scale.

Besides not writing anything into /tmp/testfile.txt , there are several printf() statements that do not seem to be running. So, the code you have shown us should not compile and if it did compile it should print data to standard output that you say is not appearing. But, since you don't include <newline> characters in most of your output, it may be stuck in a buffer instead of being made visible. And, since we don't know what characteristics you scale needs, we might not be seeing anything because the scale is hanging. And, the line could be dropping after 10 minutes if you don't have those characteristics set appropriately. And, you never check any of your I/O statements for error returns, so we have no indication if something is going wrong.

Delete the line including <asm/termios.h> and uncomment the line including

<terminos.h>

Did that and received the following:

scale9.c: In function �scale9':
scale9.c:53:2: warning: passing argument 1 of �tcsetattr' makes integer from pointer without a cast [enabled by default]
  tcsetattr(fp1, TCSANOW, &options); /* apply the settings */
  ^
In file included from scale9.c:18:0:
/usr/include/termios.h:70:12: note: expected �int' but argument is of type �struct FILE *'
 extern int tcsetattr (int __fd, int __optional_actions,
            ^
scale9.c:67:2: warning: passing argument 1 of �tcflush' makes integer from pointer without a cast [enabled by default]
  tcflush(fp1, TCOFLUSH);
  ^
In file included from scale9.c:18:0:
/usr/include/termios.h:90:12: note: expected �int' but argument is of type �struct FILE *'
 extern int tcflush (int __fd, int __queue_selector) __THROW;
            ^
scale9.c:78:2: warning: passing argument 1 of �tcgetattr' makes integer from pointer without a cast [enabled by default]
  tcgetattr(fp1, &options); //The tcgetattr function fills the termios structure 
  ^
In file included from scale9.c:18:0:
/usr/include/termios.h:66:12: note: expected �int' but argument is of type �struct FILE *'
 extern int tcgetattr (int __fd, struct termios *__termios_p) __THROW;

So, now that you're using the correct header, it is telling you that the termios related functions expect a file descriptor (not a stdio stream pointer) as their 1st argument. What have you done to fix that?

What does your code look like now?

Have you added code to check function calls for success and to report errors that were detected?

I repeat: What return statement did you add to your function and where did you place it?

I repeat: What terminal characteristics does your scale hardware expect on its communication link to your system?

1 Like

Don -

Thanks.

That was it. Put in the \n and everyting worked. I should remember put in error checking and to flush a buffer. Sorry for my stupidity.

BTW - In the Debian distribution that I have, this is what works...
#include <asm/termios.h>

---------- Post updated at 12:27 AM ---------- Previous update was at 12:19 AM ----------

Don -

Thanks. The

 \n

did it. I should know to use error checking and to flush a buffer. Sorry for my stupidity.

BTW In th eDebian distribution I have, the location of

<terminos.h>

is

/usr/include/x86_64-linux-gnu/asm/termios.h

Thanks again