Arduino változók

Forrás: https://www.arduino.cc/en/Reference/HomePage

A fontosabb változók áttekintése:

A fontosabb Arduino változók áttekintése

Változók típusai és érvényességük

Az Arduino-ban a változók hatálya - csakúgy, mint a C-ben - függ attól, hogy hol defeiniáljuk ezeket. A void() hívása előtt definálhatók a globális változók, melyek a program egész területén elérhetők, viszont ezáltal a teljes futásidő alatt foglalják a memóriájukat.

Az adott funkciókon belül definiált változók érvényessége csak a funkción belülre terjed, a funkcióból való visszatérés után ezeknek a területe a memóriában felszabadul a következő hívásig. A szabály alól kivételt képeznek a statikus változók, lásd: Static.

Az adott eljáráson, például "for" cikluson belül definiál változók csak az eljáráson belül érvényesek.

Példa

int gPWMval;  // globális változó, az egész programban elérhető

void setup()
{
  // ...
}

void loop()
{
  int i;    // az "i" változó csak a loop()-on belül használható,
  float f;  // csakúgy, mint az "f"
  // ...

  for (int j = 0; j <100; j++){
            // a "j" változó csak ezen a cikluson belül használható
  }

}

A "volatile" egy, a fordítónak szóló jelzés, melyet a változó előtt kell használni, hogy megváltoztassa annak a lefordítási módját. Konkrétan ezzel a jelzővel utasítjuk a fordítót, hogy ne egy tárolóregiszterbe töltse az adott változót (mint a többit), hanem a RAM-ba, egy rögzített helyre. Ez például interrupt hívásoknál lehet fontos (lásd: attachinterrupt()). Amennyiben a interrupt hívása egybeesik a tárolóregiszter aktualizálásával, a megszakításhoz alkalmazott változó elveszítheti az értékét.

A statikus változókat a funkciókon belül lehet használni. A szabály szerint a funkciókon belüli változók érvényessége csak az adott funkcióra terjed ki, minden újrahívás esetén ezek is újra inicializálásra kerülnek. A statikus változóknak is csak az adott funkcióra terjed ki a hatályuk, de nem kerülnek minden híváskor újra inicializálásra, az értéküket a meghívások között is megtartják.

A "const" kulcsszóval definiálhatjuk a konstansokat, lásd: Konstansok

Konstansok

A konstansok előre definiált kifejezések, melyek megkönnyítik a programozást és átláthatóbbá teszik a forráskódot.

Míg a program-logikai szinteket a true (igaz, 1) és false (hamis, 0) konstansokkal, addig a pin-ek állapotát a HIGH (magas, 1) illetve a LOW (alacsony, 0) konstansokkal lehet jellemezni.

A HIGH / LOW állapotok (TTL) kiértékeléséről itt olvashat: Arduino TTL logikai szintek.

A HIGH állapot egy jel olvasása esetén az 5V-os bemeneteken 3V jelszint felett, míg a 3,3V bemeneteken 2,0V felett jelentkezik. A LOW állapotok 5-os board-oknál 1,5V alatt, 3,3V-os boardoknál kb. 1,0V alatt jelentkeznek.

A köztes feszültségszinteket (5V-os boardoknál 1,5V - 3,0V, 3,3V-os board-oknál 1,0V - 2,0V) érdemes kerülni, mert a bemeneti állapot bizonytalanná válik.

Amennyiben a bemeneti felhúzóellenállás előzőleg aktiválásra került az adott pin-en, akkor onnan jó eséllyel soha nem fogunk HIGH állapotot olvasni, lásd: digitalRead().

Kimenetek esetén a HIGH állapot kiadását követően a pin a maximális feszültségszintet veszi fel, azaz 3,3V-os board-oknál a 3,3V-ot, az 5V-osoknál az 5V-ot.

Amennyiben előzően a belső felhúzóellenállást aktiváltuk, a kimeneti feszültség is HIGH jel esetén az 5V helyett kevesebb (kb. 3,3V) lesz, lásd: digitalWrite()

