středa 19. dubna 2017

Nový, digitální laboratorní zdroj

Starý zdroj a jeho neduhy


Před třemi lety jsem si postavil "laboratorní zdroj" prakticky zadarmo z ATX zdroje z vyřazeného PC. Tady o tom nadšeně bloguji. A takto vypadal:


Na první pohled vše fungovalo dobře, ale časem se ukázala jedna výrobní vada, jedna konstrukční chyba a dva fatální nedostatky celého zdroje. Výrobní vadou bylo, že při velkém proudovém nárazu se zdroj jednoduše vypnul. Zafungovaly tam zbytky nějaké nadproudové ochrany, a protože úprava ATX zdroje na proměnlivé napětí byla velmi nedokonalá a krutá, nadproudová ochrana spínala v podstatě náhodně i u malých proudů, přestože zdroj měl být schopen dodávat až 12 ampér.

Konstrukční chybou bylo použít jeden displej pro výstupní napětí i odebíraný proud. Měl jsem tam sice přepínač mezi napětím a proudem, takže jsem si mohl pořád přepínat sem a tam, ale jak člověk nevidí obě klíčové hodnoty naráz, je to nešikovné.

No a ty dva fatální nedostatky? Prvním je chybějící omezení výstupního proudu. Pokud jsem totiž zapojil jakýkoliv pokusný obvod špatně, tak po připojení k tomuto "laboratornímu" zdroji obvykle následovaly kouřové efekty a jak známo, kouř je uzavřený uvnitř součástek, a jakmile jednou unikne, součástku už nic nepohání a proto přestane fungovat. Kdybych měl možnost omezit proud ze zdroje třeba na 50 mA, tak by mi přežilo mnoho součástek při mých pokusech.

Druhý fatální nedostatek je vlastně taky konstrukční chybou, ale samotného ATX zdroje. Projevilo se to, když jsem se snažil změřit odběr proudu obvodu s ESP8266 pomocí mého nového a velmi drahého digitálního osciloskopu. Stalo se to 20. června 2016 a tehdy jsem to popsal na mém Google+ profilu: https://plus.google.com/+PetrStehlík/posts/6pjpoezBvHe

Ve zkratce jde o to, že "záporný" pól ATX zdroje (tedy společná zem na sekundární straně) je vodivě propojen s ochranným kolíkem v elektrické zásuvce! To jsem vůbec netušil. No a jelikož je i zemnicí vývod osciloskopové sondy připojen také na ochranný kolík v elektrické zásuvce (což jsem taky netušil), tak kdykoliv něco měřím osciloskopem v obvodu napájeném z mého starého "laboratorního" zdroje a zemnění osciloskopické sondy nemám připojeno na zem obvodu, tak část obvodu krutě zkratuju přes přívodní kabely ATX zdroje a osciloskopu a elektrické vedení v domě!

Po této nepříjemné zkušenosti jsem se rozhodl, že můj nový laboratorní zdroj musí být galvanicky zcela oddělený od elektrické sítě, včetně ochranného kolíku. Nejjednodušší bude použít zdroj třeba k notebooku, kde jsem si proměřením ověřil, že k ochrannému kolíku sekundární strana vodivě připojena není.

No a tady už prozrazuji, o čem vlastně tento blog post je - ostatně jsem to hned v srpnu 2016 nakousl na Google+:
https://plus.google.com/+PetrStehlík/posts/L4PeEYdzkk3

Nový zdroj


Koupil jsem si totiž v Číně docela levný modul, který má zjevně sloužit ke stavbě zdroje. Jmenuje se
DP30V5A a je to prý upgraded version DPS3005 (nebo naopak?). Vlastnosti jsou popsány takto: Constant Voltage current Step-down Programmable converter Power Supply Ammeter voltmeter Module.

