Arduino változók
Változók típusai és érvényességük
Változók kiterjedése
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ó } }
volatile
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.
static
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.
const
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.
HIGH | LOW
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()
INPUT | OUTPUT | INPUT_PULLUP
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
LED_BUILTIN
true | false
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, ..)
integer konstansok
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ípus | példa | formázása | megjegyzés |
---|---|---|---|
10 (decimális) | 123 | nincs | |
2 (bináris) | B11110011 | első karaktere: B | Csak 8 bites értékek esetén működik (0..255). Csak 0 és 1 karaktereket tartalmazhat. |
8 (oktális) | 0173 | első karaktere: 0 | Csak 0..7 karaktereket tartalmazhat. |
16 (hexadecimális) | 0x7B | első karakterei: 0x | Csak 0..9, A-F, a-f karaktereket tartalmazhat. |
unsigned int | 30u | a decimális szám után: u | - |
long | 30l | a decimális szám után: l | - |
unsigned long | 30ul | a 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.
karakter konstansok
Ábrázolás | Leírás | Megjelenése |
---|---|---|
\0 | null terminal | byte 0x00 (in ASCII encoding) |
\' | single quote | byte 0x27 (in ASCII encoding) |
\" | double quote | byte 0x22 (in ASCII encoding) |
\? | question mark | byte 0x3f (in ASCII encoding) |
\\ | backslash | byte 0x5c (in ASCII encoding) |
\a | audible bell | byte 0x07 (in ASCII encoding) |
\b | backspace | byte 0x08 (in ASCII encoding) |
\f | form feed - new page | byte 0x0c (in ASCII encoding) |
\n | line feed - new line | byte 0x0a (in ASCII encoding) |
\r | carriage return | byte 0x0d (in ASCII encoding) |
\t | horizontal tab | byte 0x09 (in ASCII encoding) |
\v | vertical tab | byte 0x0b (in ASCII encoding) |
\nnn | arbitrary octal value | byte nnn |
\xnn | arbitrary hexadecimal value | byte nn |
\unnnn | Unicode character that is not in the basic character set | code point U+nnnn |
\Unnnnnnnn | Unicode character that is not in the basic character set. | code point U+nnnnnnnn |
Konstans mérete | Típusa | Prefixe | Példák | UTF megfeleltetés |
---|---|---|---|---|
1 byte karakter konstansok | char | x, kódban nincs | 'a', '\n', '\13' | UTF-8 (\xF0\x9F\x8D\x8C) |
2 byte karakter konstansok | char16_t | u | u'貓', u'á' | UTF-16 (\uD83C\uDF4C) |
4 byte karakter konstansok | char32_t | U | U'貓', U'🍌' ('U0001f34c') | UTF-32 (\U0001f34c) |
wide karakter konstansok | wchar_t | L | L'β', 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ó-karakter | példa | leírás |
---|---|---|
'u' vagy 'U' | 11U | Az adott konstanst előjel nélküli (unsigned) típusnak deklarálja (force-olja) |
'l' vagy 'L' | 22L | Az adott konstanst long típusnak deklarálja (force-olja) |
'ul' vagy 'UL' | 33UL | Az adott konstanst előjel nélküli (unsigned) long típusnak deklarálja (force-olja) |
lebegőpontos konstansok
lebegőpontos konstans | matematikai kifejtése | valós érték kifejtése |
---|---|---|
10.0 | 10 | 10 |
2.34E5 | 2.34 * 10 ^ 5 | 234000 |
67e-12 | 67.0 * 10 ^ -12 | .000000000067 |
C típuskonstansok
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
void
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 () { // ... }
boolean
A boolean típus a true vagy false értéket veheti fel. Minden boolean változó egy bájt memóriát foglal.
char
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
unsigned 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. 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
charn_t
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
byte
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
int
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
short
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
intN_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 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
- int64_t : 64 bit
Arduino típus | C típus | stdint.h típus | Bits | Előjel | Tartomány |
---|---|---|---|---|---|
unsigned char | char | uint8_t | 8 | Unsigned | 0 .. 255 |
char | signed char | int8_t | 8 | Signed | -128 .. 127 |
unsigned int | unsigned short | uint16_t | 16 | Unsigned | 0 .. 65,535 |
int | short | int16_t | 16 | Signed | -32,768 .. 32,767 |
unsigned long | unsigned int | uint32_t | 32 | Unsigned | 0 .. 4,294,967,295 |
long | int | int32_t | 32 | Signed | -2,147,483,648 .. 2,147,483,647 |
- | unsigned long long | uint64_t | 64 | Unsigned | 0 .. 18,446,744,073,709,551,615 |
- | long long | int64_t | 64 | Signed | -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
unsigned int
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
long
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
unsigned long
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
word
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
double
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
float
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
Karakterlánc (char array)
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)
String - object
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
array
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.
pointer
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
sizeof
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 }