de-vraag
  • Klausimai
  • Žymos
  • Vartotojai
Pranešimai
Apdovanojimai
Registracija
Užsiregistravę gausite pranešimus apie atsakymus ir komentarus į savo klausimus.
Prisijungti
Jei jau turite paskyrą, prisijunkite ir patikrinkite naujus pranešimus.
Už pridėtus klausimus, atsakymus ir komentarus bus skiriami apdovanojimai.
Daugiau
Šaltinis
Redaguoti
 ValrikRobot
ValrikRobot
Question

Kaip padalyti įeinančią eilutę?

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?

52 2014-03-31T06:35:44+00:00 3
Anonymous Penguin
Anonymous Penguin
Redaguotas klausimas popietr kovas 2015 в 11:54
Arduino
arduino-mega
serial
string
Šis klausimas turi 1 atsakymas atsakymų anglų kalba, norėdami juos perskaityti prisijunkite prie savo paskyros.
Solution / Answer
 jfpoilpret
jfpoilpret
popietr kovas 2014 в 6:12
2014-03-31T18:12:50+00:00
Daugiau
Šaltinis
Redaguoti
#39583347

Skirtingai nei kiti atsakymai, aš verčiau laikyčiausi atokiau nuo String dėl šių priežasčių:

  • dinamiškas atminties naudojimas (dėl to gali greitai atsirasti aplinkos fragmentacija ir atminties išsekimas)
  • didelį lėtumą dėl konstravimo, naikinimo ir priskyrimo operatorių

Į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).

Ellis Percival
Ellis Percival
Redaguotas atsakymas priešpietr vasaris 2016 в 6:26
72
0
 drodri
drodri
priešpietr kovas 2014 в 7:51
2014-03-31T07:51:40+00:00
Daugiau
Šaltinis
Redaguoti
#39583346

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);
        }
    }
}
 TrakJohnson
TrakJohnson
Redaguotas atsakymas popietr vasaris 2017 в 4:10
11
0
Federico Fissore
Federico Fissore
priešpietr kovas 2014 в 7:36
2014-03-31T07:36:29+00:00
Daugiau
Šaltinis
Redaguoti
#39583345

Galite naudoti Stream.readStringUntil(terminator), kiekvienai daliai nurodydami skirtingą terminatorių.

Tada kiekvienai daliai iškvieskite String.toInt.

Stream.readStringUntil() - Arduino Reference
The Arduino programming language Reference, organized into Functions, Variable and Constant, and Structure keywords.
arduino.cc
toInt() - Arduino Reference
The Arduino programming language Reference, organized into Functions, Variable and Constant, and Structure keywords.
arduino.cc
7
0
Pridėti klausimą
Kategorijos
Visi
Technologijos
Kultūra / poilsis
Gyvenimas / Menai
Mokslas
Profesionalus
Verslas
Vartotojai
Visi
Naujas
Populiarus
1
Roxana Elizabeth CASTILLO Avalos
Registruota prieš 4 dienas
2
Hideo Nakagawa
Registruota prieš 5 dienas
3
Sergiy Tytarenko
Registruota prieš 6 dienas
4
shoxrux azadov
Registruota prieš 1 savaitę
5
Koreets Koreytsev
Registruota prieš 1 savaitę
DA
DE
EL
ES
FR
ID
IT
JA
KO
LT
NL
PT
RU
SK
TR
ZH
© de-vraag 2022
Šaltinis
arduino.stackexchange.com
pagal licenciją cc by-sa 3.0 nurodant autorystę