user69682: I have a Firmata sketch, that accepts string messages, partitions them and sends its' parts back to a Firmata client program. My problem is certainly at the sketch's side. The problem is that Firmata.sendString(argument1) and Firmata.sendString(argument2) methods don't send anything. More information is found in the sketch's code. How can I get the sendString methods to work?
/*
 * This sketch accepts strings in the following form:
 * CMDn(arg1,arg2)
 * CMDn — command name,
 * arg1 и arg2 — unnecessary arguments.
 * Each argument's length can be from 1 to 4 characters,
 * They're saved to separate variables.
 *
 * This sketch sends back the parsed commands partially:
 * the command name, argument #1 (if present), argument #2 (if present)
 */


#include <Firmata.h>


void stringCallback(char *received) {
  //CMDn(arg1,arg2)
  //CMDn(arg1)
  //CMDn(1)
  //CMDn()
  //012345678901234
  //          11111

  //This scheme up there is just for 
  //understanding the indexes of the chars in the string
  //in its various possible variations

  //Let's declare all the necessary variables
  char methodName[5];
  char argument1[5];
  char argument2[5];
  byte commaLocation = 0;

  //If the received string doesn't match the strings' syntax,
  //send an error message
  if (!(received[4] == '(' && strlen(received) <= 15)) {
    Firmata.sendString("ERR;");
    return;
  }

  //Let's take the 0-3 chars in the string and send it back.
  //It's probably the command name
  for (int i = 0; i < 4; i++) {
    methodName[i] = received[i];
  }
  methodName[4] = '\0'; //does or doesn't the compiler add the terminator automatically?
  Firmata.sendString(methodName); //send it
  //This string is being sent without problems.


  //If there is some arguments in the string,
  //it is detectable if the string char 5 is not ')'/
  if (received[5] != ')') {
    //Lent's find out if the input string has a `comma`
    //inside the parentheses. If it does, it means that
    //there are two arguments in the string.

    Firmata.sendString("46 passed");    
    for (int i = 6; i < (strlen(received) - 1); i++) {
      //If there is a comma, save its' index and break the loop
      if (received[i] == ',') {
        commaLocation = i;
        break;
      }
    }

    //If a comma is not present, its location variable equals 0,
    //sincerely we just collect all the chars between the parentheses
    //to the 'argument1' variable and send it.
    if (commaLocation == 0) {
      Firmata.sendString("61 passed");
      for (int i = 5; i < ; i++) {
        argument1[(i - 5)] = received[i];
      }


      argument1[strlen(argument1)] = '\0'; //Either this is executed or not, the outcome doesn't change 

      Firmata.sendString(argument1); //This very command doesn't work. It just does not send anything. 
                                     //Looks like 'argument1' is empty, but I'm awfully sure that it must 
                                     //not be empty. Anyway, the 'argument1' does not show up in the client
    }

    //If there is a comma present, then write chars before the comma
    //to 'argument1', and after the comma - to 'argument2'
    if (commaLocation != 0) {
      Firmata.sendString("77 passed");
      //let's write what is before the comma:
      for (int i = 5; i < commaLocation; i++) {
        argument1[i - 5] = received[i];
        Firmata.sendString("81 iterator");
      }

      //let's write what's after the comma;
      char argument2[5];
      for (int i = (commaLocation + 1); i < (strlen(received)); i++) {
        argument2[(i - (commaLocation + 1))] = received[i];
        Firmata.sendString("87 iterator");
      }
      
      argument1[strlen(argument1)] = '\0'; //Either this is executed or not, the outcome doesn't change 
      argument2[strlen(argument2)] = '\0'; 

      Firmata.sendString(argument1); //Not working
      Firmata.sendString(argument2); //Not working
    }
  }
}


void sysexCallback(byte command, byte argc, byte *argv) {
  Firmata.sendSysex(command, argc, argv);
}


void setup() {
  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
  Firmata.attach(STRING_DATA, stringCallback);
  Firmata.attach(START_SYSEX, sysexCallback);
  Firmata.begin(57600);
}

void loop() {
  while (Firmata.available()) {
    Firmata.processInput();
  }
}

Expected output:




