Raspberry Pi


63) Řízení otáček ventilátoru v RasPi přes I2C

Měl jsem teď trochu volno, a tak jsem si vymyslel, že zkusím navrhnout nějaký jednoduchý obvod pro řízení otáček malého ventilátoru, který by se dal připojit k RasPi a který by v závislosti na teplotě procesoru automaticky řídil výkon ventilátoru.

Nejjednodušším řešením by bylo využít jeden pin na GPIO v Raspberry Pi, který by generoval PWM signál.
Tohle řešení má několik nevýhod.
  1) Ztráta jednoho GPIO pinu.
  2) Generování PWM zbytečně zatěžuje RasPi a navíc je nestabilní.
  3) V tomto nejjednodušším případě není možné vyhodnocovat aktuální stav ventilátoru (skutečné otáčky)

Pokud vám tyto nevýhody nevadí, tak tady je popsáno toto jednoduché ovládání:

Ovládání pomocí GPIO


Řešení s ATtiny

Já jsem se ale rozhodl pro trochu složitější řešení.

Abych ušetřil GPIO piny a abych nemusel RasPi zbytečně zatěžovat generováním PWM signálu, použil jsem pro řízení otáček mikrokontroler ATtiny, který bude s RasPi komunikovat přes I2C a sám se bude starat o generování PWM signálu.

S mikrokontrolerem jsem měl jasno hned na začátku. Kvůli komunikaci I2C bylo nutné zvolit alespoň ATtiny25, který v sobě obsahuje USI (Univerzální Sériový Interfejs). 
Při pozdějším přidávání dalších funkcí se ale paměť pro program v ATtiny25 rychle zaplnila a tak jsem použil o trochu výkonnější ATtiny85.

V původním plánu bylo i zpětné zjišťování otáček ventilátoru pomocí vestavěného čidla ve ventilátoru.

Jak se ale ukázalo, vestavěný výstup z tachometru ventilátoru je při PWM řízení otáček téměř nepoužitelný.
 Signál na TACHO výstupu vypadá totiž nějak takto:
   (červený kanál je PWM signál na řídící elektrodě FET tranzistoru, žlutý kanál je napětí na TACHO výstupu)


Větší obrázky tady a tady


Zkoušel jsem různé techniky digitální i analogové filtrace signálu, ale nic z toho se nepodařilo dotáhnout do úspěšného konce.
Když se mi konečně podařilo najít řešení, které dokázalo alespoň zjistit jestli se ventilátor točí (pomocí počítání impulzů), chtěl jsem to ověřit na jiném ventilátoru. Zjistil jsem ale, že ten jeho TACHO výstup je úplně odlišný. Takže univerzální řešení pro vyhodnocení TACHO výstupu ventilátoru asi neexistuje.


TACHO výstup z jiného ventilátoru při PWM napájení.

Když jsem pak zjišťoval, jak to řeší profesionálové, zjistil jsem, že podvádí. Po dobu měření otáček totiž do ventilátoru pustí na chvíli plný výkon. V signálu z tachometru je při konstantním napájení už jen obyčejný obdélníkový signál, jehož frekvence je 1/30 otáček ventilátoru za minutu. Takto čistý signál už není problém zpracovávat. Nevýhoda ale je, že pokud by byl ventilátor zadřený a pustil by se do něj plný výkon, tak by se mohl pootočit a zadřený ventilátor by se tak nerozpoznal.

Nakonec jsem tedy přistoupil k plánu "B" - přidělal jsem k ventilátoru vlastní čidlo otáček (Hallovu sondu).
Konkrétně jsem použil typ SS49E.

Výstupem z Hallova senzoru je pak takovýto signál:


Ventilátor se točí

STOP v LOW stavu

STOP v HIGH stavu

Jak je z obrázků vidět, napětí se pohybuje mezi hodnotami 2V až 3V. Takovéto úrovně jsou ale nepoužitelné. ATtiny by nedokázalo vyhodnotit 2V jako logickou "0".

Podle katalogového listu by měl mít signál ve stavu logické "1" hodnotu alespoň 2V. Ve stavu logické "0" maximálně 1V.
Pokud samotné čidlo není schopné dodávat signál s takovým rozkmitem, musí se pomocí děliče napětí upravit tak, aby byl někde uprostřed tohoto pásma. Pomocí servisního režimu (popsáno níže) se pak ověří, že ATtiny rozezná oba logické stavy. 

 

Místo magnetické sondy je možné použít i optické reflexní čidlo, takže toto řešení se hodí i pro nejmenší ventilátory, na které stačí nalepit černobílý papírový terčík a namířit na něj fotočidlo s LED diodou.
Pro pokusy jsem použil infrazávoru TCRT5000


infrazávora TCRT5000
  
Ve skutečnosti světlo z infradiody není vidět

 

 


Popis I/O pinů a schéma

ATtiny85 má k dispozici 5 vstupně výstupních pinů (+ jeden pin RESET). 
Dva z těchto pinů jsem použil pro I2C komunikaci s RasPi.
Jeden pin slouží k ke generování PWM signálu pro řízení otáček ventilátoru.
Další pin je vstup od čidla otáčení.

