Pregunta:
Cuales son los requerimientos temporales para ejecutar ese código??
Por que si bien lo que propone
@Nuyel está OK, las funciones de procesamiento de strings lo están recorriendo una y otra vez bajo la acción de cada indexOf() y eso es una demanda tiempo potencialmente excesiva....dependiendo de los requerimientos temporales de ejecución del código, el contexto de ejecución y el baudrate del enlace.
El problema con intentar aplicar un esquema de tiempo crítico es que Arduino tiene demasiado pasando en segundo plano como para intentarlo, como el mecanismo es de Consulta-Respuesta el único tiempo crítico es en realizar los cambios entre envió a recepción, para el caso de recepción darle tiempo para que el esclavo responda. Por ello se implementa un bucle que se queda a la espera de que el esclavo envíe la respuesta inmediatamente después de generar el cambio a modo lectura, de esta forma intencionalmente se espera a que el esclavo procese el comando y realice la muestra de datos, luego el esclavo debería enviar toda la respuesta junta, el ejemplo que puse le da hasta 10s de tiempo de espera lo que en la práctica es excesivo, pero igual si la recibe en 10ms sale del bucle y lee TODA la respuesta.
En la práctica si buscara velocidad preferiría usar un formato codificado en binario, por ejemplo, enviar la trama [byte dirección][byte comando] y recibir [dirección][longitud][dato1][valor1]....[daton][valorn][CRC], luego hacer las asignaciones directamente.
Pero no podemos tratar a Arduino con tanto detalle, el serialEvent no es ni siquiera un ISR sino más bien polling que ocurre después del loop dentro del main (no se ve, pero Arduino tiene un main()) validando si existen datos, el Arduino procesa la comunicación por interrupciones de una manera en la que el usuario no tiene control, esto evita que los novatos arruinen la comunicación, por eso en el código se usa el Serial.flush() que básicamente le dice "espera hasta que la transmisión termine" ya que sin ello el Serial.print solo manda los datos al buffer pero no significa que la transmisión esté completa.
Cuando se genera la recepción el Arduino procesa usando interrupciones y almacena los datos en un buffer de 64bytes interno, el delay() al basarse en software tampoco genera bloqueo que las deshabiliten por lo que no debería haber perdida de datos, solo hay problemas de sincronía ya que el delay de hecho se extiende si se ejecuta una interrupción, en cambio, si intentas meterte en una interrupción, en primer lugar no tenemos acceso a la del serial real, y ejecutar otras SÍ pueden suspender la recepción causando perdida de paquetes, por eso es preferible que el chip pierda todo el tiempo que quiera al recibir los datos y enviarlos teniendo la trama completa una vez que ya los procesó.
En resumen, esta implementación es mala en procesamiento, usa mucha memoria y ciertamente toma tiempo, pero en el tema de la transmisión y recepción no debería tener conflictos. Por ello es que se envía y queda a la espera de la respuesta, una vez que detecta entrada de datos queda en lectura hasta que la transmisión termine por timeOut (que el código establece en 250ms sin recibir nuevos datos), entonces ya lo procesa todo sin tener que preocuparse del tiempo ya que los esclavos no deberían transmitir hasta la siguiente consulta. Si la trama ocupa más de los 64 bytes del buffer sí le recomendaría entonces reducir el tiempo de verificación en la función de espera, pero tendrá que buscar el punto de equilibrio según su aplicación.