leggere e confrontare più stringhe da seriale

ciao a tutti.
Ho collegato un display lcd e 4 bottoni ad arduino. Arduino è collegato ad un pc con l'usb e ho creato con autoit un programma che tra le altre cose manda alcune informazioni ad arduino in modo da farle vedere sul display lcd. Quando vado (ad esempio), nel menu LAN del mio lcd, arduino manda la stiringa LAN_IP al pc che mi risponde con !IP:192.168.10.2* dove ! e * sono i caratteri che mi delimitano l'inizio e la fine della stringa. Arduino legge carattere per carattere in un ciclo, quindi controllo che

if ((string[0]=='I') && (string[1]=='P') && (string[2]==':')) {
       IP_computer = "";
       for (i=3;i<(string_len-1);i++) {
           IP_computer += string[i];
       }
}

Tutto questo è nel ciclo loop(). Funziona se le stringhe da confrontare sono poche, ma se devo verificare anche il gateway, la subnet e altri valori, il sistema fa casini.
Pensavo quindi di fare la richiesta della variabile che mi serve solo quando si entra in un determinato menu, oppure all'inizio del programma, prima di fare qualsiasi altra cosa. Il problema è che... non ci riesco :frowning:
La gestione del menu la faccio attraverso questo script: Tutorial: come gestire menu e display LCD con Arduino – Coagula – Giuseppe Di Cillo
La routine che uso è questa (tralascio le cose non utili alla mia questione):

char string[24];
int i=0;
int string_len;
int inByte;
int last_inByte;

void setup()
{
  lcd.setCursor(0,1);
  lcd.print("Attendere...    ");
  Serial.begin(9600);
}

void read_serial()  // FUNCTION FOR READING THE SERIAL MESSAGE
{
   Serial.println ("SOL FOUND and reading");  // THE SOL (Start of Line) found notice.
   Serial.print("READ : !\n");  //Saying that it has read "!" on the serial port
   while (inByte!= '*') // As long as EOL not found, keep reading
   if (Serial.available() > 0) // if new data is available
        { inByte = Serial.read(); // Read new byte
           Serial.print("READ : "); // Display the new byte
           string[string_len] = inByte; // Save the data in a character array
           Serial.println(string[string_len]); // Print the characters that was recieved
           string_len++;}
    else if (Serial.available() == 0)
          {Serial.println("EOL not available, data string invalid"); // If EOL not in the string
          Serial.println("$N"); //FAIL SIGNATURE
           break;
           }

 if (inByte == '*')
  {       
       Serial.println ("eol FOUND, and full string was");  // Echoes Success Message
       Serial.println ("$Y"); //SUCCESS SIGNATURE
       //Serial.println ("trst" + stringaLetta);
       for (i=0;i<(string_len-1);i++) {
           Serial.print(string[i]);
       }
       Serial.print ("\n");
       //lettura=true;
   }
 } // read_serial() end

void loop() {
  inByte = Serial.read();
  string_len=0;
  if (inByte == '!') read_serial();  // If Start of line ("!") is found, call read_serial() function
  if ((string[0]=='I') && (string[1]=='P') && (string[2]==':')) {
       IP_computer = "";
       for (i=3;i<(string_len-1);i++) {
           IP_computer += string[i];
       }
    lcd.setCursor(0,1);
    lcd.print(IP_computer);       
  } 

   
  if ((string[0]=='S') && (string[1]=='B') && (string[2]==':')) {
       Subnet_computer = "";
       for (i=3;i<(string_len-1);i++) {
           Subnet_computer += string[i];
       }
    lcd.setCursor(0,1);
    lcd.print(Subnet_computer);       
  }
 
   if ((string[0]=='G') && (string[1]=='W') && (string[2]==':')) {
       GW_computer = "";
       for (i=3;i<(string_len-1);i++) {
           GW_computer += string[i];
       }
    lcd.setCursor(0,1);
    lcd.print(GW_computer);       
  } 
  
  if ((string[0]=='I') && (string[1]=='P') && (string[2]=='_') && (string[3]=='E')) {
       IP_computer_format = "";
       for (i=6;i<(string_len-1);i++) {
           IP_computer_format += string[i];
       }
    lcd.setCursor(0,1);
    lcd.print(IP_computer_format);       
  }  
  if ((string[0]=='S') && (string[1]=='B') && (string[2]=='_') && (string[3]=='E')) {
       Subnet_computer_format = "";
       for (i=6;i<(string_len-1);i++) {
           Subnet_computer_format += string[i];
       }
    lcd.setCursor(0,1);
    lcd.print(Subnet_computer_format);       
  } 
  if ((string[0]=='G') && (string[1]=='W') && (string[2]=='_') && (string[3]=='E')) {
       GW_computer_format = "";
       for (i=6;i<(string_len-1);i++) {
           GW_computer_format += string[i];
       }
    lcd.setCursor(0,1);
    lcd.print(GW_computer_format);       
  }   
  readArduinoLeds();
  readArduinoButtons();
  readButtons();  //I splitted button reading and navigation in two procedures because 
  navigateMenus();  //in some situations I want to use the button for other purpose (eg. to change some settings)
  delay(20);
}//loop()...

