Arduino típuskonvertálások (összefoglaló)

típusLehetséges konverziók a típusbaLehetséges konverziók a típusból
boolean-boolArray → Byte
bytealaptí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
wordalaptí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
floatalaptípus → float : float()
char array → float: AVR_C_LIB: atof()
float/double → char array: AVR_C_LIB: dtostrf()
doublechar 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 charlásd: CHAR
karakterlánc - char_arrayfloat/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()
arrayA 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

Egy érték konvertálása a char típusba.

Szintaktika

char (x)

x: bármely típus

Egy érték konvertálása a byte típusba.

Szintaktika

byte (x)

x: bármely típus

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

Egy érték konvertálása a word típusba, illetve 2 bemeneti bájtból egy word érték "összeállítása".

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

Egy érték konvertálása a long típusba.

Szintaktika

long (x)

x: bármely típus

Egy érték konvertálása a float típusba.

Szintaktika

float (x)

x: bármely típus

Arduino egyedi típuskonverziók

byte BoolArrayToByte(bool boolArray[8])
{
  byte result = 0; 
 
  for(int i = 0; i < 8; i++)
  {
    if(boolArray[i])
    {
      result = result | (1 << i);
    }
  }
 
  return result;
}

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));

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'};
  String ebbe_a_Stringbe(chArray);

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);
}

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);
}

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);
}

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);
 
}

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
}