Protože zbyl jeden ještě nevyužitý pin, vyvedl jsem na něj signál "STOP ALARM". Tento signál se aktivuje v případě, že by se měl ventilátor otáčet (PWM výkon je větší než 0%), ale ve skutečnosti se neotáčí (motor je zadřený). Na tento pin je možné připojit signalizační LED, nebo pískák. 

Resetovací pin jsem nevyužil.

Servisní režim se aktivuje tehdy, pokud je při zapnutí napájení do ATtiny pin PB1 v logické "1" (připnutý na napájení).
Pak LED na PB3 kopíruje logický stav na výstupu čidla otáčení (PB4). V tomto režimu je možné mechanicky nastavit čidlo tak, aby se jeho výstup bezpečně překlápěl mezi stavy "0" a "1".

Připojením PB1 do logické "1" se zároveň přes FET tranzistor pustí napájení do motoru ventilátoru, takže by se měl roztočit na plný výkon. 

Když se pak zruší propoj mezi PB1 a napájením, motor se zastaví - je možné s ním ručně otáčet a nastavovat čidlo.

Servisní režim trvá až do resetu ATtiny.  

 


Software

Celé řízení ventilátoru se skládá ze dvou částí.

Jedna část programu (Python) se nachází v Raspberry Pi a slouží ke zjišťování teploty procesoru, přepočtu této teploty na požadovaný PWM výkon a vyhodnocování informací, které se získávají z ventilátoru.

Druhá část programu je v ATtiny. Ta se stará o příjem I2C příkazů, generování PWM signálu a testování signálu z čidla otáčení.

Python

Před prvním použitím programu je třeba nastavit správné konstanty pro přepočet.

Jedná se o :
 - minimální PWM výkon, který dokáže udržet ventilátor bezpečně v chodu
 - maximální teplotu procesoru, nad kterou poběží ventilátor na 100% výkonu
 - minimální teplotu procesoru, pod kterou se ventilátor vypne 

Minimální a maximální teploty se nastaví podle potřeby. Například 36 a 42°C.
Minimální PWM výkon se musí zjistit testováním. V programu je zabudovaná funkce, pomocí které je možné ručně zadávat PWM výkon v rozsahu 5 až 255 a sledovat, při jaké hodnotě se ventilátor bude ještě bezpečně točit.

Tato funkce se aktivuje při spuštění programu s parametrem " test".

sudo python /home/pi/ventilator.py test

 

Pro zjišťování teploty procesoru jsem v programu použil příkaz:
cat /sys/class/thermal/thermal_zone0/temp

Vrácené číslo udává teplotu v tisícinách °C.  Rozlišení teploty (minimální krok při změně teploty) je 0,538°C . 

Existuje i příkaz pro zjišťování teploty grafického čipu, ale ten v programu nepoužívám, protože je v textové formě a musel by se ještě převádět na číslo. Obě hodnoty jsou ale dost podobné, tak nemá cenu se tím zatěžovat.
/opt/vc/bin/vcgencmd measure_temp

 

 

 

ATtiny:

ATtiny zajišťuje hlavně nezávislé generování PWM signálu pro napájení ventilátoru. K tomu slouží 3 registry:


(fialové hodnoty jsou nastaveny v programu)

