static-httpd

Sitio web estático (HTML + CSS) que sostiene el blog del autor
Log | Files | Refs

index.html (9366B)


      1 <!DOCTYPE html>
      2 <html>
      3 <head>
      4 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      5 <meta name="viewport" content="width=device-width, initial-scale=1" />
      6 <title>Monitorización de capacidad de tanque de gasoil mediante sensor de ultrasonido</title>
      7 <link rel="icon" type="image/png" href="/favicon.png" />
      8 <link rel="stylesheet" type="text/css" href="../article.css" />
      9 </head>
     10 <body>
     11 <header>
     12 <p class="title">Monitorización de capacidad de tanque de gasoil mediante sensor de ultrasonido</p>
     13 <p class="date">21 de junio de 2022 • fjbalon</p>
     14 </header>
     15 <p>Este proyecto consiste en desarrollar un método para monitorizar la capacidad utilizada en un tanque de gasoil, que nutre una caldera. Existen diversas técnicas para lograrlo, pero la que considero más sencilla y más técnica es hacerlo a través de un sensor ultrasónico. Este sensor enviará los datos digitalizados a una Raspberry Pi 3B, que los procesará y almacenará, de tal forma que permita mantener un registro de monitorización y estadísticas de tiempo.</p>
     16 <p>Mi idea es poder tener la información accesible desde el PC u otros equipos informáticos, con el objetivo de poder predecir cuándo será necesario rellenar el tanque de nuevo, antes de que se gaste el gasoil, y poder observar la tasa de uso de gasoil en el tiempo, con tal de poder aplicar inteligencia. Por ejemplo, cotejar y relacionar el gasto de inverno con respecto verano; las horas y duración de las duchas, el gasto de calefacción, etcétera.</p>
     17 <h2>Funcionamiento del sensor</h2>
     18 <p>¿Cómo funciona el sensor de ultrasonido y cómo calculamos la distancia?. El funcionamiento es simple. El sensor crea un pulso de disparo en TRIG (trigger), enviando pulsos de 40kHz (manteniendo el estado de TRIG en HIGH durante un mínimo de 10µs). Inmediatamente, el circuito de control en el sensor cambiará el estado del pin de ECHO a HIGH, y manteniéndose así hasta que el pulso ultrasónico rebote con un objeto y regresa al receptor. En función del tiempo durante el cual el pin de ECHO permanece HIGH, esperando recibir de vuelta el pulso enviado, podemos calcular la distancia entre sensor y objeto. El emisor de pulsos es T, y el receptor es R.</p>
     19 <p>Por poner un ejemplo, si calculamos el tiempo para el cual el ECHO es HIGHT como 588µs, y tomando que la velocidad del sonido en la atmósfera terrestre es de 343,2m/s:</p>
     20 <math xmlns="http://www.w3.org/1998/Math/MathML" alttext="D=\frac{\upsilon}{(t/2)}=\frac{343,2}{(588\mu/2)}=5656565656" display="block">
     21 <mrow>
     22     <mi>D</mi>
     23     <mo>=</mo>
     24     <mfrac>
     25     <mi>υ</mi>
     26     <mrow>
     27         <mo stretchy="false">(</mo>
     28         <mrow>
     29         <mi>t</mi>
     30         <mo>/</mo>
     31         <mn>2</mn>
     32         </mrow>
     33         <mo stretchy="false">)</mo>
     34     </mrow>
     35     </mfrac>
     36     <mo>=</mo>
     37     <mfrac>
     38     <mrow>
     39         <mn>343,2</mn>
     40         <mi>m/s</mi>
     41     </mrow>
     42     <mrow>
     43         <mo stretchy="false">(</mo>
     44         <mrow>
     45         <mrow>
     46             <mn>588</mn>
     47             <mo>⁢</mo>
     48             <mi>μs</mi>
     49         </mrow>
     50         <mo>/</mo>
     51         <mn>2</mn>
     52         </mrow>
     53         <mo stretchy="false">)</mo>
     54     </mrow>
     55     </mfrac>
     56     <mo>=</mo>
     57     <mn>1,17cm</mn>
     58 </mrow>
     59 </math>
     60 <h2>Conexiones electrónicas</h2>
     61 <p>Conectamos el pin TRIG del sensor ultrasónico al pin físico 16, es decir, el pin GPIO23 de la raspy. Usamos posteriormente una combinación de resistencia de 1kΩ y 2kΩ para convertir el pin de ECHO a 3.3V (aproximadamente) y conéctelo al pin físico 18 (GPIO24). Finalmente proporcionamos las conexiones de +5V y GND. El esquema de comunicaciones electrónicas quedaría tal que:</p>
     62 <img class="color-invertible" style="width:50%" src="resources/ultrasonido01.png"/>
     63 <h2>Cálculo de distancia contra objeto</h2>
     64 <p>Una vez sabemos cómo calcular la distancia y tenemos conectado el sensor a nuestra CPU, el siguiente paso consiste en probar las ecuaciones anteriores bajo un código (usaremos Python), que muestre por stdout cada segundo la distancia medida. El código será:</p>
     65 <pre><code>import RPi.GPIO as GPIO
     66 import time
     67 
     68 GPIO.setmode(GPIO.BCM)
     69 GPIO_TRIGGER = 23
     70 GPIO_ECHO = 24
     71 GPIO.setup(GPIO_TRIGGER, GPIO.OUT)
     72 GPIO.setup(GPIO_ECHO, GPIO.IN)
     73 
     74 GPIO.output(GPIO_TRIGGER, True)
     75 time.sleep(0.00001)
     76 GPIO.output(GPIO_TRIGGER, False)
     77 
     78 StartTime = time.time()
     79 StopTime = time.time()
     80 
     81 while GPIO.input(GPIO_ECHO) == 0:
     82     StartTime = time.time()
     83 
     84 while GPIO.input(GPIO_ECHO) == 1:
     85     StopTime = time.time()
     86 
     87 TimeElapsed = StopTime - StartTime
     88 distance = (TimeElapsed * 34320) / 2
     89 
     90 print ("Distance = %.1f cm" % distance)</code></pre>
     91 <p>Obteniendo unos resultados positivos como:</p>
     92 <pre><code>./distance.py
     93 Distance = 85.8 cm</code></pre>
     94 <h2>Cálculo de subcuboide</h2>
     95 <p>Dado un cuboide de 112x100x71, que corresponde a las medidas aproximadas del tanque de gasoil:</p>
     96 <img class="color-invertible" style="width:25%" src="resources/cuboide.png"/>
     97 <p>Y recibido el valor de distancia entre sensor y gasoil, es sencillo calcular las medidas del subcuboide resultante. Por ejemplo, dada una distancia de 85cm:</p>
     98 <img class="color-invertible" style="width:50%" src="resources/subcuboide.png"/>
     99 <p>Obtendríamos un subcuboide de 15x112x71 que corresponde a  
    100 <math xmlns="http://www.w3.org/1998/Math/MathML" alttext="x*(y-d)*z=112*(100-85)*71=119280cm^{3}=119L">
    101 <mrow>
    102     <mrow>
    103     <mi>x</mi>
    104     <mo>*</mo>
    105     <mrow>
    106         <mo stretchy="false">(</mo>
    107         <mrow>
    108         <mi>y</mi>
    109         <mo>-</mo>
    110         <mi>d</mi>
    111         </mrow>
    112         <mo stretchy="false">)</mo>
    113     </mrow>
    114     <mo>*</mo>
    115     <mi>z</mi>
    116     </mrow>
    117     <mo>=</mo>
    118     <mrow>
    119     <mn>112</mn>
    120     <mo>*</mo>
    121     <mrow>
    122         <mo stretchy="false">(</mo>
    123         <mrow>
    124         <mn>100</mn>
    125         <mo>-</mo>
    126         <mn>85</mn>
    127         </mrow>
    128         <mo stretchy="false">)</mo>
    129     </mrow>
    130     <mo>*</mo>
    131     <mn>71</mn>
    132     </mrow>
    133     <mo>=</mo>
    134     <mrow>
    135     <mn>119280</mn>
    136     <mo></mo>
    137     <mi>c</mi>
    138     <mo></mo>
    139     <msup>
    140         <mi>m</mi>
    141         <mn>3</mn>
    142     </msup>
    143     </mrow>
    144     <mo>=</mo>
    145     <mrow>
    146     <mn>119</mn>
    147     <mo></mo>
    148     <mi>L</mi>
    149     </mrow>
    150 </mrow>
    151 </math>
    152 de un total de
    153 <math xmlns="http://www.w3.org/1998/Math/MathML" alttext="112*100*71=795200cm^{3}=795L">
    154 <mrow>
    155     <mrow>
    156     <mn>112</mn>
    157     <mo>*</mo>
    158     <mn>100</mn>
    159     <mo>*</mo>
    160     <mn>71</mn>
    161     </mrow>
    162     <mo>=</mo>
    163     <mrow>
    164     <mn>795200</mn>
    165     <mo></mo>
    166     <mi>c</mi>
    167     <mo></mo>
    168     <msup>
    169         <mi>m</mi>
    170         <mn>3</mn>
    171     </msup>
    172     </mrow>
    173     <mo>=</mo>
    174     <mrow>
    175     <mn>795</mn>
    176     <mo></mo>
    177     <mi>L</mi>
    178     </mrow>
    179 </mrow>
    180 </math>
    181 <p>, un 14% de capacidad.</p>
    182 <p>Una vez obtenidos los datos, adaptamos el script de forma simple stdin/stdout (para monitorización) de forma que devuelva un float con los litros restantes según los parámetros de entrada:</p>
    183 <pre><code>ancho=112 # Coordinate axis x: ancho / width
    184 alto=100 # Coordinate axis y: alto / height
    185 profundidad=71 # Coordenate axis z: profundidad / depth
    186 
    187 def volumenCuboide(x,y,z):
    188     return x * y * z
    189 
    190 def subcuboide(x,y,z,d):
    191     s = y - d
    192     return volumenCuboide(x,s,z)
    193 
    194 l = subcuboide(ancho,alto,profundidad,distance)/1000 # Divsion by 100 for cm^3 to liters
    195 print ("%.1f" % l)</code></pre>
    196 <p>Así:</p>
    197 <pre><code>./gasoil40kHz.py
    198 119.4</code></pre>
    199 <h2>Instalación en tanque</h2>
    200 <p>Con todo ideado y probado, aquí os muestro unas fotografías reales de cómo conseguí dejarlo más o menos estable, de la forma más perpendicular posible al eje x del tanque.</p>
    201 <p>Me valgo de uno de los tapones del tanque para colocar, usando adhesivos, y de la forma más perpendicular posible al eje x del tanque, el sensor de ultrasonido. Aprovecho que los cable son finos para pasarlos por el aislante de la propia prensa del tapón, quedando el resto del circuito fuera.</p>
    202 <img style="width:100%" src="resources/tanque-gasoil.png"/>
    203 <p>Una vez instalado, para realizar la obtención de datos gráficos configuramos la máquina receptora de los datos del sensor en un agente de <a href="https://zabbix.com">Zabbix</a>. Añadimos un UserParameter que contenga la llamada al script, de forma que obtengamos los valores directamente desde el servidor de Zabbix.</p>
    204 <pre><code># /etc/zabbix/zabbix_agentd.conf
    205 PidFile=/var/run/zabbix/zabbix_agentd.pid
    206 LogFile=/var/log/zabbix/zabbix_agentd.log
    207 LogFileSize=0
    208 AllowKey=system.run[*]
    209 Server=172.16.0.1
    210 ServerActive=172.16.0.1
    211 Hostname=gasoil40kHz
    212 Include=/etc/zabbix/zabbix_agentd.d/*.conf
    213 UserParameter=Gasoil,/home/pi/gasoil.py</code></pre>
    214 <p>Con esto y en monitorización a través de Zabbix de estos valores, podemos configurar y dibujar gráficas.</p>
    215 <img class="color-invertible" style="width:100%" src="resources/graph.png"/>
    216 <p>Como se ve en la gráfica, el procedimiento requiere de pulido. Hay un cierto baile de datos en cuanto a las lecturas, por eso he empleado una gráfica de puntos para notar las variaciones de lectura, que pueden deberse a gases propios del fluido monitorizado; o a movimientos de la superficie del tanque provocados por el extractor de gasoil hacia la caldera. De todas formas, para el uso y la línea de tiempo sobra y basta.</p>
    217 <p>El margen de error presente se encuentra en unos 6l. Pero con dicho margen se puede hacer una aproximación fidedigna del rango de capacidad y consumo del tanque.</p>
    218 </body>
    219 </html>