Estou enviando uma lista de posições de servo através da conexão serial para o arduino no seguinte formato
1:90&2:80&3:180
Que seria analisado como:
servoId : Posição & servoId : Posição & servoId : Posição
Como eu dividiria esses valores e os converteria em um número inteiro?
Ao contrário de outras respostas, I'prefiro ficar longe de String
pelas seguintes razões:
Em um ambiente embarcado como o Arduino (mesmo para um Mega que tem mais SRAM), I'prefiro usar **funções C padrão***:
strchr()
: busca por um caractere em uma string em C (i.e. char *
)strtok()
: divide uma string em C em substratos, com base em um caractere separadoratoi()
: converte uma string em C para uma string em 'int'.Isso levaria à seguinte amostra 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, "&");
}
A vantagem aqui é que nenhuma alocação dinâmica de memória ocorre; você pode até declarar input
como uma variável local dentro de uma função que leria os comandos e os executaria; uma vez que a função é retornada, o tamanho ocupado por input
(na pilha) é recuperado.
Você poderia fazer algo como o seguinte, mas por favor leve em conta várias coisas:
Se você utilizar readStringUntil()````, ele vai esperar até receber o personagem ou timeouts. Assim, com sua string atual, a última posição vai durar um pouco mais, pois ela tem que esperar. Você pode adicionar um trailing
&`para evitar este timeout. Você pode facilmente verificar este comportamento em seu monitor, tente enviar a string com e sem o ```&
extra e você verá este tempo limite.
Você realmente não precisa do índice servo, você pode simplesmente enviar sua string de posições, e obter o índice servo pela posição do valor na string, algo como: 90&80&180&
. Se você usar o índice servo, talvez você queira verificá-lo (converta para ``int```, e então combine o índice de laço i) para garantir que nada deu errado com a sua mensagem.
Você tem que verificar se a string de retorno de readStringUntil```` não está vazia. Se a função timeouts, você não'não recebeu dados suficientes, e assim qualquer tentativa de extrair seus valores de
int```` irá produzir resultados estranhos.
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);
}
}
}
Você pode utilizar Stream.readStringUntil(terminator)
passando um terminador diferente para cada peça.
Em cada parte você então chama String.toInt'.