RS232 -> Particle.publish every 30 seconds not working

Hello,
My Particle Electron is connected to a RS232 Serial port on a piece of machinery which outputs serial data once every second. This string of serial data looks something like:

1/21/2017 6:11:02AM,1234123.23, 254.5434, 12.6, 98.552

My goal is for the Electron to read this string, and send every 30th (every 30 seconds) value to the cloud. I have run into two issues with my code. First was dealing with the End Of Line character. My hardware is outputting \n as the EoL character, which is causing my Particle Webhook to break. (My webhook is trying to take my data payload and send it via http push to another server). My second problem is only sending the 30th line, or sending data every 30 seconds.

My code is posted below. It is currently in a working form that sends data EVERY second.

Can anyone help get this code working?

// Constants
const size_t READ_BUF_SIZE = 64;
const unsigned long CHAR_TIMEOUT = 10000;

// Global variables
char readBuf[READ_BUF_SIZE];
size_t readBufOffset = 0;
unsigned long lastCharTime = 0;

// Count for skipping 30 secs/lines of data
int eol_cnt = 0;


void setup() {
  Serial1.begin(9600);
  Serial.begin(9600);
}

void loop() {
  // Read data from serial
  while (Serial1.available()) {
    if (readBufOffset < READ_BUF_SIZE) {
      char c = Serial1.read();
      if (c != '\n') {
        // Add character to buffer
        readBuf[readBufOffset++] = c;
        lastCharTime = millis();
      }
      else {
        // End of line character found, process line
        readBuf[readBufOffset] = 0;
        Serial.printf("readBuf = \"%s\"\n", readBuf);
        readBuf[strlen(readBuf) - 1] = '\0';
        Serial.printf("readBuf = \"%s\"\n", readBuf);
        Serial.printlnf("got: %s", readBuf);
        Particle.publish("RS232", readBuf);
        readBufOffset = 0;
      }
    }
    else {
      Serial.println("readBuf overflow, emptying buffer");
      Particle.publish("debug", "readBuf overflow, emptying buffer");
      readBufOffset = 0;
    }
  }
  if (millis() - lastCharTime >= CHAR_TIMEOUT) {
    lastCharTime = millis();
    readBuf[readBufOffset] = 0;
    Serial.printlnf("got timeout: %s", readBuf);
    readBufOffset = 0;
  }
}

How does your EOL ('\n') get into your readBuf - looking at that code, it shouldn't be in there at all :confused:
Could it be that you actually got another non-printable character in there?

About every 30th time publish, just add a counter (global or static) to only publish when its >= 30`

  ...
      else {
        // End of line character found, process line
        readBuf[readBufOffset] = 0;
        Serial.printf("readBuf = \"%s\"\n", readBuf);
        readBuf[strlen(readBuf) - 1] = '\0';
        Serial.printf("readBuf = \"%s\"\n", readBuf);
        Serial.printlnf("got: %s", readBuf);
        if (++readCount >= 30) {    
          Particle.publish("RS232", readBuf);
          readCount = 0;
        }
        readBufOffset = 0;
      }
  ...

You have got several print statements in your code, providing some of that output would also help identifying your problem.

This lines are superfluous

readBuf[strlen(readBuf) - 1] = '\0';
Serial.printf("readBuf = \"%s\"\n", readBuf);

You are already setting the zero-terminator ('\0') at the end of your received string, and strlen(readBuf) does already expect the zero-terminator ('\0') in place. Overwriting it with the same thing again does not do anything really.
And the print will always output the same string as the previous one, due to the non-effect of the previous line.

2 Likes

Thanks a million for clarifying this for me! I have cleaned up the code as per your recommendations, and it is working like a champ!

3 Likes