Cum să controlezi ventilatorul Noctua din Raspberry Pi

<p><a href=/posts/how-to-control-a-noctua-nf-a20-pwm-fan-from-raspberry-pi/noctua-pwm-pi-ezgif.com-optimize.e400dfe08b35d68aee56e4e16fae8785.gif class=fancybox><picture><img class=img-fluid src=/posts/how-to-control-a-noctua-nf-a20-pwm-fan-from-raspberry-pi/noctua-pwm-pi-ezgif.com-optimize.e400dfe08b35d68aee56e4e16fae8785.gif alt="ventilator Noctua NF-A20 PWM" loading=lazy height=895 width=1711></picture></a></p><p>Îmi construiesc <a href=/ro/posts/minipc-rack-partea-1/>un homelab</a> și am nevoie să controlez ventilatorul <a href=https://noctua.at/en/nf-a20-pwm-chromax-black-swap target=_blank rel=noopener>Noctua NF-A20 PWM chromax.black.swap 200x200mm</a> folosind Raspberry Pi. Așa am reușit să fac asta.</p><h2 id=componente-necesare>Componente necesare:</h2><ul><li>Un Raspberry Pi</li><li>Ventilatorul Noctua NF-A20 PWM (ar trebui să funcționeze la fel și cu alte ventilatoare de 12V)</li><li>Un multimetru</li><li><a href=https://www.optimusdigital.ro/ro/surse-ridicatoare-reglabile/12534-sursa-ridicatoare-lm2577-dc-dc.html target=_blank rel=noopener>Sursă Ridicătoare LM2577 DC-DC</a></li><li><a href=https://www.optimusdigital.ro/ro/componente-electronice-tranzistoare/935-tranzistor-s9013-npn-50-pcs-set.html target=_blank rel=noopener>Transistor NPN</a></li><li>Rezistență de 1K Ohm</li></ul><h2 id=diagramă>Diagramă:</h2><p><a href=/posts/how-to-control-a-noctua-nf-a20-pwm-fan-from-raspberry-pi/diagram.6b98eb62e389136c2a1f5c245243f014.png class=fancybox><picture><source srcset=/posts/how-to-control-a-noctua-nf-a20-pwm-fan-from-raspberry-pi/diagram_hu240544990833317495.webp type=image/webp><img class=img-fluid src=/posts/how-to-control-a-noctua-nf-a20-pwm-fan-from-raspberry-pi/diagram.6b98eb62e389136c2a1f5c245243f014.png alt="imagine diagramă" loading=lazy height=1824 width=1883></picture></a></p><h2 id=să-începem-de-la-pi>Să începem de la Pi:</h2><p>1- Conectează un fir de la pin-ul GPIO 16, sau orice pin simplu, la rezistența de 1k, apoi conectează celălalt capăt la tranzistor pe pin-ul din mijloc.</p><p>2- Un fir de la pin-ul din dreapta al tranzistorului la orice pin Ground sau minus/negativ al Pi-ului. Fața tranzistorului este cea plată.</p><p>3- Un fir de la pin-ul din dreapta al tranzistorului la conectorul negativ/minus de 5V marcat &ldquo;IN-&rdquo; al sursei ridicătoare.</p><p>4- Un fir de la orice pin de 5V al Pi-ului (le găsești în parea de sus, dreapta) la conectorul pozitiv/plus de 5V marcat &ldquo;IN+&rdquo; al sursei ridicătoare.</p><p>5- <strong>Important</strong>: ajustează sursa la 12V sau mai puțin.<br>NU conecta ventilatorul acum pentru că îl poți arde instant dacă îl conectezi la o tensiune mai mare decat 12V.<br>    A- Ca să pornești sursa ridicătoare temporar conectează un fir de la un pin ground/minus/negativ al Pi-ului direct la teminalul marcat &ldquo;IN-&rdquo; al sursei SAU poți executa codul python din urmatoarea secțiune. Trebuie doar să execuți <code>speed(fan, 100) / time.sleep(180)</code>.<br>    B- Conectează multimetru la conectorii marcați &ldquo;OUT+&rdquo; și &ldquo;OUT-&rdquo; apoi selectează măsurarea voltajului la multimetru (de obicei marcat cu &ldquo;2V&rdquo;).<br>    C- Pe sursă învârte șurubul mic și galben de pe componenta albastră până când multimetrul arată 12V sau puțin mai mic, ca să fim siguri ca nu se strică. Eu l-am lăsat pe al meu la 11.5V.</p><p><a href=/posts/how-to-control-a-noctua-nf-a20-pwm-fan-from-raspberry-pi/power-converter-nob.09666e2f6a0cb904a3d9dbb80a0fa25b.png class=fancybox><picture><source srcset=/posts/how-to-control-a-noctua-nf-a20-pwm-fan-from-raspberry-pi/power-converter-nob_hu2864229298055400022.webp type=image/webp><img class=img-fluid src=/posts/how-to-control-a-noctua-nf-a20-pwm-fan-from-raspberry-pi/power-converter-nob.09666e2f6a0cb904a3d9dbb80a0fa25b.png alt="șurubel de ajustare tensiune sursă" loading=lazy height=255 width=999></picture></a></p><p>    D- Când ești gata deconectează multimetrul și firul conectat la ground, sau oprește programul python.</p><p>Am găsit schema pin-urilor ventilatorului Noctua aici: <a href=https://faqs.noctua.at/en/support/solutions/articles/101000081757-what-pin-configuration-do-noctua-fans-use- target=_blank rel=noopener>https://faqs.noctua.at/en/support/solutions/articles/101000081757-what-pin-configuration-do-noctua-fans-use-</a> <a href=/posts/how-to-control-a-noctua-nf-a20-pwm-fan-from-raspberry-pi/noctua-pinout.db5471cf55cd488e3de87f4205f2f44e.png class=fancybox><picture><source srcset=/posts/how-to-control-a-noctua-nf-a20-pwm-fan-from-raspberry-pi/noctua-pinout_hu15230658805204666452.webp type=image/webp><img class=img-fluid src=/posts/how-to-control-a-noctua-nf-a20-pwm-fan-from-raspberry-pi/noctua-pinout.db5471cf55cd488e3de87f4205f2f44e.png alt="schemă pin-uri noctua" loading=lazy height=160 width=1037></picture></a></p><p>5- Un fir de la conectorul marcat &ldquo;OUT-&rdquo; (12V negativ) al sursei la pin-ul 1 al conectorului noctua.</p><p>6- Un fir de la conectorul marcat &ldquo;OUT+&rdquo; (12V pozitiv) al sursei la pin-ul 2 al conectorului noctua.</p><p>5- Un fir de la pin-ul 4 al conectorului noctua la pin-ul GPIO 12 al Pi-ului. <a href=https://pinout.xyz/pinout/pin32_gpio12/ target=_blank rel=noopener>Acest pin are capabilitate PWM</a> .</p><h2 id=codul-python>Codul python:</h2><p>Am folosit următorul cod din acest <a href=https://www.the-diy-life.com/connecting-a-pwm-fan-to-a-raspberry-pi/ target=_blank rel=noopener>tutorial publicat pe the-diy-life.com de Michael Klements</a> ( <a href=https://github.com/mklements/PWMFanControl/blob/main/FanProportional.py target=_blank rel=noopener>cod sursă</a> ), și l-am modificat ca să folosească tranzistorul ca să oprească ventilatorul pentru că ventilatorul nu poate scădea viteza până la 0 RPM. <a href=https://noctua.at/en/nf-a20-pwm-chromax-black-swap/specification target=_blank rel=noopener>Viteza minimă de rotație este de 20%</a> (350RPM).</p><div class=highlight><pre tabindex=0 style=color:#d0d0d0;background-color:#202020;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-python data-lang=python><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 1</span><span><span style=color:#999;font-style:italic>#!/usr/bin/env python3</span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 2</span><span><span style=color:#6ab825;font-weight:700>import</span> <span style=color:#447fcf;text-decoration:underline>RPi.GPIO</span> <span style=color:#6ab825;font-weight:700>as</span> <span style=color:#447fcf;text-decoration:underline>GPIO</span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 3</span><span><span style=color:#6ab825;font-weight:700>import</span> <span style=color:#447fcf;text-decoration:underline>time</span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 4</span><span><span style=color:#6ab825;font-weight:700>import</span> <span style=color:#447fcf;text-decoration:underline>signal</span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 5</span><span><span style=color:#6ab825;font-weight:700>import</span> <span style=color:#447fcf;text-decoration:underline>sys</span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 6</span><span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 7</span><span><span style=color:#999;font-style:italic># Ventilatorul Noctua PWM are nevoie de 25 kHz (kilo!), vezi pagina 6 de pe:</span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 8</span><span><span style=color:#999;font-style:italic># https://noctua.at/pub/media/wysiwyg/Noctua_PWM_specifications_white_paper.pdf</span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868"> 9</span><span>PWM_FREQ = <span style=color:#3677a9>25</span> <span style=color:#999;font-style:italic># [Hz] frecvență PWM</span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">10</span><span>FAN_PIN = <span style=color:#3677a9>12</span> <span style=color:#999;font-style:italic># pin BCM pentru control ventilator PWM</span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">11</span><span>TRAN_PIN = <span style=color:#3677a9>16</span> <span style=color:#999;font-style:italic># NPN Transistor</span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">12</span><span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">13</span><span><span style=color:#6ab825;font-weight:700>def</span> <span style=color:#447fcf>speed</span>(fan, percent): </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">14</span><span> <span style=color:#24909d>print</span>(<span style=color:#ed9d13>&#34;set fan to&#34;</span>, percent) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">15</span><span> <span style=color:#6ab825;font-weight:700>if</span> (percent &lt; <span style=color:#3677a9>20</span>): </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">16</span><span> GPIO.output(TRAN_PIN, <span style=color:#6ab825;font-weight:700>False</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">17</span><span> fan.ChangeDutyCycle(<span style=color:#3677a9>20</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">18</span><span> <span style=color:#6ab825;font-weight:700>else</span>: </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">19</span><span> GPIO.output(TRAN_PIN, <span style=color:#6ab825;font-weight:700>True</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">20</span><span> fan.ChangeDutyCycle(percent) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">21</span><span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">22</span><span><span style=color:#6ab825;font-weight:700>try</span>: </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">23</span><span> signal.signal(signal.SIGTERM, <span style=color:#6ab825;font-weight:700>lambda</span> *args: sys.exit(<span style=color:#3677a9>0</span>)) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">24</span><span> GPIO.setwarnings(<span style=color:#6ab825;font-weight:700>True</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">25</span><span> GPIO.setmode(GPIO.BCM) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">26</span><span> GPIO.setup(TRAN_PIN, GPIO.OUT) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">27</span><span> GPIO.setup(FAN_PIN, GPIO.OUT, initial=GPIO.LOW) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">28</span><span> fan = GPIO.PWM(FAN_PIN, PWM_FREQ) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">29</span><span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">30</span><span> <span style=color:#999;font-style:italic># facem cateva cicluri pentru testare</span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">31</span><span> speed(fan, <span style=color:#3677a9>100</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">32</span><span> time.sleep(<span style=color:#3677a9>30</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">33</span><span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">34</span><span> speed(fan, <span style=color:#3677a9>50</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">35</span><span> time.sleep(<span style=color:#3677a9>30</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">36</span><span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">37</span><span> speed(fan, <span style=color:#3677a9>0</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">38</span><span> time.sleep(<span style=color:#3677a9>30</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">39</span><span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">40</span><span> speed(fan, <span style=color:#3677a9>20</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">41</span><span> time.sleep(<span style=color:#3677a9>30</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">42</span><span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">43</span><span> speed(fan, <span style=color:#3677a9>70</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">44</span><span> time.sleep(<span style=color:#3677a9>30</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">45</span><span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">46</span><span> speed(fan, <span style=color:#3677a9>100</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">47</span><span> time.sleep(<span style=color:#3677a9>30</span>) </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">48</span><span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">49</span><span><span style=color:#6ab825;font-weight:700>except</span> <span style=color:#bbb>KeyboardInterrupt</span>: </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">50</span><span> <span style=color:#6ab825;font-weight:700>pass</span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">51</span><span> </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">52</span><span><span style=color:#6ab825;font-weight:700>finally</span>: </span></span><span style=display:flex><span style="white-space:pre;-webkit-user-select:none;user-select:none;margin-right:.4em;padding:0 .4em;color:#686868">53</span><span> GPIO.cleanup() </span></span></code></pre></div><p>Finalizat!</p><hr width=100% id=EOF><p style=color:#777>Ultima modificare la 2024-11-18</p>