Dále se ATtiny stará o příjem příkazů z I2C komunikační linky a o odesílání informací zpátky do RasPi. K tomu jsem použil hotovou knihovnu pro I2C komunikaci ( https://github.com/rambo/TinyWire ).

Jak se ale ukázalo, občas dochází při komunikaci k chybám. Možná je to způsobeno rychlostí generování PWM signálu, protože když jsem tuto rychlost snížil na frekvenci 4kHz, tak k výpadkům v komunikaci už nedocházelo. Problém byl pak ale v tom, že na nižší frekvenci PWM signálu už ventilátor nepříjemné pískal.

Proto jsem vrátil zpátky vysokou frekvenci PWM signálu (32kHz) a v Pythonu jsem odchytával chyby v komunikaci. Když k nějaké chybě došlo, provedl program ještě několik pokusů o navázání spojení s ATtiny. 

Poslední věcí, kterou ATtiny hlídá, je čidlo otáčení ventilátoru. Jak jsem psal výše, nebylo při PWM řízení otáček možné použít vestavěné čidlo ve ventilátoru, ale musel jsem přidat čidlo, které bylo oddělené od PWM napájení ventilátoru.

Nevýhoda je v tom, že musí být provedeny mechanické úpravy (buď vlepení Hallovy sondy dovnitř ventilátoru, nebo přilepení dalšího magnetu na rotor ventilátoru, případně nějaký držák na optočidlo).

Tady je pro inspiraci několik ukázek mých pokusů o mechanické připevnění čidel:


Připojení magnetického čidla bez nutnosti rozebírat ventilátor.
Při velké axiální vůli rotoru ale hrozí, že dojde ke kontaktu čidla a magnetického kroužku.

 


Vlepení magnetického čidla přímo do ventilátoru.
Vhodné pouze pro větší ventilátory, ve kterých je dostatek prostoru.
Výhodou je velká amplituda výstupního signálu, která se pak dobře zpracovává.

 


Nalepení dalšího magnetu zvenku na rotor.
Tohle není moc dobré řešení.
 Magnet se musí umístit tak, aby byl rotor dokonale vyvážený - jinak bude při vyšších otáčkách vibrovat.
Také Hallova sonda se kvůli pravidelnému kolísání magnetické síly při otáčení vrtule rozkmitávala.

 

Optické čidlo s černobílým terčíkem.
Dá se použít i na nejmenší ventilátory.
Při výrobě terčíku je nutné dodržet pravidelné střídání černé a bílé barvy (dodržet střídu 50%).

 

 

ATtiny dokáže zpátky do RasPi posílat informace o aktuálním stavu ventilátoru.

Přepnutí na požadovanou veličinu se provede speciálními příkazy odeslanými přes I2C.

Přepnutí na odesílání aktuálních otáček bus.write_byte(i2c_adresa, 1)
Přepnutí na odesílání informací o stavu výstupu "STOP ALARM" bus.write_byte(i2c_adresa, 2)
Přepnutí na zjišťování aktuálního PWM bus.write_byte(i2c_adresa, 3)
Příkaz pro zpožděné zastavení ventilátoru bus.write_byte(i2c_adresa, 4)

Všechny ostatní hodnoty slouží ke změně výkonu PWM generátoru. 
Například :

Zastavení ventilátoru bus.write_byte(i2c_adresa, 0)
Spuštění ventilátoru na 50% výkonu bus.write_byte(i2c_adresa, 127)
Spuštění ventilátoru na 75% výkonu bus.write_byte(i2c_adresa, 192)
Spuštění ventilátoru na 100% výkonu bus.write_byte(i2c_adresa, 255)

 

Příkaz v Pythonu pro zjištění požadované hodnoty je pak:

    i2c_data = bus.read_byte(i2c_adresa)

 

Při odeslání příkazu pro zpožděné zastavení ventilátoru se ještě po dobu 1 minuty bude ventilátor točit na 75% výkonu a pak se výkon sníží na 0%. Tato funkce by měla být spuštěna před vypnutím RasPi. Zajistí dochlazení procesoru a automatické vypnutí. 

Při zjišťování otáček je třeba dát pozor na počet impulzů, které generuje ventilátor na jednu otáčku.
Pokud dostává čidlo otáčení 2 impulzy na otáčku, stačí získané číslo vynásobit 10.
Když čidlo dává jen 1 impulz na otáčku, je třeba pro zjištění správných otáček vynásobit získané číslo 20.

 

Přepočet rychlosti otáčení bych se pokusil ještě trochu objasnit.
Původní myšlenka byla jednoduchá:
 - pomocí funkce PulseIn() se zjistí šířka HIGH impulzu z čidla v mikrosekundách
 - na jednu otáčku rotoru pak připadají 4 takovéto šířky (HIGH + LOW + HIGH + LOW) (v mikrosekundách)
 - výsledná hodnota otáček za minutu by tedy měla být:
       (60 000 000 / (4 * šířka_HIGH))  .... po zjednodušení tedy:  (15 000 000 / šířka_HIGH)


Jak se ale ukázalo při měření skutečných otáček, tohle vůbec neplatí. Hlavní problém je v tom, že funkce PulseIn() nevrací hodnotu v mikrosekundách - tak jako je tomu u "normálního" Arduina.
Je to pravděpodobně způsobené nastavením frekvence PWM, která ovlivňuje základní frekvenci ATtiny, od které se pak odvíjí všechny ostatní časové konstanty.
Další problém může být v nesymetrii signálů HIGH a LOW při špatně nastavené rozhodovací úrovni.


Rozdílné šířky HIGH a LOW úrovní
 signálu z čidla otáčení.

Když jsem nastavil správnou úroveň signálu z čidla otáčení, bylo třeba ještě upravit vzorec, aby se správně vypočítaly otáčky.

Po různých korekcích jsem nakonec vytvořil tento vzorec, který převádí šířku HIGH impulzu na otáčky za minutu tak, že se téměř v celém rozsahu otáček chyba pohybuje pod 10%:

rpm = 10 * ((975000 / šířka_HIGH_impulzu) - 7) 

Při následném proměřování celého rozsahu otáček jsem dospěl k těmto rozdílům mezi skutečnými a vypočtenými otáčkami:

 

Programy ke stažení

Program pro Python ventilator.py
Zdroják pro ATtiny85 ventilator.ino
Přeložený HEX pro ATtiny85
(+ bootloader)
ventilator.ino.hex
ventilator.ino.with_bootloader.hex

 


Aktualizace 22.10.2016

Doplnění ještě jednoho způsobu řízení ventilátoru pomocí ATtiny13. 

Detaily tady

 

 


 

 


úvodní strana webu AstroMiK.org

poslední úprava stránky 22.10.2016