What I send
What I receive (excluding the debug messages, ; stands for newline)




DHTt()
DHTt


DHTt(1)
DHTt; 1


DHTt(1,2)
DHTt; 1; 2




Real output:




What I send
What I receive (excluding the debug messages)




DHTt()
DHTt as long as there are no arguments, there are no problems. But the arguments are necessary for my task


DHTt(1)
DHTt the argument are not sent


DHTt(1,2)
DHTt two arguments are not sent neither




user31038: Here's a simplified version of your command parser using cstrings and pointers:
void parseArgs(char * rec){
  char cmd[32];
  char arg1[32]= {0};
  char arg2[32]= {0};
  char * ptr; // this is a re-usable workhorse pointer
  char * ptrDelim; // another workhorse to split arguments
  
  // first copy all of it to cmd
  strcpy(cmd, rec);
  // find end of command
  ptr = cmd;
  while( isalpha(ptr[0]) ) ptr++;
  ptr[0] = '\0'; // mark end of command string
  
  
  // find first arg
  ptr = strchr(rec, '(')+1; // set ptr to char to right of open paren
  strcpy(arg1, ptr); // copy stuff after open paren to arg1:
  ptr = strchr(arg1, ')');// find max extent of arg1
  if(ptrDelim=strchr(arg1, ',')){
    ptrDelim[0]='\0'; // end arg1's string at delim
    ptrDelim++; // move right one char
    strcpy(arg2, ptrDelim); // copy stuff after comma
    arg2[strlen(arg2)-1] = '\0'; // chop off ")"
  }else{
    ptr[0]='\0';    
  }//end if comma?
  
    
 Serial.println("\nGiven:" + String(rec)+";");   
 Serial.println("Command:" + String( cmd )+";"); 
 Serial.println("Arg1:" + String( arg1 )+";"); 
 Serial.println("Arg2:" + String( arg2 )+";"); 
  
}

Examples:
parseArgs("CMDn()");
parseArgs("CMDn(arg1)");
parseArgs("CMDn(arg1,arg2)");


user69682: Firmata.sendString does not send anything to the client in two cases:

If the message is empty;
If the message does not contain the \0 terminator in it.

In this case, while you're sending methodName, you're manually assigning the terminator to the string; and the sender works:
methodName[4] = '\0';

The only thing necessary to do to solve this argument problem is making each char variable end with a null terminator. Here you can see the solved code:
#include <Firmata.h>

//setup() and loop() won't be here, there are no changes in them

unsigned long charIndex(const char * findIn, unsigned int symbol) {
  //Find 'symbol' in char array 'findIn'. Unlike
  //strchr(), returns unsigned long or 0 if 'symbol' not found
  
  char * pointer = strchr(findIn, symbol);
  if (pointer != NULL) return (pointer - findIn);
  if (pointer == NULL) return 0;
}


void stringCallback(char *received) {
  //Let's declare all the necessary variables
  char methodName[5];
  char argument1[5];
  char argument2[5];
  int commaLocation = 0;
  int lasti;

  byte nullTerminatorIndex = strlen(received); //For understanding

  //If the received string doesn't match the strings' syntax,
  //send an error message
  if (!(received[4] == '(' && strlen(received) <= 15)) {
    Firmata.sendString("ERR;");
    return;
  }

  //Let's take the 0-3 chars in the string and send it back.
  //It's probably the command name
  for (int i = 0; i < 4; i++) {
    methodName[i] = received[i];
  }
  methodName[4] = '\0'; //**The compiler doesn't add terminators automatically**.
  Firmata.sendString(methodName); //send it
  //This string is being sent without problems.


  //If there is some arguments in the string,
  //it is detectable if the string char 5 is not ')'/
  if (received[5] != ')') {
    //Lent's find out if the input string has a `comma`
    //inside the parentheses. If it does, it means that
    //there are two arguments in the string.

    Firmata.sendString("46 passed");    
    if (charIndex(received, ',') != 0) commaLocation = charIndex(received, ',');

    //If a comma is not present, its location variable equals 0,
    //sincerely we just collect all the chars between the parentheses
    //to the 'argument1' variable and send it.
    if (commaLocation == 0) {
      Firmata.sendString("61 passed");
      for (int i = 5; i < (nullTerminatorIndex - 1); i++) {
        argument1[(i - 5)] = received[i];
        lasti = (i - 5);
      }

      argument1[(lasti + 1)] = '\0';
      lasti = 0;

      Firmata.sendString(argument1); 
    }

    //If there is a comma present, then write chars before the comma
    //to 'argument1', and after the comma - to 'argument2'
    if (commaLocation != 0) {
      Firmata.sendString("77 passed");
      //let's write what is before the comma:
      for (int i = 5; i < commaLocation; i++) {
        argument1[i - 5] = received[i];
        lasti = (i - 5);
      }

      argument1[(lasti + 1)] = '\0';
      lasti = 0;

      //let's write what's after the comma;
      char argument2[5];
      for (int i = (commaLocation + 1); i < (nullTerminatorIndex - 1); i++) {
        argument2[(i - (commaLocation + 1))] = received[i];
        lasti = (i - (commaLocation + 1));
      }

      argument2[(lasti + 1)] = '\0';
      lasti = 0;

      Firmata.sendString(argument1);
      Firmata.sendString(argument2); 
    }
  }
}


