Servo pozicijų sąrašą siunčiu per nuosekliąją jungtį į "arduino" tokiu formatu
1:90&2:80&3:180
Kuris būtų analizuojamas kaip:
servoId : Position & servoId : Position & servoId : Position
Kaip galėčiau suskaidyti šias vertes ir paversti jas sveikuoju skaičiumi?
Skirtingai nei kiti atsakymai, aš verčiau laikyčiausi atokiau nuo String
dėl šių priežasčių:
Įterptinėje aplinkoje, pavyzdžiui, "Arduino" (net ir "Mega", turinčioje daugiau SRAM), verčiau naudoti standartines C funkcijas:
strchr()
: simbolio paieška C eilutėje (t. y. char *
)strtok()
: suskaido C eilutę į pojuostes pagal skiriamąjį simbolįatoi()
: konvertuoja C eilutę į int
Tai leistų sukurti tokį kodo pavyzdį:
// 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, "&");
}
Privalumas yra tas, kad nereikia atlikti jokio dinaminio atminties paskirstymo; galite netgi deklaruoti input
kaip vietinį kintamąjį funkcijos, kuri skaitytų komandas ir jas vykdytų, viduje; kai funkcija grįžta, atstatomas input
užimtas dydis (steke).
Galėtumėte daryti panašiai, tačiau atsižvelkite į keletą dalykų:
Jei naudosite readStringUntil()`````, ji lauks, kol gaus simbolį arba pasibaigs laikas. Taigi su jūsų dabartine eilute paskutinė pozicija truks šiek tiek ilgiau, nes ji turi laukti. Kad išvengtumėte šio laiko limito, galite pridėti galinį simbolį ```&```. Šią elgseną galite lengvai patikrinti monitoriuje, pabandykite išsiųsti eilutę su papildoma ```&
ir be jos, ir pamatysite tokį timeout uždelsimą.
Iš tikrųjų jums nereikia servopavarų indekso, galite tiesiog nusiųsti pozicijų eilutę ir gauti servopavarų indeksą pagal reikšmės poziciją eilutėje, pvz: 90&80&180&
. Jei naudojate servo indeksą, galbūt norėsite jį patikrinti (konvertuoti į ````int````` ir tada suderinti su ciklo indeksu i), kad įsitikintumėte, jog jūsų pranešime neatsitiko nieko blogo.
Turite patikrinti, ar grįžtanti eilutė iš readStringUntil
nėra tuščia. Jei funkcija užtruko, vadinasi, negavote pakankamai duomenų, todėl bet koks bandymas išgauti ```int```` reikšmes duos keistų rezultatų.
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);
}
}
}
Galite naudoti Stream.readStringUntil(terminator)
, kiekvienai daliai nurodydami skirtingą terminatorių.
Tada kiekvienai daliai iškvieskite String.toInt
.