Kategória: Arduino.
Table of Contents
|
Egyszerű bemenetek
Nyomógomb
A nyomógomb felfogható bináris szenzorként, így az ott ismertetett kód használható. A bekötése viszont meglepően nem triviális, és nem ússzuk meg a próbapanelt. A nyomógomb belseje úgy van kialakítva, hogy a közeli 2-2 láb össze van kötve. Egyébként teljesen szimmetrikus, mindegy, hogy milyen irányban kötjük be. Az egyik fele legyen A, a másik bele B; ez esetben a kapcsolás:
- Nyomógomb A -> Arduino 5V
- Nyomógomb A -> 10k ellenállás -> Arduino GND
- Nyomógomb B -> Arduino 2
A viszonylag nagyobb ellenállásra annak érdekében van szükség, hogy eltörpüljön a feszültségesés a nyomógombon, tehát alatta is lényegében 5V körüli értékként, azaz logikai magasként érzékelje. A bekötésnél nekem problémáim voltak azzal, ha a szembe levő lábat választottam; egyfajta "inverz kontakthibát" tapasztaltam: néha akkor is áramot jelzett, amikor nem volt lenyomva. Néha elég volt csak éppen hozzáérni. Lehet, hogy a próbapanel volt hibás, mindenesetre átlós lábakat használva rendesen működött.
Teszt: nyomjuk meg a nyomógombot: a 13-as LED bekapcsolódik; engedjük el: a 13-as LED elalszik.
Potenciométer
A potenciométer (gyakori rövidítéssel egyszerűen csak pot, de előfordult, hogy egyszerűen csak analóg olvasóként hivatkoznak rá) lényegében egy változtatható ellenállás, amely csavarással a feszültséget osztja. Mivel 5 Volt feszültséget kap az Arduino-tól, a kimeneten egy 0 és 5 közötti érték jelenik meg. Ezt célszerű egy analóg lábra kötni, ahol egy 0 és 1023 közötti értéket kapunk.
A potenciométer tipikusan része a kezdőkészleteknek, de a 37 szenzor csomag is tartalmazza.
A legegyszerűbb kapcsolásban kiírjuk a a beolvasott értéket a soros monitorra.
- Pot bal -> Arduino GND
- Pot közép -> Arduino A0
- Pot jobb -> -> Arduino 5V
A kódban tizedmásodpercenként kiírjuk az éppen beolvasott értéket:
void setup() { Serial.begin(9600); } void loop() { Serial.println(analogRead(A0)); delay(100); }
A soros monitor mellett érdemes a soros rajzolót (Serial Plotter) is megnéznünk, hiszen igen látványos eredményt tudunk létrehozni.
Joystick
A joystick egy két dimenziós beviteli eszköz, gyakorlatilag két potenciométer, mely része a 37 szenzor készletnek. Bekötés:
- Joystick GND -> Arduino GND
- Joystick +5V -> Arduino 5V
- Joystick VRx -> Arduino A0
- Joystick VRy -> Arduino A1
- Joystick SW -> Arduino 2
Kód:
int joystickX = A0; int joystickY = A1; int joystickButton = 2; void setup() { pinMode(joystickX, INPUT); pinMode(joystickY, INPUT); pinMode(joystickButton, INPUT); Serial.begin(9600); } void loop () { Serial.print(analogRead(joystickX)); Serial.print(", "); Serial.print(analogRead (joystickY)); Serial.print(", "); Serial.println(digitalRead(joystickButton)); delay(100); }
Teszt: indítsuk el a Serial Monitort, és mozgassuk a joystick-ot. Mindkét dimenzióban nyugalmi helyzetben 511 körüli értéket kapunk, és a 0-1023 intervallumban olvasunk be értékeket. (Megjegyzés: az én példányomnál nem működött a nyomógomb; a fenti kóddal elvileg működnie kell.)
Érzékelők
Ide azokat sorolom, amelyek a külső környezet valamilyen tulajdonságát számszerűsítik, és az eredmény közvetlenül, vagy nagyon minimális átalakítással felhasználható. Ilyen eszköz pl. az egyszerű hőérzékelő.
LM35 hőmérséklet érzékelő
Ez talán a legegyszerűbb és legolcsóbb hőmérséklet érzékelő, mely tipikusan része a kezdőkészleteknek. Kapcsolás:
- LM35 bal -> Arduino 5V
- LM35 közép -> Arduino A0
- LM35 jobb -> Arduino GND
A kódban egy trükköt alkalmazunk a pontosabb értékért. Tudnunk kell, hogy 10 mV változás jelent 1°C változást, 0-ról indulva. 1 Volt tehát 100 °C-ot jelentene, melynek mérésére az LM35 már nem is képes, így egy nagyon szűk tartományban adna csak olyan értékeket, melyek pontosabbak is lehetnének. Az analogReference(INTERNAL) beállítással a 0-5 Volt intervallum lecsökken 0-1,1 Voltra, így jobban lehet finomhangolni a mért értéket. A soros monitorra kerül az eredmény.
void setup() { Serial.begin(9600); pinMode(A0, INPUT); analogReference(INTERNAL); } void loop() { int sensorValue = analogRead(A0); Serial.print("Sensor value: "); Serial.println(sensorValue); float voltage = sensorValue * 1.1 / 1024; // 1.1V because INTERNAL analog reverence; it would be 5V by default Serial.print("Voltage: "); Serial.println(voltage); float temperatureC = voltage * 100; // temperature (°C) = 0°C (no offset) + 1°C/10mV Serial.print(temperatureC); Serial.println(" °C"); delay(1000); }
Teszt: próbáljuk meg változtatni a hőmérsékletet, és figyeljük a soros monitort. Figyeljük meg, hogy szoba hőmérsékleten 0 mért feszültség 0,20-0,25 Volt közötti, mégis, a szenzor érték 200 körüli; a pontosság ezáltal fél fok helyett tizedfok körüli.
Dallas 18B20 hőmérséklet érzékelő
Ennek a létjogosultságát leginkább az adja, hogy míg az LM35 érzékelőt csak analóg portra köthetjük, a DS18B20 érzékelőt akár digitális portra is, ráadásul a OneWire technológia segítségével akár 64-et is ráköthetünk, ugyanarra a lábra. (Viszont annak ellenére, hogy ez a OneWire technológia igen ígéretes, furcsamód csak ennél az eszköznél találkoztam vele, emiatt nincs felsorolva az általános technikák között.) Ez a hőmérséklet érzékelő egyébként része a 37 szenzor készletnek. Kinézete: 3 lába van, félbe vágott hengerre hasonlít (kb. mint egy tranzisztor), és DALLAS 18B20 felirat van rajta.
A megvalósítást ezen az oldalon találjuk: https://create.arduino.cc/projecthub/TheGadgetBoy/ds18b20-digital-temperature-sensor-and-arduino-9cc806.
Bekötés, ha a lábak jobb oldalon vannak:
- DS18B20 felső -> Arduino 2
- DS18B20 középső -> Arduino 5V
- DS18B20 alsó -> Arduino GND
Ha önmagában használjuk, akkor a az adat és a feszültség közé egy 4,7 kΩ ellenállást is kell tenni, de ha a 37 szenzor csomagból vettük ki, akkor az már ezt tartalmazza.
A kód lefordításához szükségünk van két könyvtárra:
- OneWire: http://www.pjrc.com/teensy/arduino_libraries/OneWire.zip
- DallasTemperature: https://github.com/milesburton/Arduino-Temperature-Control-Library
#include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS 2 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); void setup() { Serial.begin(9600); sensors.begin(); } void loop() { sensors.requestTemperatures(); Serial.print("Celsius temperature: "); Serial.print(sensors.getTempCByIndex(0)); Serial.print(" - Fahrenheit temperature: "); Serial.println(sensors.getTempFByIndex(0)); delay(1000); }
Figyeljük meg a függvény nevét: getTempCByIndex(0): több IC-t tudunk ugyanarra a lábra dugni, és ez az elsőt jelenti.
Teszt: változtassuk a hőmérsékletet, miközben figyeljük a soros monitort.
DHT11 és DHT22 hőmérséklet és páratartalom érzékelő
A DHT11 kék, a DHT22 pedig fehér; ez utóbbi drágább, viszont nagyobb tartományban és nagyobb pontossággal mér. A DHT11 része a 37 szenzor csomagnak. Beállítása ugyanaz mindkét esetben.
Bekötés
DHT11:
- DHT11 S -> Arduino 2
- DHT11 középső -> Arduino 5V
- DHT11 - -> Arduino GND
DHT22:
- DHT11 + -> Arduino 5V
- DHT11 out -> Arduino 2
- DHT11 - -> Arduino GND
Látható tehát, hogy egyetlen általános digitális lábbal megoldható a beolvasás.
Kód: szükség van megfelelő library-re. Számos DHT könyvtár létezik. A példában az Adafruit DHT Sensor Library-jét használjuk, mely mindkét típusra alkalmas. Ehhez fel kell telepítenünk az alábbiakat:
- Adafruit Unified Sensor by Adafruit
- DHT sensor library by Adafruit
#include <DHT.h> #define DHTPIN 2 #define DHTTYPE DHT11 DHT dht(DHTPIN, DHTTYPE); void setup() { Serial.begin(9600); dht.begin(); } void loop() { Serial.print("Humidity: "); Serial.print(dht.readHumidity()); Serial.print("% Temperature: "); Serial.print(dht.readTemperature()); Serial.println("°C "); delay(1000); }
DHT22 esetén írjuk át a kódban a DHT11-et DHT22-re; mást nem kell változtatni rajta.
Teszt: indítsuk el a Serial Monitort, és közben próbáljuk megváltoztatni a hőmérsékletet és a páratartalmat (pl. egy ráleheléssel).
Megjegyzés: a 37 szenzor csomagban található még két hőmérséklet érzékelő, az egyik kis fekete lapkára szerelve, a másik nagyobb piros lapkára. Igazából egyiket sem sikerült működésre bírnom. Viszont a DHT-ban ugyanolyan hőmérséklet érzékelő található.
BMP180 légnyomás- és hőmérséklet érzékelő
Ez az 1$ alatti alkatrész általában nem része a kezdőszetteknek, sem a 37 szenzor csomagnak, így ha használni szeretnénk, azt külön meg kell vásárolni. Vagy a típusra keressünk rá, vagy a barometric pressure sensor keresőkulcsra. Amit rendeltem, külön érkezett az érzékelő és a tű, azt rá kellett forrasztani. Az eszköz I2C-vel van ellátva, ennek megfelelő a bekötés ill. a kód is.
Bekötés:
- BMP180 VIN -> Arduino 3.3V (fontos, hogy ne az 5V-ra kössük!)
- BMP180 GND -> Arduino GND
- BMP180 SCL -> Ardunio A5
- BMP180 SDA -> Arduino A4
Kód: a használatához telepítenünk kell egy BMP180 könyvtárat. Ha rákeresünk erre, többet is találunk; én az Adafruit BMP085 Library-t telepítettem; ugyanaz kell ugyanis a BMP085 típusnak is, mint a BMP180-nak. Egyetlen példaprogram van csak, melynek neve BMP085test. Ez ne riasszon el bennünket, működik BMP180-nal is. A könyvtár tartalmaz magasság "mérést" is, bár az inkább számíts int mérés, és nem jól működik. Az eszköz valójában két dolgot mér: a légnyomást és a hőmérsékletet. A példaprogramból készített egyszerűsített kód, mely a légnyomást írja ki úgy, hogy azt a serial plotterrel is meg tudjuk jeleníteni, a következő:
#include <Wire.h>
#include <Adafruit_BMP085.h>
Adafruit_BMP085 bmp;
void setup() {
Serial.begin(9600);
bmp.begin();
}
void loop() {
//Serial.println(bmp.readTemperature());
Serial.println(bmp.readPressure());
delay(100);
}
Megjegyzésbe téve találjuk a hőmérséklet beolvasásának lehetőségét is, ami °C-ban adja vissza.
Teszt: a légnyomást sajnos nem tudjuk változtatni, legalábbis házi körülmények között nem. 101700 Pa körüli értéket mért, ami kb. 200 Pa-lal több mint a háztartásban megtalálható másik érzékelő által mért érték. A mért értéknek van pár Pa kilengése, így e két tényezőből valószínűsíthető, hogy működik. A hőmérséklet tesztelése jóval egyszerűbb, elég csak rálehelni, és máris felugrik a mért érték.
Vízérzékelő
A vízérzékelő általában nem része a kezdőcsomagnak, pedig igen hasznos, az analóg érzékelők "állatorvosi lova" is lehetne, egyszerű és látványos használata matt. Ha meg szeretnénk vásárolni, akkor a keresőkulcs ez: Arduino water sensor. Általában hosszúkás, téglalap alakú, és hosszú párhuzamos vonalak láthatóak rajta. (Az enyém piros, Funduino felirattal.)
Kapcsolás:
- Vízérzékelő S -> Arduino A0
- Vízérzékelő + -> Arduino 5V
- Vízérzékelő - -> Arduino GND
Kód: az analóg érzékelőknél leírtak szerint.
Teszt: nyissuk meg a Serial Monitort, vagy ez esetben inkább a Serial Plottert. Ne felejtsük el beállítani a baud-ot (9600). Majd nedvesítsük be az érzékelőt, várjuk meg, hogy megszáradjon, nedvesítsük be ismét, töröljük le. Közben figyeljük meg, hogy a kirajzolt diagram látványosan követi azt, hogy mikor mennyire volt nedves. A száradás folyamata meglepően lineáris.
Figyeljük meg azt is, hogy ahogy az Arduino fogadja az adatot, úgy villog rajta az RX LED.
Talajnedvesség érzékelő
Angolul soil moisture sensor. Általában nem része a kezdőkészletnek, és a 37 szenzor készletnek sem, a 45 részesnek viszont igen. Ez is olcsó, száz forintos nagyságrendért megvásárolható. Klasszikus érzékelő típus, melynek van analóg és digitális kimenete is. Tipikusan két részből áll: egy villa alakú mérőből (amit a földbe kell szúrni) és egy erősítőből. A már bemutatott analóg tesztet használjuk, az ott bemutatott programot töltsük föl. Az érzékelőt és az erősítőt 2 kábellel kell összekötni, az erősítőt az Arduino-ra pedig értelemszerűen. Ne az 5V-ra, hanem a 3.3V-ra kössük rá. Érdemes a Serial Plotter kimenetét figyelni, száraz földdel kezdeni a tesztet, és közben öntsünk rá vizet. (Nálam a nagyobb nedvességtartalom alacsonyabb értékként jelent meg, de lehet, hogy amiatt, mert fordítva kötöttem be.)
Infravörös érzékelő távirányítóval
Szokásos rövidítése: IR. Általában része az alapkészleteknek, és a 37 szenzoros készletben is benne van. Kössük az érzékelőt a 2-es lábra, a VCC-t az 5V-ra, a mínuszt pedig a GND-re. (A natív esetben balról jobbra: OUT, GND, VCC.) Telepítsük az IRRemote csomagot, majd töltsük fel az alábbi kódot:
#include <IRremote.h> IRrecv irrecv(2); decode_results results; void setup() { Serial.begin(9600); irrecv.enableIRIn(); // Start the receiver } void loop() { if (irrecv.decode(&results)) { switch (results.value) { case 0XFFFFFFFF: break; case 0XFF6897: Serial.println(0); break; case 0XFF30CF: Serial.println(1); break; case 0XFF18E7: Serial.println(2); break; case 0XFF7A85: Serial.println(3); break; case 0XFF10EF: Serial.println(4); break; case 0XFF38C7: Serial.println(5); break; case 0XFF5AA5: Serial.println(6); break; case 0XFF42BD: Serial.println(7); break; case 0XFF4AB5: Serial.println(8); break; case 0XFF52AD: Serial.println(9); break; default: Serial.println(results.value, HEX); } irrecv.resume(); } }
Figyeljük a soros monitort, miközben nyomkodjuk a számokat a távirányítón. (Megjegyzés: nálam nem működött a natív érzékelő, a 37 szenzor csomagban található érzékelő viszont működött.) Fontos a távirányító típusa, mely az Arduino készletekben általában NEC.
A témával kapcsolatban hasznos leírást találunk itt: http://www.circuitbasics.com/arduino-ir-remote-receiver-tutorial/.
Akadály érzékelő
Az akadály érzékelő (angolul: Obstacle Avoidance Sensor) a robotoknál lehet hasznos. Része a 37 szenzor csomagnak. Van rajta egy infravörös LED (átlátszó) és egy érzékelő (fekete); az érzékelő a visszaverődő infravörös fényt érzékeli. Érzékelési tartománya 2-40 cm, melyet csavarhúzóval tudunk beállítani.
Bekötés:
- Akadály érzékelő 1 (GND) -> Arduino GND
- Akadály érzékelő 2 -> Arduino 5V
- Akadály érzékelő 3 -> Arduino 2
- Akadály érzékelő 4 -> szabadon marad.
Kód: a digitális érzékelőnél bemutatott kód használható, de vegyük figyelembe, hogy a LOW érték jelenti az akadályt, a HIGH érték pedig azt, hogy nincs akadály.
Teszt: helyezzünk akadályt az érzékelő elé, és figyeljük a 13-as LED-et. (Megjegyzés: nálam bizonytalanul működött.)
Ultrahangos távolságérzékelő
Az infravörös távolságérzékelő bináris eredményt adott, mivel a fénysebesség túl nagy ahhoz, hogy pár centis távolságok esetén ki tudjuk mérni, az ultrahangos érzékelő (angolul: ultrasonic sensor) segítségével viszont már ki tudjuk számolni a távolságot, mivel a mérésnél mikroszekundumokról beszélünk, és számolhatunk hangsebességgel. Az érzékelő általában nem része az alapkészletnek, de érdemes megvásárolni, kb. 1$-os árért. A működési elve a következő: az egyik "szeme" (a bal oldali, VCC-hez közelebb eső része) ultrahangot bocsájt ki (ezt hívjuk triggernek), a másik pedig fogadja (ezt hívjuk echo-nak). Meg fogunk ismerkedni egy újabb utasítással: pulseIn() (https://www.arduino.cc/reference/en/language/functions/advanced-io/pulsein/), mely addig vár, míg a paraméterben átadott lábra a paraméterben átadott jel (HIGH vagy LOW) meg nem érkezik (így az elején megfelelően be kell állítani, ezt majd látni fogjuk a kódban), és eredményül az eltelt mikroszekundumok számát adja. A hangsebességből már számolható a távolság: s = v * t / 2 (az osztás kettővel amiatt kell, mert a hang kétszer teszi meg a távolságot: oda és vissza), itt v = 340 m/s, t pedig az eltelt idő mikroszekundumokban. Ha a távolságot cm-ben szeretnénk megkapni, akkor s = 34000 [cm / s] * 100000 * t [s] / 2 = t * 0.034 / 2.
Bekötés:
- UH VCC -> Arduino 5V
- UH Trig -> Arduino 9
- UH Echo -> Arduino 10
- UH GND -> Arduino GND
Kód:
const int trigPin = 9; const int echoPin = 10; void setup() { pinMode(trigPin, OUTPUT); pinMode(echoPin, INPUT); Serial.begin(9600); } void loop() { digitalWrite(trigPin, LOW); delayMicroseconds(2); digitalWrite(trigPin, HIGH); delayMicroseconds(10); digitalWrite(trigPin, LOW); long duration = pulseIn(echoPin, HIGH); int distance = duration * 0.034 / 2; Serial.print("Distance: "); Serial.println(distance); delay(1000); }
Teszt: indítsuk el a Serial Monitort, és tartsunk akadályt az UH érzékelő elé, különböző távolságokban.
Nyomkövető
Angolul tracking sensor. Része a 37 szenzor gyűjteménynek. Kinézete: hosszúkás, az érzékelője pedig kék és fekete. A teszthez használjuk a megfelelő bekötést (VCC, OUT, GND) és töltsük fel a digitális érzékelőnél bemutatott programot. Ha fehér valamit teszünk az érzékelő elé, akkor kigyullad az érzékelőn a LED és elalszik a 13-as LED. Ha feketét, akkor fordítva.
Felhasználási terület: robotok esetén vonalkövetés.
Mozgásérzékelő
Angolul motion detector, gyakori rövidítéssel PIR, ami a pyroelectric sensor (vagy passive infrared) rövidítése. A rövidítés a működési elvével kapcsolatos, ugyanis valójában a hőmérséklet megváltozására érzékeny az eszköz. Az eszköz általában nem része a kezdőkészleteknek és a 37 szenzor gyűjteménynek sem, 1$ körüli összegért megvásárolható külön.
Bekötés felülnézetből:
- PIR bal -> Arduino 5V
- PIR közép -> Arduino 2
- PIR jobb -> Arduino GND
Kód: a digitális érzékelő kódja használható.
Teszt: közelítsünk az érzékelőhöz ill. távolodjunk tőle, és közben figyeljük a lapra épített LED-et. (Megjegyzés: számomra meglepően érzéketlennek tűnik, összehasonlítva pl. az mBot-hoz vásárolható mozgásérzékelővel.)
Gázérzékelők
Az MQ jelű gázérzékelők (gas sensor) különböző gázfajtákat érzékelnek:
- MQ-2: füst
- MQ-3: alkohol
- MQ-4: metán
- MQ-5: metán
- MQ-6: LPG
- MQ-7: szénmonoxid
- MQ-8: hidrogén
- MQ-9: éghető gáz
- MQ-135: levegő minőség
Általában nem része a kezdőcsomagnak, és a 37 szenzor készletnek sem, viszont darabja kb. 1 dollárért megvásárolható.
Bekötés és kód: az analóg érzékelőknél leírtak szerint. (A D0-t nem kell bekötni.) Teszt: helyezzünk a közelébe olyan gázt, amire érzékeny. Pl. én MQ-2-t vásároltam, és egy gyufát meggyújtva majd rögtön elfújva füst keletkezik, aminek hatására látványosan emelkedni kezdett a mért érték. Az eszköz egyébként nemcsak a füstre, hanem egyéb összetevőkre is érzékeny, és pl. egy ráleheléskor is magasabb értéket mutat. (Megjegyzés: az elején várni kellett pár percet, hogy elérjen egy nyugalmi minimumértéket.)
Fotoellenállás
Angolul photo resistor, de hívják még fotocellának (photocell) is. Egyszerű és látványos eszköz: segítségével azt tudjuk megállapítani, hogy mennyire van világos. Az alapkészletek többnyire tartalmazzák, és a 37 szenzor készletnek is része.
Bekötés: natív módon a következő kis áramkört kell kialakítani:
- Arduino 5V -> 10 kΩ ellenállás -> itt két részre bontjuk
- (1) -> fotoellenállás -> Arduino GND
- (2) -> Arduino A0
A 37 szenzoros gyűjteményben ez az áramkör már meg van. Ott 3 lábat kell bekötni, az alábbi módon (sajnos elrontották a jelölést):
- Fotoellenállás - -> Arduino A0
- Fotoellenállás középső -> Arduino GND
- Fotoellenállás S -> Arduino 5V
Kód: lehet ugyanaz, mint az analóg érzékelőknél bemutatott.
Teszt: indítsuk el a Serial Plottert, és világítsunk rá az érzékelőre, majd takarjuk el.
Érintés érzékelő
Angolul touch sensor. Kinézete: általában koncentrikus köröket tartalmaz, a 37 szenzor csomagban viszont piros, és a végén egy fémdrótba keretezett két lábú fekete érzékelő van. Kipróbáláshoz használjuk a digitális érzékelő bekötést; az A0-t nem kell bekötni. Érintsük ujjunkat az érzékelőhöz, miközben a 13-as LED-et figyeljük.
Ütközés érzékelő
Angolul collision sensor vagy crash sensor, néha (helytelenül) touch sensor. Általában nem része az alapkészletnek, valamint a 37 darabos szenzor gyűjteménynek semi, viszont filléres összegért megvásárolható. Gyakorlatilag úgy működik mint egy kapcsoló, viszont a kialakítása olyan, hogy leginkább egy robot ütközését érzékelje. A digitális érzékelőnél leírtakat alkalmazzuk, értelemszerű bekötéssel.
Elhajlás érzékelő
Angolul tilt sensor. Ránézésre hasonlít a polaritásos kondenzátorra. Az enyém fekete és az van ráírva az oldalára, hogy AETHOX. A nyomógombnál leírtak szerint kell bekötni, valamint a digitális értékelőknél ismertetett kód használható itt is. Teszt: tartsuk függőlegesen a (próbapanelre beleszúrt) érzékelőt: a 13-as LED nem világít; fordítsuk el úgy, hogy fekvő helyzetbe kerüljön: a 13-as LED világít.
A 37 szenzor készletben van egy ún. mágikus lámpa (angolul magic light cup) pár mely gyakorlatilag tartalmaz egy-egy elhajlás érzékelőt és egy-egy LED-et. Ha a LED-et PWM lábra kötjük és a párjának az elhajlásával vezéreljük, akkor olyan hatást lehet vele kelteni, mintha a fényt átöntenénk az egyikből a másikba. (Ez mondjuk inkább érdekes mint hasznos.)
Gyorsulásérzékelő és giroszkóp
Az MPU 6050 jelű eszköz 3 dimenziós gyorsulásérzékelésre, 3 dimenziós elfordulásérzékelésre és még hőmérséklet érzékelésre is alkalmas. A gyorsulásérzékelés angolul accelerometer, az elfordulásérzékelő angolul gyroscope. Ez a szinte filléres eszköz általában nem része az alapkészleteknek, ill. a 37 érzékelőből álló szenzorgyűjteménynek sem. Beüzemelni sajnos nem egyszerű, de a probléma talán betudható annak, hogy olyan eszközt sikerült rendelnem, amelyet forrasztani kellett, és lehet, hogy némi kontakt hiba van benne.
Kapcsolás:
- MPU 6050 VCC → Arduino 3.3V
- MPU 6050 GND → Arduino GND
- MPU 6050 SCL → Arduino A5
- MPU 6050 SDA → Arduino A4
- MPU 6050 XDA → nem kell bekötni
- MPU 6050 XCL → nem kell bekötni
- MPU 6050 ADO → nem kell bekötni
- MPU 6050 INT → Arduino 2
A nyers adatokat kiolvasó és soros monitorra kiíró kód az alábbi:
#include<Wire.h> const int MPU6050_addr=0x68; int16_t AccX, AccY, AccZ, Temp, GyroX, GyroY, GyroZ; void setup() { Wire.begin(); Wire.beginTransmission(MPU6050_addr); Wire.write(0x6B); Wire.write(0); Wire.endTransmission(true); Serial.begin(9600); } void loop(){ Wire.beginTransmission(MPU6050_addr); Wire.write(0x3B); Wire.endTransmission(false); Wire.requestFrom(MPU6050_addr, 14, true); AccX = Wire.read()<<8 | Wire.read(); AccY = Wire.read()<<8 | Wire.read(); AccZ = Wire.read()<<8 | Wire.read(); Temp = Wire.read()<<8 | Wire.read(); GyroX = Wire.read()<<8 | Wire.read(); GyroY = Wire.read()<<8 | Wire.read(); GyroZ = Wire.read()<<8 | Wire.read(); Serial.print("AccX = "); Serial.print(AccX); Serial.print(" || AccY = "); Serial.print(AccY); Serial.print(" || AccZ = "); Serial.print(AccZ); Serial.print(" || Temp = "); Serial.print(Temp); Serial.print(" || GyroX = "); Serial.print(GyroX); Serial.print(" || GyroY = "); Serial.print(GyroY); Serial.print(" || GyroZ = "); Serial.println(GyroZ); delay(1000); }
Ha értelmezhetetlen adatokat ad (pl. csupa 0-t), akkor a következőket tehetjük:
- Várunk; kb. 10 másodperc, amíg magához tér.
- Az i2c_scanner nevű programmal (https://playground.arduino.cc/Main/I2cScanner/) érdemes lehet ellenőrizni, hogy a cím valóban 0x68-e (lehet 0x69 is).
- Ellenőrizzük a kábelezést. Pl. egy minimális kontakt hiba is problémát okozhat.
Ha stabilan érkeznek a mért adatok, akkor próbáljuk meg elforgatni, mozgatni, és közben figyeljük a soros monitoron az adatokat. A nyers adatok értelmezése kissé bonyolult, ehhez telepítsük valamelyik MPU6050 Arduino könyvtárat, és a példaprogramokat használjuk fel a további lépések megtételéhez.
Néhány hasznos oldal a témában, amelyek a kapcsolás és a kód mellett a működési elvet is vázolják:
- https://playground.arduino.cc/Main/MPU-6050/
- https://maker.pro/arduino/tutorial/how-to-interface-arduino-and-the-mpu-6050-sensor
- https://howtomechatronics.com/tutorials/arduino/arduino-and-mpu6050-accelerometer-and-gyroscope-tutorial/
- https://www.electronicshub.org/getting-started-arduino-mpu6050/
Rázkódás érzékelő
Angolul vibration sensor. Fekete, henger alakú, belül rézszínű. A jelölésnek megfelelően kell bekötni, a digitális szenzor kódját használni, és teszteléshez rázogatni kell, vagy inkább ütögetni magát a hengert, miközben figyeljük a lapkán a LED-et.
Hangérzékelő
Angolul sound sensor. A 37 szenzor készletben kettő is található. Mindkettő piros, és van rajta egy szürke oldalú henger, végén fekete hártyával. Az A0 az analóg, a D0 pedig a digitális kimenet, így elvileg analóg és digitális módon is használhatjuk. Látványosabb a digitális: az ott bemutatott kacsolással és kóddal indítsuk el, miközben mindenféle hangokat adunk ki.
A hangérzékelőnek valójában egy speciális fajtása a kopogás érzékelő (knock sensor). Ez is része a 37 szenzor készletnek. Rajta található egy fehéres, átlátszó tokba szerelt rugó. Analóg és digitális lábon is kipróbálhatjuk. Teszt: magán az érzékelőn kopogjunk, egyébként eléggé érzéketlen a kopogásra.
Mágneses mező érzékelők
Angolul magnetic field sensors. A 37 szenzor készletben öt is helyet kapott: három fekete és kettő piros. Technológiáját tekintve három Hall érzékelő és kettő reed kapcsoló. A Hall érzékelő egy háromlábú tranzisztorra hasonlít, míg a reed vékony üvegszálat tartalmaz. A két fekete Hall érzékelő közül a két fekete közül az egyik analóg, a másik digitális. Nehéz megkülönböztetni őket; a digitálisnál a mínusz láb fölött is van kettő valami. Az hasonlóan kinéző piros lényegében megegyezik a fekete analóg párjával, az viszont ott egyrészt az érzékenységet be lehet állítani, másrészt van neki digitális kimenete is. A reed kapcsolóknál mágnes hatására szakadásból rövidzár lesz, így bináris eredményt ad.
Teszt:
- A két analóg Hall mágneses érzékelő: az analóg érzékelőknél bemutatott módon kössük rá és töltsük fel a kódot. Közelítsünk mágnest az érzékelőhöz, miközben figyeljük a soros monitort. Mágnes nélkül 500 körüli értéket kell kapnunk, és függően a mágnes polaritásától egy 500-nál lényegesen magasabb vagy lényegesen alacsonyabb értéket kapunk.
- A digitális Hall érzékelő és a két reed relé: a digitális érzékelők kódját töltsük fel megfelelő bekötéssel, és a mágnes közelítésével a 13-as LED-et figyeljük. Itt mindegy a mágnes polaritása.
Pulzus érzékelő
A 37 részes szenzor készletben helyet kapott egy igen érdekes érzékelő: a pulzusmérő. Ez az analóg érzékelő valójában egy IR LED-ből és ez IR érzékelőből áll, és azt méri, hogy mennyi infravörös fényt árnyékol valami. Egy nagyon jó bemutató leírást láthatunk itt: https://www.hackster.io/Johan_Ha/from-ky-039-to-heart-rate-0abfca. A környezeti zajok miatt igen nehéz hasznos információt kinyerni belőle.
Fény akadály érzékelő
A 37 szenzor készlet része. A fekete színű érzékelőjében egy kis rész van, és azt "figyeli", hogy kerül-e oda valami. A digitális teszteknél látott módon kössük be és az ottani kódot használjuk, a kipróbáláshoz pedig helyezzük egy vékony tárgyat (pl. papírlapot) az érzékelőbe.
Színérzékelő
A színérzékelő (angolul color sensor) általában nem része a kezdőszettnek, és a 37 szenzor készletnek sem, kb. 2 dollárért rendelhető. Alább a TCS230 és TCS3200 típust mutatom be. Hasznos oldalak:
- https://www.best-microcontroller-projects.com/tcs230.html (picit elméletibb)
- https://randomnerdtutorials.com/arduino-color-sensor-tcs230-tcs3200/ (picit gyakorlatiasabb; a lenti kód az itteni átalakításával készült)
A színérzékelő nem pont úgy működik, ahogyan azt elképzeljük (tehát odatartjuk valahova, és megmondja, milyen színű), de talán pont emiatt érdekes, különösen oktatásra, kísérletezésre.
Először röviden a működési elvéről: az érzékelő 64, 8x8-as elrendezésű fotodiódát tartalmaz. A fotodióda egy olyan eszköz, ami árammá alakítja a fényt. A 64 érzékelőből 16 piros szűrőt (hullámhossz: 700~635 nm), 16 zöld szűrőt (560~520), 16 kék szűrőt (490-450) tartalmaz, míg 16 nem tartalmaz szűrőt. Az S2 és S3 bemenetekkel (ld. később) tudjuk vezérleni azt, hogy melyik érzékelő adatát szeretnénk beolvasni. Lehetőségek (S2-S3):
- LOW-LOW: piros
- LOW-HIGH: kék
- HIGH-LOW: szűrő nélküli
- HIGH-HIGH: zöld
Az S0 és S1 bemenetekkel (ugyancsak ld. lejjebb) a frekvencia skálázást tudjuk beállítani. Lehetséges értékek (S0-S1):
- LOW-LOW: kikapcsolt
- LOW-HIGH: 2%
- HIGH-LOW: 20%
- HIGH-HIGH: 100%
A leggyakrabban használt érték a 20%, mi is azt fogjuk használni.
Az eszközön 8 láb található, melynek kialakítása az alábbi (állítsuk úgy azt eszközt, hogy fent bal oldalt lássuk a GND feliratot):
- Fent, balról jobbra:
- GND - föld
- OE - kimeneti frekvencia engedélyezése
- S1 - frekvencia skálázás
- S0 - frekvencia skálázás
- Lent, balról jobbra
- VCC - táp
- OUT - kimenet
- S2 - szűrés
- S3 - szűrés
Az eszköz beüzemelése két lépésből áll: először megnézzük, hogy milyen színre milyen értékeket kapunk, majd abból meghatározunk egy algoritmust, ami megpróbálja kitalálni, hogy a látott szín milyen.
Kapcsolás (mindkét esetben):
- Színérzékelő GND - Arduino GND
- Színérzékelő OE - nincs bekötve
- Színérzékelő S1 - Arduino 5
- Színérzékelő S0 - Arduino 4
- Színérzékelő VCC - Arduino 5V
- Színérzékelő OUT - Arduino 8
- Színérzékelő S2 - Arduino 6
- Színérzékelő S3 - Arduino 7
A kalibrációhoz az alábbi kódot használjuk:
#define S0 4 #define S1 5 #define S2 6 #define S3 7 #define sensorPin 8 void setup() { pinMode(S0, OUTPUT); pinMode(S1, OUTPUT); pinMode(S2, OUTPUT); pinMode(S3, OUTPUT); pinMode(sensorPin, INPUT); // Setting frequency scaling to 20% digitalWrite(S0,HIGH); digitalWrite(S1,LOW); Serial.begin(9600); } int redFrequency = 0; int greenFrequency = 0; int blueFrequency = 0; int clearFrequency = 0; void loop() { for (int i = 0; i < 10; i++) { // red digitalWrite(S2, LOW); digitalWrite(S3, LOW); redFrequency = pulseIn(sensorPin, LOW); delay(100); // green digitalWrite(S2, HIGH); digitalWrite(S3, HIGH); greenFrequency = pulseIn(sensorPin, LOW); delay(100); // blue digitalWrite(S2, LOW); digitalWrite(S3, HIGH); blueFrequency = pulseIn(sensorPin, LOW); delay(100); // clear digitalWrite(S2, HIGH); digitalWrite(S3, LOW); clearFrequency = pulseIn(sensorPin, LOW); delay(100); Serial.println("R = " + String(redFrequency) + " G = " + String(greenFrequency) + " B = " + String(blueFrequency) + " C = " + String(clearFrequency)); } Serial.println("*****"); delay(1000); }
Teszt: a kód úgy van elkészítve, hogy tízszer egymás után megméri és kiírja a mért értékeket a soros monitorra, majd egy csillagokból álló sort ír ki és tart egy másodperc szünetet. Indítsuk tehát el a soros monitort, tartsuk oda különböző színekhez, majd a végén másoljuk az eredményt a vágólapra, majd egy szövegszerkesztőbe, további elemzés céljából. Próbáljunk szabályokat alkotni az egyes színekre.
Én egy Rubik-kocka 6 oldalát mértem le közvetlen közelről, éjszaka, mesterséges fény mellett. Az alábbi kód illusztrálja az eredményt, melyet a fenti kapcsolással használjunk:
#define S0 4 #define S1 5 #define S2 6 #define S3 7 #define sensorPin 8 void setup() { pinMode(S0, OUTPUT); pinMode(S1, OUTPUT); pinMode(S2, OUTPUT); pinMode(S3, OUTPUT); pinMode(sensorPin, INPUT); // Setting frequency scaling to 20% digitalWrite(S0,HIGH); digitalWrite(S1,LOW); Serial.begin(9600); } int redFrequency = 0; int greenFrequency = 0; int blueFrequency = 0; void loop() { // red digitalWrite(S2, LOW); digitalWrite(S3, LOW); redFrequency = pulseIn(sensorPin, LOW); delay(100); // green digitalWrite(S2, HIGH); digitalWrite(S3, HIGH); greenFrequency = pulseIn(sensorPin, LOW); delay(100); // blue digitalWrite(S2, LOW); digitalWrite(S3, HIGH); blueFrequency = pulseIn(sensorPin, LOW); delay(100); String colorGuess = ""; if (redFrequency > 110) { if (greenFrequency > 110) { colorGuess = "blue"; } else { colorGuess = "green"; } } else { if (greenFrequency > 130) { colorGuess = "red"; } else if (greenFrequency > 75) { colorGuess = "orange"; } else if (blueFrequency > 50) { colorGuess = "yellow"; } else { colorGuess = "white"; } } Serial.println(colorGuess); delay(1000); }
Jó eséllyel át kell írni a számokat, de lehet, hogy a meghatározás logikáját is. Eredményül a soros monitoron megjelenik a megállapított szín angol neve.
Ebben a projektben tehát egy minimális mesterséges intelligenciát is programoztunk!