A pinMode() funkció paraméterei:

  • INPUT: az adott pin bemenetként kerül alkalmazásra
  • INPUT_PULLUP: az adott pin bemenet; belső felhúzóellenálláson keresztül
  • OUTPUT: az adott pin kimenetként kerül alkalmazásra

A pin, melyre az adott board-on LED van csatlakoztatva. Az UNO esetén ez a 13. pin.

A false a nulla (0) logikai kifejezését szolgálja.
A true bármely érték megfelelője lehet, mely nem nulla (-10, 2, 3.1415, ..)

Az integer konstansok egész számok előre (nem változtathatü módon) történő definiálására szolgálnak. A definiális több számrendszerben is elvégezhető:

számrendszer/típuspéldaformázásamegjegyzés
10 (decimális)123nincs
2 (bináris)B11110011első karaktere: "B"Csak 8 bites értékek esetén működik (0..255).
Csak 0 és 1 karaktereket tartalmazhat.
8 (oktális)0173első karaktere: "0"Csak 0..7 karaktereket tartalmazhat.
16 (hexadecimális)0x7Belső karakterei: "0x"Csak 0..9, A-F, a-f karaktereket tartalmazhat.
unsigned int30ua decimális szám után: "u"-
long30la decimális szám után: "l"-
unsigned long30ula decimális szám után: "ul"-

A fentieknek megfelelően a konstans-magadásnál figyelni kell arra, hogy a definiált értéket bevezető nullák nélkül adjuk meg, hacsak nem akarjuk a számot oktális értéknek megadni.

ÁbrázolásLeírásMegjelenése
\0null terminalbyte 0x00 (in ASCII encoding)
\'single quotebyte 0x27 (in ASCII encoding)
\"double quotebyte 0x22 (in ASCII encoding)
\?question markbyte 0x3f (in ASCII encoding)
\\backslashbyte 0x5c (in ASCII encoding)
\aaudible bellbyte 0x07 (in ASCII encoding)
\bbackspacebyte 0x08 (in ASCII encoding)
\fform feed - new pagebyte 0x0c (in ASCII encoding)
\nline feed - new linebyte 0x0a (in ASCII encoding)
\rcarriage returnbyte 0x0d (in ASCII encoding)
\thorizontal tabbyte 0x09 (in ASCII encoding)
\vvertical tabbyte 0x0b (in ASCII encoding)
\nnnarbitrary octal valuebyte nnn
\xnnarbitrary hexadecimal valuebyte nn
\unnnnUnicode character that is not in the basic character setcode point U+nnnn
\UnnnnnnnnUnicode character that is not in the basic character set.code point U+nnnnnnnn
Konstans méreteTípusaPrefixePéldákUTF megfeleltetés
1 byte karakter konstansokcharx, kódban nincs'a', '\n', '\13'UTF-8 (\xF0\x9F\x8D\x8C)
2 byte karakter konstansokchar16_tuu'貓', u'á'UTF-16 (\uD83C\uDF4C)
4 byte karakter konstansokchar32_tUU'貓', U'🍌' ('U0001f34c')UTF-32 (\U0001f34c)
"wide" karakter konstansokwchar_tLL'β', L'貓'

Példák:

// OB121.com példaprogram - Vámos Sándor (2019)
// karakter konstansok alkalmazása az Arduino-ban
 
    // integer character constants,
    int c1='a'; 
    int c2='🍌'; 
 
    // multicharacter constant
    int c3='ab'; 
 
    // 16-bit wide character constants
    char16_t uc1 = u'a';
    char16_t uc2 = u'á';
    char16_t uc3 = u'¢'; 
    char16_t uc4 = u'猫'; 
 
    // 32-bit wide character constants
    char32_t Uc1 = U'a'; 
    char32_t uc2 = U'á';
    char32_t Uc3 = U'¢'; 
    char32_t Uc4 = U'猫'; 
    char32_t Uc5 = U'🍌'; 
 
    // wide character constants
    wchar_t wc1 = L'a'; 
    wchar_t uc2 = L'á';
    wchar_t wc3 = L'¢'; 
    wchar_t wc4 = L'猫'; 
    wchar_t wc5 = L'🍌'; 

