Arduino bevezető

Kategória: Arduino.

Szükséges eszközök

A lenti projektek elkészítéséhez a következőket kell megvenni:

  • Arduino kezdőkészlet (keresőkulcs: Arduino Starter Kit). Egy jól felszerelt készlet ára kb. 20$. Fontos, hogy tartalmazza az alábbiakat:
    • Arduino UNO lapka (lehet igazából másfajta is, viszont bizonyos példák más esetekben másképp működhetnek).
    • USB kábel.
    • Kábelek (keresőkulcs: Arduino jumper): valójában szükség van apa-apa, apa-anya és anya-anya kombinációra is. (A tapasztalatom szerint érdemes plusz kábeleket is venni, mivel az alapkészlet hiányos lehet. A Geekcreit-nek van olyan csomagja, mely tartalmaz mindhárom típusból 40 darabot; azt javaslom pluszban megvásárlásra, melynek ára kb. 4$.)
    • Próbapanel (breadboard).
    • Alap elektronikai eszközök: LED-ek, ellenállások.
    • Változtatható ellenállás (potentiometer).
    • Nyomógombok.
    • Kijelzők: 7 szegmenses, 4 karakteres, 8x8-as mátrix.
    • LCD kijelző. (Előfordulhat, hogy egy olcsóbb készletben ez nincs benne, ez esetben külön meg kell rendelni. Kereső kifejezés: LED 1602 with I2C. Fontos, hogy legyen rajta I2C adapter.)
    • Távirányító + infravörös érzékelő.
    • 74HC595 számú IC.
    • Berregő (buzzer).
    • Értékelők: fotoellenállás (photoresistor), hőmérséklet érzékelő, láng érzékelő, … (Az érzékelőkről később lesz részletesen szó. Még a legegyszerűbb kezdőcsomagban is van pár alapérzékelő, mellyel ki lehet próbálni, működik-e. Programozás szempontjából az érzékelők többsége hasonlóan működik.)
    • Motorok: szervó motor, léptető motor.
  • Érzékelő csomag: a leggazdaságosabb csomag keresőkifejezése ez: 37 in 1 sensor kit for Arduino. Ahogy a neve is sugallja, ez 37 eszközt, nagyrészt érzékelőt tartalmaz, és ár/érték arányban igen gazdaságos, mindössze 10$ körüli az ára. (Egy eszköz átlagára postaköltséggel kevesebb mint 100 Ft; összehasonlításul a hasonló LEGO érzékelők ára több tízezer forint darabja.) Bizonyos hasznos érzékelők még ebben sincsenek benne, azokat külön tudjuk megvásárolni; az adott érzékelőknél jelezve vannak, hogy ez része-e az érzékelő csomagnak vagy sem. Az érzékelő csomag 37 eleméből valójában 10 kimenet, így az érzékelők száma 27. A tartalma az alábbi (amiből az is látható, hogy nagyjából fele jelent valódi értéket, de szerintem még így is bőven megéri).
    • Többszínű LED-ek: van 3 darab RGB (ebből egy 7 színű villogó) és 2 darab kétszínű LED. (Egy érdekes, a többi felesleges.)
    • Lézer: vezérlése a LED-éhez hasonló. Érdekes, de oktatási szempontból nincs neki jelentősége.
    • Berregők: van egy passzív és egy aktív berregő. Az aktív berregő inkább csak idegesítő, a passzív berregő viszont többnyire része az alapkészletnek, és ennek különösebb hozzáadott értéke nincs.
    • Relé: előfordulhat, hogy az alapkészlet nem tartalmaz, ugyanakkor ez egy fontos elem.
    • Nyomógomb: az alapkészletek mindig része, így itt felesleges.
    • Joystick: ha az alapkészletnek nem része, akkor hasznos.
    • Elhajlás érzékelő: kb. úgy működik mint a potenciométer, és mivel az tipikusan része az alapkészletnek, itt ennek túl nagy jelentősége nincs (egyébként van belőle 3).
    • Fotoellenállás: hasznos, de az alapcsomagnak ugyancsak tipikusan része.
    • Hőmérséklet érzékelők: 4 ilyen van, melyek közül egy is elég lenne, mégpedig a DHT11 jelű hőmérséklet- és páratartalom érzékelő.
    • Mágnes érzékelők: 5 darab van a csomagban, melyből 3 Hall és 2 reed érzékelő; más felosztásban két analóg (melynél számít a polaritás is) és három digitális (vagy van mágnes vagy nincs). Mondjuk egy digitális reed szenzor és egy analóg Hall szenzor elég lenne, a többi felesleges.
    • Hang érzékelők: van kettő belőle; igazából egy is elég lenne.
    • Kopogás érzékelő: érdekes, kicsit nehézkesen működik, de egynek elmegy.
    • Rázkódás érzékelő: szintén.
    • Érintés érzékelő: ez is.
    • Akadály érzékelő: ez is.
    • Fény akadály érzékelő: ez is.
    • Szívritmus érzékelő: érdekes, bár elsőre többet gondolnánk bele, mint amennyit ténylegesen tud. Ugyanakkor egy kiválóan felépített anyag áll rendelkezésre, nagyon hazsnos tudnivalókkal.
    • Nyomkövető érzékelő: érdekes, bár egynek önmagában nincs túl nagy jelentősége.
    • Lángérzékelő: érdekes, bár az alapkészleteknek is része lehet.
    • IR kapcsolat: ez két érzékelőként szerepel a felsorolásban, melyek közül az egyik az adó (tehát nem is érzékelő), a másik a vevő. Egyébként nagyon hazsnos páros.