69682: <p>I have a Firmata sketch, that accepts string messages, partitions them and sends its' parts back to a Firmata client program. My problem is certainly at the sketch's side. The problem is that <code>Firmata.sendString(argument1)</code> and <code>Firmata.sendString(argument2)</code> methods don't send anything. More information is found in the sketch's code. How can I get the <code>sendString</code> methods to work?</p>
<pre class="lang-CPP prettyprint-override"><code>/*
 * This sketch accepts strings in the following form:
 * CMDn(arg1,arg2)
 * CMDn — command name,
 * arg1 и arg2 — unnecessary arguments.
 * Each argument's length can be from 1 to 4 characters,
 * They're saved to separate variables.
 *
 * This sketch sends back the parsed commands partially:
 * the command name, argument #1 (if present), argument #2 (if present)
 */


#include &lt;Firmata.h&gt;


void stringCallback(char *received) {
  //CMDn(arg1,arg2)
  //CMDn(arg1)
  //CMDn(1)
  //CMDn()
  //012345678901234
  //          11111

  //This scheme up there is just for 
  //understanding the indexes of the chars in the string
  //in its various possible variations

  //Let's declare all the necessary variables
  char methodName[5];
  char argument1[5];
  char argument2[5];
  byte commaLocation = 0;

  //If the received string doesn't match the strings' syntax,
  //send an error message
  if (!(received[4] == '(' &amp;&amp; strlen(received) &lt;= 15)) {
    Firmata.sendString(&quot;ERR;&quot;);
    return;
  }

  //Let's take the 0-3 chars in the string and send it back.
  //It's probably the command name
  for (int i = 0; i &lt; 4; i++) {
    methodName[i] = received[i];
  }
  methodName[4] = '\0'; //does or doesn't the compiler add the terminator automatically?
  Firmata.sendString(methodName); //send it
  //This string is being sent without problems.


  //If there is some arguments in the string,
  //it is detectable if the string char 5 is not ')'/
  if (received[5] != ')') {
    //Lent's find out if the input string has a `comma`
    //inside the parentheses. If it does, it means that
    //there are two arguments in the string.

    Firmata.sendString(&quot;46 passed&quot;);    
    for (int i = 6; i &lt; (strlen(received) - 1); i++) {
      //If there is a comma, save its' index and break the loop
      if (received[i] == ',') {
        commaLocation = i;
        break;
      }
    }

    //If a comma is not present, its location variable equals 0,
    //sincerely we just collect all the chars between the parentheses
    //to the 'argument1' variable and send it.
    if (commaLocation == 0) {
      Firmata.sendString(&quot;61 passed&quot;);
      for (int i = 5; i &lt; ; i++) {
        argument1[(i - 5)] = received[i];
      }


      argument1[strlen(argument1)] = '\0'; //Either this is executed or not, the outcome doesn't change 

      Firmata.sendString(argument1); //This very command doesn't work. It just does not send anything. 
                                     //Looks like 'argument1' is empty, but I'm awfully sure that it must 
                                     //not be empty. Anyway, the 'argument1' does not show up in the client
    }

    //If there is a comma present, then write chars before the comma
    //to 'argument1', and after the comma - to 'argument2'
    if (commaLocation != 0) {
      Firmata.sendString(&quot;77 passed&quot;);
      //let's write what is before the comma:
      for (int i = 5; i &lt; commaLocation; i++) {
        argument1[i - 5] = received[i];
        Firmata.sendString(&quot;81 iterator&quot;);
      }

      //let's write what's after the comma;
      char argument2[5];
      for (int i = (commaLocation + 1); i &lt; (strlen(received)); i++) {
        argument2[(i - (commaLocation + 1))] = received[i];
        Firmata.sendString(&quot;87 iterator&quot;);
      }
      
      argument1[strlen(argument1)] = '\0'; //Either this is executed or not, the outcome doesn't change 
      argument2[strlen(argument2)] = '\0'; 

      Firmata.sendString(argument1); //Not working
      Firmata.sendString(argument2); //Not working
    }
  }
}


