čtvrtek 30. března 2017

Nová čidla pro WiFi Teploměr - měření vysoké teploty a vlhkosti

Před třemi měsíci jsem psal zhodnocení WiFi Teploměru s termostatem v roce 2016 spolu s výhledem na rok letošní. Nyní je čas ukázat, co se povedlo za první tři měsíce nového roku vymyslet a postavit. Na konci článku je zábavné video! :-)

Měření vysokých teplot

Můj WiFi Teploměr umí díky digitálním čidlům DS18B20 měřit teploty v rozsahu -55 ℃ až 125 ℃. Na měření teploty vzduchu nebo vody to stačí, ale objevily se i žádosti o měření mnohem vyšších teplot. Například se mi ozvali lidé, kteří udí maso a rádi by měli přehled o dění v udírně, zatímco sedí v nedaleké hospůdce u vychlazeného půllitru. Podobným případem je měření teplot spalin v komíně, protože řízení dnešních moderních kotlů na tuhá paliva je úplná věda. Určitě existuje i řada dalších míst či situací, kde bychom rádi měřili teploty nad 125 ℃.

Pro tyto případy jsem vymyslel a postavil následující převodník, který dokáže na 1-Wire sběrnici (kterou WiFi Teploměr používá) připojit klasický termočlánek. Ten je z kovu, a proto vydrží i vysoké teploty - běžně až 600 ℃, přičemž teoretické maximum převodníku je 1000 ℃:


Zásadní výhodou je, že se na jednu sběrnici (na jeden kabel) dá připojit libovolný počet těchto převodníků, tedy libovolný počet termočlánků měřících vysoké teploty na různých místech:


Podobné řešení jsem hotové nenašel a proto ho považuji za docela unikátní. Samozřejmě se dají na stejné sběrnici kombinovat tyto převodníky na měření vysoké teploty s klasickými čidly DS18B20 na měření běžných teplot. I proto přichází můj převodník rovnou s 3,5mm stereo jackem, jak je používám pro jednoduché budování sítě teplotních čidel pro WiFi Teploměr.

Měření vlhkosti

Kromě měření teplot v obytných místnostech (pro účely řízení vytápění či větrání) se od zájemců o WiFi Teploměr často objevovaly požadavky na měření vlhkosti vzduchu. Dlouhou dobu jsem to považoval za nevýznamné, ale nedávno mi praskl filtr vody ve sklepě, tryskající voda přímo z vodovodní přípojky vytopila čtyři místnosti a rázem mě začalo velmi zajímat, jak vlhko tam je a jak (pomalu) postupuje vysoušení těch místností zrovna během nejsilnějších mrazů.

Samozřejmě je vhodné měřit vlhkost vzduchu i při běžných situacích - například v koupelně po sprchování je dobré vědět, jak dlouho musí být zapnutý ventilátor, než vysaje přebytečnou vlhkost (což by ostatně mohl řídit i WiFi Teploměr s termostatem). Anebo v obytných místnostech naměřená hodnota vlhkosti napoví, kdy je potřeba vlhkosti do vzduchu přidat (typicky přetopené panelové byty) či naopak ubrat (typicky dokonale zaizolované novostavby, kde vodní pára z vaření, praní, mytí a vůbec dýchání lidí dokáže nadělat paseku). Další velkou oblastí je pěstování rostlin, například ve sklenících. Tam potom může WiFi Teploměr s termostatem řídit větrání nejen podle teploty, ale i podle vlhkosti.


Proto jsem postavil digitální vlhkostní čidlo, které dokáže poměrně přesně měřit v celém rozsahu 0 - 100 % relativní vlhkosti vzduchu. Kromě vlhkosti měří velmi přesně i teplotu v rozsahu od -40 do 125 ℃, takže toto čidlo dokáže nahradit i klasické čidlo DS18B20 na měření teploty! Toto čidlo je také určeno pro klasickou 1-Wire sběrnici a opět jich může být připojeno na jednom kabelu několik naráz. Stejně tak je možné kombinovat tato čidla vlhkosti s běžnými čidly pro měření teploty a taky s mými převodníky pro měření vysoké teploty:


