Hlavní navigace

IoT v Javě: univerzální knihovna Bulldog

2. 5. 2016
Doba čtení: 3 minuty

Sdílet

Termín IoT zřejmě znáte. Propojování malých počítačů se senzory, motůrky či LED diodami, arduina řídící osvětlení, sběr a analýza dat. To je pouze malá část velmi širokého světa.

Samozřejmě naleznete mnoho knihoven, které vám programování vašeho use-case, když už ne vyřeší, tak výrazně usnadní. Problém nastává, pokud chcete svůj program nasadit na jinou destičku. Náhle se ponoříte do komplikovaného světa nízkoúrovňových periferií a zjistíte, že každý výrobce tento problém řeší úplně jinak než jeho konkurenti.

Pro každou větší platformu existují nepřeberná množství knihoven pro různé jazyky, které hůře či lépe přináší přístup k periferiím jako GPIO, PWM I2C apod. Nicméně problém zůstává, pokud se pokusíte takový kód přenést mezi platformami. Tento problém za vás vyřeší knihovna Bulldog.

Bulldog je nízkoúrovňová knihovna napsaná v jazyce Java závislá na operačním systému Linux, jejímž cílem je programátorovi přinést rozhraní, které s potřebou minimální či žádné modifikace umožní psát kód nezávislý na zvoleném zařízení. Bulldog nyní pracuje na třech typech zařízení:

  • Raspberry Pi (všechny verze)
  • Cubieboard 1 a 2
  • BeagleBoneBlack

Nicméně současný vývoj knihovny má za cíl opustit platformní závislost a být funkční na libovolném zařízení s ARM procesorem. Zároveň je ve vývoji rozšíření knihovny pro platformu x86.

Ukažme si kód, který rozsvítí LED diodu připojenou k zařízení Raspberry Pi na pinu P1_11.

package sample;
import io.silverspoon.bulldog.core.gpio.DigitalOutput;
import io.silverspoon.bulldog.core.platform.Board;
import io.silverspoon.bulldog.core.platform.Platform;
import io.silverspoon.bulldog.core.util.BulldogUtil;
import io.silverspoon.bulldog.raspberrypi.RaspiNames;

public class BulldogLED {

    public static void main(String[] args) {
        Board board = Platform.createBoard();
        DigitalOutput output = board.getPin(RaspiNames.P1_11).as(DigitalOutput.class);
        output.high();
        BulldogUtil.sleepMs(1000);
        output.low();
    }
}

Nyní si kód rozeberme, po začátek metody main se jedná o normální spustitelný java kód. Na prvním řádku metody main je získán objekt typu board. Tento objekt zpřístupňuje veškerou funkcionalitu desky, na které kód běží, v našem případě Raspberry Pi.

Na dalším řádku vytváříme objekt, který reprezentuje výstupní zařízení, v našem případě LED diodu připojenou na pinu P1_11.

Zbývající tři řádky kódu vykonají následující:

  • Zvýšením napětí na výstupu rozsvítí LED diodu,
  • počká jednu vteřinu,
  • snížením napětí na výstupu zhasne LED diodu.

Poznámka: povšimněte si, že kód nijak neřeší, na jaké verzi Raspberry Pi je spuštěn, toto řeší Bulldog sám uvnitř, již při volání metody Platform.createBoard(). Jako důsledek poběží tento kód na libovolném Raspberry Pi (od verze A po verzi 2). Zároveň jste si možná všimli, že jediná část kódu, která omezuje platformu, je název pinu.

Nyní přepíšeme náš kód, aby fungoval na platformě BeagleBoneBlack, kde LED diodu připojíme k pinu P8_1:

package sample;
import io.silverspoon.bulldog.core.gpio.DigitalOutput;
import io.silverspoon.bulldog.core.platform.Board;
import io.silverspoon.bulldog.core.platform.Platform;
import io.silverspoon.bulldog.core.util.BulldogUtil;
import io.silverspoon.bulldog.beagleboneblack.BBBNames;

public class BulldogLED {

    public static void main(String[] args) {
        Board board = Platform.createBoard();
        DigitalOutput output = board.getPin(BBBNames.P8_1).as(DigitalOutput.class);
        output.high();
        BulldogUtil.sleepMs(1000);
        output.low();
    }
}

V tomto příkladu se kód chová naprosto stejně jako u Raspberry Pi, jediným rozdílem je název pinu, který je závislý na platformě.

Samozřejmě se nabízí otázka, nebylo by možné napsat náš kód tak, aby běžel na uvedených platformách bez komplikovaného rozlišování pinů jednotlivých zařízení? Možné to je.

package sample;
import io.silverspoon.bulldog.core.gpio.DigitalOutput;
import io.silverspoon.bulldog.core.platform.Board;
import io.silverspoon.bulldog.core.platform.Platform;
import java.util.List;
import io.silverspoon.bulldog.core.gpio.Pin;
import io.silverspoon.bulldog.core.util.BulldogUtil;


public class BulldogLED {

    public static void main(String[] args) {
        Board board = Platform.createBoard();
        List allPins = board.getPins();
        DigitalOutput output = allPins.get(0).as(DigitalOutput.class);
        output.high();
        BulldogUtil.sleepMs(1000);
        output.low();
    }
}

Nyní máme pěkný přenositelný kód, který bude fungovat v okamžiku jeho nasazení na zvolenou platformu. Samozřejmě je v příkladu vidět, že používáme pin s indexem 0, což omezuje naši aplikaci na konkrétní piny na jednotlivých platformách. V našem případě se bude jednat o:

  • Pin P1_3 na Raspberry Pi
  • Pin P8_3 na BeagleBoneBlack
  • Pin PB10 na Cubieboard

Výše uvedený seznam je díky deterministickému uspořádání pinů v seznamu neměnný.

ict ve školství 24

Závěrem pár slov, v příkladech k tomuto článku jste viděli, že programování mikrozařízení nemusí být komplikované. Příště se zaměříme na technologii v pozadí Bulldoga a na další projekty platformy Silverspoon, která Bulldog využívá.

Několik odkazů na konec:

Autor článku

Quality engineer v práci, učitel C/C++ ve volném čase, IoT nadšenec.