void sysexCallback(byte command, byte argc, byte *argv) {
  Firmata.sendSysex(command, argc, argv);
}


void setup() {
  Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION);
  Firmata.attach(STRING_DATA, stringCallback);
  Firmata.attach(START_SYSEX, sysexCallback);
  Firmata.begin(57600);
}

void loop() {
  while (Firmata.available()) {
    Firmata.processInput();
  }
}
</code></pre>
<p>Expected output:</p>
<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th>What I send</th>
<th>What I receive (excluding the debug messages, <code>;</code> stands for newline)</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>DHTt()</code></td>
<td><code>DHTt</code></td>
</tr>
<tr>
<td><code>DHTt(1)</code></td>
<td><code>DHTt</code>; <code>1</code></td>
</tr>
<tr>
<td><code>DHTt(1,2)</code></td>
<td><code>DHTt</code>; <code>1</code>; <code>2</code></td>
</tr>
</tbody>
</table>
</div>
<p>Real output:</p>
<div class="s-table-container">
<table class="s-table">
<thead>
<tr>
<th>What I send</th>
<th>What I receive (excluding the debug messages)</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>DHTt()</code></td>
<td><code>DHTt</code> <em>as long as there are no arguments, there are no problems. But the arguments are necessary for my task</em></td>
</tr>
<tr>
<td><code>DHTt(1)</code></td>
<td><code>DHTt</code> <em>the argument are not sent</em></td>
</tr>
<tr>
<td><code>DHTt(1,2)</code></td>
<td><code>DHTt</code> <em>two arguments are not sent neither</em></td>
</tr>
</tbody>
</table>
</div> 31038: <p>Here's a simplified version of your command parser using cstrings and pointers:</p>
<pre><code>void parseArgs(char * rec){
  char cmd[32];
  char arg1[32]= {0};
  char arg2[32]= {0};
  char * ptr; // this is a re-usable workhorse pointer
  char * ptrDelim; // another workhorse to split arguments
  
  // first copy all of it to cmd
  strcpy(cmd, rec);
  // find end of command
  ptr = cmd;
  while( isalpha(ptr[0]) ) ptr++;
  ptr[0] = '\0'; // mark end of command string
  
  
  // find first arg
  ptr = strchr(rec, '(')+1; // set ptr to char to right of open paren
  strcpy(arg1, ptr); // copy stuff after open paren to arg1:
  ptr = strchr(arg1, ')');// find max extent of arg1
  if(ptrDelim=strchr(arg1, ',')){
    ptrDelim[0]='\0'; // end arg1's string at delim
    ptrDelim++; // move right one char
    strcpy(arg2, ptrDelim); // copy stuff after comma
    arg2[strlen(arg2)-1] = '\0'; // chop off &quot;)&quot;
  }else{
    ptr[0]='\0';    
  }//end if comma?
  
    
 Serial.println(&quot;\nGiven:&quot; + String(rec)+&quot;;&quot;);   
 Serial.println(&quot;Command:&quot; + String( cmd )+&quot;;&quot;); 
 Serial.println(&quot;Arg1:&quot; + String( arg1 )+&quot;;&quot;); 
 Serial.println(&quot;Arg2:&quot; + String( arg2 )+&quot;;&quot;); 
  
}
</code></pre>
<p>Examples:</p>
<pre><code>parseArgs(&quot;CMDn()&quot;);
parseArgs(&quot;CMDn(arg1)&quot;);
parseArgs(&quot;CMDn(arg1,arg2)&quot;);
</code></pre>
 69682: <p><code>Firmata.sendString</code> does not send anything to the client in two cases:</p>
