Tag Archives: java

I/O v Javě, rychlé I/O, PWM modulace a tak dále

Prvotně publikováno na raspi.cz 29.3.2013.

V nedávném článku „Propojujeme Raspberry Pi a Arduino“ si Buben postěžoval, že

  • RPi postrádá PWM
  • Nelze rozumně spolehlivě reagovat na změny na vstupních pinech, protože synchronní polling by bral moc času procesoru a byl by z důvodu multiprocesingu v linuxu nespolehlivý

… a že tedy je lepší předat obsluhu I/O Arduinu.

S výsledkem této úvahy souhlasím. Složitější I/O nemá obtěžovat CPU, mají ho dělat kanálové procesory – tak nás IBM učí už více než 50 let. A volba Arduina není špatná. Nicméně předpoklady, na základě kterých Buben toto tvrzení postavil, jsou nepravdivé.

Pro spoustu aplikací stačí počet I/O portů, které má RPi – a pro spoustu aplikací stačí ihardwarová podpora, kterou má RPi pro řešení obou výše uvedených problémů.

Hardwarové PWM výstupy

Přímo na expanzním portu snadno najdete pin GPIO1 (18), což je zároveň výstup hardwarového PWM, které má RPi v sobě. Ale uznávám, že jedno PWM je nanic. Každý smysluplný kus železa potřebuje alespoň tři serva = tři PWM kanály. Co s tím?

Samozřejmě je blbost aplikačně simulovat PWM tím, že budeme na GPIO pin sypat jedničky a nuly. To by skutečně stálo všechen procesorový výkon a navíc by to nebylo spolehlivé  – přepínání tasků v linuxu by způsobilo nahodilé a nepříjemné výpadky v modulaci.

Ale co kdyby ty jedničky a nuly na výstup za nás sypal někdo jiný? Někdo, kdo to umí bez zátěže procesoru?

Ano, to je správná cesta. V paměti připravíme „obraz“ jednoho PWM pulzu (tj. třeba 500 nul a pak 500 jedniček = máme pulz s plněním 50%) a pak stačí říct řadiči DMA, ať tento kus paměti fixním tempem neustále dokola posílá na daný pin. A ejhle, funguje to.

Hotovou implementaci pro základní PWM najdete zde: https://github.com/sarfata/pi-blaster/

Detailnější popis je na stránce autora.

Aplikaci stačí nainstalovat a spustit (nebo nechat spouštět automaticky při bootu). Ovládání je pak jednoduché: Příkazem

echo "1=0.3" > /dev/pi-blaster

nastavíme pin 1 na PWM plnění 30%,

echo "1=1" > /dev/pi-blaster

dá plnění 100% atd. Zatížení procesoru je nulové a signál je hezky pravidelný, bez výpadků. Takto může být obsluhováno více GPIO pinů, defaultně jich pi-blaster řídí 8.

Pokud nechcete pomocí PWM řídit úroveň jasu LEDky, ale chcete ovládat serva, nepotřebujete „standardní“ PWM, ale trochu jiné. U serv je to tak, že frekvence pulzů by měla být 100 Hz; impulz o délce 1 msec je 0% výkonu, impulz o délce 2 msec je 100% výkonu. Kratší pulzy jsou chyba, delší taky.  Chce se vám s tím ladit? Jistě ne. Takže potřebujeme hotové řešení.

Najdeme ho tady: https://github.com/richardghirst/PiBits/tree/master/ServoBlaster

Výše popsaný projekt pi-blaster vznikl jako rozšíření myšlenky ServoBlasteru. Pi-blaster má hezčí implementaci (ovládání přes soubor).

Hardwarová detekce změny stavu GPIO pinu – jak nepollovat I/O procesorem

Procesor, na kterém je RPi postaveno, samozřejmě umí na změnu stavu vstupního GPIO pinu navázat přerušení.

Tedy zbývá jen zjistit, zda je tato služba podporována v linuxu a dá se používat?

Ano, je tam a funguje.

Tedy ve své aplikaci můžete snadno říct „až se změní stav GPIO0, zavolej mojí funkci X()“.

Test jsem provedl v Javě, což je pro real-time programování výrazně nevhodný jazyk. Nicméně Javu mám jako svůj denní nástroj a přemýšlím v ní; navíc jsem už líný používat pointery a podobné věci, ze kterých se v céčku dá postavit operační systém, a rád se od nich nechám odstínit.

