parsing a string

I will ask this another way I guess. I have a program that reads in a line and acts on each character for a control over GMS. It reads a string, looks for characters after a # symbol. I would like it to continue if it does not find what is expected, it looks for g1 or g0 or b1 or b0. I use 5 characters with a 1 or 0 to indicate on or off. Now I need to send the entire set for it to read to the end, I would like to just send what I want changed. Here is the code:

// Example 55.7
 
#include <SoftwareSerial.h> 
char inchar; // Will hold the incoming character from the GSM shield
SoftwareSerial SIM900(7, 8);
 
int led1 = 10;
int led2 = 11;
int led3 = 12;
int led4 = 13;
int led5 = 5; 
int led6 = 6;
void setup()
{
  Serial.begin(19200);
  // set up the digital pins to control
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  pinMode(led6, OUTPUT);
  
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
  digitalWrite(led4, LOW);
  digitalWrite(led5, LOW);
  digitalWrite(led6, LOW);
 
  // wake up the GSM shield
  SIM900power(); 
  SIM900.begin(19200);
  delay(20000);  // give time to log on to network.
  SIM900.print("AT+CMGF=1\r");  // set SMS mode to text
  delay(100);
  SIM900.print("AT+CNMI=2,2,0,0,0\r"); 
  // blurt out contents of new SMS upon receipt to the GSM shield's serial out
  delay(100);
  }
 
void SIM900power()
// software equivalent of pressing the GSM shield "power" button
{
  digitalWrite(9, HIGH);
  delay(2000);
  digitalWrite(9, LOW);
  Serial.println("power");
  delay(7000);
  Serial.println("ready");
}
 
void loop() 
{
  //If a character comes in from the cellular module...
  if(SIM900.available() >0)
  {
    inchar=SIM900.read(); 
    if (inchar=='#')
    {
      delay(10);
 
      inchar=SIM900.read(); 
      if (inchar=='g')
      {
        delay(10);
        inchar=SIM900.read();
        if (inchar=='0')
        {
          digitalWrite(led1, LOW);
          Serial.println("-g");
        } 
        else if (inchar=='1')
        {
          digitalWrite(led1, HIGH);
          digitalWrite(led2, LOW);
          digitalWrite(led3, LOW);
          digitalWrite(led4, LOW);
          Serial.println("+g");
          
        }
        delay(10);
        inchar=SIM900.read(); 
         if (inchar=='b')
        {
          inchar=SIM900.read();
          if (inchar=='0')
          {
            digitalWrite(led2, LOW);
            Serial.println("-b");
          } 
          else if (inchar=='1')
          {
            digitalWrite(led2, HIGH);
            digitalWrite(led1, LOW);
            digitalWrite(led3, LOW);
            digitalWrite(led4, LOW);
            Serial.println("+b");
          }
          delay(10);
          inchar=SIM900.read(); 
          if (inchar=='y')
          {
            inchar=SIM900.read();
            if (inchar=='0')
            {
              digitalWrite(led3, LOW);
              Serial.println("-y");
            } 
            else if (inchar=='1')
            {
              digitalWrite(led3, HIGH);
              digitalWrite(led1, LOW);
              digitalWrite(led2, LOW);
              digitalWrite(led4, LOW);
              Serial.println("+y");
            }
            delay(10);
            inchar=SIM900.read(); 
            if (inchar=='r')
            {
              delay(10);
              inchar=SIM900.read();
              if (inchar=='0')
              {
                digitalWrite(led4, LOW);
                Serial.println("-r");
              } 
              else if (inchar=='1')
              {
                digitalWrite(led4, HIGH);
                digitalWrite(led1, LOW);
                digitalWrite(led2, LOW);
                digitalWrite(led3, LOW);
                Serial.println("+r");
              }
              delay(10);
              inchar=SIM900.read(); 
           if (inchar=='w')
           delay(10);
          {
            inchar=SIM900.read();
            if (inchar=='0')
            {
              digitalWrite(led5, LOW);
              Serial.println("-w");
            } 
            else if (inchar=='1')
            {
              digitalWrite(led5, HIGH);
              Serial.println("+w");
            }
            delay(10);
            inchar=SIM900.read(); 
            if (inchar=='a')
            {
              delay(10);
              inchar=SIM900.read();
              if (inchar=='0')
              {
                digitalWrite(led6, LOW);
                Serial.println("-a");
              } 
              else if (inchar=='1')
              {
                digitalWrite(led6, HIGH);
                delay (1000);
                digitalWrite(led6, LOW);
                Serial.println("+alert");
              }
            }
          }
          Serial.println("Done...");
          SIM900.println("AT+CMGD=1,4"); // delete all SMS
        }
      }
    }
  }
}
  }
}

Hi there. I'm no expert, but here is some code you can look over and maybe it will help you have an idea what to do. Note that it is just a guide -- this code may not compile, and you'll need to mix it in with your other existing code. You can look this over and see if it makes sense. Cheers :smiley:

// read function that doesn't return until it gets a character.
char syncRead() {
  while (1) {
    if (sim900.available() > 0) {
      return sim900.read();
    }
    delay(10);
  }
}

// There should be one LED number for each character in the string.
String controls = "gbyrwa";
int ledIndex[] = {10, 11, 12, 13, 5, 6};

void loop() {
  char inChar = syncread();

  begin:
  if (inchar == "#") {
    // keep looping until we see an unexpected character and hit a 'goto' command.
    while (1) {
      inChar = syncRead();
      int index = controls.indexOf(inChar);
      if (index < 0) {
        goto begin;  // unrecognized character
      } else {
        int led = ledIndex[index];
        inChar = syncRead();
        if (inChar == '0') {
          digitalWrite(led, LOW);
          Serial.print("-");
          Serial.println(commands[index]);
        } else if (inChar == '1') {
          digitalWrite(led, HIGH);
          Serial.print("+");
          Serial.println(commands[index]);
        } else {
          goto begin;
        }
     }
  }
}

With a very simple command syntax like that, you could parse it using a simple two-state finite state machine. This would consist of a boolean which indicates whether you have received the first character of the current pair. Each time another character is available on the serial port you would test this state variable to find whether you're expecting the first or second character.

If you're expecting the first character and the new character is a valid value for the first character, save it and change the state to reflect that you're now waiting for the second character.

If you're expecting the second character and the new character is valid for the second character then you now have the complete message and can act on it. In any case, afterwards you would reset the state to indicate that you're waiting for the first character again.