de-vraag
  • Otázky
  • Značky
  • Používatelia
Oznámenia
Odmeny
Registrácia
Po registrácii budete informovaní o odpovediach a komentároch na vaše otázky.
Prihlásiť sa
Ak už máte konto, prihláste sa a skontrolujte nové oznámenia.
Za pridané otázky, odpovede a komentáre budú udelené odmeny.
Viac na
Zdroj
Upraviť
 ValrikRobot
ValrikRobot
Question

Ako rozdeliť prichádzajúci reťazec?

Posielam zoznam pozícií serv cez sériové pripojenie do arduina v nasledujúcom formáte

1:90&2:80&3:180

Ktorý by sa analyzoval ako:

servoId : Position & servoId : Position & servoId : Position

Ako by som tieto hodnoty rozdelil a previedol na celé číslo?

52 2014-03-31T06:35:44+00:00 3
Anonymous Penguin
Anonymous Penguin
Edited question 9 marec 2015 в 11:54
Arduino
arduino-mega
serial
string
This question has 1 odpoveď in English, to read them log in to your account.
Solution / Answer
 jfpoilpret
jfpoilpret
31 marec 2014 в 6:12
2014-03-31T18:12:50+00:00
Viac na
Zdroj
Upraviť
#39583347

Na rozdiel od iných odpovedí by som sa radšej vyhol String z nasledujúcich dôvodov:

  • dynamické využitie pamäte (ktoré môže rýchlo viesť k fragmentácii haldy a vyčerpaniu pamäte)
  • dosť pomalé kvôli operátorom konštrukcie/destrukcie/priradenia

Vo vstavanom prostredí, ako je Arduino (dokonca aj v prípade Mega, ktoré má viac pamäte SRAM), by som radšej použil štandardné funkcie C:

  • strchr(): hľadanie znaku v reťazci C (t. j. char *)
  • strtok(): rozdelí reťazec C na podreťazce na základe oddeľovacieho znaku
  • atoi(): konvertuje reťazec C na int

To by viedlo k nasledujúcej ukážke kódu:

// 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, "&");
}

Výhodou je, že tu nedochádza k dynamickému prideľovaniu pamäte; môžete dokonca deklarovať input ako lokálnu premennú vo vnútri funkcie, ktorá by čítala príkazy a vykonávala ich; po návrate funkcie sa obnoví veľkosť obsadená input (v zásobníku).

Ellis Percival
Ellis Percival
Edited answer 17 február 2016 в 6:26
72
0
 drodri
drodri
31 marec 2014 в 7:51
2014-03-31T07:51:40+00:00
Viac na
Zdroj
Upraviť
#39583346

Mohli by ste urobiť niečo podobné, ale berte do úvahy niekoľko vecí:

Ak použijete readStringUntil(), bude čakať, kým nedostane znak alebo časový limit. Teda pri vašom aktuálnom reťazci bude posledná pozícia trvať o niečo dlhšie, pretože musí čakať. Môžete pridať koncovku &, aby ste sa tomuto časovému limitu vyhli. Toto správanie si môžete ľahko overiť v monitore, skúste poslať reťazec s dodatočným & a bez neho a uvidíte takéto oneskorenie timeoutu.

V skutočnosti nepotrebujete index serva, môžete jednoducho poslať reťazec pozícií a získať index serva podľa pozície hodnoty v reťazci, niečo ako: 90&80&180&. Ak použijete index serva, možno ho budete chcieť skontrolovať (previesť na ```int```` a potom porovnať s indexom slučky i), aby ste sa uistili, že sa vo vašej správe nič nepokazilo.

Musíte skontrolovať, či vracaný reťazec z readStringUntil`` nie je prázdny. Ak sa funkcia oneskorí, nedostali ste dostatok údajov, a tak akýkoľvek pokus o získanie vašich hodnôtint```` prinesie čudné výsledky.

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
Edited answer 8 február 2017 в 4:10
11
0
Federico Fissore
Federico Fissore
31 marec 2014 в 7:36
2014-03-31T07:36:29+00:00
Viac na
Zdroj
Upraviť
#39583345

Môžete použiť Stream.readStringUntil(terminator), pričom pre každú časť zadáte iný terminátor.

Na každej časti potom zavoláte 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
Pridať otázku
Kategórie
Všetky
Technológia
Kultúra / Rekreácia
Život / Umenie
Veda
Profesionálne
Obchod
Používatelia
Všetky
New
Popular
1
365
Registered pred dňom
2
True Image
Registered pred dňom
3
archana agarwal
Registered pred 3 dňami
4
Maxim Zhilyaev
Registered pred 6 dňami
5
adambotsfford adambotsfford
Registered pred týždňom
DA
DE
EL
ES
FR
ID
IT
JA
KO
LT
NL
PT
RU
SK
TR
ZH
© de-vraag 2022
Zdroj
arduino.stackexchange.com
na základe licencie cc by-sa 3.0 s uvedením autora