U és L formázó-karakterek

formázó-karakterpéldaleírás
'u' vagy 'U'11UAz adott konstanst előjel nélküli (unsigned) típusnak deklarálja (force-olja)
'l' vagy 'L'22LAz adott konstanst "long" típusnak deklarálja (force-olja)
'ul' vagy 'UL'33ULAz adott konstanst előjel nélküli (unsigned) "long" típusnak deklarálja (force-olja)
lebegőpontos konstansmatematikai kifejtésevalós érték kifejtése
10.01010
2.34E52.34 * 10 ^ 5234000
67e-1267.0 * 10 ^ -12.000000000067

A Arduino - mivel C bázisú - természetesen elérhetővé teszi a C változótípusait (intn_t, uintn_t,..) csakúgy, mint az ezekhez rendelt konstansokat is. Ezek közül néhány fontosabb:

  • INTn_MIN: Az INT-ek minimum értéke (pl. INT16_MIN)
  • INTn_MAX: Az INT-ek maximum értéke (pl. INT16_MAX)
  • UINTn_MAX: Az előjel nélküli INT-ek maximum értéke (pl. UINT16_MAX)
// OB121.com példaprogram - Vámos Sándor (2019)
// C típuskonstansok alkalmazása az Arduino-ban
 
Serial.print("INT8_MIN");
Serial.println(INT8_MIN);
Serial.print("INT16_MIN");
Serial.println(INT16_MIN);
Serial.print("INT32_MIN");
Serial.println(INT32_MIN);
 
Serial.print("INT8_MAX");
Serial.println(INT8_MAX);
Serial.print("INT16_MAX");
Serial.println(INT16_MAX);
Serial.print("INT32_MAX");
Serial.println(INT32_MAX);

Adattípusok

A void kulcsszó olyan funkciók deklarációjához használható, melyek meghívásuk esetén nem adnak visszatérési értéket.

// a "setup" és "loop" funkciók az Arduino alap-programszerkezetéhez tartoznak 
// visszatérési értékük nincs

void setup () 
{ 
  // ... 
} 

void loop () 
{ 
  // ... 
}

A boolean típus a true vagy false értéket veheti fel. Minden boolean változó egy bájt memóriát foglal.

A típus egy bájton egy karakter tárolására alkalmas, pl: "A". A változó értéktartománya -128 .. 127-ig terjed. A C alap-megfeleltetése szerint a típus az int8_t-nek vagy c-char-nak felel meg, lásd: strint.h type.

A karakterlánc ismertetése itt található: char_array.

Speciális karakter a '\0' (null terminal), amivel a karakter-láncokat kell lezárni.

  char myChar = 'A';
  char myChar = 65;      // a két definíció egyenértékű

A típus lehetséges konvertálási lehetőségei itt találhatók: Arduino típuskonvertálások

A típus egy bájton egy karakter tárolására alkalmas, pl: "A". A típus megegyezik a "char"-ral, de a változó értéktartománya itt 0 .. 255-ig terjed. A C alap-megfeleltetése szerint a típus az uint8_t-nek felel meg, lásd: strint.h type.

unsigned char myChar = 240;

A típus lehetséges konvertálási lehetőségei itt találhatók: Arduino típuskonvertálások

A C-ben alapvetően négy "char" típus található, ezek mindegyike használható az Arduino-nál (lásd: karakter konstansok):

  • char (c_char): 8 bit
  • char16_t : 16 bit
  • char32_t : 32 bit
  • wchar_t : 64 bit

A byte típus egy nyolc bit terjedelmű előjel nélküli típus. Értéktartománya 0 .. 255-ig terjed.

A típus lehetséges konvertálási lehetőségei itt találhatók: Arduino típuskonvertálások

A típus előjeles, két bájt terjedelmű változókat tárolhat. Értéktartománya: -32.768 .. 32.767 (- 2 ^ 15 .. 2 ^ 15 - 1). A számértékek tárolását az un. kettes komplementer képzéssel valósítja meg. Az INT típus 4 bájt hosszú változata a LONG. A típus általában megegyezik a SHORT-tal. A C alap-megfeleltetése szerint a típus az int16_t-nek felel meg, lásd: strint.h type.