Vlhkostní čidla pro 1-Wire sběrnici jsem na trhu nenašel a proto, podobně jako výše popsaná čidla pro měření vysoké teploty, považuji toto své řešení za unikátní. Navíc jsem si dal záležet i na vzhledu: inspiroval jsem se čistou barvou známou z jablečných výrobků a navrhl a vytiskl jsem malinkou krabičku na 3D tiskárně. Myslím, že toto čidlo v interiéru ostudu nenadělá.


Čidlo vlhkosti (a teploty) je opět určeno pro můj WiFi Teploměr, takže je připraveno k okamžitému zařazení do sítě čidel pouhým zasunutím stereo jack konektoru do stereo rozdvojky.
Aktuální verze je určena do interiéru, pro pokojové teploty.

Dostupnost a podpora

Převodník pro měření vysokých teplot termočlánkem i digitální vlhkostní čidlo jsou dostupné na www.teploty.info/cidla.html. Jsou podporované WiFi Teploměrem v aktuální verzi firmware (v7.9, březen 2017). Starší verze firmware nebudou s těmito novými čidly pracovat ideálně a proto bude vhodné ho aktualizovat. Taktéž stránky i grafy na www.teploty.info jsou připravené zobrazovat kromě naměřených teplot i vlhkost.

Zábavné video nakonec




pondělí 27. března 2017

3D tisk užitečných věcí

Mám už pátým měsícem 3D tiskárnu a konečně jsem měl chvíli čas vymyslet si nějaké užitečné věci. Návrh a tisk zacvakávacích krabiček už zvládám celkem dobře jak z PLA tak i z PETG:


Používám na to skript Generic Electronic Device Packaging for Tyndall version 2 odněkud z Thingiverse.com, ve kterém stačí jen správně nastavit proměnné v polích pro otvory a podpěry a je to. No, někdy to trvá týden a třeba 4 testovací výtisky, než všechny díry a podložky trefím správně, ale jde to myslím pořád lépe takto v OpenSCADu než třeba v Tinkercadu (či jiném myšovacím CADu).


Dobrá zpráva je, že PLA i PETG se nesmršťují (nebo se smršťují stejně?), takže je dokonce možné je zkombinovat v jedné krabičce a sedí to přesně na setiny milimetru (černá je PETG, bílá je PLA):


Včera jsem ale potřeboval něco navrhnout a vytisknout opravdu rychle. Zjistil jsem totiž, že jak jsem před třemi a půl lety pověsil na svod rýny čidlo pro měření teploty na slunci, tak že upadlo a bezmocně visí na kabelu hlavou dolů:


Kromě toho, že lepicí páska už nedržela, se také totálně rozpadlo pouzdro na čidlo, které jsem tehdy v nouzi narychlo vyrobil z krytky na vrták do dřeva. Plast na slunci za 3,5 roku totálně zkřehl a rozpadl se na šupiny. Což je dobře, protože už dlouho předtím se původně průhledný plast zakalil a tak mi měření teploty asi nefungovalo ani dost dobře.


Proto jsem si už před pár týdny koupil skleněnou zkumavku, která zůstane čirá navždy. Čidlo jsem do ní narychlo vlepil a hledal způsob, jak ho uchytit na svod rýny. No a jak se říká "když držím v ruce kladivo, všechny problémy naráz vypadají jako hřebíky", tak s 3D tiskárnou člověka napadne si jakýkoliv držák vymodelovat a vytisknout.

Jak jsem si usmyslel, tak jsem během pár minut i učinil. A rovnou to i vytiskl z PLA, o kterém se říká, že ho venkovní vlivy rychle zničí. Tak tohle bude aspoň takový test, jak dlouho vystavěné slunci, větru, dešti a mrazu vydrží.


Pro zajímavost přikládám i zdrojový kód, kterým jsem tento držák vytvořil:


