Elías, parte de este staff, nos ha hecho el favor de escribir este enunciado ya que conoce a la perfección este tema.
Solución:
Al contrario de otras respuestas, prefiero alejarme de String
por las siguientes razones:
- uso de memoria dinámica (que puede conducir rápidamente a fragmentación del montón y agotamiento de la memoria)
- bastante lento debido a operadores de construcción / destrucción / asignación
En un entorno integrado como Arduino (incluso para un Mega que tiene más SRAM), prefiero usar funciones C estándar:
strchr()
: busca un personaje en una C string (es decirchar *
)strtok()
: divide una C string en subcadenas, basadas en un carácter separadoratoi()
: convierte una C string a unaint
Eso conduciría a la siguiente muestra de código:
// Calculate based on max input size expected for one command
#define INPUT_SIZE 30
...
// Get next command from Serial (add 1 for final 0)
char input[INPUT_SIZE + 1];
byte size = Serial.readBytes(input, INPUT_SIZE);
// Add the final 0 to end the C string
input[size] = 0;
// Read each command pair
char* command = strtok(input, "&");
while (command != 0)
// Split the command in two values
char* separator = strchr(command, ':');
if (separator != 0)
// Actually split the string in 2: replace ':' with 0
*separator = 0;
int servoId = atoi(command);
++separator;
int position = atoi(separator);
// Do something with servoId and position
// Find the next command in input string
command = strtok(0, "&");
La ventaja aquí es que no tiene lugar ninguna asignación de memoria dinámica; incluso puedes declarar input
como una variable local dentro de una función que leería los comandos y los ejecutaría; una vez que se devuelve la función el tamaño ocupado por input
(en la pila) se recupera.
Esta función se puede utilizar para separar un string en pedazos basados en cuál es el carácter separador.
String xval = getValue(myString, ':', 0);
String yval = getValue(myString, ':', 1);
Serial.println("Y:" + yval);
Serial.print("X:" + xval);
Convertir String en int
int xvalue = xvalue.toInt(xval);
int yvalue = yvalue.toInt(yval);
Este fragmento de código toma un string y lo separa según un carácter dado y devuelve El elemento entre el carácter de separación
String getValue(String data, char separator, int index)
int found = 0;
int strIndex[] = 0, -1 ;
int maxIndex = data.length() - 1;
for (int i = 0; i <= maxIndex && found <= index; i++)
if (data.charAt(i) == separator
return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
Puede hacer algo como lo siguiente, pero tenga en cuenta varias cosas:
Si utiliza readStringUntil()
, esperará hasta que reciba el carácter o los tiempos de espera. Así, con tu actual string, la última posición durará un poco más, ya que hay que esperar. Puede agregar un final &
para evitar este tiempo de espera. Puede comprobar fácilmente este comportamiento en su monitor, intente enviar el string con y sin extra &
y verá ese retraso en el tiempo de espera.
En realidad, no necesita el índice de servo, solo puede enviar su string de posiciones, y obtenga el índice de servo por la posición del valor en el string, algo como: 90&80&180&
. Si usa el índice de servo, tal vez desee verificarlo (convertir a int
y luego haga coincidir el índice de bucle i) para asegurarse de que no haya ningún problema con su mensaje.
Tienes que comprobar que la devolución string desde readStringUntil
no está vacío. Si la función se agota, no recibió suficientes datos y, por lo tanto, no ha intentado extraer su int
los valores producirán resultados extraños.
void setup()
Serial.begin(9600);
void loop()
for(int i=1; i<=3; i++)
String servo = Serial.readStringUntil(':');
if(servo != "")
//here you could check the servo number
String pos = Serial.readStringUntil('&');
int int_pos=pos.toInt();
Serial.println("Pos");
Serial.println(int_pos);