Kategória: Arduino.
Table of Contents
|
Fényes alkalmazások
Egyszerű LED-es alkalmazás
Az ember annál egyszerűbb, valamit is csináló elektronikai alkalmazást szinte el sem tud képzelni, mint a LED villogtatót. Erről már volt szó beépített LED-del, most valósítsuk meg külsővel! Az egyszerűség érdekében a kód maradjon az, amit a bevezetőben már láttunk, a 13-as láb melletti LED villogtatásánál, viszont most emellett használjunk egy tényleges külső LED-et is.
A gyakorlatban meglepő módon nem is annyira egyszerű! A problémát az okozza, hogy nem tudjuk csak úgy bedugni a LED hosszabb szárát a 13-as lyukba, a rövidebbet pedig a mellette levő GND-be, ugyanis ez esetben egyszerűen kiég. Szükség van előtét ellenállásra. Az ellenállás ne legyen túl nagy, mert akkor nagyon halvány lesz az eredmény, de túl kicsi se, nehogy kiégjen; kb. pár száz Ω-os legyen. (Én 220 Ω-os ellenállást használtam, és azzal szépen működött.) Mindehhez szükség van egy beszúrkálós próbapanelre, ill. - ha csak nem szeretnénk nagyon megerőszakolni az alkatrészeket - két apa kábelre is. (Mindezek egyébként tipikusan részei az alapkészletnek, amúgy a próbapanel kivételével filléres tételek. Emiatt ha van annyi LED-ünk, hogy belefér egy-egy tönkretétele, egy életben egyszer érdemes kipróbálni előtét ellenállás nélkül: tapasztaljuk meg mi magunk is, hogy tényleg tönkremegy.)
Kapcsolás:
- Arduino 13 -> ellenállás (pár száz Ω) -> LED (fontos a polaritás: ebben a sorrendben előbb jön a hosszabb szára, ami a + fele, anódnak hívjuk) -> Arduino GND.
A próbapanelen oldal végig hosszában össze vannak kötve a lyukak, belül pedig ötösével. Elvileg bárhogy kapcsolhatjuk, viszont az a konvenciót, hogy az oldalán levők a feszültség és a 0.
Teszt: ha mindent jól csináltunk, a bekapcsolt LED lassan villog.
A LED fényerejének változtatása PWM segítségével
A fenti példa látványos, ám nagyon bináris volt: van világított, vagy nem. A digitális lábakon is tudunk analóg jelent szimulálni PWM technikával: nagyon gyorsan váltakoztatva az idő bizonyos százalékában HIGH, bizonyos százalékában pedig LOW állapotban van. Vegyük például a következő kódot:
void setup() { pinMode(12, OUTPUT); } void loop() { digitalWrite(12, HIGH); delay(1); digitalWrite(12, LOW); delay(4); }
Kössünk egy LED-et a 12-es lábra, előtét ellenállás nélkül; a LED világítani fog, de nem megy tönkre, mert 1 Voltként fogja érzékelni a 20%-ban 5 Volt, 80%-ban nulla osztást. Ezzel viszont az a probléma, hogy gyakorlatilag a teljes processzoridőd arra használjuk, hogy gyorsan módosítsa a kimenő jelent 0 és 5V között, ez tehát nem egy működőképes opció. Viszont léteznek olyan lában, melyek hardveresen képesek a PWM-re: egy 0 és 255 közötti számot kell analóg módon kiírni, és ennek megfelelő lesz az eredmény. Az ilyen lábak mellett ~ jel található, és ezek a következők: 3, 5, 6, 9, 10, 11. Először győződjünk meg erről! Töltsük fel az alábbi kódot:
void setup() { pinMode(9, OUTPUT); analogWrite(9, 100); } void loop() {}
Valamelyik GND-ből és a 9-es lábból vezessünk ki egy-egy kábelt. Először mérjük meg multiméterrel az eső feszültséget: valamivel 2V alatt kell, hogy legyen. Majd oszcilloszkóppal nézzük meg részletesebben! Azt kell látnunk kb. 1 ms-os "nagyításban", hogy a jel sűrűn változik 0V és 5V között.
Látható, hogy egy teljes periódus 2ms, másodpercenként tehát ötszázszor van 5V->0V és 0V->5V átmenet.
Most térjünk vissza az eredeti feladatra! A kapcsolással kezdjük, mivel nagyon hasonlít a korábbihoz:
- Arduino 9 -> előtét ellenállás (pár száz Ω) -> LED -> Arduino GND.
A kód a következő:
const int ledPin = 9; void setup() { pinMode(ledPin, OUTPUT); } void loop() { for (int fadeValue = 0; fadeValue <= 255; fadeValue +=5) { analogWrite(ledPin, fadeValue); delay(25); } for (int fadeValue = 255; fadeValue >= 0; fadeValue -=5) { analogWrite(ledPin, fadeValue); delay(25); } }
A digitális lábakra 0 és 255 közötti "analóg" értékeket tudunk kiírni. A példában fokozatosan erősítjük majd csökkentjük a jel értékét, ezáltal a LED-en erősödő és elhalványuló fényerőt kapunk eredményül.
Valójában elég kényelmetlen előtét ellenállást alkalmazni a LED-eknél, még egy ilyen egyszerű áramkör esetén is szükségünk volt próbapanelre. Így lássunk egy másik technikát, melyben megtapasztalhatjuk a PWM erejét! Szedjünk le minden alkatrészt az Arduino-ról, és töltsük fel rá a következő programot:
const int ledPin = 11; void setup() { pinMode(ledPin, OUTPUT); } void loop() { for (int fadeValue = 0; fadeValue <= 50; fadeValue +=5) { analogWrite(ledPin, fadeValue); delay(25); } for (int fadeValue = 50; fadeValue >= 0; fadeValue -=5) { analogWrite(ledPin, fadeValue); delay(25); } }
Vegyük le a feszültségről, és helyezzük rá a LED-et, mindenféle előtét ellenállás nélkül, közvetlenül a megfelelő lyukakba: az anódot (pozitív fele, hosszabb szár) a 11-esbe, a katódot (negatív fele, rövidebb szár) pedig a GND-be. Amiatt ezekbe, mert a 13-as láb melletti GND és a 11-es láb elég közel vannak egymáshoz ahhoz, hogy ezt ott helyben is meg tudjuk tenni. (A 12-es és 13-as láb nem megfelelő erre a célra, mivel nincs mellette ~.) Majd kössük rá a feszültségre ismét. A LED nem ég ki, hanem szépen villog, noha nem kapott előtét ellenállást! Mi történt valójában? Folyamatosan kap 5 Voltot és 0 Voltot is, viszont olyan rövid ideig, hogy szinte "egybefolyik" számára: még az 50-es érték is valamivel kevesebb mint 1 Voltnak felel meg (a 255 lenne az 5 Volt). Ez a technika nagyon fontos lesz a későbbiekben, amikor a LED-re épülő összetettebb megjelenítőket (pl. a 7 szegmenses számkijelzőt) fogjuk használni. Most viszont ne felejtsük el kihúzni, mert egy véletlen tartós 5 Volt a 11-es lábon végzetes lehet a LED számára.
Többszínű LED-ek
A 37-in-1 szenzor gyűjteménybe bekerült néhány többszínű LED is (ezek tehát nem szenzorok), most ezek bemutatása következik.
RGB LED-ek
Ezek a legáltalánosabb LED-ek, bármilyen színt ki lehet "keverni" a piros, zöld és kék színekből. Kétféle tokozással kerül forgalomba: az egyik egy henger alakó, mely félgöbben végződik, 3_CIr felirattal, a másik pedig egy vízszintes lapka, 3_Clor felirattal.
Bekötés: a lapka maga tartalmaz ellenállást (ez a többire is igaz), így nem szükséges előtét ellenállást alkalmaznunk. Valamint a következő trükkel a kábeleket is megspóroljuk: ahova a GND kerülne, arra egyszerűen logikai LOW-t (0V, GND) teszünk, így működni fog. (Nem tudom, mennyire szabályos, de gyors, és működik.) tehát a bekötés:
- RGB LED - -> Arduino 8 (vagy Arduino GND, ha nagyon szabályosak szeretnénk lenni)
- RGB LED R -> Arduino 9
- RGB LED G -> Arduino 10
- RGB LED B -> Arduino 11
A kód a következő:
int gndPin = 8; // PIN 8 works as GND int redPin = 9; int greenPin = 10; int bluePin = 11; void setup() { pinMode(gndPin, OUTPUT); digitalWrite(gndPin, LOW); pinMode(redPin, OUTPUT); pinMode(bluePin, OUTPUT); pinMode(greenPin, OUTPUT); } int red[] = {255, 255, 255, 255, 0, 0, 0, 0}; int green[] = {255, 255, 0, 0, 255, 255, 0, 0}; int blue[] = {255, 0, 255, 0, 255, 0, 255, 0}; void loop() { for (int i=0; i<8; i++) { analogWrite(redPin, red[i]); analogWrite(greenPin, green[i]); analogWrite(bluePin, blue[i]); delay(1000); } }
A két RGB LED nem teljesen egyforma, fel van cserélve az R és a G; a fenti kód a "kilógó" változatra vonatkozik. Ha mindent jól csináltunk, akkor a főbb színeket mutatja a LED sorban.
Kétszínű LED-ek
Két kétszínű (piros és zöld) LED is helyet kapott a 37 szenzor csomagban: az egyik kisebb, a másik nagyobb. Jellemzőjük, hogy magának a LED-nek is 3 lába van.
Bekötés: itt is el tudjuk kerülni a kábelek használatát, az alábbi bekötéssel:
- RG LED S (ez a zöld) -> Arduino 12
- RG LED középső (ez a piros) -> Arduino 13
- RG LED - (ez a GND) -> Arduino GND
Ennek a bekötésnek a hátránya, hogy a lapkán levő LED is villog. A kód:
int greenPin = 12; int redPin = 13; void setup() { pinMode(greenPin, OUTPUT); pinMode(redPin, OUTPUT); } void loop() { analogWrite(redPin, 255); analogWrite(greenPin, 0); delay(1000); analogWrite(redPin, 0); analogWrite(greenPin, 255); delay(1000); }
Animálós LED
A gyűjteményben található egy olyan LED, melyre csak áramot kell kötni, és mindenféle színben pompázik (látszólag) véletlenszerűen. Két lába van, a hosszanti oldalán elnyúlik, és a lapkán (valószínűleg tévedésből) az olvasható, hogy DHT11.
Használatát kód nélkül is demonstrálni tudjuk, ha az S-sel jelölt láb 5 Voltra kerül, a mínusszal jelölt pedig a GND-re; ezt meg tudjuk tenni az analóg lábak melletti 5V-GND-GND segítségével, közvetlenül.
Ha kóddal szeretnénk vezérleni, akkor a következőképpen tudjuk megtenni. Bekötés:
- LED S -> Arduino 12
- LED - > Arduino GND
(Itt is beletehetjük közvetlenül; a középső, nem használt láb a 13-as lyukba kerül.)
int ledPin = 12; void setup() { pinMode(ledPin, OUTPUT); digitalWrite(ledPin, HIGH); } void loop() {}
Lézer
A 37 szenzor gyűjtemény része. Réz henger van a lapkán, onnan lehet felismerni. Használata: az animálós LED-nél leírtak szerint.
Megjelenítők
Hétszegmenses kijelző
A 7 szegmenses kijelző egy igazán kiváló tanuló eszköz arra, hogy miért ne használjuk, és ezt megismerve egyrészt jobban megérjük, másrészt jobban becsüljük a fejlettebb technikákat. Általában része az alapcsomagnak.
A működése a következő: valójában 8 különálló LED-ből áll az eszköz, ebből 7 szegmens a vonalkák, a nyolcadik pedig a pont. 10 lába van, ebből kettőt a GND-re kell kötni, a másik 8 pedig a 8 szegmens anódja egyenként. A bekötéshez pár száz Ohm-os előtét ellenállást kell alkalmazni; én 220 Ohm-osat használtam. Érdemes a kijelzőt beleszúrni egy próbapanelba úgy, hogy a felső és az alsó 5 tű külön oldalra kerüljön. A bekötés:
- Kijelző felső 1 -> ellenállás -> Arduino 9
- Kijelző felső 2 -> ellenállás -> Arduino 8
- Kijelző felső 3 -> Arduino GND
- Kijelző felső 4 -> ellenállás -> Arduino 7
- Kijelző felső 5 -> ellenállás -> Arduino 6
- Kijelző alsó 1 -> ellenállás -> Arduino 11
- Kijelző alsó 2 -> ellenállás -> Arduino 10
- Kijelző alsó 3 -> Arduino GND
- Kijelző alsó 4 -> ellenállás -> Arduino 5
- Kijelző alsó 5 -> ellenállás -> Arduino 4
A kódban egyesével be kell állítani a megfelelő logikai értéket:
int states[10][7] = { {HIGH, HIGH, HIGH, HIGH, LOW, HIGH, HIGH}, // 0 {HIGH, HIGH, LOW, LOW, LOW, LOW, LOW }, // 1 {LOW, HIGH, HIGH, LOW, HIGH, HIGH, HIGH}, // 2 {HIGH, HIGH, HIGH, LOW, HIGH, HIGH, LOW }, // 3 {HIGH, HIGH, LOW, HIGH, HIGH, LOW, LOW }, // 4 {HIGH, LOW , HIGH, HIGH, HIGH, HIGH, LOW }, // 5 {HIGH, LOW, HIGH, HIGH, HIGH, HIGH, HIGH}, // 6 {HIGH, HIGH, HIGH, LOW, LOW, LOW, LOW }, // 7 {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH}, // 8 {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, LOW } // 9 }; void displayNumber(int number) { for (int i = 5; i <= 11; i++) { digitalWrite(i, states[number][i-5]); } } void setup() { for (int i = 4; i <= 11; i++) { pinMode(i, OUTPUT); } digitalWrite (4, LOW); } void loop() { for (int i = 0; i < 10; i++) { displayNumber(i); delay(1000); } }
Végeredményben nagyon jól látható, hogy ezt miért nem érdemes használni:
- A bekötéshez 10 kábelre és 8 előtét ellenállásra van szükség. Az összekötés sok időt elvesz.
- A 14 digitális lábból elvesz 8-at. Mivel az Arduino-n összesen 20 olyan láb van, melyre tudunk értéket kiírni, ezzel a technikával legfeljebb 2 számjegyet tudunk egyszerre kiírni. (Talén emiatt van az, hogy az én kezdőkészletembe 2 darabot adtak?)
- Lényegében csak a 10 számjegy kijelzésére alkalmas (bár a pontot is figyelembe véve elvileg 256 különböző mintát tudunk kirajzolni). Tehát alkalmatlan valódi adatok megjelenítésre.
- A kód meglehetősen hosszú. Ahhoz, hogy kiírjunk egy 5-öst, a mai világban már elvárnánk azt, hogy elég legyen a kódba azt írni, hogy print(5), és a rendszer tegye a dolgát, nem?
Négy számjegyes kijelző
A 4 számjegyes kijelzőt már nem is lehet a fenti, egy számjegyesnél bemutatott technikával megoldani, már csak a megfelelő számú láb hiánya miatt sem. Ugyanis mind a négy számjegy 8 szegmensből áll, ami már önmagában 32, de kell minimum egy katód. Az Arduino-nak összesen 32 lába van, de ebből max. 20 olyan, mely ilyen célra végső soron használható. Látni fogjuk, hogy ez a kijelző típus oktatási célra kiválóan alkalmas, ugyanis nagyon jó, máshol is hasznosítható (hasznosított) ötletek vannak benne, de a gyakorlatban önmagában nem igazán alkalmas a használatra.
A kimenetek számának hiányát a következő ötlettel oldották meg: mind a 8 szegmensnek szegmensenként közös az anód (tehát pl. a tizedespont mind a 4 számjegynél ugyanaz), szegmensenként pedig közös a katód (tehát pl. a baloldali számjegy mind a 8 szegmense ugyanarra a katódra van kötve). Ezzel a módszerrel tetszőleges szegmenst be tudunk kapcsolni. Viszont hogyan oldjuk meg azt a problémát, hogy különböző helyi értékeknél különböző értékek jelenjenek meg? Itt használhatjuk ki a szemünk tehetetlenségét: ha valami nagyon gyorsan (pl. másodpercenként ötvenszer) vibrál, azt folyamatosnak látjuk. A megoldás tehát a következő: bekapcsoljuk a bal oldali helyi értéket, a többit lekapcsoljuk, megjelenítjük egy pillanatra a bal oldali számjegyet, majd ki is kapcsoljuk. Utána a másodikkal, a harmadikkal, végül a negyedikkel. Majd ismét kezdjük az elejéről.
Le feledjünk, hogy LED-ekkel van dolgunk, mely 5 Volt hatására kiég. Többféleképpen kezelhetjük a problémát:
- Az egy számjegyes kijelzőnél bemutatott módon, mindegyik szegmenshez előtét ellenállást alkalmazunk.
- Jobban belegondolva: itt elegendő a szegmens kiválasztó katódokhoz előtét ellenállást tenni, ezáltal nem kell 8, elég 4 is.
- Van egy elegáns, de veszélyes megoldás: előtét ellenállás nélkül, a PWM-nél bemutatott módon. Ha kellően nagy frekvenciával kapcsolgatjuk ki-be a LED-et, akkor elegendő azt biztosítani, hogy az idő max. 20%-ában legyen bekapcsolva, amit 1 Voltként fog értelmezni. A fent vázolt algoritmust annyival kell kiegészíteni, hogy miután kiírtuk mind a 4 számjegyet, kapcsoljuk ki az összeset, és hagyjuk úgy egy nagyon rövid ideig (ha a felvillanás 0,5 ms, akkor 10 ms várakozás két kiírás között jó választás lehet).
Most a harmadik esetet mutatom be. Ennek a hátránya, hogy itt tényleg nem szabad hibázni, mert különben ha csak néhány tizedmásodpercig 5 Volt esés fut a LED-en (az egyik anódra tartósan HIGH, az egyik katódra pedig tartósan LOW kerül), akkor tönkremegy. Emiatt a kódot előbb fel kell tölteni, mint bekötnénk az eszközt, nehogy egy korábbi program az eszköz szempontjából végzetes szemetet hagyjon maga mögött.
int digits[] = {2, 5, 6, 13}; int segments[] = {3, 7, 11, 9, 8, 4, 12, 10}; void setup() { for (int i = 0; i < 8; i++) { pinMode(segments[i], OUTPUT); } for (int i = 0; i < 4; i++) { pinMode(digits[i], OUTPUT); digitalWrite(digits[i], HIGH); } } void loop() { displayNumber(millis() / 100); } void displayNumber(int numberToDisplay) { long beginTime = millis(); for (int i = 3; i >= 0; i--) { digitalWrite(digits[i], LOW); displayDigit(numberToDisplay % 10); delayMicroseconds(500); displayDigit(10); digitalWrite(digits[i], HIGH); numberToDisplay /= 10; } while((millis() - beginTime) < 10); } int states[11][7] = { {1,1,1,1,1,1,0}, // 0 {0,1,1,0,0,0,0}, // 1 {1,1,0,1,1,0,1}, // 2 {1,1,1,1,0,0,1}, // 3 {0,1,1,0,0,1,1}, // 4 {1,0,1,1,0,1,1}, // 5 {1,0,1,1,1,1,1}, // 6 {1,1,1,0,0,0,0}, // 7 {1,1,1,1,1,1,1}, // 8 {1,1,1,1,0,1,1}, // 9 {0,0,0,0,0,0,0} // off }; void displayDigit(int digitToDisplay) { for (int i = 0; i < 7; i++) { digitalWrite(segments[i], states[digitToDisplay][i]); } }
Miután feltöltöttük a kódot, kössük be a 4 számjegyes kijelzőt az alábbi módon (célszerűen húzzuk ki a kábelt, majd csak a bekötést követően dugjuk ismét be). Ehhez szúrjuk a kijelzőt a próbapanel közelébe úgy, hogy a felső fele az egyik, az alsó fele pedig a másik részben helyezkedik el, majd a következő bekötést hajtsuk végre:
- 4 szegmenses kijelző felső 1 (első számjegy) -> Arduino 2
- 4 szegmenses kijelző felső 2 (A szegmens) -> Arduino 3
- 4 szegmenses kijelző felső 3 (F szegmens) -> Arduino 4
- 4 szegmenses kijelző felső 4 (második számjegy) -> Arduino 5
- 4 szegmenses kijelző felső 5 (harmadik számjegy) -> Arduino 6
- 4 szegmenses kijelző felső 6 (B szegmens) -> Arduino 7
- 4 szegmenses kijelző alsó 1 (E szegmens) -> Arduino 8
- 4 szegmenses kijelző alsó 2 (D szegmens) -> Arduino 9
- 4 szegmenses kijelző alsó 3 (tizedespont) -> Arduino 10
- 4 szegmenses kijelző alsó 4 (C szegmens) -> Arduino 11
- 4 szegmenses kijelző alsó 5 (G szegmens) -> Arduino 12
- 4 szegmenses kijelző alsó 6 (negyedik számjegy) -> Arduino 13
A szegmensek az alábbiak:
AAA
F B
F B
F B
GGG
E C
E C
E C
DDD DP
Ennek a bekötésnek az az előnye, hogy a szegmensen egymás mellett levő lábak az Arduino-n is egymás mellé kerülnek. Ugyanakkor látható, hogy két láb kivételével ez elfoglalja az összes digitális kimenetet (a maradék kettő a 0 és az 1, ami a soros kommunikációra van fenntartva), a szükséges kábelek számát (12) is soknak tartom, ráadásul a kábelek is elég jól eltakarják a kijelzőt. Tehát ez ebben a formában nemigazán alkalmas arra, hogy komolyabb projektekre használjuk. Ellen ellenére elterjedt és népszerű, ehhez viszont további trükkökre van szükség…
Kitérő: a TM1638-as eszköz
Most, hogy láttuk a többszámjegyes kijelzés lehetőségeit és korlátait, talán jobban értékeljük a TM1638-as eszközt, aminek segítségével 8 számjegyet tudunk kiíratni, és ezen kívül van rajta 8 nyomógomb, valamint 8 piros LED (egyes típusokon 8 kétszínű: piros-zöld LED). Mindezt az eddigi technológiákkal - akárhogyan optimalizálunk is - művészet lenne rákötni. Viszont itt az ún. shift out technológiát alkalmazzák, melyre még később visszatérünk. A kód viszont rendkívüli mértékben leegyszerűsíthető, ahogyan a bekötés is.
Bekötés:
- TM1638 VCC -> Arduino 3.3V
- TM1638 GND -> Arduino GND
- TM1638 STB -> Arduino 7
- TM1638 CLK -> Arduino 9
- TM1638 DIO -> Arduino 8
Látható tehát, hogy mindössze 5 lábbal megoldható a teljes bekötés, melyből mindössze 3 az adatláb (az eredeti koncepcióval erre 64 adatlábra, a 4 számjegyesnél megmutatott módszerrel pedig 16 adatlábra lenne szükség).
A natív kód önmagában eléggé bonyolult, viszont ha feltelepítjük ezt a könyvtárat: https://github.com/rjbatista/tm1638-library, akkor az is igen egyszerűvé válik.
#include <TM1638.h> TM1638 module(8, 9, 7); void setup() {} void loop() { module.setDisplayToDecNumber(millis() / 100, 0); }
8x8-as mátrix kijelző
A 8x8-as mátrix kijelző önmagában szintén inkább csak érdekes mist hasznos. Ebben 64 darab LED van mátrix-szerűen betokozva, így a klasszikus módon (külön anód, közös katód) esélytelen bekötni. Valójában összesen 16 lába van, mégpedig mindegyik sornak egy-egy anódja, és mindegyik oszlopnak egy-egy katódja. Alapból katódokra magas, míg az anódokra alacsony értéket teszünk, és mivel a LED-ben csak a másik irányba folyik ára, kikapcsolt állapotban lesz mindegyik. Ha valamelyik LED-et világítani szeretnénk, akkor a megfelelő anódra kell a magas és az anódra az alacsony értéket írni. De ügyelnünk kell arra, hogy utána ki is kapcsoljuk, és így vibráltassuk, és legalább ötször olyan hosszú ideig legyen kikapcsolt állapotban, mint bekapcsolva, különben kiég a LED. A valóságban végigpásztázunk az összes képponton, és felvillantjuk majd rögtön le is kapcsoljuk azt, amelyiket azt szeretnénk, hogy világítson, és a nagyon gyors vibrálást látja a szemünk folyamatos világításnak. Amint tehát látható, elég nehézkes, mivel 16 lábat kell bekötni, ráadásul a főprogramunkat is elveszi. A valóságban viszont még rosszabb a helyzet…
Először a kódot adom meg, mivel ha egy korábbi program szemete az egyik, anódként használt lábra állandó magas, egy katódként használt lábra pedig állandó alacsony értéket "felejtett", akkor az tönkretenné az egyik LED-et.
int cols[8] = {6, 11, 10, 3, A1, 4, 8, 9}; int rows[8] = {2, 7, A3, 5, 13, A2, 12, A0}; int leds[8][8] = { {1,1,1,1,1,1,1,1}, {1,0,0,0,0,0,0,0}, {1,0,1,1,1,1,1,1}, {1,0,1,0,0,0,0,1}, {1,0,1,0,0,1,0,1}, {1,0,1,1,1,1,0,1}, {1,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1} }; void setup() { for (int i = 2; i <= 13; i++) { pinMode(i, OUTPUT); } pinMode(A0, OUTPUT); pinMode(A1, OUTPUT); pinMode(A2, OUTPUT); pinMode(A3, OUTPUT); for (int i = 0; i < 8; i++) { digitalWrite(cols[i], HIGH); digitalWrite(rows[i], LOW); } } void loop() { for (int row = 0; row < 8; row++) { for (int col = 0; col < 8; col++) { if (leds[row][col] == 1) { digitalWrite(rows[row], HIGH); digitalWrite(cols[col], LOW); } digitalWrite(rows[row], LOW); digitalWrite(cols[col], HIGH); } } }
Látható, hogy a kód folyamatosan "szaladgál" körbe-körbe, és ha kell, felvillantja a LED-et. A kód kirajzolja a megadott spirált.
Most lássuk a bekötést! Ez szintén nem egyszerű, több okból kifolyólag sem. Az egyik: sem sorban szerepelnek a sorok és oszlopok, hanem össze-vissza. A következő a lábak jelentése (S: sor, O: oszlop):
- Felső sor: O8, O7, S2, O1, S4, O6, O4, S1
- Alsó sor: S5, S7, O2, O3, S8, O5, S6, S3
Igyekeztem úgy kialakítani a bekötést, hogy ami egymás mellett van a mátrix LED-en, az lehetőleg egymás mellé kerüljön az Arduino-n is. A bekötés:
- Mátrix felső sor 1 -> Arduino 9
- Mátrix felső sor 2 -> Arduino 8
- Mátrix felső sor 3 -> Arduino 7
- Mátrix felső sor 4 -> Arduino 6
- Mátrix felső sor 5 -> Arduino 5
- Mátrix felső sor 6 -> Arduino 4
- Mátrix felső sor 7 -> Arduino 3
- Mátrix felső sor 8 -> Arduino 2
- Mátrix alsó sor 1 -> Arduino 13
- Mátrix alsó sor 2 -> Arduino 12
- Mátrix alsó sor 3 -> Arduino 11
- Mátrix alsó sor 4 -> Arduino 10
- Mátrix alsó sor 5 -> Arduino A0
- Mátrix alsó sor 6 -> Arduino A1
- Mátrix alsó sor 7 -> Arduino A2
- Mátrix alsó sor 8 -> Arduino A3
Arról, hogy a kód megfelelően kezelje ezt a bekötést, a rows és cols tömbök gondoskodnak.
Teszt: most már bedughatjuk ismét az Arduino-t, és ha mindent jól csináltunk, akkor egy spirált kell látnunk. A valóságban viszont az a valószínűbb, hogy néhány pixel világít ugyan, de ezek nem alakítanak ki egy jó látható ábrát. Ennek az az oka, hogy elég könnyen alakul ki kontakthiba: érdemes finoman összeszorítani két ujjunkkal a bekötéseket.
Végeredményben tehát felhasználtunk 16 lábat, 16 kábelt és a loop() függvényt ahhoz, hogy egy statikus dolgot kirajzoljunk, ami kontakthiba miatt csak nehézkesen sikerül. A gyakorlatban tehát ez ebben a formában használhatatlan, persze erre is van megoldás…
32x8-as mátrix kijelző
Már a 8x8-as bekötése és programozása is nehézkes volt, és az ott megtapasztaltak szerint lehetetlenség e fölé menni, pedig lehetséges! A MAX7219 jelű áramkör segítségével SPI technikával egymás után kötött 8x8-as LED mátrixokat is meg tudunk címezni. A példában 4 ilyen kijelző van egymás után kötve. (Egyébként nem volt egyszerű működő kódot találni, végül ez segített: https://leetsacademy.blogspot.com/2017/02/32x8-led-dot-matrix-with-max7219-using.html.)
Bekötés:
- 32x8 VCC -> Arduino 5V
- 32x8 GND -> Arduino GND
- 32x8 DIN -> Arduino 11 (MOSI)
- 32x8 CS -> Arduino 10
- 32x8 CLK -> Arduino 13 (SCK)
Kód: először az alábbi könyvtárakat telepítsük fel:
- https://github.com/adafruit/Adafruit-GFX-Library (ez feltelepíthető a library manager-ből is)
- https://github.com/markruys/arduino-Max72xxPanel
A Max72xxPanel valójában a GFX könyvtárra épül, és örökli annak bizonyos függvényeit. Miután feltelepítettük a fenti könyvtárakat, a következő kódot töltsük fel az Arduino-ra:
#include <SPI.h> #include <Adafruit_GFX.h> #include <Max72xxPanel.h> int pinCS = 10; int numberOfHorizontalDisplays = 1; int numberOfVerticalDisplays = 4; Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays); void setup() { matrix.setIntensity(2); matrix.setRotation(1); printText("Szia!"); } void printText(String text) { matrix.fillScreen(LOW); int x = 0; for (int i = 0; i < text.length(); i++) { matrix.drawChar(x, 0, text[i], HIGH, LOW, 1); x += 6; } matrix.write(); } void loop() {}
Ha mindent jól csináltunk, akkor kiírja, hogy "Szia!". Némi magyarázat:
- A setIntensity függvénnyel a képpontok fényességét adhatjuk meg, mely 0..15 közötti értékeket vehet fel.
- setRotation: ezzel tudjuk a megfelelő irányba forgatni. Az 1-es paraméter azt jelenti, hogy a baloldali lesz az Arduino-hoz közel, és úgy fogja vízszintesen írni. (Az alapértelmezett nem megfelelő.)
- fillScreen(LOW): törli a képernyőt
- drawChar: szöveget közvetlenül nem tudunk kiírni, csak karaktereket egyesével, ezzel a függvénnyel. Ezt a GFX-től örökli.
- write: a kiíró, kirajzoló függvények csak egy puffert módosítanak, és ez küldi ki ténylegesen a mátrixra az ábrát.
Futószöveget is ki tudunk írni, ld. pl. a beépített Ticker nevű példát. Viszont az valószínűleg egy más felépítésű eszközre készülhetett, és némi változtatást végre kell hajtani, amit sajnos helyben nem tudunk megtenni, máshova le kell menteni. Szükséges változtatások:
- A sorok és oszlopok számét fel kell cserélni (numberOfHorizontalDisplays és numberOfVerticalDisplays az elején).
- A setup() függvénybe be kell írni a következő sort: matrix.setRotation(1);.
- Szerintem az intenzitást érdemes lejjebb venni.
Kétsoros LCD kijelző
A termék kódja LCD1602. Kétféle színben lehet vásárolni: kék és zöld, ill. kétféle formában: van-e rajta I2C adapter vagy nincs. Kereső kifejezések vásárláshoz (egyik opció kell a három közül):
- LCD 1602 with I2C (javaslom ezt; nem kell forrasztani)
- LCD 1602 + potentiometer (lehetséges, hogy forrasztani is kell)
- LCD 1602 + I2C adapter for LCD 1602 (biztosan kell forrasztani)
I2C adapter nélkül
Ehhez szükség van feszültségosztóra (angolul potentiometer). Kapcsolás:
- LCD VSS -> Arduino GND
- LCD VDD -> Arduino 5V
- LCD V0 -> Feszültségosztó közép
- LCD RS -> Arduino D12
- LCD RW -> Arduino GND
- LCD E -> Arduino D11
- LCD D4 -> Arduino D5
- LCD D5 -> Arduino D4
- LCD D6 -> Arduino D3
- LCD D7 -> Arduino D2
- LCD A -> Arduino 5V
- LCD K -> Arduino GND
- Feszültségosztó 5V (felülnézetből jobb oldali) -> Arduino 5V
- Feszültségosztó GND (felülnézetből bal oldali) -> Arduino GND
A beépített LiquidCrystal könyvtár megfelelő. Ezt a kódot töltsük fel:
#include <LiquidCrystal.h> LiquidCrystal lcd(12, 11, 5, 4, 3, 2); void setup() { lcd.begin(16, 2); lcd.print("hello, world!"); } void loop() { lcd.setCursor(0, 1); lcd.print(millis()/1000); }
A feszültségosztóval állítsuk be a fényerősséget, hogy olvasható legyen a szöveg. Ha mindent jól csináltunk, akkor az első sorban a hello, world! szöveg látható, míg alatta az indulás óta eltelt másodpercek számát.
I2C adapterrel
Látható, hogy az alap LCD kijelző bekötése igen összetett: 14 kábel kell hozzá, kell külön feszültségosztó, és szerelőlap (breadboard) vagy bővítőlap (shield) nélkül nem is megoldható. Hosszú ideig tart összeszerelni, könnyű elrontani, és szinte alig marad szabad láb. E probléma kiküszöbölésére találták ki az I2C adaptert, amit külön is megvásárolhatunk, de érdemes eleve olyan LCD kijelzőt vásárolni, amely ezt már tartalmazza.
A bekötés jóval egyszerűbb, a táp és föld mellett mindössze két kábelre van szükség, az SDA-ra és az SCL-re:
- LCD GND -> Arduino GND
- LCD VCC -> Arduino 5V
- LCD SDA -> Arduino A4 (Arduino SDA)
- LCD SCL -> Arduino A5 (Arduino SCL)
Hátránya, hogy az Arduino Uno esetén csak az A4-A5 párosra lehet kötni, így azt másra nem lehet használni.
A kód, ami a fenti műveletet hajtja végre:
#include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); void setup() { lcd.begin(16, 2); lcd.print("hello, world!"); } void loop() { lcd.setCursor(0, 1); lcd.print(millis()/1000); }
Ehhez viszont szükség van egy külső könyvtárra: Newliquidcrystal_1.3.5.zip, mely innen letölthető: https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads/. Windows alatt csomagoljuk ki ide: c:\Users\[user]\Documents\Arduino\libraries\.
A fényerősséget az I2C adapteren található kis kék tokban levő csavarral tudjuk beállítani.
Utasítások
Az LCD utasításkészlet referenciája itt található: https://www.arduino.cc/en/Reference/LiquidCrystal. A legfontosabbak:
- lcd.begin(16, 2)
- lcd.setCursor(oszlop, sor) (az első sor ill. oszlop sorszáma 0)
- lcd.clear()
- lcd.print("…")
Az mBlock-hoz létezik az I2C interfésszel ellátott 1602-es LCD-hez kiegészítő, így blokk programozással is programozható.
Ékezetes karakterek
Alapból ékezetes karaktereket nem tudunk megjeleníteni. Ezen az oldalon találunk leírást (és könyvtárat) arra, hogy hogyan tudjuk ékezetes karaktereket megjeleníteni az LCD kijelzőn.
Grafikus LCD kijelző
Ez a kijelző többnyire nem része a kezdőcsomagoknak. Pár dollárért megvásárolható; a keresőkulcs ez: SSD1306 Oled I2C LCD display. A most bemutatott változat 128x64 képpont méretű. A leírásnak ez a szakasza ez alapján készült: https://startingelectronics.org/tutorials/arduino/modules/OLED-128x64-I2C-display/, de nem pontosan követi azt.
Szükséges beállítások a fejlesztői környezeten.
Telepíteni kell a következő két Adafruit könyvtárat:
- SSD1306
- GFX
Mindkettő telepíthető a Library Manager (Tools -> Manage Libraries…) segítségével. Telepíts után viszont módosítani kell ezt: c:\Users\[user]\Documents\Arduino\libraries\Adafruit_SSD1306\Adafruit_SSD1306.h. Eredeti tartalom:
#define SSD1306_128_64 ///< DEPRECTAED: old way to specify 128x64 screen //#define SSD1306_128_32 ///< DEPRECATED: old way to specify 128x32 screen
Módosított tartalom:
//#define SSD1306_128_64 ///< DEPRECTAED: old way to specify 128x64 screen #define SSD1306_128_32 ///< DEPRECATED: old way to specify 128x32 screen
Bekötés
A bekötés a szokásos I2C bekötés:
- Oled GND -> Arduino GND
- Oled VDD -> Arduino 5V
- Oled SCK -> Arduino A5 (Arduino SCL)
- Oled SDA -> Arduino A4 (Arduino SDA)
Kód
A következő példaprogram demó formájában bemutatja a kijelzési lehetőségeket: File -> Examples -> Adafruit SSD1306 -> ssd1306_128x64_i2c. Viszont ezen is kell egyetlen karaktert módosítani ahhoz, hogy jól működön. Eredeti sor:
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) { // Address 0x3D for 128x64
Módosított sor:
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C for 128x64
A helló világot kiíró és egy vonalat rajzoló kód (a kírás angolul, mert egyelőre nem jól kezeli a magyar karaktereket):
#include <Wire.h> #include <Adafruit_SSD1306.h> #include <Adafruit_GFX.h> #define OLED_ADDR 0x3C Adafruit_SSD1306 display(-1); void setup() { display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR); display.clearDisplay(); display.display(); display.setTextSize(1); display.setTextColor(WHITE); display.setCursor(27, 30); display.print("Hello, world!"); display.drawLine(5, 58, 123, 58, WHITE); display.display(); } void loop() {}
A működése: megadjuk a kirajzolandó dolgokat, majd a display() függvény rajzolja ki azokat. Műveletek:
- print("text"): szöveget ír ki. Vonatkozó függvények: setTextSize(textSize), setTextColor(color), setCursor(x, y).
- write('c'): egyetlen karaktert ír ki
- drawLine(x1, y1, x2, y2): vonalat rajzol
- drawRect(x1, y1, x2, y2, color): téglalapot rajzol
- drawRoundRect(x1, y1, x2, y2, r, color): lekerekített téglalapot rajzol
- fillRect(x1, y1, x2, y2, color): kitöltött téglalapot rajzol
- fillRoundRect(x1, y1, x2, y2, r, color): kitöltött lekerekített téglalapot rajzol
- drawTriangle(x1, y1, x2, y2, x3, y3, color): háromszöget rajzol
- fillTriangle(x1, y1, x2, y2, x3, y3, color): kitöltött háromszöget rajzol
- drawCircle(x, y, r): körvonalat rajzol
- fillCircle(x, y, r, color): kitöltött kört rajzol
- drawBitmap(x, y, bmp, width, height): képet rajzol ki
- startscrollright(start, stop), startscrollleft(start, stop), startscrolldiagonalright(start, stop), startscrolldiagonalleft(start, stop), stopscroll(): képernyő tartalmának mozgatása.
- boolean getPixel(x, y): adott képpont értékét adja vissza.
Jelölések:
- color: szín; lehetséges értékek: BLACK, WHITE, INVERSE
- x: x-koordináta; lehetséges értékek: 0-127
- y: y-koordináta; lehetséges értékek: 0-63
- r: sugár
- width: szélesség
- height: magasság
- bmp: a kirajzolandó kép; típusa unsigned char []; ld. a példát.
Hangot kiadó alkalmazások
Ide soroljuk az aktív és passzív berregőt. A passzív berregő tipikusan része a csomagoknak, de a 37 szenzor gyűjteményben is helyet kapott. Aktív berregőt találunk a 37 szenzoros csomagban. Az aktív berregőnek elég áramot adni, és sípol, még a passzív berregőt ha áramra kötjük, semmi sem csinál, azt le kell programozni. Ránézésre ugyanúgy néznek ki; a 37 szenzoros csomagban az aktívra rá van ragasztva egy lapka, valamint a + jel közelebb van a lábakhoz.
Aktív berregő
Ez az egyszerűbb: csak adjunk neki az S-re (ill. ha külön van: a pozitív, azaz hosszabb lábára) 5 Voltot, a másikat pedig kössük a GND-ra. Elég hangosan sípol.
Passzív berregő
Nem nyilvánvaló, hogy hogyan szólaltassuk meg, különösen hogyan játsszunk le dallamot, mert ha egyszerűen csak HIGH értéket kötünk rá, akkor nem történik semmi. A megoldáshoz elő kell vennünk a matematikai és fizikai tudásunkat, így ez egy gyakorlati fizikaórának is kiválóan alkalmas!
A hang valójában hullám, az emberi fül számára hallható tartomány 20 Hz-től 20.000 Hz-ig terjed. Néhány hang frekvenciája az alábbi táblázatban található (keressünk rá a neten arra a kifejezésre, hogy frequency of notes):
Hangjegy | Frekvencia [Hz] | Félperiódus (μs) |
---|---|---|
c | 261 | 1915 |
d | 294 | 1700 |
e | 329 | 1519 |
f | 349 | 1432 |
g | 392 | 1275 |
a | 440 | 1136 |
h | 493 | 1014 |
C | 523 | 956 |
Az, hogy pl. az 'a' hang 440 Hz, fizikailag azt jelenti, hogy másodpercenként 440 teljes periódusú sinus hullám megy végbe. Egy periódus hossza 1/440 s ≈ 0.0022727 s = 2272,7 μs. A félperiódus ennek a fele, kerekítve 1136 μs. A képlet tehát: félperiódus=1/(2*frekvencia). Minden hangjegy kerekített félperiódusát szintén tartalmazza a táblázat.
ideális esetben olyan sinus hullámokat kellene generálni, melynek félperiódusa a táblázatban megadott érték. Az Arduino esetén erre nincs mód, itt csak közelíteni tudjuk, mégpedig úgy, hogy egy félperiódusnyi ideig ad le az adott láb HIGH értéket (5 Voltot), majd ugyanennyi ideig LOW értéket (0 Voltot). Ez nem sinus, hanem négyzetes jel, ráadásul az y-tengely is el van tolva 2,5 Voltnyit, így a hangás nem lesz tökéletes, de elképzelésünk ennek alapján is lesz arról, hogy a profibb készülékek hogyan generálják a hangokat.
A kódban lementjük egy tömbbe a kiszámolt értékeket. Meg kell határozni a ritmusát; a 0,3 másodperc (300 ms) egy nyolcadhangra megfelelő választás lehet. Majd lejátszunk egy dalocskát: a Boci-boci tarkát. Itt először a 'c' hangnak kell szólnia 300 ms (300.000 μs) ideig; ebbe kb. 78 olyan periódust jelent, melyben 1915 μs ideig kap HIGH és ugyanennyi ideig LOW értéket. Utána jön az 'e' hang, ugyancsak 300 ms ideig, kb. 98 periódussal. A dallam ötödik hangja ('g') egy negyedhangnyi ideig kell, hogy szóljon, ami 600 ms. Két hang között rövid szünetet kell tartanunk. A programot ezeket figyelembe véve alkotjuk meg.
int speakerPin = 12; char notes[] = "ceceggceceggChagfagfedcc "; // a space represents a rest int beats[] = {1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 4}; int tempo = 300; // ms = 1 beat void playTone(int tone, int duration) { for (long i = 0; i < duration * 1000L; i += tone * 2) { digitalWrite(speakerPin, HIGH); delayMicroseconds(tone); digitalWrite(speakerPin, LOW); delayMicroseconds(tone); } } char names[] = {'c' , 'd' , 'e' , 'f' , 'g' , 'a' , 'h' , 'C'} ; int tones[] = {1915, 1700, 1519, 1432, 1275, 1136, 1014, 956}; void playNote(char note, int beat) { // play the tone corresponding to the note name for (int i = 0; i < 8; i++) { if (names[i] == note) { playTone(tones[i], tempo * beat); } } } void setup() { pinMode(speakerPin, OUTPUT); } void loop() { int length = sizeof(notes) / sizeof(notes[0]); for (int i = 0; i < length; i++) { if (notes[i] == ' ') { delay(beats[i] * tempo); // rest } else { playNote(notes[i], beats[i]); } delay(tempo / 2); // pause between notes } }
A bekötés igazából egyszerűbb, mint látszik, ugyanis csak két lábat kell bekötni:
- Berregő - -> Arduino GND
- Berregő S -> Arduino 12
(A lábakat szándékosan választottam úgy, hogy a háromlábú berregőt be lehessen szúrni a GND-13-12 hármasba, így nem szükséges külön kábelt használni. Ez egy olyan hack, melyet ebben a speciális esetben ki tudunk használni. Nyilván nem működik a dolog, ha szükségünk lenne a 13-as láb kivezetésére.)
Ha mindent jól csináltunk, a berregő lejátssza a Boci-boci tarkát. A fent leírtak miatt a hangok nem teljesen tiszták, a tempó sem tökéletes (ugyanannyi szünetet hagy ki a nyolcad és a negyedhangok között is), viszont mindezen hiányosságok ellenére ezzel a projekttel megismerkedtünk a hanggenerálás rejtelmeivel.
Érdemes oszcilloszkóppal megvizsgálni a kimenő jelent, hogy tényleg az, aminek gondoljuk: nagyon szépen kirajzolódik, hogy igen.
Az Arduino tone() függvényét is használhatjuk közvetlenül, melyről itt találunk egy leírást: https://www.arduino.cc/en/Tutorial/toneMelody.
Meghajtás
Ide azok az eszközök kerülnek, melyek megfelelő jelre fizikailag is megmozdulnak.
Szervó motor
A szervó motor segítségével olyan projekteket lehet készíteni, ahol finom motorikai mozgásokra van szükség. Például a rajzoló óra három ilyen motort tartalmaz (kettő a pozíció beállításhoz, egy az emeléshez), a robotkar négyet. A kódjele SG90, és többnyire része az alapkészletnek. Általában 180°-nyit lehet vele elmozdulni.
Bekötés: a fenti kódjelű szervó motor esetén a kábelek össze vannak ragasztva. Nem érdemes őket széttépni, hanem ha használunk bővítőlapot, akkor simán rá tudjuk szúrni. (Anélkül egyébként is szükségünk van segéd apa-apa kábelekre, így ez esetben sem szükséges szétbontanunk.) Helyezzük a sárga kábelt valamelyik valamelyik lábra (pl. 9), így a piros a V-re (feszültség), a barna pedig a G-re (föld) kerül.
Kód:
#include <Servo.h> Servo servo; void setup() { servo.attach(9); } void loop() { for (int i = 0; i <= 180; i++) { servo.write(i); delay(10); } for (int i = 180; i >= 0; i--) { servo.write(i); delay(10); } }
Látható a kódban, hogy egy külső, egyébként alapból feltelepülő könyvtárat használunk, a Servo-t, melynek dokumentációs itt található: https://www.arduino.cc/en/reference/servo. A leglényegesebb utasítása a write(), amelynek segítségével 0 és 180 fok közötti értékre tudjuk állítani a szervó motort. A fenti példában egyik-másik irányba fordul el a motor feje. Ennél precízebb módon tudjuk vezérelni a kissé megtévesztő nevű writeMicroseconds() függvény segítségével, amelynél 1000-2000 közötti értékeket tudunk megadni (1000 = 0°, 1500 = 90°, 2000 = 180°). Viszont ez már gyártófüggő; a specifikáció is megemlíti, hogy egyes gyártók a még tágabb, 700-2300 intervallumot használják.
A gyakorlatban 3D nyomtatóval nyomtatott vagy lézerrel kivágott eszközöket lehet rákapcsolni.
Léptető motor
A léptető motor neve valószínűleg megtévesztő: ideális működés során ugyanis nem lép, hanem körbe-körbe forog. Ami miatt léptetőnek hívják az az, hogy a köröket kis lépésekben teszi meg, melynek egyrészt itt nem részletezett technikai okai vannak, másrészt olyan értelemben gyakorlati, hogy az Arduino kód megáll forgás során. Tehát érdemes kis lépésekben forgatni a motort, és közben lehetőséget biztosítani más kódrészletek lefutására is.
A léptető motor specifikációja itt található: https://www.arduino.cc/en/tutorial/stepperSpeedControl. A következő oldal segített valamelyest megérteni a működését: https://circuitdigest.com/microcontroller-projects/arduino-stepper-motor-control-tutorial. A motor kódja ez: 28BYJ-48. Ha külön vásároljuk, fontos, hogy úgy vegyük, hogy legyen hozzá ULN2003 kódjelű meghajtó modul.
Kapcsolás: a motor maga a meghajtóra van kötve, és a meghajtót kötjük az Arduino-ra.
- ULN2003 IN1 -> Arduino 8
- ULN2003 IN2 -> Arduino 9
- ULN2003 IN3 -> Arduino 10
- ULN2003 IN4 -> Arduino 11
- ULN2003 - (ez külön van, egy jumper mellett) -> Arduino GND
- ULN2003 + -> Arduino 5V
Kód:
#include <Stepper.h> #define STEPS 128 Stepper stepper(STEPS, 8, 10, 9, 11); void setup() { stepper.setSpeed(200); } void loop() { stepper.step(4); }
A szükséges könyvtár automatikusan feltelepül az Arduino IDE-vel.
(Megjegyzés: egyelőre inkább érdekesnek találtam, mint hasznosnak, logikusan gondolkodva viszont ilyet, vagy ehhez hasonlót kell használni robotok mozgatásához. Ahhoz viszont számomra gyanúsan lassan forgott, akárhogy is próbálkoztam, és a programozása is nehézkes.)
Relé
Az Arduino alapvetően kis, pár voltos feszültségekkel dolgozik. A relé (relay module) segítéségével tehetjük alkalmassá arra, hogy nagyobb feszültségű, akár a fali konnektorba dugott eszközöket vezéreljünk vele. Az eszköz egyébként hasznossága ellenére rendkívül egyszerű, olcsó, és tipikusan többcsatornás reléket tudunk vásárolni. Az alapkészleteknek is néha része, és tartalmazza a 37 szenzorból álló gyűjtemény.
Bekötés. Az Arduino-ra kötés a 37 szenzor gyűjtemény kialakítása alapján úgy, hogy a felirat vízszintesen látszódik), jobb oldalon:
- Relé felső -> Arduino GND
- Relé középső -> Arduino 5V
- Relé alsó -> Arduino 3
Kód:
int relayPin = 3; void setup() { pinMode(relayPin, OUTPUT); } void loop() { digitalWrite(relayPin, HIGH); delay(2000); digitalWrite(relayPin, LOW); delay(2000); }
Teszt: ha a fenti kódot feltöltjük, akkor kattogás hallatszik; ez jelzi a be- ill. kikapcsolást. A relé másik felé csavarhúzóval ráerősíthető kimenetek vannak, melyek jelentése a következő:
- Felső: normál kimenet
- Középső: bemenet
- Alsó: inverz kimenet
Normál működéshez a 2 vagy 3 kábel fázisát kell átvágni, majd az egyik végét a középsőre, a másikat a felsőre kötni. Ha nem szeretnénk a fali feszültséggel kísérletezni, alakítsuk ki a következő áramkört, független áramforrással, pl. egy MB102 típusú áramellőtó lappal.
- 5 Volt -> LED -> 220 Ω előtét ellenállás -> Relé középső (csavarhúzóval)
- 0 Volt -> relé felső (csavarhúzóval)
Azt fogjuk tapasztalni, hogy a LED villogni fog. Viszont ha van elég bátorságunk, akkor kialakíthatunk egy olyan áramkört is, melyben egy normál izzó villog hasonlóan.