outerD=19;
innerD=14.8;
height=10;
tiD=85;
toD=91;
translate([outerD/2+1, 0, 0]) difference() {
    difference()
    {
        cylinder(h=height,d=outerD);
        cylinder(h=height,d=innerD);
    }
    translate([1,-3,0]) cube([10,6,height]);
}
translate([-toD/2, 0, 0]) difference() {
    difference()
    {
        cylinder(h=height,d=toD);
        cylinder(h=height,d=tiD);
    }
    translate([-60,-75,0]) cube([40,150,height]);
}
translate([-3,-6,0]) cube([6,12,height]);

Na závěr fotka, jak si čidlo v bezpečí skleněné zkumavky pěkně hoví v novém držáku:


čtvrtek 23. března 2017

Daně OSVČ za rok 2016


Řešil jsem opět po roce daňové přiznání. Můj před dvěma lety popsaný postup pořád platí beze změn, takže jsem chtěl postupovat podle něj jako podle kuchařky (ostatně proto jsem to kdysi sepsal). Jenže neznám paragrafy a tak jsem hned v úvodu zabloudil v "adisepo" formuláři na několik hodin. Když jsem na to konečně přišel, rychle jsem si to sem poznačil, abych příští rok opět nebloudil.

Takže: správný postup zadání celkových příjmů OSVČ je následující: v 2. oddíle ("Dílčí základ daně") najít položku č. 37, ale nevyplňovat ji - místo toho kliknout vedle ní na tlačítko "Příloha 1". Na nové stránce v záhlaví zaškrtnout "Uplatňuji výdaje procentem z příjmů", srolovat dolů až do oddílu "B. Druh činnosti", vybrat nějakou činnost (osobně jsem zvolil "Programování", ale je to na vkusu každého soudruha), nastavit u ní sazbu výdajů % z příjmů a pak tam konečně vyplnit celkové příjmy. Takto se vše samo vypočítá a nakopíruje do správných políček nejen na této stránce, ale i na původní "2. ODDÍL - Dílčí základ daně", kam se vrátíme tlačítkem Zpět.

Je to vlastně velmi jednoduché, když člověk ví, kam kliknout.

středa 8. března 2017

Představení Orange Pi

Na Installfestu 2017 jsem měl 25 minut na představení počítačů z rodiny Orange Pi. Necelá půlhodina je samozřejmě velmi málo času - dalo by se o nich mluvit několik hodin. Přesto jsem se pokusil o jakýsi letmý přehled a srovnání s etalonem v této třídě - Raspberry Pi.

Zde je videozáznam přednášky:

Zde je odkaz na mou prezentaci v PDF.

Video startu a přehrávání videa

Na přednášce se mi ani v čase určeném původně pro oběd nepodařilo předvést start Orange Pi One, což mě velmi mrzelo. Předpokládám, že si nějak nerozuměl HDMI výstup Orange Pi One s HDMI vstupem tamního video systému. Mít víc času, dva síťové kabely a switch, propojil bych se s Orange Pi a přihlásil se na něj přes SSH. Anebo jsem mohl frajersky použít tu sériovou debug konzoli, kterou má každičký Orange Pi - serial/USB převodník jsem měl po ruce, jen jsem neměl správné piny...
Po připojení by stačilo spustit příkaz/program "h3disp", který je určený k nastavování různých HDMI frekvencí a rozlišení. Bohužel tolik času jsem tam neměl.



Proto jsem teď doma natočil krátký video záznam, který ukazuje nejen start systému Armbian a jeho desktop, ale také jsem zaznamenal průběh přehrávání testovacích videostreamů z jell.yfish.us - od 5Mbps až po 55Mbps, v H.264 i v novém HEVC (H.265). Myslím, že budete překvapeni, jak to na počítači za 250 Kč funguje (jen prosím omluvte kvalitu záznamu - mám Full HD monitor i FullHD videokameru v telefonu, ale není to bohužel správně zaostřené, takže to vypadá děsně):



h3disp