Amiket érdemes megvenni:

  • Külső áramforrás: nem kötelező tartozék, de ajánlott, hogy azzal is ki tudjuk próbálni. Az alapkészlet is tipikusan szokott tartalmazni olyat, melyre vagy egy 9V-os elemet tudunk kapcsolni, vagy 4 darab 1,5 Voltos ceruzaelemet, viszont ha van rá módunk, keressünk a háztartásban (jó eséllyel van), vagy vásároljunk megfelelő áram átalakítót. Kereső kifejezés: power supply. Ügyeljünk arra, hogy Magyarországon használható dugasz legyen rajta, és a leadott egyenfeszültség 7-12 Volt között legyen. Vehetünk változtatható ellenállású átalakítót is. Az ára 5$ körül kezdődik.
  • Bővítőlap (keresőkifejezés: shield for Arduino): ennek segítségével kényelmesebben elférünk, kapunk sok extra 5V és GND kimenetet. Az ára 2,5-3$ körüli.
  • Bővített áramellátó lap (MB102): nem kötelező, de számos esetben hasznos lehet. Az Arduino-n maximálva van az, hogy mennyi áramot tud leadni összesen, és előfordulhat, hogy ha túl sok eszközt szeretnénk rácsatlakoztatni, akkor a nagyobb fogyasztóknak külön áramellátást biztosítunk. Az is előfordult már, hogy egyszerűen szükség volt pár tűre, mely földet, 3,3 Voltot és 5 Voltot biztosított, és ez jól jött. Az ára 1$ körüli.
  • TM1638 bővített 7 szegmenses kijelző nyomógombok és LED-ek: jelentősen megkönnyíti a bevitelt és kimenetelt a hagyományos eszközökhöz képest.
  • ESP8266-01, lehetőleg programozóval. Önmagában a wifi-n keresztül történő internet kapcsolódáshoz szükséges, a programozó viszont új világot nyit számunkra.

Ez idáig kb. 40$.

Ami jó, ha van, de nem szükséges:

  • Forrasztópáka: alapból nem kell forrasztani, viszont jó ha van, mert a gyakorlatban már több esetben előfordult.
  • Extra tűkészlet (pin header strip): bizonyos eszközök úgy érkeznek, hogy nem tudjuk rákötni a kábelt, mert csak a lyukak vannak kifúrva, emiatt hasznos, ha van egy ilyen tűkészlet. Ára bő 1$ egy olyan készletnek, amely hosszú ideig megteszi.
  • Elektromos multiméter (electronic multimeter): legalább feszültséget, áramerősséget, ellenállást tudunk mérni a segítségével. Hibakereséshez jól jöhet.
  • Oszcilloszkóp: ez már nagyon "nice to have" téma, de ha valaki el szeretne mélyedni hosszabb távon is a témában, annak hasznos lehet. Nemrégiben megjelent a piacon egy egycsatornás digitális egyszerű oszcilloszkóp, melynek ára összeszerelve kb. 15$; azt szerintem érdemes megvenni. (És ha már oszcilloszkóp: jelgenerátor, hogy teljes legyen a kép, de ennek már nincs közvetlen köze az Arduino fejlesztéshez.)
  • USB-soros: ezt az adaptert az USB-be kell dugni, és lehetővé teszi, hogy a 6 USB lábat (GND, 3V3, 5V, TX, RX, RST) elérjük vele. A CH340 típusú USB to TTL UART átalakító egy dollár alatti összegért beszerezhető.

