Working on getting particle-pi to communicate with a running python script

I have a small particle program that gathers data from a python script, by way of a named pipe:

#include <fcntl.h>
#include <unistd.h>

int fifo;
char fname[] = "/tmp/fifo";
char buffer[100];
int count = 0;

void setup() {
    Serial.begin(9600);
    Serial.printf("\rStarting...\n");
}

void loop() {
    fifo = open(fname, (O_RDONLY | O_NONBLOCK));
    delay(1000);
    int bytes = read(fifo,buffer,sizeof(buffer));
    if (bytes > 0) {
        buffer[bytes] = '\0';
        Serial.printf("\n%s read %i bytes: %s\n", fname, bytes, buffer);
        close(fifo);
        count = 0;
    }
    Serial.printf("\r%i",count++);
}

The program works fine as long as the ‘Serial.printf("\r%i",count++)’ line is there. If I comment it out then I get no data. And for some reason the print line in the setup() is not printed either. What stupid thing have I done now?

Mod edit (@harrisonhjones): Formatting

Paging @jvanier

@rcomeau, you may want to use printlnf() instead of printf() to ensure the (usually) mandatory CRLF is printed and the display showing the line. The only place you print a CR is the first thing in setup() and the count++ line. This is why when you remove that line, it no longer “prints”. Add CRs to your prints and it will work.

I don’t really understand why printlnf("…") is different from printf("…\n") but indeed the program now prints the data received from my python app. But now there is another problem. The program prints the data three times the stops. My python app accesses a LoRa sensor that sends sensor data every 5 minutes. The python app shows the data arriving every 5 minutes which is then piped to the particle app. But the Particle app only prints the first three pipes then stops! Any ideas?

Rick

PS: the program has been modified to leave the pipe open all the time.

#include <fcntl.h>
#include <unistd.h>

int fifo;
char fname[] = "/tmp/fifo";
char buffer[100];

void setup() {
    Serial.begin(9600);
    Serial.println("Starting...");
    fifo = open(fname, (O_RDONLY | O_NONBLOCK));
}

void loop() {
    delay(1000);
    int bytes = read(fifo,buffer,sizeof(buffer));
    if (bytes > 0) {
        buffer[bytes] = '\0';
        Serial.printlnf("read %i bytes: %s", bytes, buffer);
        //close(fifo);
    }
}

@rcomeau, printlnf() will print a CRLF at the end of the line while \n only produces a LF. Some terminals or software libraries require the CR as a line termination character.

As for only working three times, your code doesn’t show whatfnctl.h and unistd.h contain so I can’t comment on the mechanics of the transaction. However, have you considered that the delay(1000) in loop() may create a receive buffer overrun or other condition causing data loss?

1 Like