Pro integraci Javy s GPIO na RPi existuje hezká knihovna pi4j. Více o ní napíšu za chvíli, ale ten důležitý výsledek testu je: interrupt-driven obsluha GPIO na RPi funguje. Za klidového stavu (tj. když se nic neděje, na GPIO nejsou žádné změny) to nežere žádný strojový čas. A v té ošklivé pomalé Javě to zvládá obsloužit až zhruba 2000 změn stavu za sekundu. A když přijde osamocený milisekundový impulz, neztratí se, Java ho dostane.

Podpora pro RPi GPIO v Javě – pi4j

Knihovna pi4j je přesně to, co potřebujete, pokud si chcete hrát s I/O na RPi ve vyšším jazyce.

Co umí?

  • Pro začátek samozřejmě obsluhu jednotlivých GPIO pinů. Nastavení směru, nastavení hodnoty.  A eventy o změnách stavu.
  • Taky je tam podpora pro I2C. Snadno můžete mluvit s I2C zařízeními.
  • Nezapomnělo se ani na sériové porty (UART).
  • SPI? No jasně.

Už tohle vše by bylo dobrým důvodem knihovnu používat, ale zde funkce teprve začínají. Autoři si totiž uvědomili, že když už mají dobře navržené abstraktní rozhraní pro GPIO, tak by s ním šlo obsluhovat víc věcí.

  • Máte na I2C připojený I/O expandér MCP23008 / MCP23009, o kterém jsem dříve psal? Tak si prostě místo standardního objektu „pin“ vyžádáte tento objekt od providera MCP23008GpioProvider. Toť vše. Veškerá další obsluha tohoto „drátu“ je stejná – je jedno, jestli pracujete s pinem přímo na expanzním portu, nebo s pinem za expandérem MCP23009. Wow!
  • Totéž samozřejmě platí i pro I2C I/O expandéry MCP23017 a PCF8574. A taky pro expandér MCP23S017 připojený přes SPI.
  • Koupili jste si expanzní desku PiFace? Kód je připraven.
  • Přímá podpora pro řízení krokových motorků. Stačí namapovat řídící vodiče a pak už jen můžete říkat „100 kroků plnou rychlostí doprava“.
  • Komunikace se senzorem Wii Motion Plus (modul s gyroskopem rozšiřující standardní ovladač pro Nintendo Wii, připojuje se přes I2C).
  • Obsluha LCD displejů.

Knihovna je hezky navržená a pro jednotlivé funkční bloky jsou tam hotové samply.

Jak rychle vlastně Java na RPi s I/O pracuje?

Udělal jsem takový jednoduchý test. Na jeden GPIO pin (výstupní) jsem připojil LED diodu, a zároveň jsem ho spojil na druhý pin – vstupní.

O změnách na vstupu jsem si nechal posílat eventy.

A pak jsem v jednoduché smyčce posílal na výstup jedničky a nuly.

Co jsem zjistil?

Maximální frekvence na výstupním drátu dosažitelná z mé aplikace byla zhruba 2 kHz. Nicméně kdybych si dal práci s nastavení JVM, mělo by to být výrazně lepší.

Pro délku jedničky/nuly 1 msec se už začaly některé eventy o změnách ztrácet. V průměru jsem dostal 986 eventů na 1000 změn. Vytížení CPU bylo tvrdých 100%. První eventy přišly až po cca 100 msec od zahájení vysílání – ale to je dáno přepínáním threadů v Javě; smyčka posílající 1/0 prostě nepustila procesor. Ale eventy se frontují, takže se povětšinou neztrácejí.  (U osamoceného milisekundového pulzu se eventa neztratila nikdy; ztrácení je skutečně funkcí objemu změn.)

Pro impulzy o délce 5 msec už vytížení procesoru spadlo na 50% a eventů dorazilo 998 z tisíce.

10 msec pulzy už vytěžovaly procesor jen na 30% a eventy se neztratily žádné.

Pro delší pulzy vytížení procesoru klesalo k neměřitelnosti.

A samozřejmě: když jsem takhle posílal na výstup třeba 100 Hz signál, na svitu LED byly jasně vidět nepravidelnosti . Linux prostě není real-time systém a občas vám procesor sebere na tak dlouhou dobu, že je to vidět jako zřetelné mrknutí LEDky.

Reklamy

Napsat komentář

Filed under Počítače, vývoj HW a SW

Ztracený den kvůli chybám v Javě

Příhoda je stará asi tři týdny, ale teprve teď mám čas jí napsat.

Vždy jsem za základní vlastnost Javy považoval její spolehlivost a stabilitu. Runtime bylo dobře odladěné, knihovny měly minimum chyb a případů, kdy aplikace spadla kvůli chybě Javy a ne našeho programátora, bylo minimum.

Vždy jsem se smál kolegům vyvíjejícím v .Net, kde každý deployment do složitějšího prostředí byl zdrojem adrenalinu již několik dní předem. Kolize verzí DLL x86 a x64, sdílené DLL přes celý systém atd… Java je přeci lepší, ne? 

Instaloval jsem u zákazníka nějakou naší úžasnou aplikaci. Samozřejmě napsanou v Javě. Takže nejprve Java runtime … jakou verzi tam dát? Novou 1.7.1? Tu ještě nemáme odzkoušenou v reálném světě, tak radši poslední 1.6.29. OK. Pak tam hodím aplikační kontejner (Glassfish). V něm připravím zdroje pro aplikaci – datasource pro databázi. Nastavím hodnoty pro spojení na MS SQL Server, zmáčknu PING, aby si je Glassfish ověřil … a nic. Žádná odpověď. Ne chyba spojení, ale prostě žádná reakce.

Restartnu Glassfish. Stále totéž. Nu což, budu to řešit potom, snad jsem vše zadal správně, Nainstaluju aplikaci, zkusím její testovací URL … a aplikace zatuhne. Ve chvíli pokusu o připojení do MS SQL aplikace zatuhne. Bez jakékoli hlášky.

Tak jsem experimentoval s nastavením logování, Glassfishe jako celku, systému. Vsjo marno. 

Tak tedy Google. Po několika dotazech jsem našel popis problému podezřele se blížícího tomu mému: článek 1, článek 2. Ukázalo se, že Java 1.6.29 nefunguje s MS SQL Serverem 2008 běžícím na Windows Serveru 2008 R2 x64, pokud je na serveru povolena SSL komunikace. Chyba asi není tak úplně v JDBC driveru od Microsoftu, spíše někde v socketové komunikaci. Verze 1.7.1 (a novější) resp. 1.6.26 (a starší) fungují OK.

OK. Tedy rychlá reinstalace Javy na 1.7.1, která má fungovat. Aplikace se rozbíhá, štěstí na všech stranách. Aplikaci jsem předal k testování.

O den později se mi aplikace vrátila. V nějaké obrazovce nefungovalo načítání souboru z disku. Soubor se hledal podle data. A vypadalo to, že se hledá podle data o dva dny jiného, než které je v databázi. Tak jsem vynadal programátorovi, že tam někde nechal hardcodované testovací datum. Programátor se samozřejmě vykrucoval, jak to tak vždy programátoři dělávají. A to natolik, že mi ukázal kód. A bylo vidět, že data skutečně bere z databáze.

V databázi je datum 2.11. Aplikace však vidí 31.10.

Co s tím? Být to o pár hodin, je to adept na problém s časovou zónou. Ale posun o dva dny se na časovou zónu shodit nenechá.

Takže zase logování, debugování a nakonec Google.

Sakra.

Zase je to chyba Javy. V javě 1.7.0, 1.7.1 při čtení sloupečku typu DATE (jen datum, ne DATETIME) může být vraceno datum o dva dny jinde. Prý se to děje nejen u MS SQL, ale i u Postgresu, našel jsem jinde.

Tak jsem downgradnul javu na 1.6.26 a už vše funguje správně.

Nicméně tyhle dva incidenty nás stály minimálně jeden člověkoden, možná i o něco více.

Poučení?

  • Java 1.6.26 je ta pravá a nové verze zkoušet velmi opatrně
  • Už neplatí, že runtime Javy je spolehlivý.

Blame Canada Oracle!

 

Napsat komentář

Filed under Počítače, vývoj HW a SW

Projekt Sun SPOT – Java pro elektrobastlíře a robotiky

Úspěch Lego Mindstorms NXT a snaha podporovat Javu dovedla Sun k tomu, že připravil projekt Sun SPOT (Small Programmable Object Technology). Není to jen Javová verze NXT, je to trochu jiný koncept. Je lepší či horší? Jak na co.

Lego Mindstorms asi každý zná. Jde o rozšíření klasického lega o možnost stavby a programování robotů. NXT se skládá z centrální „krabičky“ s procesorem, displejem, tlačítky a konektory, a z připojitelných periférií – ve standardní dodávce jsou tři servomotorky, ultrazvukový dálkoměr, detektor světla, dotykový senzor a zvukový senzor. Lego Mindstorms je hitovka, pro roboty z Lega se pořádají olympiády a vůbec jde o „mainstream“ produkt.

Lego Mindstorm se programuje buď v grafickém „tahátku“, které ale mnoho nefunguje, nebo v C#. A to je ta správná cesta. Komunikace mezi počítačem a Lego NXT je pomocí USB kabelu nebo Bluetooth.

Periférie jsou drahé a připojují se speciálním kabelem. Celé je to taková školní hračka – pokud ti stačí dodané součástky, užiješ si, ale reálný vývoj s tím neuděláš.

SUN se k problému postavil z druhé strany. Dodávka Sun SPOT se skládá z jednoho řídícího modulu a dvou senzorových.

Každý senzorový modul má

  • tříosý akcelerometr s rozsahem 2G nebo 6G (nastavitelné)
  • teploměr
  • světelný senzor
  • osm tříbarevných LED diod
  • šest analogových vstupů 0-3 V (v některých verzích firmware jsou dostupné jen čtyři)
  • dva DIP přepínače
  • pět logických I/O
  • čtyři vysokovýkonné (čti „100 mA“) výstupy

Každý modul je vybaven rychlým procesorem a velkou pamětí (180 MHz 32 bit ARM920T core, 512K RAM, 4M Flash), rádiovým modulem standardu IEEE 802.15.4 (2.4 GHz; s integrovanou anténou dosah cca 80-100 metrů), nabíjitelnou LiIon baterií a USB portem.

Kde je tedy ten rozdíl?

Sun SPOT nemá v základní výbavě žádná serva ani efektní čidla. Ale je možné na něj připojit COKOLI – standardní servo s PWM řízením, jakýkoli snímač s rozumným analogovým nebo digitálním výstupem, jakékoli výstupní zařízení ovladatelné čtyřmi 100 mA porty. V dodávce máte ne jeden, ale dva autonomní moduly, které si mezi sebou a se základnovou stanicí mohou povídat pomocí bezdrátového linku s rozumným dosahem. Modul sice nemá hezký rastrový displej … ale je něco špatného na LED diodách?

Pro bastlíře je SUN SPOT daleko zajímavější. Umožňuje mu strašně rychle postavit „chytré“ zařízení bez složitého rogramování jednočipových procesorů v assembleru. V Sun SPOTu bije rychlý ARM procesor a standardní Java ME runtime, takže programování jde rychle od ruky a výpočetní výkon je překvapivý.

Sun SPOT má z mého pohledu jedinou chybu – stojí dvakrát tolik než Lego NXT.

Porovnání základních rysů:

V dodávce
Lego NXT: 1 CPU modul
Sun SPOT: 1 CPu modul připojitelný k PC a 2 autonomní CPU moduly se senzorovou deskou

Senzory, zařízení, vstupy a výstupy
Lego NXT: 3 serva se zpětnou vazbou (hlášení polohy), zvukový senzor s rozpoznáváním příkazů a zvuků,
ultrazvukový dálkoměr do 250 cm, dotykový senzor, světelné čidlo, černobílý displej 
100×64 bodů
Sun SPOT: tříosý akcelerometr s rozsahem 2G nebo 6G, teploměr, světelný senzor, osm tříbarevných LED diod,
šest analogových vstupů 0-3 V, dva DIP přepínače, pět logických I/O, čtyři vysokovýkonné (čti „100 mA“) výstupy

Komunikace s PC
Lego NXT: USB, Bluetooth
Sun SPOT: USB

Bezdrátová komunikace
Lego NXT: Bluetooth, dosah jednotky metrů
Sun SPOT: IEEE 802.15.4; dosah až 100 metrů; spojení nejen mezi PC a CPU ale i mezi jednotlivými CPU navzájem; podpora MESH sítí

Hardware
Lego NXT: 32-bit AT91SAM7S256 main microprocessor (256 KB flash memory, 64 KB RAM), rychlost neudána + 8-bit ATmega48 microcontroller @ 4 MHz (4 KB flash memory, 512 Bytes RAM) 
Sun SPOT: 180 MHz 32 bit ARM920T core – 512K RAM – 4M Flash

Programování:
Lego NXT: GUI tahátko krabiček, C#, díky tomuto projektu http://lejos.sourceforge.net/p_technologies/nxt/nxj/nxj.php i Java
Sun SPOT: Standardní Java ME

U mne tedy Sun SPOT vyhrává.

Ale uznávám že jako „hračka“ pro malého (myšleno tím věkem) programátora je lepší Lego NXT – zasunout do sebe legovské kostky je jednodušší a tím, že v dodávce NXT jsou i „legovská“ serva, dá se out-of-the-box postavit spoustu zajímavých věcí.

Odkazy

http://www.sunspotworld.com/ – homepage projektu + obchod
https://spots.dev.java.net/ – development stránka u SUNu
https://spots.dev.java.net/FAQ.html – velmi pěkné FAQ, popis HW
http://parleys.com/display/PARLEYS/Sun+SPOTs+In+Action?showComments=true – prezentace, popis jak připojit různý zajímavý HW

 

Napsat komentář

Filed under Počítače, vývoj HW a SW