Arduino típuskonvertálások (összefoglaló)
típus | Lehetséges konverziók a típusba | Lehetséges konverziók a típusból | |
---|---|---|---|
boolean | - | boolArray → Byte | |
byte | alaptípusok → byte : byte() boolArray → Byte int → 2 byte (stuktúra szerint): IntToByte long → 4 byte: LongToByte Word, Double → 2, 4 byte (stuktúra szerint): (D)WordToByte | 2 byte → word: word(h, l) 2 byte → int (stuktúra szerint): ByteToInt 4 byte → long: ByteToLong 2, 4 byte (stuktúra szerint) → Word, Double: (D)WordToByte | |
int (int16_t *) | alaptípusok → int : int() char array → int: AVR_C_LIB: atoi() 2 byte → int (stuktúra szerint): ByteToInt | int → char array: AVR_C_LIB: itoa() int → 2 byte (stuktúra szerint): IntToByte | |
unsigned int (uint16_t *) | lásd: INT | ||
word | alaptípus → word : word() 2 byte → word: word(h, l) 2 byte → Word (stuktúra szerint): (D)WordToByte | Word → 2 byte (stuktúra szerint): (D)WordToByte | |
long (int32_t *) | alaptípus → long : long() char array → long: AVR_C_LIB; atol() 4 byte → long: ByteToLong | long → 4 byte: LongToByte | |
unsigned_long (uint32_t*) | Lásd: LONG | ||
short (int16_t *) | Lásd: INT | ||
float | alaptípus → float : float() char array → float: AVR_C_LIB: atof() | float/double → char array: AVR_C_LIB: dtostrf() | |
double | char array → float/double: AVR_C_LIB: atof() 4 byte → Double (stuktúra szerint): (D)WordToByte char array → double: AVR_C_LIB: strtod() | float/double → char array: AVR_C_LIB: dtostrf() Double → 4 byte (stuktúra szerint): (D)WordToByte | |
char a char_array lejjebb | alaptípusok → char : char() | ||
unsigned char | lásd: CHAR | ||
karakterlánc - char_array | float/double → char array: AVR_C_LIB: dtostrf() int → char array: AVR_C_LIB: itoa() String (object) → char array: StringToCharArray() Az alaptípusok "sprintf" függvénnyel konvertálhatók. | char array → int: AVR_C_LIB: atoi() char array → float: AVR_C_LIB: atof() char array → long: AVR_C_LIB: atol() char array → double: AVR_C_LIB: strtod() char array → String: CharArrayToString | |
String (object) | char_array → String (object): CharArrayToString (Legtöbb esetben egyszerűbb először char_array-be konvertálni, majd onnan String-be) | String (object) → char_array: StringToCharArray() String (object) → long: StringToLong() String (object) → float: StringToFloat() | |
array | A tömb típusú változók konverziójára jól használható a union definició. |
*: a C definiciókkal való megfeleltetések (pl. int = int8_t) csak az alap-board-okon érvényesek, bizonyos típusokon (pl. DUE) ezeknek a bithossza eltér, azaz a megfeleltetés nem igaz.
Arduino alaptípus-konverziók
char()
Egy érték konvertálása a char típusba.
Szintaktika
char (x)
x: bármely típus
byte()
Egy érték konvertálása a byte típusba.
Szintaktika
byte (x)
x: bármely típus
int()
Egy érték konvertálása a int típusba.
Szintaktika
int (x)
x: bármely típus
// float to int int i; float f; f = 3.6; i = (int) f; // now i is 3
word()
Szintaktika
word (x)
word (h, l)
x: bármely típus h: a felső (baloldali) bájtja a word-nek l: az alsó (jobboldali) bájtja a word-nek
long()
Egy érték konvertálása a long típusba.
Szintaktika
long (x)
x: bármely típus
float()
Egy érték konvertálása a float típusba.
Szintaktika
float (x)
x: bármely típus
Arduino egyedi típuskonverziók
boolArrayToByte
byte BoolArrayToByte(bool boolArray[8]) { byte result = 0; for(int i = 0; i < 8; i++) { if(boolArray[i]) { result = result | (1 << i); } } return result; }
StringToCharArray
String (objektum) konvertálása string / char array-ba.
String s; char arr[12]; // maximum 12 jegyű szám konvertálása s.toCharArray(arr, sizeof(arr));
CharArrayToString
A char array Stringbe konvertálása esetén ügyelni kell arra, hogy az array null-terminate ('\0') karakterrel záródjon. Ez a karaktersorozat default megadásnál automatikusan bekerül, például így:
char[] chArray = "some characters";
Array megadásánál viszont erről nekünk kell gondoskodni, például így:
char chArray[] = {'o','b','1','2','1','\0'};
Ha a terminate rendben van, akkor például így lehet a string / char array-t konvertálni String (objektum)-ba.
char[] chArray = "ob121"; char chArray[] = {'o','b','1','2','1','\0'}; // a legegyszerűbb, ha egyenlővé tesszük a char arrayt a stringgel (ebben az irányban működik) String S = chArray; // vagy ez a megoldás is működik: String ebbe_a_Stringbe(chArray);
StringToLong
String (objektum) konvertálása long-ba. A konverzió két lépésből áll:
- String(object) ⇒ string / char array
- string / char array ⇒ Long (az AVR_C_LIB atol funkciójával)
long stringToLong(String s) { char arr[12]; // maximum 12 jegyű szám konvertálása s.toCharArray(arr, sizeof(arr)); return atol(arr); }
StringToFloat
String (objektum) konvertálása float-ba. A konverzió két lépésből áll:
- String(object) ⇒ string / char array
- string / char array ⇒ Long (az AVR_C_LIB atof funkciójával)
float stringToFloat(String s) { char arr[12]; // maximum 12 jegyű szám konvertálása s.toCharArray(arr, sizeof(arr)); return atof(arr); }
IntToByte / ByteToInt
Integer konvertálása bájt-ba vagy bájt konvertálása Integer-be.
(A byte-ok tartalma nyilván értelmezhetetlen lesz, hiszen az int típus kettes komplementerrel lett képezve. Ellenben viszont a byte-strukturájú I²C így továbbítani tudja a tartalmát 2 byte-ban, és a másik oldalon ugyanígy össze kell rakni az INT-tet a két byte-ból.
Az egyik lehetőség, hogy a bit-shifteléssel hozzuk létre a két bájtot (majd rakjuk ismét össze):
// Example from OB121.com // Vamos Sandor // Convert int to 2-bytes // Convert back int start_val = -30000; byte high_byte, low_byte; void setup() { Serial.begin(9600); } void loop() { Serial.println("for the conversion:"); Serial.println(start); high_byte = (start_val >> 8); low_byte = (start_val); Serial.println("conversion high_byte:"); Serial.println(high_byte); Serial.println("conversion low_byte:"); Serial.println(low_byte); start_val = (high_byte << 8) | low_byte; Serial.println("after the conversion:"); Serial.println(start_val); delay(10000); }
Némileg egyszerűbb megoldás, ha tudunk arról, hogy az union definició - bár az Arduino refenciában nem található - létezik. Ennek a segítségével több változót definiálhatunk egymásra a memóriában:
// OB121.com példaprogram - Vámos Sándor (2019) // Az union definició alkalmazása az Arduino-ban // changing the byte array to the int union { int szam; uint8_t bytes[2]; } combined_in; union { int szam; uint8_t bytes[2]; } combined_out; void setup() { Serial.begin(9600); } void loop() { combined_in.szam = INT16_MAX; // dec. values combined_out.szam = 0; Serial.println(combined_in.szam, DEC); combined_out.bytes[0] = combined_in.bytes[0]; // copy int values over bytes combined_out.bytes[1] = combined_in.bytes[1]; Serial.println(combined_out.szam, DEC); delay(10000); }
LongToByte / ByteToLong
Long (int32_t) konvertálása bájt-ba vagy bájt konvertálása Long-ba (int32_t).
(A byte-ok tartalma nyilván értelmezhetetlen lesz, hiszen az int típus kettes komplementerrel lett képezve. Ellenben viszont a byte-strukturájú I²C így továbbítani tudja a tartalmát 4 byte-ban, és a másik oldalon ugyanígy össze kell rakni az LONG-ot a négy byte-ból.
// Example from OB121.com // Vamos Sandor // Convert long (int32_t) to 4-bytes // and back again long start_val = 0xDEADBEEF; byte conv[4]; void setup() { Serial.begin(9600); } void loop() { Serial.println("for the conversion:"); Serial.println(start_val, HEX); conv[0] = (start_val >> 24); conv[1] = (start_val >> 16); conv[2] = (start_val >> 8); conv[3] = start_val; Serial.println("Bytes:"); Serial.println(conv[0], HEX); Serial.println(conv[1], HEX); Serial.println(conv[2], HEX); Serial.println(conv[3], HEX); start_val = (conv[0] << 8) | conv[1]; start_val = (start_val << 8) | conv[2]; start_val = (start_val << 8) | conv[3]; Serial.println("after the conversion:"); Serial.println(start_val, HEX); delay(10000); }
(D)WordToByte / ByteTo(D)Word
Word és Double típusú változók konvertálása byte-láncba, majd vissza. A konverzióhoz a legegyszerűbb az Arduino referenciájában nem ismertetett, de azért jól használható union definiciót használni:
// OB121.com példaprogram - Vámos Sándor (2019) // Az union definició alkalmazása az Arduino-ban // changing the byte array to the word union { word szo; uint8_t bytes[2]; } combined; // changing the byte array to the word union { double dupla; uint8_t bytes[4]; } combinedD; void setup() { Serial.begin(9600); } void loop() { combined.szo = 0xABCD; combinedD.dupla = 0xDEADBEEF; // cannot displayed Serial.println(combined.szo, HEX); combined.bytes[0] = 0x34; combined.bytes[1] = 0x12; combinedD.bytes[0] = 0x11; Serial.println(combined.szo, HEX); delay(10000); }
Arduino String formázás "sprintf"-fel
Az Arduino nem igazán publikált funkciói közé tartozik a String formázás. Ezzel a különböző, numerikus típusú változokat lehet egységesen és meglehetősen egyszerűen String típusba konvertálni. Megadható például a tizedesjegyek száma, a pozíciókitöltő nullák száma, ..
Fontos tudni, hogy a „sprintf” függvény egy általános célú C függvény, a konvertálások egy része az Arduino-n nem működik (ezt a lenti kódban jelzem)! A lebegőpontos konvertálást ennek ellenére egy közbevetőleges dtostrf függvénnyel meg lehet valósítani (példa a kódban).
Egy példakódon keresztül szeretném szemlélteni ennek a formázásnak a menetét:
/* OB121.com, Vamos Sandor, 2019 * String formatálási példák "sprintf" használatával. * * A sprintf függvény a formázási karakterláncot és a változókat a "data" karakterláncba írja. * Olyan formázási-karakterláncsablont biztosít, amely helyfenntartó definíciókat tartalmaz a beilleszteni kívánt változók számára. * Ezeknek a helyfenntartó definíciókat százalékjellel (%) kell jelölni. Például: %s,%d,%f... * A helyfenntartók számának meg kell egyeznie a változók számával. A helyfenntartók definíciói: * * %d = előjeles integer %f = lebegőpontos (Aduinon nem működik) * %s = string %.1f = lebegőpontos, 1 tizedes pontosság (Aduinon nem működik) * %c = character %.3f = lebegőpontos, 3 tizedes pontosság (Aduinon nem működik) * %e = hatványkitevős (Aduinon nem működik) %g = rövid megjelenés az %e vagy %f típusok helyett (Aduinon nem működik) * %u = előjel nélüli integer %o = előjel nélküli oktális * %x = előjel nélüli hex (kisbetűs) %X = előjel nélküli hex (nagybetűs) * %hd = short int %ld = long int * %lld = long long int (Aduinon nem működik) * * A lebegőpontos (%f), hatványkitevős (%e), a rövid megjelenítés (%g) és a long long int Arduino-n nem működik, * ESP32-n viszont igen! * * ============================================================================= */ char data[100]; char* myName = "ob121.com"; char* myBlog = "https://ob121.com"; char lebego[10]; int year = 2019; int num = 47; char myChar = 'a'; float myFloat = 1010; long int lInt = 1234567890; long long int vLong = 1234567890123456789; void setup() { Serial.begin(9600); while (!Serial) { delay(10); } sprintf(data, "Magyar változat %s", myName); Serial.println(data); sprintf(data, "Év: %u, az oldal linkje: %s",year,myBlog); Serial.println(data); Serial.println(); sprintf(data, "karakterek: %c , %c", num, myChar); Serial.println(data); sprintf(data, "Integer (d): %d , szélessége(8d): %8d , 0-kal kiegészítve(07d): %07d", num, num, num); Serial.println(data); sprintf(data, "Floats f: %f, .1f: %.1f, .3f: %.3f", myFloat, myFloat, myFloat); Serial.println(data); dtostrf(myFloat, 5, 2, lebego); sprintf(data,"A lebegőpontos konvertálás hiánya például a ""dtostrf""-val megkerülhető: %s.",lebego); Serial.println(data); sprintf(data, "Tudományos e: %e , g: %g", myFloat , myFloat); Serial.println(data); sprintf(data, "Alapformátumok u: %u , #o: %#o , x: %x , #X: %#X ", num, num, num, num); Serial.println(data); sprintf(data, "ld: [%ld + 1 = %ld]", lInt, lInt+1); Serial.println(data); sprintf(data, "lld: [%lld + 1 = %lld]", vLong, vLong+1); Serial.println(data); } void loop() { //do nothing }