<ul>
<li>If the message is empty;</li>
<li><strong>If the message does not contain the <code>\0</code> terminator in it</strong>.</li>
</ul>
<p>In this case, while you're sending <code>methodName</code>, you're manually assigning the terminator to the string; and the sender works:</p>
<pre class="lang-cpp prettyprint-override"><code>methodName[4] = '\0';
</code></pre>
<p>The only thing necessary to do to solve this argument problem is making each <code>char</code> variable end with a null terminator. Here you can see the solved code:</p>
<pre class="lang-cpp prettyprint-override"><code>#include &lt;Firmata.h&gt;

//setup() and loop() won't be here, there are no changes in them

unsigned long charIndex(const char * findIn, unsigned int symbol) {
  //Find 'symbol' in char array 'findIn'. Unlike
  //strchr(), returns unsigned long or 0 if 'symbol' not found
  
  char * pointer = strchr(findIn, symbol);
  if (pointer != NULL) return (pointer - findIn);
  if (pointer == NULL) return 0;
}


void stringCallback(char *received) {
  //Let's declare all the necessary variables
  char methodName[5];
  char argument1[5];
  char argument2[5];
  int commaLocation = 0;
  int lasti;

  byte nullTerminatorIndex = strlen(received); //For understanding

  //If the received string doesn't match the strings' syntax,
  //send an error message
  if (!(received[4] == '(' &amp;&amp; strlen(received) &lt;= 15)) {
    Firmata.sendString(&quot;ERR;&quot;);
    return;
  }

  //Let's take the 0-3 chars in the string and send it back.
  //It's probably the command name
  for (int i = 0; i &lt; 4; i++) {
    methodName[i] = received[i];
  }
  methodName[4] = '\0'; //**The compiler doesn't add terminators automatically**.
  Firmata.sendString(methodName); //send it
  //This string is being sent without problems.


  //If there is some arguments in the string,
  //it is detectable if the string char 5 is not ')'/
  if (received[5] != ')') {
    //Lent's find out if the input string has a `comma`
    //inside the parentheses. If it does, it means that
    //there are two arguments in the string.

    Firmata.sendString(&quot;46 passed&quot;);    
    if (charIndex(received, ',') != 0) commaLocation = charIndex(received, ',');

    //If a comma is not present, its location variable equals 0,
    //sincerely we just collect all the chars between the parentheses
    //to the 'argument1' variable and send it.
    if (commaLocation == 0) {
      Firmata.sendString(&quot;61 passed&quot;);
      for (int i = 5; i &lt; (nullTerminatorIndex - 1); i++) {
        argument1[(i - 5)] = received[i];
        lasti = (i - 5);
      }

      argument1[(lasti + 1)] = '\0';
      lasti = 0;

      Firmata.sendString(argument1); 
    }

    //If there is a comma present, then write chars before the comma
    //to 'argument1', and after the comma - to 'argument2'
    if (commaLocation != 0) {
      Firmata.sendString(&quot;77 passed&quot;);
      //let's write what is before the comma:
      for (int i = 5; i &lt; commaLocation; i++) {
        argument1[i - 5] = received[i];
        lasti = (i - 5);
      }

      argument1[(lasti + 1)] = '\0';
      lasti = 0;

      //let's write what's after the comma;
      char argument2[5];
      for (int i = (commaLocation + 1); i &lt; (nullTerminatorIndex - 1); i++) {
        argument2[(i - (commaLocation + 1))] = received[i];
        lasti = (i - (commaLocation + 1));
      }

      argument2[(lasti + 1)] = '\0';
      lasti = 0;

      Firmata.sendString(argument1);
      Firmata.sendString(argument2); 
    }
  }
}
</code></pre>