Z popisu můžeme vytušit, že je to digitálně řízený (programovatelný) zdroj konstantního napětí či konstantního proudu, který mění vstupní stejnosměrné napětí na výstupní jako step-down konvertory, takže téměř beze ztrát. Výstupní napětí může být až 30 V (ale vždy o cca 2 V nižší než napětí vstupní), výstupní proud až 5 A (to podle výkonu zdroje na vstupu, díky step-down konverzi může být výstupní proud i vyšší než proud ze zdroje).

Kromě této verze na 30 V a 5 A jsou k dostání další varianty lišící se maximálním výstupním napětím (až 50 V) a proudem (až 15 A). Můžete si vybrat, podle toho, jak silný zdroj vstupního stejnosměrného napětí máte a jak moc velký proud budete na výstupu potřebovat.


Všechny verze mají společné velmi jemné nastavování výstupního napětí a proudu: napětí v setinách voltu a proud dokonce v jednotkách miliampér! Velmi úžasné a praktické.


Krabička je křehká, návod čínsky:


Balení pofiderní, ale cestu přežilo celkem bez úhony:


Modul je připraven k montáži do nějakého panelu:


Zezadu  je vidět pořádná cívka, pěkné kondenzátory a poctivý chladič. Celkem to vzbuzuje důvěru, nebo aspoň naději:


Jak mi koncem července 2016 přišel, ihned jsem mu zapojil na vstup 90W zdroj od notebooku (18 V a 4,5 A), a na výstup jsem připojil kablík s napájecím jackem 5,5 mm / 2,1 mm.

Od té doby jsem ho takto používal prakticky denně a nemohl si vynachválit, jak úžasné je mít možnost omezit výstupní proud zdroje. Skutečně to používám neustále a už mi to mockrát zachránilo [vy víte co]. Teď se mi smějí všichni čtenáři, kteří už skutečný laboratorní zdroj doma mají roky, ale pokud je tu ještě někdo, kdo doma zdroj s omezením proudu nemá, tak ihned pořídit! Je to prostě nepostradatelná věc.

Už mě ale unavilo to pořád nosit takto rozdělané a proto jsem se rozhodl mu pořídit pěknou krabičku. Hlavně jsem chtěl na vstup přidat konektor, abych mohl připojovat jakýkoliv zdroj od kteréhokoliv notebooku, a ssebou přenášel jen tento maličký modulek a nikoliv neskladný zdroj k ntb spolu se všemi jeho kabely.

Díky 3D tiskárně i3 MK2 už nemusím krabičky vytesávat ze dřeva či železa. Stačí si je navrhnout a vytisknout. Tady jsem udělal začátečnickou chybu, a nepodíval se nejdřív na internet, kde bych jinak našel už hotovou krabičku (protože všechno, co děláte, už někdo udělal před vámi a navíc nahrál na internet - Jára Cimrman by mohl vyprávět).

Místo toho jsem se (oslněn mými aktuálními úspěchy v modelování 3D objektů) vrhl ihned na tvorbu krabičky na míru. Měl jsem docela jasnou představu zkoseného čelního panelu (aby byl displej dobře čitelný a ovládací prvky dobře přístupné), ale nevěděl jsem přesně, jak bych to jednoduše udělal v mém oblíbeném OpenSCADu. Proto jsem zkusil cloudový CAD Onshape.com, ve kterém jsem zatím naprostým nováčkem. Tady je výsledek mého krátkého snažení (šlo v něm tvořit nečekaně pohodlně a rychle!): krabička laboratorního zdroje (na OnShape.com si ji můžete zkopírovat, upravit a vytisknout).


A takto vypadá výsledek:


Krabičku jsem vytiskl z PETG, aby vydržela vyšší teploty, pokud by se modul zahříval (ve skutečnosti se mi ještě nikdy neohřál, protože vysoké proudy při své běžné práci nepoužívám, ale co kdyby jednou...). Nahoře jsem přidal i řadu větracích otvorů, aby to vypadalo úplně profi :-) Vzadu je pak konektor, který jsem vypreparoval z jednoho notebooku. Byla to taková šikovná kostička, dokonce měla na boku otvor pro šroubek, tak jsem ji tam přišrouboval - přesně tam sedí.