Több board-on és plattformon az "int" típus nem 2, hanem 4 bájtos, azaz a DINT típusnak felel meg!

Ilyen board-ok: Arduino Due, SAMD alapú board-ok (például MKR1000 és Zero).

Néhány példa az INT típus számérték-tárolására:

Szám
(decimális formában)
INT
(bináris formában)
100 2#0000_0000_0110_0100
10 2#0000_0000_0000_1010
2 2#0000_0000_0000_0010
1 2#0000_0000_0000_0001
0 2#0000_0000_0000_0000
-1 2#1111_1111_1111_1111
-2 2#1111_1111_1111_1110
-10 2#1111_1111_1111_0110
-100 2#1111_1111_1001_1100

A típus lehetséges konvertálási lehetőségei itt találhatók: Arduino típuskonvertálások

Képzése megegyezik az INT-ével: a típus előjeles, két bájt terjedelmű változókat tárolhat. Értéktartománya: -32.768 .. 32.767 (- 2 ^ 15 .. 2 ^ 15 - 1). Előnye azt INT-tel szemben, hogy a terjedelme minden plattformon azonos. A C alap-megfeleltetése szerint a típus az int16_t-nek felel meg, lásd: strint.h type.

A típus lehetséges konvertálási lehetőségei itt találhatók: Arduino típuskonvertálások

Az Arduino, mivel a fordítója C bázisú, az "alap" C változótípusokat is ismeri és kezeli. Ilyen típus intN_t is. Ennek a használatával (ha szükséges), elkerülhető, hogy a különböző board-ok az INT-et más-más bithosszal értelmezzék, ez a típus ugyanis rögzíti az alkalmazott bithosszt:

  • int8_t : 8 bit
  • int16_t : 16 bit, az Uno-n ez felel meg az INT típusnak
  • int32_t : 32 bit, az Uno-n ez felel meg az DINT típusnak, az Arduino Due, SAMD boardokon ez felel meg az INT típusnak
  • int64_t : 64 bit
Arduino típusC típusstdint.h típusBitsElőjelTartomány
unsigned charcharuint8_t8Unsigned0 .. 255
charsigned charint8_t8Signed-128 .. 127
unsigned intunsigned shortuint16_t16Unsigned0 .. 65,535
intshortint16_t16Signed-32,768 .. 32,767
unsigned longunsigned intuint32_t32Unsigned0 .. 4,294,967,295
longintint32_t32Signed-2,147,483,648 .. 2,147,483,647
-unsigned long longuint64_t64Unsigned0 .. 18,446,744,073,709,551,615
-long longint64_t64Signed-9,223,372,036,854,775,808 .. 9,223,372,036,854,775,807

A típusokkal együtt a konstansok is elérhetők a C-ből, lásd: C típuskonstansok

uintN_t

Az Arduino, mivel a fordítója C bázisú, az "alap" C változótípusokat is ismeri és kezeli. Ilyen típus uintN_t (előjel nélküli integer) is. Ennek a használatával (ha szükséges), elkerülhető, hogy a különböző board-ok az UINT-et más-más bithosszal értelmezzék, ez a típus ugyanis rögzíti az alkalmazott bithosszt:

  • uint8_t : 8 bit
  • uint16_t : 16 bit, az Uno-n ez felel meg az unsigned int típusnak
  • uint32_t : 32 bit, az Uno-n ez felel meg az unsigned long típusnak, az Arduino Due, SAMD boardokon ez felel meg az unsigned int típusnak
  • uint64_t : 64 bit

A típusokkal együtt a konstansok is elérhetők a C-ből, lásd: C típuskonstansok

A típus előjel nélküli, két bájt terjedelmű változókat tárolhat. Értéktartománya: 0 .. 65.535 (0 .. 2 ^ 16 - 1). A C alap-megfeleltetése szerint a típus az uint16_t-nek felel meg, lásd: strint.h type.