Ho provato a spostare le singole richieste nel ciclo setup, ma non va. Dove sbaglio? Ci sto perdendo le notti per questa cavolata :frowning:

void setup()
{
  lcd.setCursor(0,1);
  lcd.print("Attendere...    ");
  Serial.begin(9600);
  while (DatiOk == false) {
      inByte = Serial.read();
      string_len=0;
      if (inByte == '!') read_serial();  // If Start of line ("!") is found, call read_serial() function
      if ((string[0]=='P') && (string[1]=='C') && (string[2]=='_') && (string[3]=='O') && (string[4]=='N')) {
        string[0]='z';
        Pc_starts = true;
      } 
      if (Pc_starts == true){
        //Leggi Ip
          Serial.print("LAN_IP");  // invio la richiesta al pc di mandarmi l'IP
          inByte = Serial.read();
          string_len=0;
          Serial.print("inByte=" + inByte);
          if (inByte == '!') read_serial();  // If Start of line ("!") is found, call read_serial() function
          for (i=3;i<(string_len-1);i++) {
            IP_computer += string[i];
          }          
          Serial.print(IP_computer;
          delay(50);

        //Leggi Subnet
          Serial.print("LAN_SB");  // invio la richiesta al pc di mandarmi la subnet
          inByte = Serial.read();
          string_len=0;
          Serial.print("inByte=" + inByte);
          if (inByte == '!') read_serial();  // If Start of line ("!") is found, call read_serial() function
          for (i=3;i<(string_len-1);i++) {
            SB_computer += string[i];
          }          
          Serial.print(SB_computer);
          DatiOk = true;
      }  
    }
}

Grazie,
iltomma

Ma tutte le stringhe ti arrivano con "!" e "" come delimitatori?
Tu metti IP, SB,GW... ma non puoi mettere un carattere di inizio stringa differente, così risparmi 2 byte.
Ed in base al carattere di inizio, sai già a cosa corrisponde la quaterna che ricevi.
Ad esempio "!", "+", "-" e lasci sempre "
" come finale.

errore n°1:
il ciclo di lettura dei byte in read_serial() è probabilmente (anzi sicuramente) più veloce dell'arrivo di dati via seriale. Quindi è corretto usare il

while(inByte!= '*')

ma l'utilità di questo while viene sminchiata da questo if:

if (Serial.available() == 0)
          {Serial.println("EOL not available, data string invalid"); // If EOL not in the string
          Serial.println("$N"); //FAIL SIGNATURE
           break;
           }

POI
errore n°2:
se non hai ricevuto il "!" oppure la stringa letta NON è corretta (vedi l'if di prima) tu la usi lo stesso con gli IF.

Quindi: io sposterei tutti gli IF in una funziona a parte ad esempio "elabora_input()", che chiami solo quando ricevi una stringa completa e corretta.
anche l'idea di leo è molto buona, perchè non solo rendi più leggibile gli if, ma li puoi proprio eliminare usando uno switch (che puoi usare meno efficacemente anche adesso)

esempio:

switch(string[0]){
case 'I': [...codice vario...]; break;
case 'G': [...];break;
default: [...codice di errore per codice non riconosciuto...];
}