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ámrendszerpé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.

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.

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

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 karakterlánc ismertetése itt található: char_array.

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

Konvertálási lehetőségek

bármely típus → char : char()

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.

unsigned char myChar = 240;

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

Konvertálási lehetőségek

bármely típus → byte : byte()

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.

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

Konvertálási lehetőségek

bármely típus → int : int()
char array → int: avr_libc standard könyvtár; atoi()

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

Konvertálási lehetőségek

bármely típus → word : word()

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.

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

Konvertálási lehetőségek

bármely típus → long : long()
char array → long: avr_libc standard könyvtár; atol()

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

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

Konvertálási lehetőségek

bármely típus → float : float()
float/double → char array: avr_libc standard könyvtár; dtostrf()
char array → float: avr_libc standard könyvtár; atof()

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

Konvertálási lehetőségek

float/double → char array: avr_libc standard könyvtár; dtostrf()
char array → float/double: avr_libc standard könyvtár; atof()

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

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 érdemes null-karakterrel zárni (pl. Str3 fent). 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 sorvége vezérlőt is lehet tárolni, például így:

char myString [] = "Ez az első sor" 
"ez a második sor" 
"etcetera";

Konvertálási lehetőségek

float/double → char array: avr_libc standard könyvtár; dtostrf()
char array → int: avr_libc standard könyvtár; atoi()
char array → float: avr_libc standard könyvtár; atof()
char array → long: avr_libc standard könyvtár; atol()

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ö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.

Típuskonverzió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

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

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
}