Luca
Luca

Reputation: 21

Pocketbeagle Serial port communication issue with Honeywell HPMA115S0

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: %s\n", 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: %s\n", errno, strerror(errno));
}

Any help? Thank you!

Upvotes: 1

Views: 138

Answers (2)

Luca
Luca

Reputation: 21

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);

Upvotes: 1

Tarmo
Tarmo

Reputation: 4770

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: %s\n", 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: %s\n", errno, strerror(errno));
}

Upvotes: 0

Related Questions