index.html (8375B)
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>¿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> 17 <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> 18 <math xmlns="http://www.w3.org/1998/Math/MathML" alttext="D=\frac{\upsilon}{(t/2)}=\frac{343,2}{(588\mu/2)}=5656565656" display="block"> 19 <mrow> 20 <mi>D</mi> 21 <mo>=</mo> 22 <mfrac> 23 <mi>υ</mi> 24 <mrow> 25 <mo stretchy="false">(</mo> 26 <mrow> 27 <mi>t</mi> 28 <mo>/</mo> 29 <mn>2</mn> 30 </mrow> 31 <mo stretchy="false">)</mo> 32 </mrow> 33 </mfrac> 34 <mo>=</mo> 35 <mfrac> 36 <mrow> 37 <mn>343,2</mn> 38 <mi>m/s</mi> 39 </mrow> 40 <mrow> 41 <mo stretchy="false">(</mo> 42 <mrow> 43 <mrow> 44 <mn>588</mn> 45 <mo></mo> 46 <mi>μs</mi> 47 </mrow> 48 <mo>/</mo> 49 <mn>2</mn> 50 </mrow> 51 <mo stretchy="false">)</mo> 52 </mrow> 53 </mfrac> 54 <mo>=</mo> 55 <mn>1,17cm</mn> 56 </mrow> 57 </math> 58 <h2>Conexiones electrónicas</h2> 59 <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> 60 <img class="color-invertible" style="width:50%" src="resources/ultrasonido01.png"/> 61 <h2>Cálculo de distancia contra objeto</h2> 62 <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> 63 <pre><code>import RPi.GPIO as GPIO 64 import time 65 66 GPIO.setmode(GPIO.BCM) 67 GPIO_TRIGGER = 23 68 GPIO_ECHO = 24 69 GPIO.setup(GPIO_TRIGGER, GPIO.OUT) 70 GPIO.setup(GPIO_ECHO, GPIO.IN) 71 72 GPIO.output(GPIO_TRIGGER, True) 73 time.sleep(0.00001) 74 GPIO.output(GPIO_TRIGGER, False) 75 76 StartTime = time.time() 77 StopTime = time.time() 78 79 while GPIO.input(GPIO_ECHO) == 0: 80 StartTime = time.time() 81 82 while GPIO.input(GPIO_ECHO) == 1: 83 StopTime = time.time() 84 85 TimeElapsed = StopTime - StartTime 86 distance = (TimeElapsed * 34320) / 2 87 88 print ("Distance = %.1f cm" % distance)</code></pre> 89 <p>Obteniendo unos resultados positivos como:</p> 90 <pre><code>$ ./distance.py 91 Distance = 85.8 cm</code></pre> 92 <h2>Cálculo de subcuboide</h2> 93 <p>Dado un cuboide de 112x100x71, que corresponde a las medidas aproximadas del tanque de gasoil:</p> 94 <img class="color-invertible" style="width:25%" src="resources/cuboide.png"/> 95 <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> 96 <img class="color-invertible" style="width:50%" src="resources/subcuboide.png"/> 97 <p>Obtendríamos un subcuboide de 15x112x71 que corresponde a 98 <math xmlns="http://www.w3.org/1998/Math/MathML" alttext="x*(y-d)*z=112*(100-85)*71=119280cm^{3}=119L"> 99 <mrow> 100 <mrow> 101 <mi>x</mi> 102 <mo>*</mo> 103 <mrow> 104 <mo stretchy="false">(</mo> 105 <mrow> 106 <mi>y</mi> 107 <mo>-</mo> 108 <mi>d</mi> 109 </mrow> 110 <mo stretchy="false">)</mo> 111 </mrow> 112 <mo>*</mo> 113 <mi>z</mi> 114 </mrow> 115 <mo>=</mo> 116 <mrow> 117 <mn>112</mn> 118 <mo>*</mo> 119 <mrow> 120 <mo stretchy="false">(</mo> 121 <mrow> 122 <mn>100</mn> 123 <mo>-</mo> 124 <mn>85</mn> 125 </mrow> 126 <mo stretchy="false">)</mo> 127 </mrow> 128 <mo>*</mo> 129 <mn>71</mn> 130 </mrow> 131 <mo>=</mo> 132 <mrow> 133 <mn>119280</mn> 134 <mo></mo> 135 <mi>c</mi> 136 <mo></mo> 137 <msup> 138 <mi>m</mi> 139 <mn>3</mn> 140 </msup> 141 </mrow> 142 <mo>=</mo> 143 <mrow> 144 <mn>119</mn> 145 <mo></mo> 146 <mi>L</mi> 147 </mrow> 148 </mrow> 149 </math> 150 de un total de 151 <math xmlns="http://www.w3.org/1998/Math/MathML" alttext="112*100*71=795200cm^{3}=795L"> 152 <mrow> 153 <mrow> 154 <mn>112</mn> 155 <mo>*</mo> 156 <mn>100</mn> 157 <mo>*</mo> 158 <mn>71</mn> 159 </mrow> 160 <mo>=</mo> 161 <mrow> 162 <mn>795200</mn> 163 <mo></mo> 164 <mi>c</mi> 165 <mo></mo> 166 <msup> 167 <mi>m</mi> 168 <mn>3</mn> 169 </msup> 170 </mrow> 171 <mo>=</mo> 172 <mrow> 173 <mn>795</mn> 174 <mo></mo> 175 <mi>L</mi> 176 </mrow> 177 </mrow> 178 </math> 179 <p>, un 14% de capacidad.</p> 180 <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> 181 <pre><code>ancho=112 # Coordinate axis x: ancho / width 182 alto=100 # Coordinate axis y: alto / height 183 profundidad=71 # Coordenate axis z: profundidad / depth 184 185 def volumenCuboide(x,y,z): 186 return x * y * z 187 188 def subcuboide(x,y,z,d): 189 s = y - d 190 return volumenCuboide(x,s,z) 191 192 l = subcuboide(ancho,alto,profundidad,distance)/1000 # Divsion by 100 for cm^3 to liters 193 print ("%.1f" % l)</code></pre> 194 <p>Así:</p> 195 <pre><code>$ ./gasoil40kHz.py 196 119.4</code></pre> 197 <p>Script final en servidor git en <a href="/git/lab/file/programming-python/gasoil/gasoil.py.html">gasoil.py</a>.</p> 198 <h2>Implementación en tanque</h2> 199 <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> 200 <img style="width:100%" src="resources/tanque-gasoil.png"/> 201 <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> 202 <pre><code># /etc/zabbix/zabbix_agentd.conf 203 PidFile=/var/run/zabbix/zabbix_agentd.pid 204 LogFile=/var/log/zabbix/zabbix_agentd.log 205 LogFileSize=0 206 AllowKey=system.run[*] 207 Server=172.16.0.1 208 ServerActive=172.16.0.1 209 Hostname=gasoil40kHz 210 Include=/etc/zabbix/zabbix_agentd.d/*.conf 211 UserParameter=Gasoil,/home/pi/gasoil.py</code></pre> 212 <p>Con esto y en monitorización a través de Zabbix de estos valores, podemos configurar y dibujar gráficas.</p> 213 <img class="color-invertible" style="width:100%" src="resources/graph.png"/> 214 <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> 215 </body> 216 </html>