Jak jsem uvedl, "h3disp" dokáže editovat soubor script.bin, který obsahuje informace ke startu systému, krom jiného i nastavení grafického režimu: v této diskusi se poměrně podrobně rozebírá několik monitorů, které původně neběžely, ale pak se rozběhly (s poměrem stran 5:4 a podobně) a zde je zdrojový kód h3disp, kde nejlépe můžete vidět, kolik grafických režimů podporuje. Myslím, že tam najdete i ten svůj. Všimněte si, že je rozdíl mezi HDMI a DVI, je potřeba to v "h3disp" jasně zadat (parametrem -d pro DVI). Toto bude nejspíš ten důvod, proč mi to na Installfestu nenaběhlo - jejich HDMI vstup jistě fungoval jako DVI monitor.

GPIO

Pro bastlíře je skvělé, že všechny Orange Pi mají na 40pinovou (Zero 26pinovou) lištu vyvedenu celou řadu pinů procesoru, se kterými si můžete hrát jako na Arduinu, tj. rozsvěcet světýlka, číst hodnoty všemožných senzorů nebo třeba připojit celý displej. Na Raspberry Pi slouží pro pohodlný Arduino-like přístup k těmto pinům knihovna WiringPi. Je dostupná i pro Orange Pi: www.orangepi.org/Docs/WiringPi.html
A pokud jste orientovaní spíš na Python, tak potom zkuste tuto knihovnu: github.com/duxingkei33/orangepi_PC_gpio_pyH3

Pokud vám chybí ještě nějaká informace k Orange Pi, která na mé přednášce nezazněla, dejte vědět, doplním ji sem.

neděle 5. března 2017

Arduino - vzdálené programování

Před pár hodinami jsem měl přednášku na Installfestu, kde jsem se snažil shrnout své několikaleté zkušenosti se vzdáleným programování Arduin přes Bluetooth, WiFi a Ethernet. Cílem tohoto článku je doplnit onu přednášku o konkrétní čísla, útržky programů a další drobnosti, které se do přednášky z časových, technických či jiných důvodů nedostaly:


Zde je odkaz na mou prezentaci v PDF.

Bootloader a pojistky

Jádrem přednášky byla "teorie" o bootloaderech - krátkých prográmcích, které jsou uložené ve vyhrazené části Arduino flash paměti a které se podle nastavení fuses ("pojistek") spouštějí po zapnutí či resetu Arduina, resp. mikrokontroléru ATmega328p.

Pojďme se proto podívat, co všechno fuses umějí u ATmegy328p nastavit. Na kalkulačce vybereme "AVR part name" ATmega328P a už to vidíme:

Toto nastavení platí pro "standardní" hodnoty pojistek u Arduina s bootloaderem Optiboot - tyto hodnoty jsou Low=FF a High=D6 (což se dá předvyplnit dole na stránce, pokud známe hexadecimální hodnoty pojistek a chceme se podívat, co ty hodnoty znamenají v lidské řeči).

Čteno shora dolů tam máme: externí krystal s frekvencí 8 nebo více MHz (což je OK, Arduino má standardně 16 MHz krystal). Dále je zapnutý Boot Reset vector, což je důležité, pokud chceme, aby se po resetu skočilo do bootloaderu. A v rozbalovacím menu je vybrána velikost Boot Flash sekce "256 slov". Jak jsem na přednášce stihl říct, 256 slov se rovná 512 bajtům.

Zároveň vidíme, kam bude mířít ten Boot Reset vector - na adresu $3F00, což je decimálně  16128, ale i toto číslo je v 16bitových slovech, takže v bajtech se jedná o adresu 32256. Na tuto adresu budeme chtít nahrát náš bootloader, protože sem po zapnutí či resetu skočí mikrokontrolér pomocí onoho Boot Reset vectoru. Mimochodem, adresa 32256 je právě 512 bajtů od konce 32kB (32768bajtové) flash paměti, což odpovídá tomu, že bootloader je vždy uložen na nejvyšších adresách flash paměti.

Z dalších nastavení "pojistek" vidíme, že při "Chip Erase" (mazání čipu) nedojde ke smazání paměti EEPROM (což je dobře, pokud v ní máme uložené nějaké vlastní hodnoty), a poslední zapnutou volbou je SPI programování, což je naprosto klíčové. Pokud byste si vypnuli toto SPI programování, anebo o dvě volby níže si zapnuli vypnutí resetu (Reset Disabled), tak už standardně daný mikrokontrolér  nebudete schopni naprogramovat a pak je poslední záchranou na přednášce zmíněné paralelní vysokonapěťové ("parallel high-voltage") programování.