Arduino-s helló világ: villogó LED

Az Arduino fejlesztéshez szükségünk van fejlesztő környezetre. Ezt alapvetően kétféle módon tudjuk használni:

Ebben a leírásban az offline szerkesztőt fogjuk használni.

A fejlesztői felületen készítsük el ezt a kódot:

int led = 13;
 
void setup() {
  pinMode(led, OUTPUT);
}
 
void loop() {
  digitalWrite(led, HIGH);
  delay(1000);
  digitalWrite(led, LOW);
  delay(1000);
}

Mentsük el. Az Arduino programok kiterjesztése .ino, és a fájlnévnek meg kell egyeznie a könyvtárnévvel. Válasszunk egy alkalmas könyvtárat, a forrás neve pedig legyen mondjuk blink.ino, ami automatikusan a blink könyvtárba kerül.

A kód magyarázata:

  • Minden Arduino kódnak tartalmaznia kell a paraméter és visszatérési érték nélküli setup() és loop() függvényt. Az előbbi egyszer fut le induláskor, az utóbbi folyamatosan.
  • Az Arduino UNO lapkán található többek között számos láb (angolul pin), ami lehet kimeneti és bemeneti egyaránt. Az Arduino kód legvégső soron nem csinál mást, csak ezeket olvassa, ill. írja. A 13-as láb mellett található egy kis LED; az valójában össze van belül kötve a 13-as lábbal.
  • Az Arduino kód valójában (valamelyest egyszerűsített) C++. Implicit módon tartalmazza az Arduino.h beolvasását, így bizonyos függvények, konstansok alapból elérhetőek. Létrehozhatunk benne globális és lokális változókat, függvényeket. Itt egy globális változó a led, ami azt mondja meg, hogy mely lábat szeretnénk használni.
  • A pinMode() függvénnyel azt adjuk meg, hogy az adott lábat kimenőként vagy bemenőként szeretnénk-e használni. Mivel információt írunk ki rá, és nem olvasunk be, ezért most kimenőként használjuk.
  • A digitalWrite() függvény digitálisan kiír adott értéket adott lábra. A digitális érték HIGH és LOW lehet, ami 5 Voltot vagy 0 Voltot ír az adott portra.
  • A delay() függvény segítségével várunk; a paraméterként megadott időt ezredmásodpercben kell értelmezni.

A kód tehát a következő: beállítjuk a 13-as lábat kimenetként, majd végtelen ciklusban magasra állítjuk, várunk egy másodpercet, alacsonyra állítjuk, várunk egy másodpercet. Tehát lassan villogni fog a beépített LED:

Kapcsoljuk USB kábellel az Arduino UNO-t a számítógéphez. Ellenőrizzük az alábbiakat az Arduino fejlesztő felületen:

  • Tools -> Board: itt az Arduino/Genuino Uno kell, hogy kiválasztva legyen; ha nem ez van kiválasztva, akkor válasszuk ki.
  • Tools -> Port: itt az a port kell, hogy kiválasztva legyen, mely mellett zárójelben ott van az, hogy Arduino/Genuino Uno.

Ebben az egyszerű esetben nincs szükség áramkör kialakítására. Most fordítsuk le és töltsük fel a programot. Ezt a következőképpen tudjuk megtenni: Sketch -> Upload; Ctrl + U billentyűkombináció; a menü alatti ikonok közül a jobbra mutató nyíl (balról a második). Ha mindent jól csináltunk, a LED villogni fog.

Ahhoz, hogy lássuk: a számítógép ekkor már csak az áramot adja, a logika magán az Arduino eszközön fut, érdemes kipróbálni a következőt: húzzuk ki az USB kábelt, és csatlakoztassunk rá a jobb oldalán levő dugaszra 7-12 Volt közötti egyenáramot (keresőkulcs: power supply).

