www.elektronik.si
String -> int

www.elektronik.si -> Arduino sekcija

Avtor: ElGrigonKraj: okolica Lenarta PrispevekObjavljeno: Sob Apr 20, 2019 11:35 pm    Naslov sporočila:  String -> int
----------------------------------------------------------------------------
Pozdrav,

Kako naj pretvorim string podatek v int?

String dobim po serial komunikaciji v obliki npr. 71 82 00 00 in to moram pretvoriti v int, od tega je uporabno samo 82 00 00.

Avtor: polkic PrispevekObjavljeno: Ned Apr 21, 2019 7:10 am    Naslov sporočila:  
----------------------------------------------------------------------------
Pozdravljen,

string bi najprej obdelal (porezal stran tisto kar ne nucam) nato pa pretovril v int s pomočjo stringtoint. https://www.arduino.cc/en/Tutorial.StringToIntExample

Lep pozdrav.

Avtor: igo PrispevekObjavljeno: Ned Apr 21, 2019 10:38 am    Naslov sporočila:  
----------------------------------------------------------------------------
To se običajno naredi obratno od postopka, s katerim si iz svojega podatka dobil tisti string.

Stvar je v tem, da je serijskemu portu povsem vseeno, kaj prenaša. Vedno bo poslano oziroma sprejeto n-krat po 8 bitov, njihov pomen pa je odvisen od načina kodiranja, kako so bili podatki pretvorjeni v niz z n členi po 8 bitov.

Primer:
Imaš 32-bitno HEX število Podatek71=0x00820000, ki ima pomen številka 71 (recimo skupno število nekih impulzov). Torej 24 uporabnih bitov, ki morajo imeti na sprejemni strani točno določen pomen.
Najprej z
if(Podatek71 > 0x00FFFFFF) preveriš, ali je število manjše od največjega dovoljenega, nato mu spredaj dodaš pomen
Podatek4TX = Podatek71 I 0x71000000 ;// Podatek za TX
Potem ga s shiftanjem >>8 in maskiranjem pretvoriš v niz (string) 4-krat po 8 bitov, z njimi napolniš TX buffer in sprožiš pošiljanje.

Na sprejemni strani pa najprej z maskiranjem z 0xFF000000 preveriš pomen (71), nato pa 32-biten Podatek71 na sprejemni strani s shiftanjem <<8 sestaviš nazaj v 00820000.
Podatek71 = Podatek71 << 8;
Podatek71 = Podatek71 + SprejetiNiz[i];

S tem boš dobil HEX število 820000, kar je DEC 8512680.

Če boš Podatek71 zapakiral in razpakiral na kak drug način, je lahko njegov pomen tudi ASCII za na lcd ali BCD desetiško kodiranje ali ...
... povsem odvisno od trenutnega navdiha.

Avtor: ElGrigonKraj: okolica Lenarta PrispevekObjavljeno: Ned Apr 21, 2019 11:26 am    Naslov sporočila:  
----------------------------------------------------------------------------
To s shiftanjem bi šlo, če bi potreboval cel niz. Iz 71 82 00 00 sta važna le bit 4 in 5. Vedno sta polna le ti dva bita.

Kaj, če uporabim
char RX[8]=mySerial.Read();
int RXdata= RX[5]*16+RX[4];
S tem bi dobil vrednost 130.

Avtor: igo PrispevekObjavljeno: Ned Apr 21, 2019 1:51 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Če si sprejel 8 8-bitnih vrednosti, potem je tak postopek skoraj povsem pravilen.
Množiti moraš z 256, kar je enakovredno shiftanju v levo za <<8 .

RXdata = RX[5]*256 + RX[4];


Če pa si sprejel 4 8-bitne vrednosti
( char RXdata[4]= my.serialRead() ), kar bi se dalo sklepati iz 71 82 00 00, potem je 82 8-bitna HEX vrednost, ki jo ni treba posebej pretvarjati v desetiško, moraš pa vedeti, ali je vrednost desetiška ali šestnajtiška, saj je v osnovi šestnajtiška, ki jo potem v desetiško pretvori funkcija za izpis na lcd ali podobna. In seveda jo moraš izluščiti iz sprejetega paketa
RXdata = RX[2]; , ker je to byte2 po vrsti (0, 1, 2, 3) izmed prejetih.


V glavnem bit[...] je mišljena pozicija bita znotraj 8-, 16-, 32-, ... bitne spremenljivke.
Poziciji 5 in 4 sta pri paketu osmih 8-bitnih prejetih spremenljivkah, kjer je vsaka cifra zase prejet podatek 7,1, 8, 2, 0, 0, 0, 0, kjer gre lahko vsak od 0 do 255.
Pozicija 2 je pri štirih 8-bitnih spremenljivkah 71, 82, 00, 00, kjer gre vsaka izmed štirih od 0x00 do 0xFF šestnajstiško ali od 000 do 255 decimalno.

Zato je treba najprej definirati obliko zapisa (HEX, DEC, BIN, ...), potem pa izluščiš ven tisto, kar potrebuješ.

Avtor: ElGrigonKraj: okolica Lenarta PrispevekObjavljeno: Ned Apr 21, 2019 2:11 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Nisem še tako daleč. HMI mi pošlje HEX npr. 71 82 00 00. Izluščiti moram samo 82. Niti ne vem kaj mi prebere na Serial oz. v kakšnem nizu to prebere.
Kolikor sem se igral z exampli Serial kar zleti skozi vsak prejet bit in ne prebere podatka naenkrat.

Avtor: igo PrispevekObjavljeno: Ned Apr 21, 2019 2:44 pm    Naslov sporočila:  
----------------------------------------------------------------------------
V tem primeru so sprejete 4 8-bitne HEX vrednosti.
char RXdata[4] = my.serialRead();

Potem uporabiš samo
RXdata[2]; // tu je 0x82 v HEX.


Primer:
if(RXdata[3] == 0x71) // če je 0x71, je sprejet veljaven Podatek71
{
Podatek71 = RXdata[2];
}
if(RXdata[3] == 0x72) // to je podatek s povsem drugim pomenom72
{
Podatek72 = RXdata [2];
}


Lahko uporabiš tudi switch / case stavek
switch(RXdata[3])
{
case 0x71:
Podatek71=RXdata[2];
break;
case 0x72:
Podatek72=RXdata[2];
break;
}

Glej Arduino reference za switch case.


Če boš potem
char Podatek71 prikazal na LCD, bo izpisalo desetiško 130 .

Avtor: ElGrigonKraj: okolica Lenarta PrispevekObjavljeno: Ned Apr 21, 2019 7:56 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Bom priklopil HMI in da vidim ali pošlje tako kot prikazuje simulator.

Če zadevo shranim v String, bi moral videt cel buffer iz prejetega serial paketa?

Avtor: igo PrispevekObjavljeno: Ned Apr 21, 2019 9:07 pm    Naslov sporočila:  
----------------------------------------------------------------------------
Ja. V buffer dobiš 4 8-bitne vrednosti, ki jih shraniš v char RXdata[4];
Potem lahko z vsakim členom niza RXdata[i] počneš, kar želiš.
Lahko jih združiš, maskiraš z 0xF... , ..., uporabiš znotraj if(...) in podobno.

Stran 1 od 1

Powered by phpBB © 2001,2002 phpBB Group