I have a String (not 's') which I would like to analyse character by character to emulate a state machine-like system. Basically, I'm looking for a specific phrase and I wanted to store the value which appears right next to the phrase. How can I go about doing this? I've got the basic concept but still am unsure of how to implement in the IDE.
Yes, you shouldn't use String for many reasons, most of which are advanced topics. They will cause subtle, inexplicable failures, so it's best to not start down that path.
Here is a C string implementation that watches for "KEYWORD=", using a Finite-State machine:
enum state_t { RX_KEYWORD, RX_SEPARATOR, RX_VALUE };Â // The possible states
static state_t state; // A variable of that enumerated type (basically an integer)
static char  keyword[] = "KEYWORD"; // The string to watch for
static uint8_t keywordIndex;Â Â Â Â Â // How much has matched so far
static int16_t value = 0;Â Â Â Â Â Â Â // Value to save
//static char  value[ 32 ];      // Value to save
//static float value = 0;       // Value to save
static bool emptyValue = true;
//===========================
// This FSM parses watches for a specific keyword. As each character
//Â is received, it either changes the current "state", or contributes
//Â to a parameter's value.
//
// No temporary buffers are used, and invalid keywords are immediately
//Â rejected.
bool getCommand( char c )
{
 bool gotIt = false; // Assume we're not done.
 switch (state) {
  case RX_KEYWORD:     //--------------------------------
   if (c == keyword[ keywordIndex ]) {
    // Another char matched, step to the next one.
    keywordIndex++;
    if (keywordIndex == sizeof(keyword)-1) {
     // All matched, start watching for the separator
     state = RX_SEPARATOR;
    }
  } else {
    // Didn't match, restart
    keywordIndex = 0;
   }
   break;
  case RX_SEPARATOR:   //--------------------------------
   if (c == '=') {
    emptyValue = true;
    value   = 0;
    state   = RX_VALUE;
   } else {
    // Restart
    keywordIndex = 0;
   }
   break;
  case RX_VALUE:     //--------------------------------
   if (isdigit( c )) {
    emptyValue = false;
    value   = value*10 + (c - '0'); // accumulate another digit
   } else {
    gotIt = true; // no more digits, indicate value is complete
    // Restart
    keywordIndex = 0;
    state = RX_KEYWORD;
   }
   break;
 }
 return gotIt;
}
//===========================
void setup()
{
 Serial.begin( 9600 );
 Serial.print( F("fghfgh example started.\n"
         "Watching for \"") );
 Serial.print( keyword );
 Serial.println( F("=value\" strings.") );
}
//===========================
void loop()
{
 while (Serial.available()) {
  bool gotSome = getCommand( Serial.read() );
//Â Â Serial.print( (uint8_t) state );Â // Show the state for each char received
//Â Â Serial.print( '/' );
//Â Â Serial.print( keywordIndex );
//Â Â Serial.print( ',' );
  if (gotSome) {
   Serial.print( F("Keyword received! value = ") );
   if (emptyValue)
    Serial.print( F("<empty>") );
   else
    Serial.print( value );
   Serial.println();
  }
 }
}
It's just a starting point. It does not recognize a string that contain portions of the keyword. For example, "KEYKEYWORD" would not be recognized as containing "KEYWORD", but you probably don't want to accept that, as it could be a valid, distinct string. I suspect the keywords are separated by delimiters (e.g., a comma or space) that cannot be part of the keyword.
There are placeholders for other value types, like char or float. If you want those types, give it a try and ask follow-up questions.
I have a String (not 's') which I would like to analyse character by character to emulate a state machine-like system. Basically, I'm looking for a specific phrase and I wanted to store the value which appears right next to the phrase. How can I go about doing this? I've got the basic concept but still am unsure of how to implement in the IDE.
What code are you currently using? Below is a simple String method of finding a specific character string in a captured String, then obtaining the adjacent characters.
//zoomkat 3-5-12 simple delimited ',' string
//from serial port input (via serial monitor)
//and print result out serial port
String readString, substring;
//String servo1;
int loc;
void setup() {
Serial.begin(9600);
Serial.println("serial delimit test 1.0"); // so I can keep track of what is loaded
}
void loop() {
//expect a string like AA BB01/10/2014 CC12:23:25 DD32.2 EE5432 FF54.35,
if (Serial.available()) {
char c = Serial.read(); //gets one byte from serial buffer
//if (c == '\n') { //looks for end of data packet marker
if (c == ',') {
Serial.println(readString); //prints string to serial port out
//do stuff
loc = readString.indexOf("BB");
//Serial.println(loc);
substring = readString.substring(loc+2, loc+12);
Serial.print("date is: ");
Serial.println(substring);
loc = readString.indexOf("CC");
//Serial.println(loc);
substring = readString.substring(loc+2, loc+11);
Serial.print("time is: ");
Serial.println(substring);
loc = readString.indexOf("DD");
//Serial.println(loc);
substring = readString.substring(loc+2, loc+6);
Serial.print("DD is: ");
Serial.println(substring);
loc = readString.indexOf("EE");
//Serial.println(loc);
substring = readString.substring(loc+2, loc+6);
Serial.print("date is: ");
Serial.println(substring);
loc = readString.indexOf("FF");
//Serial.println(loc);
substring = readString.substring(loc+2);
Serial.print("FF is: ");
Serial.println(substring);
readString=""; //clears variable for new input
substring="";
}
else {
readString += c; //makes the string readString
}
}
}
It seems like you're asking the same question again, but we don't know why our previous answers didn't work for you. These answers are very similar, including why you shouldn't use the String class.
/*
 String to Integer conversion
Reads a serial input string until it sees a newline, then converts
the string to a number if the characters are digits.
The circuit:
No external components needed.
created 29 Nov 2010
by Tom Igoe
This example code is in the public domain.
*/
String inString = "";Â Â // string to hold input
void setup() {
 // Open serial communications and wait for port to open:
 Serial.begin(9600);
 while (!Serial) {
  ; // wait for serial port to connect. Needed for native USB port only
 }
 // send an intro:
 Serial.println("\n\nString toInt():");
 Serial.println();
}
void loop() {
 // Read serial input:
 while (Serial.available() > 0) {
  int inChar = Serial.read();
  if (isDigit(inChar)) {
   // convert the incoming byte to a char
   // and add it to the string:
   inString += (char)inChar;
  }
  // if you get a newline, print the string,
  // then the string's value:
  if (inChar == '\n') {
   Serial.print("Value:");
   Serial.println(inString.toInt());
   Serial.print("String: ");
   Serial.println(inString);
   // clear the string for new input:
   inString = "";
  }
 }
}
The part that didn't work for me was replacing the String with the lower-case version for this type of implementation.
fghfghdfghtrdhdtrf:
I have a String (not 's') which I would like to analyse character by character to emulate a state machine-like system. Basically, I'm looking for a specific phrase and I wanted to store the value which appears right next to the phrase. How can I go about doing this? I've got the basic concept but still am unsure of how to implement in the IDE.
In case you want to find an "exact match" in a string (char array), the strstr() function is for you.
In case you want to seperate parts of a string into several substrings by finding "seperating characters" within the original string, maybe the strtok function can do for you.
It all depends on what you want to do.
If you cannot describe the details, perhaps provide an example of what you want!