{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 9. előadás\n", "*Tartalom:* Raspberry Pi: Python GPIO\n", "\n", "### RaspberryPi: Python GPIO\n", "\n", "\n", "A RaspberryPi (továbbiakban: RPi) egy mikroszámítógép. A tantárgy keretein belül a RPi 3 változatát fogjuk tárgyalni. Ennek is két fajtája a létezik, a RPi 3B (régebbi) és a RPi 3B+ (újabb). Az előadás szempontjától nem teszünk lényeges különbséget a kettő között. \n", "\n", "A két modell bemutató videója az alábbi linkeken található: \n", "[RPi 3B](https://www.youtube.com/watch?v=uXUjwk2-qx4) és\n", "[RPi 3B+](https://www.youtube.com/watch?v=i62xdD4QKtA)\n", "\n", "#### A RPi 3B specifikációja\n", "\n", "- Quad Core 1.2GHz BCM2837 CPU - 64bit\n", "- 1GB SDRAM\n", "- BCM43143 WiFi & Bluetooth Low Energy\n", "- Wi-fi (802.11 b/g/n, 2,4 GHz)\n", "- Bluetooth 4.1 Classic, Bluetooth Low Energy\n", "- 40pin-es kiterjesztett GPIO\n", "- 4 x USB 2.0 port\n", "- 4 pólusú jack a sztereó hang és kompozit videó kimenethez\n", "- HDMI kimenet\n", "- CSI kamera port csatlakozó a Raspberry Pi kamera részére\n", "- DSI Display Port csatlakozó érintőképernyőhöz\n", "- Micro SD kártya csatlakozó az operációs rendszer betöltéséhez és az adatok tárolására\n", "- Javasolt tápegység minimum 1.2A 5V, de maximum 2.5A 5.1V\n", "- Micro USB-s tápcsatlakozás maximum 2.5A 5.1V - nagyobb átfolyó áramtól a csatlakozók, illetve a nyomtatott áramköri hutalozás maradandóan károsodhat, ezért több, vagy nagyobb fogyasztású külső eszköznek érdemes direkt tápellátást biztosítani!\n", "- Mechanikai kompatibilitás a B+ és Pi 2 verziókkal\n", "\n", "#### A RPi 3B+ specifikációja\n", "\n", "- CPU: Broadcom BCM2837B0, Cortex-A53 64-bit SoC @ 1.4GHz - 10%-al gyorsabb a sima Pi 3-nál, meglátjuk majd, hogy mire elég.\n", "- Memória: 1GB LPDDR2 SDRAM - ez változatlan\n", "- Wifi: IEEE 802.11 b/g/n/ac szabványú kétsávos rendszer (2.4 GHz és 5GHz) - ez egy ütős változás!\n", "- LAN: Gigabit Ethernet (Microchip LAN7515), ami jelen esetben max. 300Mbps - ez háromszorosa a korábbi verziókénak, végre!!!\n", "- USB: 4x USB 2.0 - sokan várnák az USB 3-as csatlakozást, de az indokolatlanul drágítaná az eszközt.\n", "- GPIO: a Pi 1 B+ óta megszokott 40-pin, hála a tervezőknek.\n", "- Videó és hang (ez sem módosult):\n", " - HDMI kimenet\n", " - MIPI DSI display port\n", " - MIPI CSI kamera port\n", " - 4 pólusú 3.5mm-es jack aljzaton sztereó hang és kompozit videó kimenet\n", "- Multimédia képességek: H.264, MPEG-4 dekóder (1080p30); H.264 enkóder (1080p30); OpenGL ES 1.1, 2.0 grafikus gyorsítás\n", "- SD kártya támogatás: Micro SD támogatás az operációs rendszer futtatásához és adattároláshoz\n", "- Tápellátási lehetőségek:\n", " - 5Vdc/2.5A (max.) micro USB csatlakozón keresztül\n", " - 5Vdc GPIO tüskéken át\n", " - PoE (Power over Ethernet) lehetőség megfelelő HAT alkalmazásával\n", "- Működési hőmérséklet tartomány: 0-50°C között\n", "\n", "\n", "#### Operációs rendszer\n", "\n", "Alapvetően a kezdők számára javasolt és megvásárolható egy előre telepített SD kártya, amely tartalmaz egy ún. NOOBS (New Out Of Box System) rendszert. Ez egy telepítő-menedzser, amely könnyebbé teszi az operációs rendszer telepítését. A haladó felhasználók letölthetik a NOOBS-ot [INNEN](https://www.raspberrypi.org/downloads/) és telepíthetik azt egy üres SD kártyára. Erről részletesebb leírás [ITT](https://www.raspberrypi.org/documentation/installation/noobs.md) és [ITT](https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up) található. \n", "\n", "A NOOBS tartalmazza az alábbi operációs rendszerek telepítését: \n", "- Raspbian\n", "- LibreELEC\n", "- OSMC\n", "- Recalbox\n", "- Lakka\n", "- RISC OS\n", "- Screenly OSE\n", "- Windows 10 IoT Core\n", "- TLXOS\n", "\n", "Bár alapvetően a NOOBS csak a Raspbian és LibreELEC rendszerek telepítőcsomagját tartalmazza, a többi rendszer választásakor rendelkeznünk kell internet kapcsolattal, ahonnan letöltődik a kívánt csomag.\n", "\n", "A RPi optimális működéshez Raspbian rendszer javasolt, amely egy Debian-alapú Linux. Sajnos a RPi 3B+ nem támogatja az Ubuntu kernelt, így az Ubuntu MATE és Ubuntu Core rendszerek csak a sima RPi 3 és RPi 2 változatokon használhatók.\n", "\n", "\n", "#### Bootolási módok\n", "\n", "A RPi számos bootolási lehetőséget nyújt:\n", "- Bootflow: Boot sequence description; részletesebben [ITT](https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/bootflow.md) \n", "- SD card: SD card boot description; korábban szó volt róla\n", "- USB: USB boot description\n", " - Device boot: Booting as a mass storage device; részletesebben [ITT](https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/device.md)\n", " - Host boot: Booting as a USB host; részletesebben [ITT](https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/host.md)\n", " - Mass storage boot: Boot from Mass Storage Device (MSD); részletesebben [ITT](https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/msd.md)\n", " - Network boot: Boot from ethernet; részletesebben [ITT](https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/net.md)\n", " \n", "A régebbi RPi változatoknál, valamint azokban az esetekben amikor a RPi 3 bootolása valami miatt meghiúsul, újfajta bootolási módszereket vezettek be, ezek az MSD és az Ethernet. Ehhez nem kell mást tenni, mint FAT32 formátumra formázni az SD kártyát és rámásolni a legfrisebb [bootcode.bin](https://github.com/raspberrypi/firmware/raw/master/boot/bootcode.bin) fájlt. Ez bekapcsolja az új boot módokat, valamint bug fixeket tartalmaz a bootolási meghiúsulások kiküszöbölésére. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Python GPIO\n", "\n", "A GPIO (General Purpose Input Output) egy általános felhasználású port, ahogy a neve is sugallja, mellyel különféle kimeneti és bemeneti jeleket tudunk manipulálni. A RPi GPIO lábkiosztása az alábbi képen látható:\n", "\n", "\n", "\n", "\n", "\n", "Látható, hogy csak a zölddel jelölt lábak használhatók teljes mértékben GPIO-ként, a sárgával jelölt lábak csak bizonyos feltétel mellett, és a pirosak egyáltalán nem. Ez utóbbiak főként tápegység kimenetként működnek, melyek értéke általában 3.3V és 5V. Ezeken kívűl a feketével jelölt lábak földellésként viselkednek, jelölésük a GND (Ground).\n", "\n", "Ahhoz, hogy használhassuk a RPi GPIO portját, fel kell telepíteni a hozzá tartozó csomagot, melyet az alábbi parancssori parancsok futtatásával tehetünk meg:\n", "\n", "`sudo apt-get update`\n", "\n", "`sudo apt-get upgrade`\n", "\n", "`sudo apt-get install rpi.gpio` vagy haladóknak `sudo pip install RPi.GPIO`\n", "\n", "Ezután ahhoz, hogy használni tudjuk a GPIO-t, importálni kell a megfelelő python könyvtárat a kódunkba:\n", "\n", "`import RPi.GPIO as GPIO`\n", "\n", "Ezt követően inicializálnunk kell a GPIO-t:\n", "\n", "`GPIO.setmode(GPIO.BOARD)` vagy `GPIO.setmode(GPIO.BCM)`\n", "\n", "Mi a különbség a kettő között?\n", "1. A GPIO.BOARD arra utal, hogy a lábakat a panelen levő sorszámozás alapján fogjuk használni. Ez a sorszámozás úgy néz ki, hogy a bal felső láb az 1-es, a mellette levő a 2-es, alattal evő sorban a 3-4-es, és így tovább lefele haladva. Ld.:\n", " 1 2\n", " 3 4\n", " 5 6\n", " . .\n", " . .\n", " . .\n", " 39 40\n", "2. A GPIO.BCM pedig arra utal, hogy a Broadcom SOC channel által elnevezett nevekkel fogunk hivatkozni az egyes lábakra. Ezek azok a nevek, amelyek a fenti képen is szereplnek. Pl. GPIO4, GPIO5, stb.\n", "\n", "Mostmár készen állunk a GPIO lábak használatára, akár kimenetként vagy bemenetként, akár valamilyen logikai értékként, stb. Nézzünk néhány konkrét példát:\n", "\n", "`GPIO.setup(12, GPIO.OUT)` # ez a parancs a 12-es lábat állítja be kimenetként a setup() metódus segítségével\n", "\n", "`GPIO.output(12, GPIO.HIGH)` # ezzel a 12-es lábat logikai magas szintre állítjuk, ami 3,3V\n", "\n", "`GPIO.output(12, GPIO.LOW)` # ezzel viszont logikai alacsony szintre állítjuk, ami 0V\n", "\n", "\n", "Ahhoz, hogy akármilyen szerzort vagy aktuátort vezéreljünk, szükségünk lesz egy ún. \"breadboard\"-ra. Egy ilyen kellék és a kötési módja az alábbi képen látható:\n", "\n", "\n", "\n", "A középen levő két oszlop lyukai vízszintes irányban képeznek kapcsolatot, míg a szélén levő két vonalban helyezkedő lyukak hosszanti irányba képeznek kapcsolatot, ahogyan be is vannak keretezve.\n", "\n", "Nézzünk egy egyszerű LED villogtató példát:\n", "\n", "A LED egy kétutas félvezető, amely a rákapcsolt feszültség hatására fényt bocsát ki. Mivel a nevében is szerepel, hogy ez egy dióda, ezért csak egy irányba folyik rajta áram. Figyelni kell tehát a kötésmódra. \n", "\n", "\n", "\n", "Az anódra kerül a pozitív feszültség (3,3V), míg a katódra a földelés (GND). A lábakat úgy tudjuk általában megkülönböztetni, hogy az anód a hosszabb. Továbbá, mivel a GPIO lábak által szolgáltatott 3,3V túl magas a LED-nek, ezért egy ellenállással csökkentjük a LED-re eső feszültséget. A LED-nek 2,1V feszültségre és kb. 20mA áramra van szüksége a működéshez. A GPIO lábak azonban 3,3V feszültséget és csak 16mA áramot szolgáltanak. Nézzük hát a képletet, amivel kiszámolhatjuk a szükséges ellenállás méretét:\n", "\n", "\\begin{equation*}\n", "R = \\frac{U}{I} = \\frac{3.3V-2.1V}{16mA} = \\frac{1.2V}{0.016A} = 75\\Omega\n", "\\end{equation*}\n", "\n", "Mivel a piaci forgalomban a 75Ω-os ellenállás speciális értékűnek minősül, és általában drágábbak, vagy csak nagyobb tételben vásárolható, ezért számunkra tökéletesen megfelel a sima 82Ω-os, elektronikai szaküzletekben kapható ellenállás.\n", "\n", "Miután tehát összekötöttük az áramkört az alábbi képen látható módon, megírhatjuk hozzá a vezérlő Python kódot.\n", "\n", "\n", "\n", "```\n", "import RPi.GPIO as GPIO\n", "import time\n", "\n", "GPIO.setmode(GPIO.BOARD)\n", "GPIO.setup(12, GPIO.OUT)\n", "\n", "GPIO.output(12, GPIO.HIGH)\n", "time.sleep(3)\n", "\n", "GPIO.output(12, GPIO.LOW)\n", "GPIO.cleanup()\n", "```\n", "\n", "A gyakorlatban, amikor már nem használjuk tovább a GPIO lábakat, resetelni szoktuk azokat a `cleanup()` metódussal. \n", "\n", "##### Olvasás a bemenetről\n", "\n", "Hasonlóan, ahogy kimenetként definiáltuk az előbb a GPIO lábat, bemenetként is definiálhatjuk azt:\n", "\n", "`GPIO.setup(11, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)`\n", "\n", "Látjuk, hogy egy teljesen új `pull_up_down` argumentum került bevezetésre, ezt kicsit lentebb magyarázzuk. Az bemenetről való olvasáshoz az `input()` metódust használjuk, és ez a `GPIO.HIGH` vagy `GPIO.LOW` értékeket adja vissza számunkra, attól függően, hogy a bemenetünk aktív, vagy sem.\n", "\n", "`GPIO.input(11)`\n", "\n", "Térjünk kicsit vissza a korábban bevezett `pull_up_down` argumentumra. Ennek értékeit az alábbi táblázat magyarázza: \n", "\n", "| Érték | +3.3V | <+3.3V | 0V |\n", "| :----- | :-----: | :-----: | :-----: |\n", "| `GPIO.PUD_DOWN` | Aktív | Inaktív | Inaktív |\n", "| `GPIO.PUD_UP` | Inaktív | Aktív | Aktív |\n", "\n", "Nézzünk erre is egy példát, az előző feladatot egy nyomógobbal kiegészítve. Akkor fog tehát a LED világítani, ha megnyomjuk a nyomógombot. Nézzük, hogyan fog kinézni ennek a kötési rajza:\n", "\n", "\n", "\n", "```\n", "import RPi.GPIO as GPIO\n", "\n", "GPIO.setmode(GPIO.BOARD)\n", "\n", "GPIO.setup(12, GPIO.OUT)\n", "GPIO.setup(11, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)\n", "GPIO.output(12, GPIO.LOW)\n", "\n", "try:\n", " while True:\n", " GPIO.output(12, GPIO.input(11))\n", "except KeyboardInterrupt:\n", " GPIO.cleanup()\n", "```\n", "\n", "Látható a kódból, hogy a 12-es lábra kötött LED akkor lesz `GPIO.HIGH` értéken, amikor a `GPIO.input(11)` aktívvá válik, vagyis lenyomtuk a nyomógombot.\n", "\n", "#### Házi feladat\n", "\n", "Fejlesszék tovább a legelső LED-es feladatot, hogy a LED egyfolytában villogjon 1 mp-s szünetekkel.\n", "\n", "\n", "## A Sense Hat\n", "\n", "A Sense Hat egy olyan bővítő modul a RPi-hez, amely különféle szenzorokat, LED-mátrixot és joysticket is tartalmaz. Lássuk milyen szenzorkészlettel rendelkezik:\n", "- hőmérséklet\n", "- páratartalom\n", "- nyomás\n", "- orientáció\n", "\n", "Ahhoz, hogy kapcsolatunk legyen a Sense Hat-el, be kell illesztenünk a megfelelő könytárat a Python kódunkba. Ez az alábbi sorokkal történik:\n", "\n", "`from sense_hat import SenseHat`\n", "`sense = SenseHat()`\n", "\n", "### Szöveg megjelenítése a LED kijelzőn\n", "\n", "Ahhoz, hogy valamilyen szöveget - legyen az egy karakter, vagy sztring - megjelenítsünk a LED-es kijelzőn, használhatjuk a `show_message(\"Hello World\")` vagy `show_letter(\"A\")` függvényeket.\n", "Különféle megjelenítési tulajdonságokat is hozzá adhatunk a kiíró metódushoz, melyeket paramétereknek nevezünk:\n", "- scroll_speed: azt mondja meg, milyen gyorsan haladjon át a szöveg a kijelzőn. Default: 0.1\n", "- text_colour: a szöveg színét definiálja, három szín értékkel: RGB.\n", "- back_colour: ugyanúgy definiálandó, mint a text_colour, de ez a háttér színét határozza meg.\n", "\n", "\n", "#### Szöveg megjelenítése a LED kijelzőn\n", "\n", "Nézzük meg konkrét példán keresztül. Írassuk ki a \"Hello World!\" szöveget ciklikusan, piros színnel, kék háttéren, és 0.05 átfutási sebességgel.\n", "\n", "```\n", "from sense_hat import SenseHat\n", "sense = SenseHat()\n", "\n", "blue = (0, 0, 255)\n", "red = (255, 0, 0)\n", "\n", "while True:\n", " sense.show_message(\"Hello World!\", text_colour=red, back_colour=blue, scroll_speed=0.05)\n", "```\n", "\n", "#### Egy darab karakter megjelenítése a LED kijelzőn\n", "\n", "Nézzük meg ezt is példán keresztül. Írassuk ki a Széchenyi Egyetem kezdőbetűit, azaz a SZE betűket, ahol \"S\" sárga, \"Z\" fehér, \"E\" kék, a háttér cián, és a betűk megjelenítési közötti szünet 2 mp. Ehhez szükségünk lesz a `time` könyvtár `sleep()` függvényére is. A végén pedig a `clear()` metódussal töröljük a képernyőt.\n", "\n", "```\n", "from sense_hat import SenseHat\n", "from time import sleep\n", "\n", "sense = SenseHat()\n", "\n", "cyan = (0, 255, 255)\n", "blue = (0, 0, 255)\n", "white = (255, 255, 255)\n", "yellow = (255, 255, 0)\n", "\n", "sense.show_letter(\"S\", yellow, back_colour=cyan)\n", "sleep(2)\n", "sense.show_letter(\"Z\", white, back_colour=cyan)\n", "sleep(2)\n", "sense.show_letter(\"E\", blue, back_colour=cyan)\n", "sleep(2)\n", "sense.clear()\n", "```\n", "\n", "Következőnek generáljunk random színeket és így írassuk ki a \"SZE\" betűket. Ehhez létrehozunk egy függvényt, valamint szükségünk lesz a `randint()` metódusra is.\n", "\n", "```\n", "from sense_hat import SenseHat\n", "from time import sleep\n", "from random import randint\n", "\n", "sense = SenseHat()\n", "\n", "def pick_random_colour():\n", " random_red = randint(0, 255)\n", " random_green = randint(0, 255)\n", " random_blue = randint(0, 255)\n", " return (random_red, random_green, random_blue)\n", "\n", "sense.show_letter(\"S\", pick_random_colour())\n", "sleep(2)\n", "sense.show_letter(\"Z\", pick_random_colour())\n", "sleep(2)\n", "sense.show_letter(\"E\", pick_random_colour())\n", "sleep(2)\n", "\n", "sense.clear()\n", "```\n", "\n", "### Kép megjelenítése a LED kijelzőn\n", "\n", "Lehetőség van a kijelzőn képeket is megjeleníteni. Ennek a legprimitívebb változata, amikor egyszínűre fessük a teljes LED mátrixot:\n", "\n", "`sense.clear((r, g, b))`\n", "\n", "Továbbá, lehetőségünk van az egyes pixeleket (LEDeket) is befesteni. Minden pixelnek megvan a saját {x,y} koordinátája, amely a bal felső sarokból kezdődik {0,0}-val. Az indexelés az alábbi képen látható:\n", "\n", "\n", "\n", "A pixelek színeit a `set_pixel(x, y, colour)` metódussal tudjuk. Nézzünk erre is egy egyszerű kis példát:\n", "\n", "```\n", "from sense_hat import SenseHat\n", "sense = SenseHat()\n", "\n", "blue = (0, 0, 255)\n", "red = (255, 0, 0)\n", "\n", "sense.set_pixel(0, 2, blue)\n", "sense.set_pixel(7, 4, red)\n", "```\n", "\n", "Egyszerre több pixelt is kezelhetünk a `set_pixels` paranccsal, amennyiben egy tömbbe tároljuk el az egyes pixelek értékeit. Nézzük, hogyan:\n", "\n", "```\n", "g = (0, 255, 0) # Green\n", "b = (0, 0, 0) # Black\n", "\n", "pixels = [\n", " g, g, g, g, g, g, g, g,\n", " g, g, g, g, g, g, g, g,\n", " g, b, b, g, g, b, b, g,\n", " g, b, b, g, g, b, b, g,\n", " g, g, g, b, b, g, g, g,\n", " g, g, b, b, b, b, g, g,\n", " g, g, b, b, b, b, g, g,\n", " g, g, b, g, g, b, g, g\n", "]\n", "\n", "sense.set_pixels(pixels)\n", "```\n", "\n", "### Az érzékelők használata\n", "\n", "A nyomásérzékelőt a `sense.get_pressure()` metódussal tudjuk lekérdezni.\n", "\n", "```\n", "from sense_hat import SenseHat\n", "\n", "sense = SenseHat()\n", "sense.clear()\n", "\n", "pressure = sense.get_pressure()\n", "print(pressure)\n", "```\n", "Output: 1012.97997042\n", "\n", "__________________________________________________________________\n", "\n", "A páratartalmat a `get_humidity()` metódussal tudjuk lekérdezni.\n", "\n", "```\n", "from sense_hat import SenseHat\n", "\n", "sense = SenseHat()\n", "sense.clear()\n", "\n", "humidity = sense.get_humidity()\n", "print(humidity)\n", "```\n", "\n", "Output: 45.2721951219\n", "\n", "__________________________________________________________________\n", "\n", "A hőmérsékletet alapesetben a `get_temperature()` metódussal kérdezzük le.\n", "\n", "```\n", "from sense_hat import SenseHat\n", "\n", "sense = SenseHat()\n", "sense.clear()\n", "\n", "temp = sense.get_temperature()\n", "print(temp)\n", "```\n", "Output: 19.9493634245\n", "\n", "Itt viszont vigyázni kell a RPi processzor melegedéséből fakadó hibára. Mivel a processzor felmelegíti a szenzorokat is, főleg ha dobozban helyezkednek, ezért kalibrációt kell végezni a pontos hőmérséklet mérés érdekében.\n", "\n", "Ennek a képlete az alábbi:\n", "\n", "\\begin{equation*}\n", "T_{kalibrált} = T_{mért} - \\frac{T_{cpu} - T_{mért}}{Koefficiens}\n", "\\end{equation*}\n", "\n", "ahol a Koefficienst külső mérésekre alapozva kell meghatározni úgy, hogy a kalibrált érték a legközelebb álljon a környezet valós hőmérsékletéhez.\n", "\n", "\n", "### Orientáció meghatározása\n", "\n", "A mozgások meghatározására a Sense Hat rendelkezik egy ún. IMU-val (Innertial Measurement Unit), vagyis innerciális mérés-egységgel. Az ilyen egységek általában háromféle szenzorból állnak:\n", "- gyorsulásmérő (gyorsulási erőt érzékel)\n", "- giroszkóp (tájolást érzékel)\n", "- magnetométer (a Föld mágneses terét érzékeli)\n", "\n", "Amikor meghívjuk a `get_orientation()` metódust, ez három adatot szolgáltat számunkra:\n", "- pitch: dőlés\n", "- roll: perdülés\n", "- yaw: irányváltoztatás\n", "\n", "A szemléltetés kedvéért az alábbi képen látható a három mozgás tengelye.\n", "\n", "\n", "\n", "Nézzük meg egy példán keresztül, milyen adatokat kapunk.\n", "\n", "```\n", "from sense_hat import SenseHat\n", "sense = SenseHat()\n", "sense.clear()\n", "\n", "o = sense.get_orientation()\n", "pitch = o[\"pitch\"]\n", "roll = o[\"roll\"]\n", "yaw = o[\"yaw\"]\n", "print(\"pitch {0} roll {1} yaw {2}\".format(pitch, roll, yaw))\n", "```\n", "\n", "Output: pitch 356.35723002363454 roll 303.4986602798494 yaw 339.19880231669873\n", "\n", "_________________________________________________________________________________\n", "\n", "A `get_accelerometer_raw()` metódus segítségével nyers adatokat kaphatunk a gravitációs erőnk hatásáról az egyes tengelyekre (x, y, z) nézve. Ha pl. bármelyik tengelyen a gravitációs erőnk ±1G, akkor tudjuk, hogy ez a tengely lefelé mutat. A következő példában az összes tengelyre nézve lekérdezzük a gravitációs gyorsulást, majd a legközelebbi egész számra kerekítjük.\n", "\n", "\n", "```\n", "from sense_hat import SenseHat\n", "\n", "sense = SenseHat()\n", "\n", "while True:\n", "\tacceleration = sense.get_accelerometer_raw()\n", "\tx = acceleration['x']\n", "\ty = acceleration['y']\n", "\tz = acceleration['z']\n", "\n", "\tx=round(x, 0)\n", "\ty=round(y, 0)\n", "\tz=round(z, 0)\n", "\n", "\tprint(\"x={0}, y={1}, z={2}\".format(x, y, z))\n", "```\n", "Vízszintes tengelyen elforgatva a Sense Hatet, azt látjuk, hogy a \"x\" és \"y\" tengelyek értékei {-1, 1} között változnak. Ha pedig függőleges irányban forgatjuk el egy π (180°) értékkel, akkor a \"z\" tengely értéke fog {1, -1} között változni.\n", "\n", "\n", "### A joystick használata\n", "\n", "Öt féle irányba használhatjuk a Sense Hat joystickjét, lefele (lenyomni), előre, hátra, jobbra, balra. Ezen felül érzékelhetjük a lenyomást, a lenyomva tartást és a felengedést is. A következő példában írassuk ki a joystick éppen aktuális állapotát.\n", "\n", "```\n", "from sense_hat import SenseHat\n", " sense = SenseHat()\n", "\n", "\n", " while True:\n", " for event in sense.stick.get_events():\n", " print(event.direction, event.action)\n", "```\n", "\n", "Erre a joystick mozgatása közben valami hasonlót kell kapnunk:\n", "\n", "('up', 'pressed')\n", "('up', 'released')\n", "('down', 'pressed')\n", "('down', 'released')\n", "('left', 'pressed')\n", "('left', 'released')\n", "('right', 'pressed')\n", "('right', 'released')\n", "('middle', 'pressed')\n", "('middle', 'released')\n", "\n", "____________________________________________________________________________\n", "\n", "Készítsünk egy olyan programot, amely a megnyomott irányoktól függően kiírja a LED mátrixra a megfelelő irány kezdőbetűjét. \n", "\n", "```\n", "from sense_hat import SenseHat\n", "from time import sleep\n", "sense = SenseHat()\n", "\n", "while True:\n", " for event in sense.stick.get_events():\n", " if event.action == \"pressed\":\n", " \n", " if event.direction == \"up\":\n", " sense.show_letter(\"F\") # Fel\n", " elif event.direction == \"down\":\n", " sense.show_letter(\"L\") # Le\n", " elif event.direction == \"left\": \n", " sense.show_letter(\"B\") # Bal\n", " elif event.direction == \"right\":\n", " sense.show_letter(\"J\") # Jobb\n", " elif event.direction == \"middle\":\n", " sense.show_letter(\"K\") # Közép\n", "\n", " sleep(0.5)\n", " sense.clear()\n", "```\n", "\n", "______________________________________________________________________________________________________\n", "\n", "## _Used sources_ / Felhasznált források\n", "- [Shannon Turner: Python lessons repository](https://github.com/shannonturner/python-lessons) MIT license (c) Shannon Turner 2013-2014\n", "- [Siki Zoltán: Python mogyoróhéjban](http://www.agt.bme.hu/gis/python/python_oktato.pdf) GNU FDL license (c) Siki Zoltán\n", "- [BME AUT](https://github.com/bmeaut) MIT License Copyright (c) BME AUT 2016-2018\n", "- [Python Programming](https://pythonprogramming.net) (c) OVER 9000! PythonProgramming.net\n", "- [Raspberry Pi Foundation](https://github.com/RPi-Distro/python-sense-hat) Copyright 2015- Raspberry Pi Foundation" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }