Dítko během posledních dvou let v modelářském klubu postavilo maketu říčního remorkéru ČSPLO „Bečva„. Bezmála metrový model pro soutěže v kategorii F2B (Naviga) vypadá moc hezky….

Dítko během posledních dvou let v modelářském klubu postavilo maketu říčního remorkéru ČSPLO „Bečva„. Bezmála metrový model pro soutěže v kategorii F2B (Naviga) vypadá moc hezky….
Tchýně přijela na návštěvu a vypadá to, že neplánuje odjet? Zlobivý mladší sourozenec? Zbytečně dobré pracovní prostředí? Problém dokážeme snadno vyřešit s Arduinem!
Spousta lidí si stěžuje, že nemůže spát, když v místnosti tikají hodiny. Ale časem si stejně zvyknou. Co takhle to trochu vylepšit a udělat hodiny, které tikají nestandardně? Deset minut jdou běžným způsobem, pak se na půl minuty zastaví a následně zpoždění doženou… a pak zase čtvrt hodiny běží normálně. Tohle je daleko více obtěžující, než běžné tikání! A přitom ty hodiny jdou přesně – v každou chvíli je odchylka od aktuálního času menší než dvě minuty.
Tedy postavte si takovéhle super hodiny, nainstalujte je do místnosti, kde spí nechtěná návštěva, a pak už se jen kochejte výsledkem.
Blynk.cc je zajímavá platforma pro rychlé prototypování IoT řešení s vizualizací v mobilním telefonu. Pokud potřebujete vyzkoušet senzor a nechce se vám k němu psát serverovou stranu a mobilní front-end, Blynk může být správné řešení.
Podporuje Arduino (s ethernet/wifi shieldy), Particle … a napřímo podporuje i ESP-8266 (NodeMCU). A ta poslední varianta mne zaujala.
První aplikace je hotová za pět minut.
Nainstalujte si mobilkovou aplikaci a podle popisu zde založte první projekt. Získáte autorizační token.
Stáhněte si Arduino knihovnu z http://www.blynk.cc/getting-started/ . Je to ZIP soubor se čtyřmi podadresáři, které nakopírujete do adresáře libraries/ v adresáři s Arduino skeči. Restartujte Arduino IDE.
Udělejte jednoduchý skeč:
#define BLYNK_PRINT Serial // Comment this out to disable prints and save space #include <ESP8266WiFi.h> #include <BlynkSimpleEsp8266.h>
// You should get Auth Token in the Blynk App. // Go to the Project Settings (nut icon). char auth[] = "autentizační token";
void setup() { Serial.begin(115200); Blynk.begin(auth, "ssid wifi sítě", "heslo wifi sítě"); } void loop() { Blynk.run(); }
No a teď už je možné do projektu v mobilce přidat načítání a zobrazení hodnoty libovolného digitálního či analogového pinu. To se udělá prostým vložením objektu Value display (prosté zobrazení), Gauge („budík“) či Graph (graf – hodinový, denní, měsíční). Jen vložíte na stránku v mobilce ovládací prvek a řeknete mu, jaký pin mikrokontroléru (Dxx, Axx) má obsluhovat. Stejně snadno je možno nastavovat hodnoty výstupních pinů. Na straně kontroléru nic neprogramujete. Neřešíte spojení, ukládání dat na server, vizualizaci – nic.
Ale co když chci připojit ke kontroléru něco, co se musí ovládat složitěji než prostým načtením hodnoty z pinu?
Za tímto účelem má Blynk virtuální piny V1 až Vxx. jejich hodnota není vázána přímo na pin kontroléru, ale je obsluhována v aplikaci.
Třeba si takhle připojíme k NodeMCU teploměr DS18B20. Nejjednodušší možné zapojení – napájení na 3.3 V, zem na zem, datový pin teploměru na pin D4 kontroléru a přes odpor 4k7 na napájení.
Podporu pro OneWire sběrnici má NodeMCU v sobě, knihovna DallasTemperature pro čtení teploty se instaluje v manažerovi knihoven Arduino IDE automaticky.
Sketch vypadá takto:
Hlavička:
#define BLYNK_PRINT Serial // Comment this out to disable prints and save space #include <ESP8266WiFi.h> #include <BlynkSimpleEsp8266.h> #include <SimpleTimer.h> #include <OneWire.h> #include <DallasTemperature.h> #define ONE_WIRE_BUS D4 #define TEMPERATURE_PRECISION 10 OneWire oneWire(ONE_WIRE_BUS); DallasTemperature sensors(&oneWire); DeviceAddress thermometer; SimpleTimer timer; // You should get Auth Token in the Blynk App. // Go to the Project Settings (nut icon). char auth[] = "16a...........305032d";
Setup – enumerace zařízení na OneWire sběrnici, nalezení adresy teploměru a konfigurace Blynku:
void setup() { Serial.begin(115200); sensors.begin(); Serial.println("***************************************************"); Serial.print("Pocet teplomeru: "); Serial.println(sensors.getDeviceCount(), DEC); //zjisti adresy oneWire.reset_search(); if (!oneWire.search(thermometer)) Serial.println("teplomer nenalezen!"); Blynk.begin(auth, "jméno wifi", "heslo k wifi"); // jednou za tři sekundy chceme poslat teplotu timer.setInterval(3000L, sendUptime); }
A vlastní výkonná smyčka:
void loop() { Blynk.run(); timer.run(); }
Aha. Tady vlastně nic neděláme s tím teploměrem, že? Teploměr se načítá jednou za 3 sekundy – ve funkci sendUptime, která je volaná z timeru:
void sendUptime() { //nastav rozlišení sensors.setResolution(thermometer, TEMPERATURE_PRECISION);
//načti všechny teploměry sensors.requestTemperatures();
float tempC = sensors.getTempC(thermometer); Blynk.virtualWrite(10, tempC); // virtual pin Blynk.virtualWrite(11, tempC); // virtual pin
if( tempC>26 ) { Blynk.notify("Teplota moc velka!"); } }
Je tady vidět, že načtu teplotu z teploměru a pošlu jí do dvou virtuálních pinů – V10 a V11. Proč? Protože každý virtuální pin může na mobilce končit jen v jednom zobrazovači. Takže V10 bude zobrazovat aktuální hodnotu a V11 pošlu do grafu.
Jo a ještě pozor na červený text. Pokud na mobilce do projektu vložíte objekt „Push Notifications“, tak pomocí Blynk.notify můžete poslat push notifikaci. A fakt to funguje. Tj. nejen vlastní zobrazení stavu zařízení, ale i upozornění kdykoli.
Na mobilce jsem si udělal jednoduchý projekt: jednou display value z pinu V10, jednou graf z pinu V11. A tlačítko pro ovládání pinu D0 (tam má moje NodeMCU ledku). A prvek pro push notification. No a pak stačí kliknout na „spustit“ (trojúhelníček) a žije to. Na mobilce je vidět graf teplot i aktuální teplota; po kliknutí na tlačítko „led“ se rozsvítí nebo zhasne ledka:
No a pokud teplota stoupne nad 26 stupňů (zub na grafu) … na mobilce vyskočí push notifikace. I když je mobilka suspendnutá a aplikace neběží.
Výhody: Skvělé pro jednoduché testování. Nemusíte programovat front-end. Podpora push-notifikací.
Nevýhody: Není webový front-end, jen mobilkový. Nepřekvapilo by mne, kdyby to časem zpoplatnili.
Na okraj: Není nutné využívat jejich cloud. Blynk server si můžete nainstalovat i lokálně u sebe.
(Prvotně publikováno 7.3.2014 na raspi.cz.)
Kterak k Raspberry Pi připojit bezdrátový senzor něčeho, třeba teploty.
Pro plánované zařízení jsem potřeboval, aby dva mikrokontroléry byly schopny si mezi sebou na vzdálenost pár metrů vyměňovat data bezdrátově. Po chvíli hledání jsem našel zajímavý komunikační čip od Nordic Semiconductors – nFR24L01+.
nFR24L01+ není jen tak obyčejné ASK-OOK pípátko, přes které se dá prodloužit sériový port. Tenhle čip funguje až na vrstvě 4 modelu ISO/OSI, tedy udělá za vás spoustu práce. Vysílá na frekvenci 2.4 GHz (volné pásmo ISM – industrial, science, magic). Umí zpracovávat pakety o délce až 32 byte, které chrání pomocí šestnáctibitového CRC. Každý čip má nastavenou svou adresu (pětibajtovou) a je schopen přijímat data až od dalších pěti čipů. A automaticky obsluhuje potvrzení příjmu od protistrany. Tedy funguje to tak, že dáte čipu data a řeknete „odešli na stanici s adresou 1-2-3-4-5“. Čip autonomně odešle data a počká na potvrzení od protistrany. Když potvrzení nedojde, opakuje vysílání ještě několikrát. A na závěr vám řekne, zda se podařilo či nepodařilo data dodat na druhou stranu. Komunikace je přes SPI. No a to nejlepší na závěr: [tady] ho mají zabalený v hezkém hotovém modulu za 1.72 USD včetně dopravy do ČR! Tedy za tuhle cenu je jeden, potřebujete dva. Ale necelé 4 USD = 80 Kč za bezdrátový spolehlivý link mi přijde jako dobrá cena.
Aby se mi neznámé zařízení lépe ladilo, rozhodl jsem se, že odesílat budu z mikrokontroléru, ale přijímat budu do Raspberry Pi, protože by se to mohlo časem taky hodit. Jako mikrokontrolér pro podobné hračky používám čipy Picaxe. Konkrétně v tomhle případě Picaxe 20M2. Stejně jako u populárních Atmelů (Arduino) je to kompletní mikrokontrolér, který má na čipu vše potřebné – analogové i digitální vstupy i výstupy, podporu I2C, sériového portu a spousty dalších věcí. Programuje se to v „basicu“ – syntaxí je to basic, ale sémantikou spíše assembler (pracujete přímo s registry/pamětí). Vývojové prostředí je zdarma. Největší rozdíly proti Atmelu/Arduinu jsou tyto:
Na straně vysílače je to jednoduché. Všechny datové nohy bezdrátového modulu připojíme napřímo na nohy mikrokontroléru.
Na další piny připojíme 1-wire teploměr DS18B20 (do standardního zapojení popsaného na webu Picaxe) a dvě LED diody pro signalizaci (komunikace OK, chyba). Zbývá už jen napojit napájení bezdrátového modulu. A tady pozor! I když jsou datové nohy modulu tolerantní k 5 V, napájení musí být 3.3 V! A ještě jedno upozornění: k napájení modulu je nutné připojit kondenzátor 10 uF. Dokud tam nebyl, chovalo se to divně.
Schema zapojení:
Tady P.T. čtenáře přesměruji [na tento článek]. Tam je to všechno step-by-step popsáno, včetně zapnutí SPI na straně Raspberry Pi.
Zapojení je extrémně jednoduché – jen se propojí odpovídající piny RPi s odpovídajícími piny modulu.
RPi GPIO9 /MISO (Pin 21) – modul pin 7 ( MISO )
RPi GPIO10/MOSI (Pin 19) – modul pin 6 ( MOSI )
RPi GPIO11/CLK (Pin 23) – modul pin 5 ( SCK )
RPi GPIO8/CE0 (Pin 24) – modul pin 4 ( CSN )
RPi GPIO25 (Pin 22) – modul pin 3 ( CE ) – tohle je jediná věc mimo standardní SPI zapojení, tímhle pinem se ovládá, kdy je modul rádiově aktivní
RPI 3.3V (Pin 1) – modul pin 2 ( VCC/3.3V )
RPi Gnd (Pin 6) – modul pin 1 (GND)
Vhodný startovní kód pro Picaxe jsem [našel zde].
Kód pro Raspberry Pi je na již dříve [zmíněném odkazu].
Samozřejmě, že si spolu navzájem nerozuměly. Musel jsem postupně procházet datasheet obvodu a pochopit, co je potřeba změnit:
Finální kód pro obě strany najdete [zde].
Raspberry Pi tedy dostává každou chvíli paket o délce 1 byte, který obsahuje teplotu naměřenou na straně vysílače, přímo ve stupních celsia.
Finální řešení bude mít i na straně přijímače také mikrokontrolér Picaxe. Ale až někdy budete potřebovat něco měřit bezdrátově, vzpomeňte si na moduly nFR24L01+, možná budou váš problém řešit.
Jo a ještě zbývá doplnit dosah: na volném prostranství jsem měl data cca 25 metrů od vysílače. Přes dvě tlusté zdi to funguje na cca 8 metrů bez problémů.
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
… 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ů.
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).
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.
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í?
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í.
Knihovna je hezky navržená a pro jednotlivé funkční bloky jsou tam hotové samply.
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.
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í?
Blame Canada Oracle!
Situace: sqlplus se na server připojí, ale javská aplikace dostane ORA-12505 „Listener nenašel takovou službu, jakou chcete“. Co s tím?
Java aplikace při pokusu o připojení k Oracle 10g dostane chybu
java.sql.SQLException: Vyjimka vstupu/vystupu: Connection refused (DESCRIPTION=(TMP=)(VSNNUM=169870080)(ERR=12505)(ERROR_STACK=(ERROR=(CODE=12505)(EMFI=4))))
ale SQL*PLUS se stejným nastavením normálně funguje? Jak je to možné?
Po chvíli hledání na netu jsem narazil na informaci, že je to způsobeno nevhodným nastavením serveru. Řešení je jednoduché: místo „prostého“ connection stringu ve tvaru
jdbc:oracle:thin:@server:port/instance
je nutno tučný text nahradit celým popisem konexe z TNSNAMES.ORA a do sekce „CONNECT_DATA“ přidat položku (SERVER=DEDICATED).
Tj. mám-li v TNSNAMES.ORA třeba
APPTEST.world =
(DESCRIPTION =
(ADDRESS_LIST =
(load_balance=off)
(failover=on)
(ADDRESS = (PROTOCOL = TCP) (Host = adb) (Port = 1529))
(ADDRESS = (PROTOCOL = TCP) (Host = apsdb) (Port = 1529))
)
(CONNECT_DATA = (service_name=APPTEST)(FAILOVER_MODE= (TYPE=SELECT) (METHOD=BASIC) (RETRIES=1440) (DELAY =5))
)
)
pak connection string pro Javu bude
jdbc:oracle:thin:@(DESCRIPTION = (ADDRESS_LIST = (load_balance=off) (failover=on) (ADDRESS = (PROTOCOL = TCP) (Host = adb) (Port = 1529)) (ADDRESS = (PROTOCOL = TCP) (Host = apsdb) (Port = 1529)) ) (CONNECT_DATA = (service_name=APPTEST)(SERVER=DEDICATED)(FAILOVER_MODE= (TYPE=SELECT) (METHOD=BASIC) (RETRIES=1440) (DELAY =5)) ) )
a problém je vyřešen.
Původní zdroj: http://www.websina.com/bugzero/kb/oracle-connection.html
Docela mne překvapil i ten samotný fakt, že je možno takhle connection string zapsat.
Ú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á
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
Pokud se aplikace připojuje na Oracle v rámci lokálního počítače, vše funguje tak, jak má. Pokud ale přistupuje přes síť, používá zámky a někdo přetrhne spojení (vypne klientský počítač „natvrdo“, vytáhne síťový kabel), Oracle si nevšimne, že se spojení rozpadlo – a zámky zůstanou zamčené, dokud s tím DBA něco neudělá. Co s tím?
Existují dvě možnosti, jak to vyřešit.
Na „soft“ úrovni je to možné pomocí „resource profilů“ – konkrétně nastavením „IDLE_TIME“.
1) Nejprve povolíme profily v dané instanci Oracle:
alter system set resource_limit=true;
2) Pak uděláme profil s limitací IDLE_TIME na 3 minuty:
CREATE PROFILE LIMPROFILE LIMIT IDLE_TIME 3;
3) A nakonec tento profil přiřadíme k uživateli:
alter user appuser profile LIMPROFILE;
Co to udělá? Pokud v rámci spojení po zadanou dobu nepřijde žádný příkaz, spojení je přerušeno. Do „idle“ time se nepočítá čas, kdy databáze něco dělá – tj. pokud mi SELECT poběží 10 minut, je to v pořádku.
Tj. nekontrolujeme rozpad spojení, ale to, že se na něm nic neděje= budeme muset do aplikace dodělat nějaké „void“ akce typu SELECT * FROM DUAL, aby spojení nikdy nebylo neaktivní déle než zadaný čas.
Pozor! Spojení ukončené pro IDLE TIME se sice uzavře, transakce rollbacknou a zámky odemknou, ale spojení zůstane v tabulce SESSIONS ve stavu „SNIPED“. DBA jej musí smazat ručně (!!!).
Druhé řešení je lepší. V souboru network/admin/SQLNET.ORA na serveru je třeba založit novou konfigurační hodnotu:
SQLNET.EXPIRE_TIME=3
Tato hodnota říká, že pokud v TCP spojení na server více než 3 minuty neprojde žádný příkaz, server do něj pošle testovací paket, na který klientská Oracle knihovna odpoví. A pokud neodpoví, Oracle vezme spojení za mrtvé, korektně ukončí session (žádné „SNIPED“ stavy), rollbackne transakce a odemkne zámky.
Vedlejším efektem je malý nárůst síťového provozu (posílání testovacích paketů), ale za odstranění problémů se zamčenými a nedostupnými záznamy to stojí, ne?
Keywords: Oracle, DBA, locked record, session timeout
Microsoftí framework .NET nepovažuji za nejlepší možnou implementaci podobné věci. JVM je prostě lepší. Ale .NET obsahuje jednu kouzelnou funkci – zabudovaný kompilátor.
Na každém počítači, kde je .NET, je možné kompilovat objekty v C#. (Když je nainstalované i MS Visual Studio, je možné kompilovat i C++/CLR, ale to není pro širokou bázi zákazníků použitelné).
Co z toho plyne? Je možno napsat malou aplikaci, která dostane jako vstup textový soubor se skriptem v syntaxi C#, zkompiluje ho a spustí. Získáme tím silný skriptovací nástroj – oproti ve WSH zabudovanému VBScriptu či JScriptu v podstatě neomezený.
Tímto způsobem uvažovalo mnoho lidí a podobných nástrojů se dá stáhnout mnoho. Pan Programátor Oleg Shilo ovšem přemýšlel i dál a stvořil CS-Script. Kromě vlastního „interpretu“ C# skriptu (vím – není to interpret, ale kompilátror+spouštěč) udělal i sadu velmi silných knihoven a nástrojů… a vše to dal k dispozici pod licencí, která umožňuje i komerční použití.
Co to tedy umí?
Skriptování v C#, tak jak by člověk čekal. Ale taky kompilaci skriptu do EXE souboru, takže pak není potřeba žádný skriptovací systém. Nebo do DLL, takže se dá použít z dalších aplikací.
Tisk ze skriptu. Vytváření WinForms dialogů. Práce s webem(stahování URL včetně prostupu přes proxy, parsování XML, …). Použití.NET remotingu – jako klient i jako server.
Použití COM objektů – bez složitých nastavování. Následujcí kus kódu použije COM objekt pro zjištění režimu napájení. Jde to udělat jednodušeji?
//css_prescript com(SYSINFO.SysInfo.1, SisInfoLib);
using System;
using SisInfoLib;
class Script
{
[STAThread]
static public void Main(string[] args)
{
SysInfoClass sysInfo = new SysInfoClass();
switch (sysInfo.ACStatus)
{
case 0:
Console.WriteLine(„Not using AC power“);
break;
case 1:
Console.WriteLine(„Using AC power“);
break;
default:
Console.WriteLine(„Unknown AC power status“);
break;
}
if (sysInfo.BatteryLifePercent != 255)
Console.WriteLine(„Battery life „+sysInfo.BatteryLifePercent+“%“);
else
Console.WriteLine(„Battery charge status not known“);
}
}
Na tom prvním řádku (//css_prescript) je schováno to kouzlo – pomocí tohoto rozšíření jazyka se dělají věci, které by z „prostého“ C# skriptu šly dělat dost těžko.
On-fly použití WebServices, tj. v rámci skriptu se stáhne WSDL soubor, vygeneruje WebServices klient a je možno ho použít. Asi takto jednoduše:
//css_prescript wsdl(http://localhost/hello/hello.asmx?WSDL, HelloService);
//css_import HelloService;
using System;
using System.Xml;
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new HelloWorld().SayHello());
}
}
Statické použití WebServices – přiloženým nástrojem se z WSDL vygeneruje objekt klienta. A ten se používá. Snadno, rychle.
Vytvoření WebServices serveru …
using System;
using System.Web;
using System.Web.Services;
public class HelloWorld : System.Web.Services.WebService
{
[WebMethod]
public string SayHello()
{
return „Hello World (WebService)“;
}
}
… a jeho deploy do MS IIS:
cscs css2ws Hello.cs HelloWorld
a tak dále.
Prostě: moc hezké prostředí, doporučuji vyzkoušet.