0

Here's my code:

const int RED = 11;
const int GRN = 10;
const int BLU = 9;

String inputString = "";
boolean stringComplete = false;

void setup() {
  Serial.begin(9600);
  pinMode(RED, OUTPUT);
  pinMode(GRN, OUTPUT);
  pinMode(BLU, OUTPUT);
  inputString.reserve(256);

  // I'm using a common-anode led, 
  //so HIGH and LOW works in reverse
  digitalWrite(RED, HIGH);
  digitalWrite(GRN, HIGH);
  digitalWrite(BLU, HIGH);
}

void loop() {
  if(stringComplete) {
    inputString.toLowerCase();
    Serial.println("received " + inputString);

    matchString(inputString, 500);

    inputString = "";
    stringComplete = false;
  }
}

void serialEvent() {
  while(Serial.available()) {
    char inChar = (char) Serial.read();   
    inputString += inChar;
    if(inChar == '\n')
      stringComplete = true;
  }
}

void matchString(String input, int duration) {
  if(containsString(input,"red")) {
    colour(RED, duration);
    Serial.write("input matched red\n"); // added for debugging
  }
  else if(containsString(input, "green")) {
    colour(GRN, duration);
    Serial.write("input matched green\n");
  }
  else if(containsString(input, "blue")) {
    colour(BLU, duration);
    Serial.write("input matched blue\n");
  }
  else {
    delay(duration);
    Serial.write("input didn't match anything\n");
  }
}

void colour(int pin, int duration) {
  digitalWrite(pin, LOW);
  delay(duration);
  digitalWrite(pin, HIGH);
}

// added for later implementation
void colour(int pin1, int pin2, int duration) { 
  digitalWrite(pin1, LOW);
  digitalWrite(pin2, LOW);
  delay(duration);
  digitalWrite(pin1, HIGH);
  digitalWrite(pin2, HIGH);
}

// attempt to implement String.contains
boolean containsString(String input, String search) { 
  int max = input.length() - search.length();

  for(int i = 0; i <= max; i++) {
    if(input.substring(i) == search)
      return true;
  }
  return false;
}

I'm not sure what goes wrong here, I know it reads the stream of chars, but it always writes input didn't match anything back to me, keeping the led unlit...

what did I do wrong here?

3 Answers 3

1

I asked the same question on the Arduino forums and they provided me with a VERY simple (but not very obvious) workaround

so rather than doing all of this:

boolean containsString(String input, String search) { 
  int max = input.length() - search.length();

  for(int i = 0; i <= max; i++) {
    if(input.substring(i) == search)
      return true;
  }
  return false;
}

which doesn't work anyway

all I had to do was this:

boolean containsString(String input, String search) {
  return (strstr(input.c_str(), search.c_str()) != NULL);
}

for those not familiar with the C/C++ function strstr, basically what it does is that it returns the location of the string I'm looking for, or NULL if it doesn't find anything, only downside is that it requres me to use C strings, hence the .c_str()

Also allegedly it's faster to use the C functions than the built in ones because working with the String class in Arduino is generally slow, compared to working with a char array.

Sign up to request clarification or add additional context in comments.

2 Comments

that's a nice workaround. I wasn't familiar with strstr but if you say it works like a charm and is even faster, I'm gonna use that right away!
it works the same as your indexOf, except it uses char arrays, and returns null rather than 0 if it doesn't find anything, so both the solutions are equally valid I guess
1

To look for the particular strings "red", "blue" and "green", you should use indexOf('String to look for'). It will return the index of the string if found or 0 if not found.

So basically, you can do:

void matchString(String input, int duration) {
    if (input.indexOf("red") > 0) {
        colour(RED, duration);
        Serial.println("input matched red\n"); // added for debugging
    }

    //rest of the if/else statement based on the first one.
}

Or add it to your implementation of containsString.

Hope it helps!

Comments

0

According to your code you are searching for "\n" as a line terminator. Are you sure that you actually send the newlines? The Arduino serial monitor does not. My suggestion would be to echo the newlines in order to determine if you really send and detect them.

void serialEvent() {
    while(Serial.available()) {
        char inChar = (char) Serial.read();   
        inputString += inChar;
        if(inChar == '\n') {
            stringComplete = true;
            Serial.print(F("line terminator detected"));
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.