Jinými slovy: pokud chcete zachovat běžnou funkčnost Arduina, neměňte nic než nastavení velikosti Boot Flash sekce.

Při každé změně kteréhokoliv nastavení se ihned přepočítají všechny odpovídající hodnoty na celé stránce, takže dole neustále vidíte výsledné správné hodnoty pojistek a dokonce i parametry příkazu avrdude, kterými dané pojistky zapíšete do ATmegy. Takže si zkusíme třeba změnit velikost Boot Flash sekce z 256 slov na 512 slov (což je nutné, pokud potřebujeme zapsat bootloader delší než 512 bajtů, a kratší než 1024 bajtů, jako je případ Optibootu upraveného pro Ethernet). Vidíme, že adresa Boot startu se změnila na $3E00, což je decimálně a v bajtech 31744. Hodnoty pojistek se změnily (dole na stránce kalkulačky) následovně:


Čili Low zůstává FF, ale High se změnila z D6 na D4. Vedle v "AVRDUDE arguments" jsou vidět i všechny parametry pro avrdude, které dané hodnoty zapíší.

To znamená, že pokud použijete jiné Arduino jako programátor ("Arduino as ISP"), jak jsem na přednášce pro začátek doporučoval, celý avrdude příkaz (nastavení pojistek + vypálení bootloaderu Optiboot s úpravou pro Ethernet) bude vypadat následovně:

avrdude -p m328p -c avrisp -P /dev/ttyUSB0 -b 19200 \
 -U lfuse:w:0xff:m -U hfuse:w:0xd4:m \
 -U flash:w:./optiboot_atmega328.hex

Tak. Pokud použijete Arduino UNO jako programátor, tak je možná vašemu systému známé jako zařízení /dev/ttyACM0 místo /dev/ttyUSB0, ale to je kosmetický detail, se kterým si poradíte (protože tuto hodnotu vidíte krom jiného i v Arduino IDE, když si vybíráte sériový port v menu Nastavení).

Programátor "Arduino as ISP"

Jak z Arduina udělat ISP programátor pro jiná Arduina či Atmel AVR čipy je popsáno na mnoha stránkách - např. přímo od Arduina tady. Princip je jednoduchý: nejdřív do Arduina nahrajeme z Arduino příkladů program zvaný "ArduinoISP" a teprve poté zapojíme 10uF kondenzátor mezi RESET tohoto Arduina a zem. Díky kondenzátoru při příštím nahrávání programu z Arduino IDE nedojde k obvyklému resetu programovacího Arduina, což je moc dobře, protože my nechceme nahrávat nový program do něj, ale jen ho poslat skrz něj do dalšího Arduina, zapojeného za ním přes SPI port.

Sám jsem si postavil vlastní ISP programátor z jednoho nepoužívaného Arduino Nano. Na fotce je vidět i ten 10uF kondenzátor. Jak tak studuju to zapojení na té univerzální destičce, zdá se mi, že mám ten kondenzátor celou dobu zapojený špatně! Mám ho mezi RESET a VCC místo GND. Zajímavá chyba, musím to předělat:


Softwarový reset

Jak jsem na přednášce zmínil, bootloader se dostane ke slovu vždy po zapnutí či resetu Arduina/ATmegy328p. Proto pokud chceme nahrávat nový program, potřebujeme Arduino resetovat. Normálně se toto děje pomocí signálu sériového portu DTR (Data Terminal Ready - z doby, kdy k sálovým počítačům byly připojené terminály), kterýžto je přes kondenzátor připojen přímo na RESET signál Arduina.

Při programování přes WiFi jsem doporučil připojit pin GPIO0 od ESP8266 přímo na RESET pin Arduina - potom firmware esp-link automaticky resetne před programováním a vše funguje transparentně, jak jsme z Arduino IDE zvyklí. Pokud ale programujeme Arduino vzdáleně přes Bluetooth nebo přes Ethernet, nemáme jaksi po ruce signál DTR, takže si musíme pomoci jinak a Arduino resetovat softwarově.