Az Arduino UNO

A lapka leírása itt található: https://www.arduino.cc/en/reference/board. Az eszköz egy ATMega328P típusú mikrovezérlő, melynek részletes specifikációja itt található: http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf. A legfontosabbak:

  • Memória (a memóriáról bővebben: https://www.arduino.cc/en/tutorial/memory)
    • Flash memória: 32 kB; ebben tárolódik a lefordított kód
    • SRAM (static random access memory): 2 kB, ez a tulajdonképpeni használható memória; pl. a változók értékei ide kerülnek.
    • EEPROM: 1 kB; az itt tárolt adat újraindítás után is megmarad.
  • Lábak
    • Digitális: 14 digitális láb található, egymás mellett, 0-tól 13-ig jelölve. Mindegyik használható digitális írásra és olvasásra egyaránt, viszont néhány lábat speciális célra is használhatunk:
      • TX-RX soros adatkapcsolat: a 0 (RX) és az 1 (TX) lábak használhatóak erre a célra. Ha egy TX-RX kommunikációra képes eszközt rákapcsolunk ezekre a lábakra úgy, hogy a TX-et a TX-szel, az RX-et az RX-szel kapcsoljuk össze, akkor a számítógépről közvetlenül, Serial monitoron keresztül tudunk azzal az eszközzel kommunikálni. Egyébként ha így szeretnénk megvalósítani a kommunikációt az Arduino és az a másik eszközt között, akkor a TX-et az RX-szel és fordítva kell összekötni, és ez esetben gondoskodni kell külső áramforrásról, a számítógép USB-je nem megfelelő.
      • Digitális PWM: ezzel analóg jelet tudunk szimulálni. Pl. 70%-ot úgy, hogy az idő 30%-ában van LOW és 70%-ában HIGH szinten, gyorsan váltakozva. Az analóg író-olvasó függvényeket használhatjuk erre a célra. Az erre alkalmas lábak ~-mal vannak jelölve: 3, 5, 6, 9, 10, 11. Érdemes kipróbálni: küldjük egy fix analóg értéket egy adott lábra, majd oszcilloszkóppal ellenőrizhetjük.
      • Külső megszakításra alkalmas lábak: 2, 3. Részletek: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/.
      • SPI: Serial Peripheral Interface, azaz soros külső interfész. Érintett PIN-ek: tetszőleges digitális (tipikusan 10), valamint 11, 12, 13.
      • A 13-as PIN-re rá van kötve egy alaplapi LED.
    • Analóg: a másik felén található, A0-A5-tel jelölve. Innen csak beolvasni tudunk adatot. Speciális lábak:
      • Az A4-A5 lábak alkalmasak I2C (TWI) kommunikációra. Az A4 az SDA, az A5 pedig az SCL. Ennek a lényege: az egyiken az órajelet küldjük (SCL), a másikon az adatot (SDA), így több fogadó lábra is tudunk adatot küldeni. Erre példa az LCD kijelző, melyet alapból, I2C nélkül 14 kábellel tudunk összedrótozni, míg I2C-vel elég 4 kábel: feszültség, föld, SDA, SCL.

Az alábbi ábra (melynek forrása egy internetes kérdésben volt található, de a copyright információ szerint az arduino.cc oldalra vezethető vissza) a kivezetéseket illusztrálja:

Arduino_UNO_pinout.jpg

Nézzünk körül!

E leírás során az Arduino UNO R3-as modellt használtam, azon belül is az után gyártott kék színűt, nem pedig az eredeti zöldet (elvileg nincs különbség a kettő között, a gyakorlatban viszont már tapasztaltam). Valószínűleg ez a legelterjedtebb változat, de mielőtt belemennénk a részletekbe, lássuk, milyen hasonló eszközök vannak!

Sok, az Arduino UNO-val szinte 100%-ban megegyező eszköz létezik: Genuino, Funduino, Leonardo stb. Ezt egyrészt amiatt fontos tudni, hogy ha olyan nevű eszközünk van, és Arduino-zni szeretnénk, akkor nem kell feltétlenül Arduino-t vennünk, másrészt sok esetben a leírásokban ill. hardverelemekben adott típusra hivatkoznak. Ezek egymással teljesen kompatibilisak.

Kicsit felfelé nézve (de még az Arduino-s mikrokontrollereknél maradva) találjuk az Arduino Mega és Arduino Due lapokat. Kívülről is látványos különbség az Arduino UNO-val szemben a lábak száma, melyből 54 van. A memóriájuk is jóval nagyobb, pl. a program memória 512 kB (ellentétben az Arduino UNO 32 kB-jával).

"Oldalra-felfelé" tekintve találjuk az ESP8266 kódú WiFi-s világot, mely számos formában létezik. Az ESP 01 kódú alapváltozatnak nincsenek is önálló lábai, csak az, amivel össze lehet kötni más eszközökkel, programozni lehet, ill. innan kapja a tápellátást. Ujjhegynyi mérete ellenére a benne levő memória típustól függően 512 vagy 1024 kB; tehát izmosabb mint a Mega és a Due. Alapból olyan firmware van rajta, amellyel AT parancsokat végrehajtva tudunk rákapcsolódni a wifi-re, de ez felülírható (ami egyébként nem egyszerű). A WeMos tkp. az Arduino és az ESP8266 összegyúrása: mérete és elrendezése megegyezik az Arduino UNO-éval, az IC viszont nem az Arduino-nál megszokott ATmega328, hanem at ESP8266. Ide tartozik még a NodeMCU, ami szintén 32 lábas és szintén ESP8266-ot tartalmaz, viszont kinézetében szakított az Arduino UNO-val. Ezek az eszközök jók, érdekesek, és ezek a valódi IoT (Internet of Things) alap építőkövei, mivel adatokat tudnak küldeni-fogadni. Ami miatt viszont még nem szorították ki az Arduino-t, az szerintem a kiforratlanságuk. A feltöltés borzasztó lassú, ami ha egyszer történik, még rendben van, de ha sokszor egymás után (ami a gyakoribb), akkor kifejezetten zavaró. A programot ráadásul több esetben nem is lehet csak úgy feltölteni, hogy rádugom és már töltöm is, azt programozó módba kell tenni. (És naná, hogy nem működik a leírásnak megfelelően!) Ráadásul számos érzékelővel nem kompatibilis, vagy legalábbis még nem jelent meg az ESP8266 kompatibilis könyvtár.

Nagyon felfelé tekintve találjuk a különböző, PI elnevezésű mikro PC-k világát: Raspberry PI, Orange PI, Banana PI (kíváncsi vagyok, megjelenik-e valaha a túlárazott, de design-os Apple PI…). Ezek valóban már mikroszámítógépek, pl. a memóriájuk még a legizmosabb Arduino-s eszközökhöz képest nagyságrendileg ezerszer akkorák; itt még GB-os nagyságrendről beszélünk. Az interfészek is ennek megfelelően vannak kialakítva: USB-k, HDMI, jack dugó stb. került a lapkára. Viszont az Arduino-s világban megszokott tűk még itt is szerepelnek.

Életkorban lefelé találjuk a gyerekeknek megalkotott micro:bit eszközt, mely általános iskolában nagyon jó alapozó lehet a középiskolai Arduino-s foglalkozások számára.

Az Arduino fejlesztői környezet

A számítógépről futó fejlesztői környezet legfontosabb részei az alábbiak:

  • A szerkesztő, mely szintaktikus ellenőrzést ugyan nem végez, de a kulcsszavakat beszínezi.
  • A kódot fordítani a Sketch -> Verify/Compile menüponttal, a Ctrl+R billentyűkombinációval vagy a menü alatt első ikonnal lehetséges.
  • Fordítani és feltölteni az Arduino-ra: Sketch -> Upload; Ctrl+U; második ikon.
  • A File -> Examples alatt számos példaprogram található. Pl. a már bemutatott villogó itt is elérhető: File -> Examples -> 01.Basics -> Blink.
  • A lapka típusát a Tools -> Board alatt, míg a portot a Tools -> Port alatt tudjuk beállítani. Lapkafüggő, hogy ezek alatt még mi minden jelenik meg.
  • A soros adatkapcsolatot a Tools -> Serial Monitor (gyors hívó: Ctrl+Shift+M) segítségével tudjuk vezérelni: itt írja ki a képernyőre a bejövő adatokat, és itt tudunk adatokat küldeni. Pl. a már említett TX-RX mechanizmussal itt tudjuk elérni az Arduino UNO 0 és 1 lábakra kötött eszközöket. Fontos, hogy az átviteli sebesség megfelelő értékre legyen beállítva. A kódban ez így jelenik meg: Serial.begin(9600);, a seral monitoron pedig jobb oldalon lent egy lenyíló listából lehet kiválasztani. A leggyakoribb értékek: 9600 (lassú, de megbízható) és a 115200 (gyors, de bizonyos esetekben instabil lehet).
  • A soros adatkapcsolat egy másik lehetősége a Tools -> Serial Plotter, mely diagramot rajzol a kapott értékekből. Pl. ha egy analóg érzékelő értékét tizedmásodpercenként kiküldjük a soros portra, akkor látványos függvény lehet az eredmény.
  • A külső könyvtárakat háromféleképpen tudjuk beállítani.
    • Tools -> Manage Libraries… -> (vagy Sketch -> Include Library -> Manage Libraries…) itt rákeresünk a megfelelő könyvtárra (pl. DHT sensor library), és telepítjük.
    • Letöltjük az internetről (a fenti példában https://github.com/adafruit/DHT-sensor-library -> Clone or Download -> Download ZIP), majd az Arduino IDE-ből Sketch -> Include Library -> Add .ZIP Library… -> kiválasztjuk a letöltött zip fájlt és telepítjük.
    • Az internetről letöltött zip fájlt kézzel kicsomagoljuk a megfelelő helyre. Ezt a File -> Preferences megnyitásával tudjuk megnézni, és az alapértelmezett hely a következő: C:\Users\[user]\Documents\Arduino.

Az Arduino C++ programozási nyelv

Az Arduino-t egy C++ alapú programozási nyelv segítségével tudjuk programozni. A hardver viszont oly mértékben korlátozza a lehetőségeket, hogy a valóságban a C++-nak csak egy nagyon szűk szelete érhető el. Még a legösszetettebb Arduino kód is ránézésre egyszerűsített C-re hasonlít.

A referencia itt található: https://www.arduino.cc/reference/en/. Lássuk a lényegesebb részeket!

Alapok

A fájl kiterjesztése .ino, és a fájl nevének (kiterjesztés nélkül) meg kell egyeznie azzal a könyvtárral, amelyben van. A két kötelező függvény a void setup() és a void loop(). Az előbbi egyszer fut le, a rendszer indulásakor, az utóbbi pedig folyamatosan, egymás után, végtelen ciklusban. (Érdemes egyébként ezt figyelembe venni akkor is, amikor Arduino-t programozunk, más eszközzel, pl. az mBlock-kal: mindig pontosan egy setup és egy loop van.)

Az abszolút minimum kód kb. így néz ki:

void setup() {}
void loop() {}

Ha a forrásfájl neve minimal.ino, akkor annak a minimal/ könyvtárban kell lennie.

Változók

Vannak globális és lokális változók. A leggyakoribb alaptípusok és a hozzá tartozó műveletek megtalálhatóak. Beépített String típus is van, a leggyakoribb megszokott string műveletek elérhetőek: összefűtés a + művelettel (pl. "Result:" + result).

Vezérlő struktúrák

Az alap vezérlő struktúrák meg vannak, pl. a feltételkezelés, ciklus, a megszokott C/C++ szintaxissal, pl.:

if (a < b) {
  foo();
} else {
  bar();
}
for (int i=0; i<10; i++) {
  something(i);
}
while (a < b) {
  a++;
}

Ki- és bemeneti függvények

Talán a leglényegesebb része a nyelvnek az író/olvasó műveletek (pinMode(), digitalRead(), digitalWrite(), analogRead(), analogWrite()), melynek segítségével kommunikálni tudunk a külvilággal. Az adatkommunikációt a Serial osztályon keresztül érjük el, pl. Serial.println("hello"), int incomingValue = Serial.read().

Saját függvények

A C-ben megszokott struktúrájú függvényeket írhatunk: lehetnek paraméterek, visszatérési típus, a visszatérési értéket pedig a return utasítás után adhatjuk meg.

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