how do I strip nulls out of incoming serial data? (Solved)

I have a device that I wrote code for that looks for certain string data coming from the serial port. It works fine when the device I’m monitoring is set to ASCII mode. However, there is another mode that encapsulated the data in a binary format. The ASCII string is still there. The problem is that there can also be null characters, which doesn’t play well with receiving strings. My thought was to receive the characters a byte at a time, ignore any null, and then add them to a string. I just don’t know how to do that. Any advice would be appreciated.

#include <EEPROM.h>
// Set constant values - won't change.
const int relay1 =  4;      // the number of the Relay pin
const int relay2 =  5;
const int relay3 =  6;
const int relay4 =  7;

// Variables will change :
int relayvalue = 0;
int relay1state = LOW;             // relaytate used to set the relay
int relay2state = LOW;
int relay3state = LOW;
int relay4state = LOW;
int pos;
int dummy;
unsigned long rtime = millis();
int rflag;
String serval;

void setup() {
  // set the digital pin as output:
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);
  // Start the serial port
  Serial.begin(115200);
  relayvalue = EEPROM.read(0);
  if (relayvalue > 15)
    relayvalue = 0;
  dummy = relayset(relayvalue);
}

void loop()
{
  // Main loop
  if (rflag == 1 && millis() - rtime > 120000) {
    EEPROM.update(0, relayvalue);
    rflag = 0;
  }

  while (Serial.available() > 0) {
    serval = Serial.readStringUntil(13);

    pos = serval.indexOf("tance Low");
    if (pos > 0) {
      relayvalue = relayvalue - 1;
      if (relayvalue ==  -1)
        relayvalue = 0;
      dummy = relayset(relayvalue);
    }
    pos = serval.indexOf("tance High");
    if (pos > 0) {
      relayvalue = relayvalue + 1;
      if (relayvalue == 16)
        relayvalue = 15;
      dummy = relayset(relayvalue);
    }
  }
}

// Subroutine for turning relay on/off.
int relayset(int x) {
  if (bitRead(relayvalue, 0) == 1)
    relay1state = HIGH;
  else
    relay1state = LOW;

  if (bitRead(relayvalue, 1) == 1)
    relay2state = HIGH;
  else
    relay2state = LOW;

  if (bitRead(relayvalue, 2) == 1)
    relay3state = HIGH;
  else
    relay3state = LOW;

  if (bitRead(relayvalue, 3) == 1)
    relay4state = HIGH;
  else
    relay4state = LOW;

  // set the Relay with the relaystate.
  digitalWrite(relay1, relay1state);
  digitalWrite(relay2, relay2state);
  digitalWrite(relay3, relay3state);
  digitalWrite(relay4, relay4state);
  rflag = 1;
  rtime = millis();
  Serial.print(relayvalue);

}

Don't use Strings, but instead read the serial device character by character, using character arrays and the string processing functions built in to C/C++.

It is trivial to discard any particular type or range of characters using this approach. See http://www.codingunit.com/c-tutorial-strings-and-string-library-functions

OK, so how would I do the equivalent of indexOf using char arrays?

Take a look at strchr(). Note that it returns a pointer to the character being searched for, not an index number. However, you can use pointer arithmetic to figure out the index.

I'm not looking for 1 character within a string. I'm looking for a substring within a string. I would like to be able to do what my current code does except be able to ignore the nulls. Is there a way to convert char arrays to strings?

My thought was to receive the characters a byte at a time, ignore any null, and then add them to a string.

Then you need to state what you want more clearly. An example of what's coming in and what you want when the code's done would be a starting point.

I'll try to be a little more explicit. My program works if the device I'm attached to is set to ASCII mode and sends messages like this:

Message: Capacitance Low

or

Message Capacitance High

If I set the device to the other mode it encapsulates the message in some other binary data. For example

02 01 00 20 Message: Capacitance Low 0D 0A 12 43 03

The highlighted is the binary values sent. As you can see, there is a null in the data stream. This is where my problem lies.

That null is followed by a space. What happens if you search for the null and replace it with another space?

That was an example. It wouldn't necessarily be a space. Still, if I'm using the string functions, I can't search for a null because that is a string termination character. Thus I would need to receive as a char, ignore nulls, and convert to a string. Sorry if I'm a little dense. This is only the second Arduino program that I've written. Some example code to do what I want would be appreciated.

Some example code to do what I want would be appreciated.

See the link in reply #1 for lots of examples. If you read the serial line character by character, you can do anything you want.

    incomingByte = Serial.read();
    if(incomingByte == 0) {
    ignore_character();
    }
    else {
    save_character();
    }

I understand how to receive a byte or char at a time and ignore if it's a null. However, I need to check for a particular sequence of characters after ignoring the nulls. To do this I previously used indexOf which only works on strings. So, back to my original question. How do I get a byte array or a char array back to a string? Or, how do I search for a sequence of characters in a char or byte array?

strstr().

Methinks you need a c/c++ reference.

Thanks to all. strstr did the trick. Yep, I need to read a C/C+ reference. I'm new to C/C+ and was a bit overwhelmed.