detecting key in an input serial stream

Status
Not open for further replies.

RichardFerraro

Well-known member
Hello all,

Any good source code for following ?

I receive a serial char stream from Internet.
There is no way to know what is coming at me.
I want to detect a key, say "hello".

As each character received changes the input buffer,
it seems that converting to stream with each char received might be wasteful.

Thus, it seems working with the char array might be better.

My idea is to insure that the # of chars received is greater than the longest key I am detecting,
then doing a char-by-char comparison.

strstr would require a terminating /0 which the input stream will never have.

thanks,

Richie
 
@Richie:

If you try the char array approach, you need to make sure that you handle the case where part of your key word comes in at the end of the array, but the remainder of the key word comes in at the beginning of the array following the next read.

Instead, I would suggest using a simple state machine to make your way thru your desired key word as the input is parsed one character at a time. The state would start at (using your "hello" example key) EXPECTING_H. If the current character is an 'h', then the state would transition to EXPECTING_E. If any other character other than an 'h' is received, then the state would remain at EXPECTING_H. One you've received the 'h' & transitioned to EXPECTING_E, if the current character is an 'e', then the state would transition to EXPECTING_L_1. if any other character other than an 'e' is received, then the state would return to EXPECTING_H as you have to restart your search. The remaining processing would transition thru EXPECTING_L_2, then EXPECTING_O. In state EXPECTING_O, if the current character is an 'o' then you have matched your key word. And of course, if any character other than an 'o' is received, then the state would return to EXPECTING_H as before.

Good luck & have fun !! Feel free to ask more questions if/as needed.

Mark J Culross
KD5RXT
 
While the suggested state machine will work, it could get awkward for longer keys. A simpler approach is to check the input against the key string one character at a time as in the following demo code:

Code:
/***********************************
 * Program to check an input character stream for
 * the presence of a key string.
 * Tested on T3.6   11/28/2021
 *****************************************/


void setup() {
  // put your setup code here, to run once:
  while(!Serial  && (micros() < 1000));
  Serial.println("Input key matching test");

}

void loop() {
  // put your main code here, to run repeatedly:
  char ch;
  if(Serial.available()){  // get char from USB Serial
    ch = Serial.read();
    Serial.print(ch);
    if(KeyReceived(ch)) {
      Serial.println();
      Serial.println("<Key Matched>");
    }
  }

}


const char *keystring = "Hello73";
bool KeyReceived(char ch){
static uint16_t keyindex = 0; 
bool retval = false;
  if(ch == keystring[keyindex]){
    keyindex++;
    if(keyindex == strlen(keystring)){
      keyindex = 0; // start over after match
      retval = true;
    }
  } else {
    keyindex = 0; // back to key start
  }
  return retval;
}

This demo code isn't optimized or consistent with best programming practices, as it uses a global variable, but it does illustrate the algorithm.
 
Status
Not open for further replies.
Back
Top