Arduino bemenetek

Kategória: Arduino.

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:

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

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:

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!

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License