A típus lehetséges konvertálási lehetőségei itt találhatók: Arduino típuskonvertálások

A LONG típus képzését tekintve megegyezik az INT-tel, azzal a különbséggel, hogy 4 byte hosszú, így értéktartománya: -2.147.483.648 .. 2.147.483.647 (- 2 ^ 31 .. 2 ^ 31 - 1). A számértékek tárolását az un. kettes komplementer képzéssel valósítja meg. A C alap-megfeleltetése szerint a típus az int32_t-nek felel meg, lásd: strint.h type.

Konstansként megadása esetén az "L" formázókarakterrel lehet "force"-olni a típus használatát.

A típus lehetséges konvertálási lehetőségei itt találhatók: Arduino típuskonvertálások

Hasonlóan az UNSIGNED_INT típushoz, a típus előjel nélküli, négy bájt terjedelmű változókat tárolhat. Értéktartománya: 0 .. 4.294.967.295 (0 .. 2 ^ 32 - 1). A C alap-megfeleltetése szerint a típus az uint32_t-nek felel meg, lásd: strint.h type.

A típus lehetséges konvertálási lehetőségei itt találhatók: Arduino típuskonvertálások

A WORD típus egy 2 bájt hosszú tárolótípus. Képzési logikája nincs, a tartalma szabadon meghatározható, kezelhető. A típus kétszeres hosszú változata a DOUBLE.

Több board-on és plattformon a "word" típus nem 2, hanem 4 bájtos, azaz a DOUBLE típusnak felel meg!

Ilyen board-ok: Arduino Due, SAMD alapú board-ok (például MKR1000 és Zero).

A típus lehetséges konvertálási lehetőségei itt találhatók: Arduino típuskonvertálások

A DOUBLE típus egy 4 bájt hosszú tárolótípus, terjedelme gyakorlatilag a WORD duplája. Képzési logikája nincs, a tartalma szabadon meghatározható, kezelhető.

Több board-on és plattformon a "double" típus sem 4, hanem 8 bájtos!

Ilyen board-ok: Arduino Due, SAMD alapú board-ok (például MKR1000 és Zero).

A típus lehetséges konvertálási lehetőségei itt találhatók: Arduino típuskonvertálások

A típus törtszámok lebegőpontos számábrázolás-sal tárolására alkalmas 4 bájton. Értéktartománya: -3.4028235E+38 .. 3.4028235E+38.

A lebegőpontos műveletek sokkal több időt vesznek igénybe, mint a fixpontosok, időkritikus program esetén érdemes ezeket kerülni, vagy sűrűbben konvertálni.

A típus változóit minden esetben tizedesponttal kell megadni (10 ☛ 10.0), egyébként int típusúként kerülnek feldolgozásra.

   int x;
   int y;
   float z;

   x = 1;
   y = x / 2;            // az y eredménye 0 lesz, mert egész számként a ½ nem ábrázolható
   z = (float)x / 2.0;   // a z eredmény most 0,5 lesz

A típus lehetséges konvertálási lehetőségei itt találhatók: Arduino típuskonvertálások

A sting típust kétféle módon lehet kezelni. Egyrészt karakterek sorozataként, másrészt egyfefüggő önálló objektumként. Az első meoldást kis s-sel kell írni (string), míg a másodikat, melyet itt talál, nagy S-sel (String).

Speciális karakter a '\0' (null terminal), amivel a karakter-láncokat kell lezárni. Automatikus értékadás mellett ezt a fordító valósítja meg:

char greeting[] = "Hello";

A fenti esetben a karaktersorozat hossza 6 byte lesz, mert a fordító a kifejezés végére beilleszt egy null-terminált: 'H', 'e', 'l', 'l', 'o', '\0'. Kézi értékmegadásnál erről a programozónak kell gondoskodnia:

char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