K softwarovému resetu zneužijeme HW watchdog - nezávislého hlídače vestavěného do každého procesoru ATmega. Nejkratší kód, který zajistí reset celého mikrokontroléru, vypadá takto:

    wdt_enable(WDTO_250MS);
    while(1);

Funkcí wdt_enable() nastavíme čas, do kterého musíme watchdog counter resetnout, jinak resetne on nás (250 milisekund), a pak neděláme nic (while(1); se zacyklí na místě), takže watchdog za 250 milisekund skutečně resetne celý mikrokontrolér, což jsme přesně chtěli.

Pozor na starší bootloadery (dnes už jen z Číny na klonech Arduin), které zapomínaly watchdog vypnout. V takovém případě se pak vlastně Arduino donekonečna samo restartuje každou čtvrtsekundu. Pokud ale nejdříve nahrajete Optiboot (tj. ten krásný nový krátký bootloader), tak s ním problém při SW resetu watchdogem nenastává, protože má jako jednu z prvních instrukcí vypnutí watchdogu.

V případě, že programujeme Arduino přes Ethernet, musíme ještě nastavit příznak v EEPROM, aby bootloader věděl, že chceme začít nahrávat novou verzi firmware a počkal na data proudící po síti. Pak celý kód (zapsání příznaku a resetnutí Arduina) vypadá takto:

    EEPROM.update(0x22, 0x55);
    wdt_enable(WDTO_250MS);
    while(1);

Nastavení IP adres v EEPROM

Při programování Arduina přes Ethernet, jak vymyslel a popsal Will Soberbutts, je potřeba do paměti EEPROM připravit sadu IP adres tak, aby bootloader po startu věděl, jak má nastavit Ethernet shield. Osobně pro to používám následující kód:

void setup_ethernet_bootloader_address()
{
    byte addr[] = {
        192, 168, 1, 1,     // gateway
        255, 255, 255, 0,   // netmask
        0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED, // MAC
        192, 168, 1, 102    // address
    };
    for(byte i = 0; i < sizeof(addr); i++)
        EEPROM.update(i + 0x10, addr[i]);
}

Tuto funkci je dobré zavolat hned ze setup(void) funkce. Samozřejmě je nutné nastavit ty adresy podle situace ve vaší síti. MAC adresa je vymyšlená ("DeadBeefFeed") a funguje dobře. Jen pokud máte doma víc Arduin s Ethernetem, je nutné každému přiřadit jinou MAC adresu - stačí měnit jen poslední číslici,  začátek (0xDE) neměňte.

Bezpečnost

Přednáška pominula otázku bezpečnosti celého konceptu vzdáleného nahrávání nového firmware do Arduina. Pravda je, že na Ethernetu na to trošku hřeším - spoléhám se na to, že se mi doma nikdo zlý do sítě nepřipojí, že k ní prostě fyzicky nebude mít přístup. Bezdrátová připojení (Bluetooth/WiFi) jsou zřejmě zranitelnější ("tati, proč na naší ulici už týden parkuje ta černá dodávka se zatmavenými skly?"), takže by to něco chtělo. Nejjednodušší by zřejmě bylo firmware zašifrovat na PC, odeslat šifrované a rozšifrovat bootloaderem předtím, než dojde k uložení do flash paměti Arduina, ale do toho jsem se zatím nepouštěl. Vyžadovalo by to větší zásahy do bootloaderu, hodně času na ladění atd. Možná se k tomu dostanu někdy časem.

Závěr

Programovat Arduino vzdáleně je největší pohoda. Mimochodem, je to vlastně důvod, proč jsem z Arduin nepřešel na STM32 - tam jsem totiž možnost vzdáleného programování přes Ethernet vůbec nenašel. Proto všem doporučuji zkusit si to doma - jakmile to rozjedete, už nebudete chtít jinak :-)

EDIT: 5.3. v 19:30 doplněno pár drobností.