skip to Main Content

I would like to communicate with Honeywell HPMA115S0 sensor running a C program. Target system is a PocketBeagle running Debian.

I can communicate with the sensor using ‘screen’ utility by setting only port and BPS.
I can also communicate using python3 and Serial library, so i exclude any hardware problem.

But i cannot do it with C program. Everything seems to be good but when i expect an ACK i receive nothing. A curious aspect is if i run screen or the python script and close it, then i can use my C program that properly communicate.

I run stty to check the differences at system boot, then after C program and after the screen but nothing seems to be the cause. I think i have to set proper serial mask. Right now i use:

int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
struct termios tty;
memset(&tty, 0, sizeof tty);

if(tcgetattr(fd, &tty) != 0) {
    printf("Error %i from tcgetattr: %sn", errno, strerror(errno));
}

tty.c_lflag &= ~ECHO; // Disable echo
tty.c_lflag &= ~ECHOE; // Disable erasure
tty.c_lflag &= ~ECHONL; // Disable new-line echo
cfsetospeed(&tty, 9600);
cfsetispeed(&tty, 9600);
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
   printf("Error %i from tcsetattr: %sn", errno, strerror(errno));
}

Any help?
Thank you!

2

Answers


  1. Chosen as BEST ANSWER

    I ran the Python script and the C program with strace and I noticed that the problem resides in:

    cfsetospeed(&tty, 9600);
    cfsetispeed(&tty, 9600);
    

    It should use 'B9600' instead of '9600'.

    The correct form is:

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

  2. What your terminal needs is the non-canonical (a.k.a. raw) mode. The GNU libc documentation has a nice minimal example of how it’s set. Your code doesn’t clear the ICANON flag which is probably the critical one. It should look something like this:

    if(tcgetattr(fd, &tty) != 0) {
        printf("Error %i from tcgetattr: %sn", errno, strerror(errno));
    }
    tty.c_lflag &= ~(ICANON|ECHO); /* Clear ICANON and ECHO. */
    tty.c_cc[VMIN] = 1;
    tty.c_cc[VTIME] = 0;
    cfsetospeed(&tty, 9600);
    cfsetispeed(&tty, 9600);
    if (tcsetattr(fd, TCSAFLUSH, &tty) != 0) {
       printf("Error %i from tcsetattr: %sn", errno, strerror(errno));
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search