Na výstupu by každý z vás čekal typické banánky, ale já jsem je tam schválně nedal a místo toho jsem zezadu opět vyvedl jen kablík s napájecím jackem 5,5 / 2,1 mm. Doma do něj zapojuju vše počínaje WiFi Teploměry, přes různá Arduina a mám i propojku s krokosvorkami, takže si skutečně plně vystačím i bez klasických banánků.


A to je vlastně vše. Modul je krásně digitální, nastavím si poměrně pohodlně výstupní napětí a proud (oboje pak přesně drží i pod proměnlivou zátěží), vidím neustále napětí, proud i celkový příkon a je tam i deset pamětí pro vlastní přednastavené hodnoty (které zapomínám používat). Levná (cca 600 Kč) a přitom opravdu funkční věc, kterou vřele doporučuji! :-)

Ještě jsem neodolal a natočil krátké video, kde ukazuju, jak jednoduše se modul obsluhuje:


Tak a to je vše! Pokud jste nevěděli, jaký zdroj si pořídit, tak teď už snad víte :-)

pondělí 17. dubna 2017

Arduino, OpenSCAD a krokové motory

Měl jsem doma už dlouho hromádku krokových motorů odněkud ze šrotu, a když jsem teď měl chviličku volna a nápad na věc, kde by byl krokový motor nezbytný, pokusil jsem se je oživit. V následujícím videu vše ukazuju a vysvětluju:



S pomocí příkladů od knihovny Stepper, která je standardní součástní Arduino IDE, jsem napsal následující jednoduchý prográmek pro otočení krokového motoru o osminu otáčky (o 45 °) po stisknutí tlačítka připojeného na pin A0 a zem:

#include <stepper.h>

const int stepsPerRevolution = 50;
Stepper myStepper(stepsPerRevolution, 2, 3, 4, 5);

void setup()
{
    pinMode(A0, INPUT_PULLUP);
    myStepper.setSpeed(60);
}

void loop()
{
    static byte krok = 0;
    if (!digitalRead(A0)) {
        myStepper.step(6 + (((krok++ % 4) == 0) ? 1 : 0));
        delay(100);
    }
}


SCAD zdrojový kód pro unašeč CD, nasazený na hřídeli krokového motoru. Používá knihovnu Gears pro vytvoření ozubené díry. Vytištěno z PETG na i3 MK2 za 16 minut:

include <gears.scad>;
zuby_h = 7.4;
cd_d = 14.9;
cd_h = 1.2;
vyska = 8;
union() {
    difference() {
        cylinder(vyska, d1=18, d2=30);
        linear_extrude(height = zuby_h) gear(number_of_teeth=15, circular_pitch=100, clearance = 0);
    }
    translate([0, 0, vyska]) cylinder(cd_h, d1=cd_d, d2=cd_d);
}


SCAD zdrojový kód pro podstavec motoru, aby tento necestoval po stole. Vytištěný také z PETG, protože motor se zahřívá (i když stojí!), takže podstavec z PLA (ze kterého jinak tisknu vše) by se pod ním nejspíš roztekl:

prumer = 60;
vyska = 2.4;
dira_d = 12;
dira_h = 2.2;
roztec = 49.5;
sloup_d = 6;
sloup_h = 13.4;
sroub_d = 2.8;
sroub_h = 6;
union() {
    difference() {
        cylinder(vyska, d1=prumer, d2=prumer);
        translate([0, 0, vyska - dira_h]) cylinder(dira_h, d1=dira_d, d2=dira_d);
    }
    translate([roztec/2, 0, vyska]) sloupek();
    translate([-roztec/2, 0, vyska]) sloupek();
}

module sloupek() {
    difference() {
        cylinder(sloup_h, d1=sloup_d, d2=sloup_d);
        translate([0, 0, sloup_h-sroub_h]) cylinder(sroub_h, d1=sroub_d, d2=sroub_d);
    }
}

A to je vše :-)

č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í.