Ez itt a kis s-sel írandó típus, azaz a string itt karakterek (CHAR) sorozata:

  char Str1 [15];                                               
  char Str2 [8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o'};          // arduino
  char Str3 [8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o', '\ 0'};   // arduino + null-karakter
  char Str4 [] = "arduino";                                     // automatikus méretezés
  char Str5 [8] = "arduino";                                    
  char Str6 [15] = "arduino";

A karakterláncokat mindig null-karakterrel zárni, ez lehetővé teszi a string-kezelő funkciók számára (pl. Serial.print ()) hogy megállapítsák a string végét. Ezért a string-eket egy karakterrel hosszabbra kell méretezni, mint azoknak a várható tartalma, így a fenti példában a Str4 automatikusan 8 karakter hosszú lesz. A típusban a formázókaraktereket is lehet tárolni, lásd a karakter konstansoknál.

A típus lehetséges konvertálási lehetőségei itt találhatók: Arduino típuskonvertálások

Kapcsolódó funkciók

  • strlen() - karakterlánc (char array) hossza
  • strcpy() - karakterlánc (char array) másolása
  • memcpy() - karakterlánc (char array) másolása a memóriában
  • strcat() - karakterlánc (char array) hozzáfűzés
  • strcmp() - karakterláncok (char array) összehasnlítása
  • strchr() - egy karakter első előfordulása a karakterláncban (char array)
  • strstr() - egy karakterlánc első előfordulása a karakterláncban (char array)

A String objektum, eltérően a string karakterlénctól, inkább összefüggő, komplexebb szövegek kezelésére készült. Ennek egyelőre nincs kész a fordítása, az eredetije itt található: https://www.arduino.cc/en/Reference/StringObject

A típus lehetséges konvertálási lehetőségei itt találhatók: Arduino típuskonvertálások

A tömb valamilyen változótípushoz tartozó indexelhető és fix-hosszúságú értékek összessége. A tömb létrehozására néhány példa:

  int myInts [6];                         // "üres" tömb, kezdeti értékadás nélkül
  int myPins [] = {2, 4, 8, 3, 6};        // a tömb méretezése automatikusan, a megadott elemek számától függően
  int mySensVals [6] = {2, 4, -8, 3, 2};  // kezdeti értékekkel részben feltöltött tömb
  char message [6] = "hello";             // karakterlánc, ahol legalább egy karaktert "üresen" kell hagyni, lásd: string

A C-fordító nem ellenőrzi, hogy a tömb indexelésével a területről "kiindexel-e". Azaz az alábbi példa szerint

  int myArray [10] = {9,3,2,4,3,2,7,8,9,11}; 

A myArray[9] értéke 11, mivel az indexelést mindig 0-val kell kezdeni. A myArray[10]-ben, amit probléma nélkül olvashatunk, sőt, írhatunk is (!), a tömb területén kívül eső memóriaterület lesz.

A pointer a változók memóriabeli címét tárolja. Szintaktikája: type *var-name;

Néhány példa a definiálására:

int    *ip;    /* pointer to an integer */
double *dp;    /* pointer to a double */
float  *fp;    /* pointer to a float */
char   *ch     /* pointer to a character */

Példa a pointer alkalmazására:

   int  var = 20;   /* actual variable declaration */
   int  *ip;        /* pointer variable declaration */
 
void setup() {
}
 
void loop() {
   ip = &var;  /* store address of var in pointer variable*/
 
// &var: Address of var variable
// ip:   Address stored in ip variable
// *ip:  Value of *ip variable
 
}

Alkalmazások

A sizeof funkció a paraméterében megadott változó vagy tömb bájt-hosszával tér vissza.

Szintaktika

sizeof (változó)

változó: bármely típus, vagy bármilyen elem-típusú tömb

Példa

char myStr[] = "ez egy teszt";
int i;

void setup(){
  Serial.begin(9600);
}

void loop() { 
  for (i = 0; i < sizeof(myStr) - 1; i++){
    Serial.print(i, DEC);
    Serial.print(" = ");
    Serial.write(myStr[i]);
    Serial.println();
  }
  delay(5000); // csak szép lassan
}
for (i = 0; i < (sizeof(myInts)/sizeof(int)); i++) {
  // műveletek a myInts[i]-vel
}