<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Les pelotes de ficelle</title>
    <link>https://pf.olibrio.fr/es/</link>
    <atom:link href="https://pf.olibrio.fr/es/feed.xml" rel="self" type="application/rss+xml"/>
    <description>Se agarra un cabo, se tira del hilo, se deshace el ovillo. El blog de Sam: electrónica, datos, clima, IA e ingeniería inversa, investigaciones caseras.</description>
    <language>es</language>
    <lastBuildDate>Thu, 01 Oct 2026 12:00:00 +0000</lastBuildDate>
    <generator>build.py</generator>
    <item>
      <title>Un radio roto en mi motor de buje, y el tensiómetro que acabé soldando</title>
      <link>https://pf.olibrio.fr/es/posts/tensiometre-rayons-moteur-roue.html</link>
      <guid isPermaLink="true">https://pf.olibrio.fr/es/posts/tensiometre-rayons-moteur-roue.html</guid>
      <pubDate>Thu, 01 Oct 2026 12:00:00 +0000</pubDate>
      <description>Segunda rueda de motor de buje de 2.000 W que pierde un radio. En lugar de retensar de oído, diseñé y luego soldé un tensiómetro: flexión en tres puntos sobre casi toda la longitud del radio, fuerza fijada por el clic de una llave dinamométrica, lectura con un calibre. El razonamiento, los callejones sin salida, la herramienta, las primeras cifras y lo que queda por medir.</description>
      <category>bicicleta eléctrica</category>
      <category>motor de buje</category>
      <category>radios</category>
      <category>tensión</category>
      <category>tensiómetro</category>
      <category>llave dinamométrica</category>
      <category>diy</category>
      <category>soldadura</category>
      <category>mecánica</category>
      <category>ia</category>
      <content:encoded><![CDATA[<p><img src="https://pf.olibrio.fr/images/tensiometre-rayons-moteur-roue/og-tensiometre.jpg" alt="Un radio roto en mi motor de buje, y el tensiómetro que acabé soldando"></p>
<div class="tldr">
<p><strong>En dos minutos, si rompes radios en un motor de buje</strong></p>
<ul>
<li><strong>El síntoma</strong>: un radio roto en un motor de buje de 2.000 W, después de una primera rueda ya perdida de la misma manera. Treinta y seis radios cortos y gruesos, de 160 mm por 2,6 mm de diámetro, cuya tensión nadie conoce.</li>
<li><strong>Por qué no un tensiómetro comercial</strong>: en un radio tan corto y tan grueso, un aparato que lo flexiona sobre 60 mm mide sobre todo la rigidez propia del radio, no su tensión. Y la tabla de papel se acaba antes de la zona útil.</li>
<li><strong>La herramienta</strong>: una flexión en tres puntos sobre 125 mm, casi toda la longitud libre del radio. La fuerza viene del clic de una llave dinamométrica, así que es la misma cada vez. Dos rodamientos de patín sujetan el radio sin rozar, un calibre lee la flecha y conserva el máximo cuando el clic suelta la carga.</li>
<li><strong>Las primeras cifras</strong>: a 5 Nm, 100 N de tensión mueven el calibre 0,07 mm. La dispersión de la llave vale un 8 % de tensión. El primer radio medido sale hacia 850 N. Y una lección de mecánica de paso: un radio montado es cuatro veces más rígido a flexión que uno libre, porque sus extremos están sujetos.</li>
<li><strong>Lo que sigue</strong>: diez medidas en un mismo radio para la dispersión real, un banco de calibración, y luego el mapa de los treinta y seis radios. Es el siguiente paso.</li>
</ul>
</div>
<hr />
<h3 id="acto-i-el-radio-que-se-rompe">Acto I: el radio que se rompe</h3>
<p>Un motor de buje de 2.000 W es un buje de veintiún centímetros de diámetro enlazado a una llanta con radios cortos y gruesos: 160 mm en total, 2,6 mm de diámetro, treinta y seis en total, cruzados una vez. Cuando uno se rompe, nunca es una sorpresa para la rueda, solo para el ciclista. Iba por mi segunda rueda: la primera había acabado igual, un radio, luego dos, luego una llanta que se descentra y ya no se recupera.</p>
<p>Un radio casi nunca se rompe por estar demasiado tenso. Se rompe porque no lo está bastante: en cada vuelta de rueda, cuando pasa por abajo, la carga lo afloja, y un radio que se afloja y se vuelve a tensar miles de veces por kilómetro acaba por fatiga, casi siempre en el codo, en el agujero de la brida. Así que la respuesta correcta no es sustituir el radio roto, sino saber a qué tensión están los otros treinta y cinco, y llevarlos todos al mismo nivel, el correcto.</p>
<p>El problema es que ese nivel nadie me lo daba. Igualar de oído, haciendo sonar los radios, es un método antiguo que sirve para igualar pero no dice nada del valor absoluto: una rueda entera demasiado tensa suena igual de bien que una rueda entera demasiado floja, y en los foros de bicicletas eléctricas las llantas rajadas por exceso de tensión son tan frecuentes como los radios rotos por defecto. Necesitaba una medida.</p>
<h3 id="acto-ii-por-que-no-un-tensiometro-comercial">Acto II: por qué no un tensiómetro comercial</h3>
<p>Un tensiómetro de bicicleta clásico, el modelo de 18 euros igual que el de 80, funciona flexionando el radio entre dos apoyos separados unos sesenta milímetros con un muelle calibrado, y una tabla convierte la flecha leída en tensión. Funciona bien en un radio de bicicleta de 2 mm y 280 mm de largo, porque ese radio, dejado a su aire, casi no resiste la flexión: lo que el aparato mide es realmente la tensión que lo rigidiza.</p>
<p>En mi radio de 2,6 mm es otra historia. La rigidez propia de una varilla a flexión crece con la cuarta potencia de su diámetro: pasar de 2 a 2,6 mm casi la triplica. Sobre 60 mm de apoyos, la parte de la tensión en lo que mide el aparato cae por debajo de la mitad; el resto es el propio radio defendiéndose, con tensión o sin ella. Y la tabla de papel de esos aparatos se acaba de todos modos antes de 2,6 mm. Habría tenido una cifra, pero no una medida.</p>
<p>La solución cabe en dos ideas. Primero, flexionar sobre una luz lo más larga posible, porque la parte de la tensión crece con la luz: sobre 125 mm en vez de 60, pasa del 45 % a más del 70 % para un radio libre. Segundo, sustituir el muelle por una fuerza realmente repetible. Tenía una llave dinamométrica de clic de 3 a 20 Nm en un cajón. Un clic es un par conocido, el mismo cada vez, con un 4 % de margen. Con una palanca, es una fuerza conocida.</p>
<h3 id="acto-iii-el-diseno-y-sus-callejones-sin-salida">Acto III: el diseño, y sus callejones sin salida</h3>
<p>El principio no cambió desde el primer croquis hasta la herramienta soldada: tres puntos de contacto en el radio, dos de un lado en los extremos de la luz, uno en el medio del otro lado, llevado por un brazo que la llave hace girar alrededor de un pivote. La llave hace clic, el brazo ha empujado el radio con una fuerza fija, y la flecha que ha tomado depende de su tensión.</p>
<p>Lo que cambió fueron todos los detalles, y los trabajé sobre un modelo paramétrico en 3D, con un asistente de IA para mantener el modelo, abrirlo en Blender y hacer los cálculos en cada iteración. Algunos callejones sin salida merecen contarse, porque son instructivos.</p>
<p><strong>La primera versión era impresa en plástico.</strong> El cálculo la mató antes de imprimirla: para 1,5 mm de flecha que medir en el radio, el brazo de PLA se flexionaba 2,5 mm. Todo el camino de esfuerzo pasó al acero.</p>
<p><strong>La segunda flexionaba el radio fuera del plano de la rueda</strong>, hacia el exterior, porque era más fácil de construir. La rechacé: un radio trabaja en el plano de la rueda cuando el motor empuja, y quería medirlo en ese sentido. Para un radio redondo ambos son equivalentes, pero no era natural, y el pivote habría quedado en un sitio imposible una vez puesta la herramienta en una rueda real, con los radios vecinos pasando a 24 mm.</p>
<p><strong>Los apoyos son rodamientos, no pivotes fijos.</strong> La literatura sobre tensiómetros es clara: el rozamiento del radio sobre sus apoyos falsea la lectura, y mucho. Dos rodamientos de patín, 22 mm de diámetro, 8 mm de agujero, no cuestan casi nada y ruedan sin rozar. El tercer punto es una simple horquilla, porque no se mueve.</p>
<p><strong>El clic suelta la carga.</strong> Me saltó a la vista animando el mecanismo en Blender: una llave de clic toma unos tres grados de holgura en el momento de disparar, y el par cae. El radio solo necesita dos grados del brazo para volver. Si se leyera la posición del brazo después del clic, se leería cualquier cosa. De ahí una lectura de máximo retenido: la varilla de profundidad de un calibre, empujada por el brazo, se queda donde el brazo la llevó cuando este retrocede. Se lee el máximo, el del clic.</p>
<p><img alt="Vista superior del modelo 3D de la herramienta puesta sobre una rueda completa: tubo naranja sobre el radio medido, brazo azul, rodillos, llave y calibre" src="https://pf.olibrio.fr/images/tensiometre-rayons-moteur-roue/08-blender-vue-de-dessus.png" /></p>
<p><img alt="Vista lateral del modelo: el radio horizontal, los dos rodillos en el plano de los radios, el tubo encima, el brazo y la cabeza de la llave más arriba" src="https://pf.olibrio.fr/images/tensiometre-rayons-moteur-roue/09-blender-vue-de-cote.png" /></p>
<h3 id="acto-iv-la-herramienta-soldada">Acto IV: la herramienta soldada</h3>
<p>Entre el modelo y el taller la herramienta volvió a cambiar, como siempre que se tienen pletinas de acero, un equipo de soldar y una caja de tornillos a mano en lugar del inventario exacto del modelo. El modelo 3D se reajustó después sobre la herramienta real, cota por cota, con fotos. Esto es lo que existe.</p>
<p>El bastidor es un tubo cuadrado de 25 mm que se apoya por encima del radio, a 6 mm de él, y queda enteramente fuera del plano de los radios vecinos. Solo tres elementos bajan al nivel del radio: la horquilla en el extremo del lado del buje, una ranura de 3,5 mm colgada bajo el extremo del tubo, y los dos rodamientos, cada uno en el extremo de un tornillo vertical. El primer rodamiento, A, está al final de un tornillo soldado bajo el tubo, a 125 mm de la horquilla. El segundo, B, al otro lado del radio, a 60 mm de A, está al final de un tornillo soldado al brazo móvil.</p>
<p>El brazo móvil es una pletina de 4 mm colocada por encima del tubo. Gira sobre un tornillo dejado flojo, X, clavado en una placa de 4 mm soldada sobre el tubo, a 15 mm de A y 46 mm de B. Un vaso soldado sobre el brazo, a 25 mm de A, recibe el cuadrado de la llave dinamométrica, cuyo mango sale radialmente hacia la llanta. Cuando la llave empuja, el brazo gira alrededor de X y B aprieta el radio con el par dividido por 46 mm: 111 N a 5 Nm, 156 N a 7.</p>
<p>El calibre va deslizado entre el brazo y el tubo, junto a la placa del pivote, y su varilla de profundidad toca el tornillo de B. Lee directamente el desplazamiento de B respecto al tubo, es decir, la flecha del radio respecto a la cuerda que une sus dos apoyos fijos, A y la horquilla.</p>
<p><img alt="La herramienta sobre el banco, calibre atravesado sobre el tubo, rodillo A y su arandela en primer plano" src="https://pf.olibrio.fr/images/tensiometre-rayons-moteur-roue/01-outil-et-pied-a-coulisse.jpg" /></p>
<p><img alt="La parte inferior de la herramienta, con la llave dinamométrica encajada en el vaso soldado al brazo móvil" src="https://pf.olibrio.fr/images/tensiometre-rayons-moteur-roue/02-outil-dessous-cle.jpg" /></p>
<p><img alt="Los tres puntos de contacto marcados en la herramienta: A el rodillo del lado de la llanta, B el rodillo del brazo móvil, C la horquilla del lado del buje" src="https://pf.olibrio.fr/images/tensiometre-rayons-moteur-roue/03-outil-lettrage.jpg" /></p>
<p><img alt="Un radio libre montado en la herramienta: pasa por la ranura de la horquilla, bordea el rodillo B por un lado y el rodillo A por el otro" src="https://pf.olibrio.fr/images/tensiometre-rayons-moteur-roue/04-rayon-libre-dans-l-outil.jpg" /></p>
<p><img alt="Vista lateral que muestra los rodillos sobre sus tornillos, claramente por debajo del tubo: solo los rodillos y la horquilla están en el plano de los radios" src="https://pf.olibrio.fr/images/tensiometre-rayons-moteur-roue/06-galets-sur-entretoises.jpg" /></p>
<p><img alt="Alzado acotado de la herramienta: tubo sobre el radio, placa del pivote, brazo móvil, rodillos A y B, horquilla C, regla del calibre" src="https://pf.olibrio.fr/images/tensiometre-rayons-moteur-roue/07-schema-elevation.png" /></p>
<h3 id="acto-v-las-primeras-cifras-y-una-leccion-de-mecanica">Acto V: las primeras cifras, y una lección de mecánica</h3>
<p>Primera sorpresa, y la que más me enseñó. En un radio libre, sostenido en el aire dentro de la herramienta, leí 3,4 mm a 3 Nm, 4,6 mm a 5 Nm y 5,9 mm a 7 Nm. Tres puntos perfectamente alineados, 0,625 mm por Nm, pero una recta que no pasa por cero: hay 1,5 mm de lectura antes de que el radio empiece a resistir. Es la holgura de montaje, la ranura de 3,5 sobre un radio de 2,6, el pivote flojo, los tornillos. Es constante, al menos esas tres veces, y se resta. Pero impide leer una medida sola sin haberla caracterizado.</p>
<p>Segunda sorpresa: esa pendiente era dos veces y media más baja de lo que preveía el cálculo para un radio de 2,6 mm libre sobre dos apoyos. Primero busqué adónde se iba el par. No se iba a ninguna parte. La viga era la que estaba mal: un radio que se sujeta por el extremo entre dos dedos ya no es libre, y sobre todo, un radio montado en una rueda tiene sus extremos sujetos, el codo en el agujero de la brida a 20 mm de la horquilla, la cabecilla en la llanta a 15 mm del rodillo A. Con extremos sujetos tan cerca de los apoyos, la rigidez a flexión es cuatro veces la de una viga libre. Con eso, la parte de la tensión en lo que lee la herramienta vuelve a caer a un 40 % hacia 1.000 N. Menos de lo esperado, pero todavía muy medible.</p>
<p>En el radio montado leí 3,8 mm a 7 Nm. Restada la holgura, quedan 2,3 mm elásticos, y el modelo los convierte en unos 850 N, entre 640 y 1.140 según la holgura valga realmente 1,2 o 1,8 mm. Para un radio de 2,6 mm en un motor de buje, el orden de magnitud habitual es 1.000 N. Así que ese radio no anda lejos, pero la cifra sigue siendo un cálculo, no una medida: la posición exacta de los apoyos y la sujeción real del codo pesan un 20 % en el resultado. Para comparar radios entre sí, el modelo basta. Para newtons, hará falta un banco.</p>
<p>Y la tensión mecánica en el radio, porque la herramienta puede doblar lo que mide. El radio libre tomó 6,7 mm de flecha real sobre 125 mm a 7 Nm sin quedar curvado, lo que corresponde a 1.300 MPa en superficie: el límite elástico de un radio estirado, no más. En un radio montado y flojo, 7 Nm suben a 1.500 MPa. <strong>El ajuste correcto es 5 Nm</strong>: entre 800 y 1.100 MPa sea cual sea la tensión, 0,07 mm de lectura por cada 100 N alrededor de 1.000 N, y la llave en la zona de su rango donde su 4 % está garantizado. Ese 4 % de par se lee como un 8 % de tensión; es la incertidumbre dominante, y ninguna palanca la reduce. Para igualar una rueda, es suficiente.</p>
<p>Lectura esperada en el calibre a 5 Nm, holgura de 1,5 mm incluida, para un radio montado:</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Tensión del radio</th>
<th>Lectura a 5 Nm</th>
</tr>
</thead>
<tbody>
<tr>
<td>0 N</td>
<td>4,57 mm</td>
</tr>
<tr>
<td>400 N</td>
<td>3,68 mm</td>
</tr>
<tr>
<td>800 N</td>
<td>3,19 mm</td>
</tr>
<tr>
<td>1.000 N</td>
<td>3,03 mm</td>
</tr>
<tr>
<td>1.200 N</td>
<td>2,89 mm</td>
</tr>
<tr>
<td>1.600 N</td>
<td>2,68 mm</td>
</tr>
</tbody>
</table></div>
<p>La curva se aplana hacia las tensiones altas: más allá de 1.200 N la herramienta distingue mal. Para mi rueda, ese no es el problema.</p>
<p><img alt="La herramienta en su sitio sobre la rueda, llave dinamométrica encajada, mango radial por encima de la llanta, calibre atravesado" src="https://pf.olibrio.fr/images/tensiometre-rayons-moteur-roue/05-mesure-sur-la-roue.jpg" /></p>
<h3 id="acto-vi-lo-que-queda-por-hacer">Acto VI: lo que queda por hacer</h3>
<p>Todo lo anterior se apoya en un puñado de lecturas. El siguiente paso es hacer hablar a la herramienta en serio, en este orden.</p>
<ol>
<li><strong>Diez medidas a 5 Nm en un mismo radio</strong>, sin tocar la cabecilla, cursor puesto a cero entre cada una, mango de la llave siempre en la misma dirección. Es la dispersión real de la herramienta, la que cuenta.</li>
<li><strong>Cinco medidas a 3 Nm en el mismo radio</strong>, para comprobar que la holgura de 1,5 mm no se mueve.</li>
<li><strong>Un punto de control a tensión nula</strong>, en el radio libre, sujetando solo el tubo esta vez.</li>
<li><strong>Un banco de calibración</strong>: un perfil, un radio de repuesto, un dinamómetro, de 600 a 1.200 N. Es lo que convertirá los milímetros en newtons sin pasar por el modelo.</li>
<li>Luego el mapa de los treinta y seis radios, la búsqueda de la tensión objetivo y la sustitución del radio roto, anotando exactamente dónde se rompió.</li>
</ol>
<p>Si rompes radios en un motor de buje, quédate sobre todo con esto: el sonido no te dará el nivel, un tensiómetro de bicicleta clásico tampoco en 12G, y un radio montado se comporta de otra manera que un radio libre. El resto es chatarra, una llave de clic y un calibre.</p>]]></content:encoded>
    </item>
    <item>
      <title>Un remolque familiar diseñado antes de la primera soldadura: cocina, cofre de deporte, tres bicis</title>
      <link>https://pf.olibrio.fr/es/posts/remorque-famille-cuisine-velos.html</link>
      <guid isPermaLink="true">https://pf.olibrio.fr/es/posts/remorque-famille-cuisine-velos.html</guid>
      <pubDate>Sat, 19 Sep 2026 12:00:00 +0000</pubDate>
      <description>Diseño de un remolque casero arrastrado por una VW T5 de batalla larga: cocina de cajones, nevera y gas, un gran cofre para escalada, surf y senderismo, tres bicis en el techo. Por qué el eje de Mini clásico se quedaba corto, por qué lo sustituyó el de un Seat Córdoba 1.9D, dónde colocar el eje para un 7 % de carga en la lanza, qué longitud de lanza facilita la marcha atrás y por qué el verdadero riesgo en autopista no es el culebreo sino el viento lateral.</description>
      <category>remolque</category>
      <category>bricolaje</category>
      <category>blender</category>
      <category>eje</category>
      <category>mini</category>
      <category>seat córdoba</category>
      <category>vw t5</category>
      <category>carga vertical</category>
      <category>portabicis</category>
      <category>cocina nómada</category>
      <category>ia</category>
      <content:encoded><![CDATA[<p><img src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/og.jpg" alt="Un remolque familiar diseñado antes de la primera soldadura: cocina, cofre de deporte, tres bicis"></p>
<div class="tldr">
<p><strong>En dos minutos, si quiere construirse un remolque</strong></p>
<ul>
<li><strong>El proyecto</strong>: un remolque detrás de nuestra T5 larga. En la planta baja, una cocina de cajones (fregadero, hornillo) a un lado y la nevera con su bombona de gas al otro; encima, un gran cofre para el material de escalada, surf y senderismo; en el techo, las tres bicis de la familia.</li>
<li><strong>El método</strong>: dibujarlo y calcularlo todo <strong>antes</strong> de comprar un solo tubo. El modelo es un script paramétrico de Blender: se cambia una cota, se vuelve a lanzar y salen imágenes nuevas.</li>
<li><strong>La mala noticia</strong>: el eje de Mini que tenía previsto <strong>no aguanta la carga</strong>. Cargado, el remolque pone unos 540 kg sobre el eje, para unos 450 admisibles. Véase <a href="#essieu">El eje de Mini no pasó el examen de los números</a>.</li>
<li><strong>La buena</strong>: el eje de Seat Córdoba 1.9D que también tengo a mano soporta mucho más. La primera versión de esta entrada afirmaba que sus muelles helicoidales no costaban altura: era falso, suben hacia la caja. Desde el 21 de septiembre, el problema se reduce a <strong>una sola cota por medir</strong>. Véase <a href="#correction">Corrección: los muelles sí ocupan sitio</a> y luego <a href="#cordoba-montage">El Córdoba, reducido a una cota</a>.</li>
<li><strong>En autopista</strong>, el culebreo no es el problema: una T5 pesa cuatro veces lo que el remolque. <strong>El verdadero riesgo es el viento lateral, y son las bicis, no la caja</strong>: a la vuelta, basta una racha de 55 km/h para descargar una rueda cuando se circula a 110. Cifras rehechas el 21 de septiembre con el método que sirve para cerrar los puentes a los camiones. Véase <a href="#vent">El viento: tres objeciones y luego el método de los puentes</a>.</li>
<li><strong>Para dar marcha atrás con facilidad</strong>: una lanza de 2 m y, sobre todo, <strong>una viga única en el primer metro detrás de la bola</strong>. Es eso, más que la longitud, lo que evita tocar la T5 al maniobrar. Véase <a href="#fleche">Una lanza para recular sin pensarlo</a>.</li>
<li><strong>Las bicis</strong> no suben por una rampa (habría medido 4,40 m) sino con un <strong>mástil desmontable, un pescante giratorio y una polea</strong>. Véase <a href="#velos">Subir tres bicis a casi 2 m</a>. <em>Abandonado el 21 de septiembre: las bicis ya no suben a ninguna parte.</em></li>
<li><strong>Actualizaciones del 21 de septiembre</strong>: el cálculo del viento rehecho con el método de los puentes y el eje de Mini que vuelve por partida doble (<a href="#maj">primera actualización</a>), y luego dos ideas que cambian la forma del remolque: el eje hundido en la caja y las bicis bajadas del techo. <strong>La versión elegida mide 1,63 m de alto en lugar de 2,92</strong>, y la racha que aguanta a 110 km/h pasa de 55 a 91 km/h. Véase <a href="#maj2">la segunda actualización</a>.</li>
</ul>
<p><em>Todavía no hay nada construido. Esta entrada cuenta la fase en la que todo lo que se rompe solo cuesta tiempo de cálculo.</em></p>
</div>
<p><img alt="Render 3D de un remolque verde salvia cerrado, tres bicis en el techo, lanza larga con un mástil desmontado encima" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/01-fermee-velos.jpg" /></p>
<p><em>La versión del 19 de septiembre, cerrada, con las bicis cargadas. Eje de Córdoba, caja de 2,30 × 1,61 m, lanza de 2 m con el mástil de elevación desmontado y tumbado encima. La que he elegido finalmente está <a href="#retenue">más abajo</a>: mide 1,30 m menos de alto.</em></p>
<h2 id="el-pliego-de-condiciones-cabe-en-una-frase">El pliego de condiciones cabe en una frase</h2>
<p>Cuando salimos en familia a escalar, a surfear o a caminar, la T5 se llena enseguida. La idea: sacar del habitáculo todo lo que estorba —la cocina, la nevera, el material, las bicis— y meterlo en un remolque pensado para ello, donde cada cosa tenga su sitio y se abra sin desembalar el resto.</p>
<p>Lo describí de un tirón, más o menos así: un eje de Mini; en el nivel cero, cajones de cocina a un lado (fregadero y hornillo pequeño), la nevera y su bombona de gas al otro; en el nivel de arriba, un gran cofre para la escalada, el surf y los bastones, cerrado por una tapa con bisagras de maletero que se mantiene abierta con amortiguadores de gas; y encima, tres huecos para nuestras tres bicis, subidas por una rampa desmontable guardada bajo el remolque.</p>
<p>Fue una IA (Claude) la que convirtió esa frase en un modelo 3D: un script de Python que construye el remolque pieza a pieza en Blender, con todas las cotas al principio del archivo. No abrí Blender para dibujarlo. Miré las imágenes, corregí, precisé… y fue justo al pasar de las imágenes a los números cuando el proyecto cambió.</p>
<h2 id="tres-pisos-uno-por-uso">Tres pisos, uno por uso</h2>
<p>El principio es el de una cómoda: lo pesado abajo, lo voluminoso en medio, lo ligero y abultado arriba.</p>
<p><img alt="Perfil del remolque con las cotas en naranja: suelo a 0,75 m, parte superior del nivel cocina a 1,41 m, tapa a 1,88 m, bicis hasta 2,93 m; caja de 2,30 m, lanza de 2,00 m, 3,10 m entre la bola y el eje" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/02-profil-cote.jpg" /></p>
<p><em>Las cotas principales de la versión elegida. El suelo está alto (0,75 m) porque la caja pasa por encima de las ruedas: eso es lo que permite una caja más ancha que la vía.</em></p>
<p><strong>La planta baja, del lado de la acera, es la cocina.</strong> Una trampilla se levanta y hace de toldo. Debajo, dos cajones bajos salen hacia fuera: uno lleva el fregadero y su grifo, el otro un hornillo de dos fuegos. Su parte superior forma la encimera, <strong>a 0,95 m del suelo</strong>, la altura de una cocina. No es casualidad: la altura de esos cajones se calcula a partir de la altura del suelo, que depende del eje. Si se cambia de eje, la encimera sigue a 0,95 m. Encima, dos cajones para la vajilla y la despensa; al fondo, una columna para dos garrafas de 20 L, una bomba de 12 V y la batería.</p>
<p><img alt="El lado cocina del remolque, trampilla levantada como toldo, cajón del fregadero y cajón del hornillo fuera, columna de agua abierta, bicis en el techo" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/03-cuisine.jpg" /></p>
<p><em>Lado cocina, con las bicis puestas. Todo se abre sin descargar nada del techo.</em></p>
<p><strong>Al otro lado, la nevera y el gas.</strong> Una nevera trivalente de 40 L (12 V, 230 V, gas) sobre una guía extraíble, para abrirla por arriba una vez fuera. Delante, un compartimento estanco hacia el interior y ventilado hacia el exterior —rejillas alta y baja en la puerta, rejilla en el suelo, porque el propano pesa más que el aire— para una bombona de 6 kg. Detrás, la mesa y las sillas plegables.</p>
<p><img alt="El lado nevera del remolque, trampilla levantada, nevera fuera sobre su guía, puerta del compartimento de gas abierta sobre una bombona azul" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/04-frigo-gaz.jpg" /></p>
<p><em>Lado nevera. La bombona queda separada del resto por un tabique, con su propia ventilación.</em></p>
<p><strong>Arriba, el cofre.</strong> 2,26 m de largo por dentro: sitio para tumbar una tabla de surf de 7&lsquo;0, un crash pad, las cuerdas, las mochilas y los bastones. La tapa gira sobre tres bisagras de maletero y se queda abierta a 82° gracias a dos amortiguadores de gas.</p>
<p><img alt="Vista cenital del cofre abierto: tabla de surf, crash pad, cuerdas enrolladas, bolsa estanca; tapa levantada sujeta por dos amortiguadores" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/05-bac-ouvert.jpg" /></p>
<p><em>El cofre abierto, sin las bicis; y no es una decisión de puesta en escena.</em></p>
<p>Fue lo primero que me enseñó el modelo, antes de cualquier cálculo: <strong>las bicis van sobre la tapa</strong>. Mientras estén ahí, el cofre no se abre. La cocina y la nevera, sí. Es una limitación que se asume (se carga el cofre antes que las bicis) o que se esquiva (una baca fija sobre montantes y trampillas laterales), pero no algo que uno quiera descubrir en el aparcamiento de la escuela de escalada.</p>
<p><em>Actualización del 21 de septiembre: limitación levantada. Las bicis han dejado la tapa, y el cofre se abre con las bicis cargadas; véase <a href="#velos-bas">Las bicis bajan del techo</a>.</em></p>
<h2 id="el-primer-borrador-era-bonito-y-no-demostraba-nada">El primer borrador era bonito y no demostraba nada</h2>
<p>La primera versión daba imágenes limpias en una tarde. Eje de Mini, caja de 2,30 × 1,45 m, lanza de 1,35 m, eje colocado «un poco por detrás del centro para tener peso sobre la bola», rampa telescópica de cuatro tramos para subir las bicis. Todo parecía plausible.</p>
<p>Y ese es justamente el problema: <strong>un render limpio parece una validación</strong>. Nada en esas imágenes decía cuánto pesa el remolque, qué soporta el eje ni cómo se comporta a 130 km/h detrás de una furgoneta. Así que pedí lo que habría pedido un carrocero: el reparto de masas calculado de verdad, y una lanza lo bastante larga para maniobrar con facilidad con mi T5 larga.</p>
<p>El cálculo es un segundo script, independiente de Blender. Toma cada elemento —bastidor, lanza, paneles, cajones, nevera, agua, gas, material, bicis— con su masa estimada y su posición, y de ahí saca el centro de gravedad y la carga sobre la bola y sobre el eje, para cinco casos de carga: vacío; cargado sin bicis; cargado con bicis; a la vuelta, con el agua y la comida consumidas; y con bicis eléctricas.</p>
<p>Primer resultado: <strong>el remolque pesa 416 kg en vacío</strong> en su versión más ligera (bastidor de tubo de 50×30, contrachapado de chopo de 15 mm). Cargado con las bicis, 582 kg. La primerísima estimación, hecha a ojo antes de este cálculo, daba de 260 a 400 kg en vacío: la parte baja de la horquilla era muy optimista.</p>
<h2 id="essieu">El eje de Mini no pasó el examen de los números</h2>
<p>Mi eje es el tren trasero de un Mini clásico: una cuna, dos brazos tirados, conos de caucho a modo de muelles, ruedas de 10 pulgadas. Es compacto y ligero. También es el tren trasero de un coche de 650 kg, que normalmente soporta de 250 a 300 kg, y del orden de 450 kg como máximo.</p>
<p>Cargado con las bicis, el remolque pone <strong>541 kg sobre su eje</strong>; 563 kg con bicis eléctricas. Es decir, entre un 20 y un 25 % por encima de lo que el tren debe soportar, de forma permanente y en autopista. Aun aligerando todo lo aligerable, con una cocina, una nevera, 40 L de agua y tres bicis no se baja del límite.</p>
<p>Tenía otras dos opciones a mano o a mi alcance: un tren trasero de Peugeot 205 o 206, y el de un <strong>Seat Córdoba 1.9D</strong> (primera generación). El cálculo los pasa a todos por el mismo tamiz:</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th></th>
<th>Mini</th>
<th>205</th>
<th>206</th>
<th>Córdoba 1.9D</th>
</tr>
</thead>
<tbody>
<tr>
<td>Neumáticos</td>
<td>145/80 R10</td>
<td>165/70 R13</td>
<td>175/65 R14</td>
<td>175/70 R13</td>
</tr>
<tr>
<td>Vía</td>
<td>1,17 m</td>
<td>1,30 m</td>
<td>1,43 m</td>
<td>1,40 m</td>
</tr>
<tr>
<td>Carga sobre el eje, cargado + bicis</td>
<td>541 kg</td>
<td>568 kg</td>
<td>586 kg</td>
<td>584 kg</td>
</tr>
<tr>
<td>Carga máx. trasera (orden de magnitud)</td>
<td>~450 kg</td>
<td>~600 kg</td>
<td>~700 kg</td>
<td>~750 kg</td>
</tr>
<tr>
<td>Aceleración lateral antes del vuelco</td>
<td>0,57 g</td>
<td>0,60 g</td>
<td>0,65 g</td>
<td>0,64 g</td>
</tr>
</tbody>
</table></div>
<p><em>Las cargas máximas son órdenes de magnitud; el valor real del «eje trasero» figura en la placa del fabricante del coche donante.</em></p>
<p><img alt="Cuatro vistas desde abajo del mismo remolque con cuatro trenes distintos: Mini con cuna y conos, 205 con barras de torsión y amortiguadores tumbados, 206 con barras de torsión, Córdoba con eje torsional y muelles helicoidales rojos apoyados en los brazos" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/06-essieux.jpg" /></p>
<p><em>El mismo remolque sobre los cuatro trenes, generado cambiando una sola variable. La caja se ensancha sola para cubrir las ruedas. El Córdoba aparece dibujado con muelles separados apoyados en los brazos: no es el montaje del coche (véase <a href="#correction">la corrección</a>).</em></p>
<p>Sobre el papel, gana el Córdoba: el mayor margen de carga, ruedas de 13 pulgadas que encajan mejor los baches y calientan menos los rodamientos a 130, una vía ancha. Y su suspensión debería trabajar dentro de su rango original: la parte trasera de un Córdoba diésel está dimensionada para cargas del mismo orden que las del remolque (de 430 a 610 kg según la carga). Una ventaja que no había visto venir: en este tipo de eje, la viga que une los dos brazos se retuerce cuando una rueda sube y la otra no; hace de <strong>barra estabilizadora</strong>, justo lo que se quiere con bicis subidas en alto.</p>
<h3 id="correction">Corrección: los muelles sí ocupan sitio</h3>
<p><em>Añadido el 19 de septiembre de 2026, el mismo día de la publicación.</em></p>
<p>La primera versión de esta entrada decía aquí que los muelles helicoidales del Córdoba «no cuestan ni un centímetro de altura»: se alojarían entre el brazo de suspensión y la parte inferior del bastidor, en la treintena de centímetros que el neumático deja libre de todos modos bajo el suelo. Es lo que muestra el render de arriba, con sus muelles rojos.</p>
<p>Al releerlo, algo no me cuadró: en el coche, el muelle sube hasta dentro de la carrocería, muy por encima de la rueda. Una guía de desmontaje del Polo 6N, que comparte plataforma con el Córdoba 6K, lo confirma. <strong>El muelle rodea el amortiguador</strong>, los dos forman un conjunto, y <strong>su parte superior se atornilla en el maletero</strong>, en lo alto del paso de rueda, detrás de los guarnecidos. Abajo, un ojo horizontal lo fija a la viga, cerca del buje. La IA había razonado sobre un muelle separado apoyado en el brazo, como en otros ejes de este tipo, sin comprobarlo en este coche concreto. Y el render limpio hizo creíble la hipótesis: justo la trampa que se describe más abajo.</p>
<p>La consecuencia: entre el ojo inferior y la parte de abajo del bastidor quedan unos 38 cm, y el conjunto es claramente más largo. Asomaría en el nivel 0, justo debajo del cajón del hornillo por un lado y de la nevera por el otro. Cuatro salidas, aún sin decidir:</p>
<ul>
<li><strong>separar muelle y amortiguador</strong>: conservar la viga y los brazos del Córdoba, apoyar el muelle solo en una copela sobre el brazo (atornillada mejor que soldada, al ser una pieza de suspensión) y otra bajo el bastidor, con un amortiguador corto montado aparte;</li>
<li><strong>torretas en el nivel 0</strong>, reorganizando la cocina y el lado de la nevera alrededor del eje;</li>
<li><strong>subir el suelo</strong> lo que sobresale: lo más sencillo, pero las bicis y el centro de gravedad suben otro tanto, y el viento lateral ya es el punto débil;</li>
<li><strong>volver al tren del 205</strong>, cuyas barras de torsión van dentro del tubo y cuyos amortiguadores van tumbados: ningún problema de altura, pero poco margen de carga con bicis eléctricas.</li>
</ul>
<p>Para elegir necesito tres medidas del eje: la longitud del conjunto montado, la del muelle solo en reposo y la altura del ojo inferior respecto al centro de la rueda.</p>
<p><em>Actualización del 21 de septiembre: el cálculo ha reducido desde entonces esas tres medidas a una sola. Véase <a href="#cordoba-montage">El Córdoba, reducido a una cota</a>.</em></p>
<h2 id="autoroute">Aguantar la carretera detrás de la T5</h2>
<p>La regla que se oye en todas partes: peso sobre la bola, o el remolque culebrea. Aún hay que saber cuánto. Apunté a <strong>un 7 % de la masa sobre la bola</strong> a plena carga. El cálculo coloca entonces el eje a 1,20 m de la parte trasera de la caja, 5 cm por delante del centro, donde el primer borrador lo había puesto 17 cm por detrás, a ojo. Según la carga, el peso sobre la bola se queda entre el 5,8 y el 7,6 %, es decir, de 31 a 45 kg, lejos de los 100 kg que admite el enganche de la T5.</p>
<p>Para el culebreo en sí, el cálculo usa un modelo clásico de dinámica vehicular: coche y remolque vistos desde arriba, unidos por la rótula, cada uno con su masa, su inercia y sus neumáticos que derivan. Se busca la velocidad a partir de la cual una pequeña oscilación, en lugar de amortiguarse, crece.</p>
<p>Resultado: <strong>por encima de 400 km/h</strong>. En todos los casos de carga, con todos los ejes, e incluso colocando el eje para tener un peso nulo o negativo sobre la bola.</p>
<p>Un resultado tan cómodo me hace desconfiar. Un modelo que responde «todo bien» le des lo que le des puede muy bien ser un modelo que no calcula nada. Así que lo probamos con un caso cuya respuesta se conoce: una caravana de 1,5 t detrás de una berlina de 1,4 t. El mismo modelo la hace perder el control hacia los 160 km/h con un 5 % sobre la lanza, 110 km/h con un 3 %, 80 km/h sin nada, lo que coincide con lo que se lee en todas partes sobre caravanas. El modelo sabe, pues, predecir una inestabilidad; si aquí no la encuentra, es porque <strong>la T5 pesa cuatro veces lo que el remolque</strong>. El perro mueve la cola, y no al revés.</p>
<p>El verdadero riesgo está en otra parte, y es mucho más banal: <strong>el viento lateral</strong>. Tres bicis a casi 3 m de altura, un costado de 1,20 m, una vía de 1,40 m. A la vuelta, con el agua y la comida consumidas, <strong>basta una racha de costado de 55 km/h para descargar la rueda de barlovento cuando se circula a 110 km/h</strong>; en curva, unos treinta. <em>(Corrección del 21 de septiembre: la primera versión decía «unos 100 km/h». Esa cifra salía de un modelo casero, y solo vale para un remolque parado. La historia de esta corrección se cuenta <a href="#vent">más abajo</a>.)</em> La consigna es evidente: con previsión de viento fuerte, se circula más despacio, o las bicis viajan dentro de la T5.</p>
<h2 id="fleche">Una lanza para recular sin pensarlo</h2>
<p>Dar marcha atrás con un remolque corto es una prueba de nervios: se cruza antes de que uno entienda por qué. Lo que cuenta es la relación entre dos longitudes: la distancia de la bola al eje del remolque y la del eje trasero de la T5 a la bola (unos 1,10 m en una T5 larga). Cuanto mayor es esa relación, más despacio reacciona el remolque y más tiempo hay para corregir.</p>
<p>Con una lanza de 2 m, la bola queda a <strong>3,10 m del eje</strong>: una relación de 2,8. Alargar más apenas aporta (3,0 con una lanza de 2,20 m) y cuesta longitud (4,35 m en total, ya 9,60 m para el conjunto con la T5).</p>
<p>Dos errores de cálculo, de paso, resultaron más instructivos que los buenos resultados. La primera versión del cálculo anunciaba que, con el volante a tope, el remolque formaría un ángulo de <strong>164°</strong> con la T5; es decir, que la adelantaría. Una rotación en el sentido equivocado; corregida, el ángulo baja a 51°. La segunda anunciaba un contacto entre remolque y T5 a 55°, fuera cual fuera la longitud de la lanza. Sospechoso: si la longitud no cambia nada, no es ella la que limita. Era la propia cabeza de enganche, a 25 cm de la bola, que en realidad pasa <strong>por debajo</strong> del parachoques, como en cualquier remolque. Una vez quitado ese punto, apareció lo que limitaba de verdad: la apertura de la V de la lanza cerca de la bola.</p>
<p>De ahí la forma elegida: <strong>una viga central única en el primer metro detrás de la bola</strong>, y la V solo a partir de ahí. El primer contacto con la T5 se va entonces más allá de los 100° de articulación. Con el volante a tope solo se usan 51.</p>
<p><img alt="Vista cenital: la T5 con el volante a tope, el remolque detrás a 51 grados, lejos de la trasera de la furgoneta" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/07-braquage.jpg" /></p>
<p><em>Con el volante a tope, en régimen estable: 51° entre la T5 y el remolque, con buen margen antes de cualquier contacto. El remolque recorta la curva cerca de 1 m por dentro de la trayectoria de las ruedas traseras de la T5.</em></p>
<p>Un detalle que el modelo hace evidente y en el que no habría pensado: el remolque (1,61 m) es más estrecho que la T5 (1,90 m). En línea recta, <strong>no se ve por los retrovisores</strong>. Una cámara de marcha atrás inalámbrica, o dos piquetas testigo en las esquinas traseras, forman parte del proyecto.</p>
<p><img alt="Vista tres cuartos trasera del remolque enganchado a la T5, las bicis sobresalen por encima del techo de la furgoneta" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/08-attelee-t5.jpg" /></p>
<p><em>Enganchado. Las bicis sobresalen un metro por encima del techo de la T5: conviene recordarlo ante las barreras de los aparcamientos.</em></p>
<h2 id="velos">Subir tres bicis a casi 2 m</h2>
<p><em>Actualización del 21 de septiembre: esta sección describe una solución abandonada dos días después. La dejo, porque el razonamiento que mata la rampa sigue siendo válido, y porque la buena respuesta era dejar de subir las bicis. Véase <a href="#velos-bas">Las bicis bajan del techo</a>.</em></p>
<p>La rampa de mi idea inicial murió por un simple cálculo de trigonometría. Las bicis descansan a casi 1,90 m; para una pendiente de 25°, ya empinada para empujar una bici, hace falta una rampa de <strong>más de 4,40 m</strong>: cuatro tramos telescópicos, una pata en medio para que no se doble y una bici eléctrica de 25 kg que empujar con los brazos estirados. Factible entre dos con bicis normales, penoso en otro caso.</p>
<p>La alternativa la propuse yo, y es la que nos quedamos: <strong>un mástil desmontable, un pescante que gira en lo alto del mástil y una polea en la punta</strong>. El mástil, en dos tramos de aluminio de 1,50 m, se encaja en una funda soldada sobre la viga de la lanza, justo delante de la caja. El pescante, de 1,45 m de alcance, cubre los tres canales y un punto de recogida en el suelo junto al remolque. Un torno manual en el mástil, un cable que pasa por una polea arriba y luego por la de la punta del pescante, y un balancín enganchado al sillín y a la potencia de la bici para que suba horizontal.</p>
<p><img alt="El pescante en acción: mástil plantado delante de la caja, pescante girado hacia el lado cocina, una bici azul colgada de un balancín naranja a media altura, otras dos bicis ya colocadas" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/09-potence.jpg" /></p>
<p><em>La bici de la derecha, subiendo. Desmontados, el mástil y el pescante se tumban sobre la lanza (se ven en las otras vistas).</em></p>
<p>Del modelo salieron dos limitaciones. La altura, primero: para que una bici apoyada en su canal pase bajo la polea, balancín incluido, el mástil tiene que llegar a 3,45 m. Y el orden de carga: <strong>primero la bici del medio</strong>. Si no, habría que pasarla por encima de otra, y ningún mástil razonable llega tan alto. Por último, una obviedad que más vale escribir: no se levanta nada con el remolque desenganchado y mal calzado.</p>
<h2 id="maj">Actualización del 21 de septiembre: el Mini vuelve por partida doble, y el viento pasa por la biblioteca</h2>
<p><em>Dos días después de la publicación. No hay nada construido, así que todo puede moverse todavía, y se ha movido.</em></p>
<h3 id="tandem">¿Y con dos ejes de Mini?</h3>
<p>Tras la publicación me sugirieron una idea que había descartado demasiado deprisa: puesto que una cuna de Mini no basta, <strong>poner dos, una detrás de otra</strong>, con separadores de rueda de 5 cm. El argumento cabía en una línea: la carga se duplica, el comportamiento en carretera es muy superior y la resistencia al viento lateral, mucho mayor.</p>
<p>Añadir la variante al modelo costó una línea de parámetros, como con los demás ejes. Quedaba poner cifras a cada afirmación.</p>
<ul>
<li><strong>La carga: cierto, y mejor de lo previsto.</strong> Cada cuna soporta 290 kg, es decir 145 kg por rueda, más o menos lo que carga una rueda trasera de Mini en carretera. Cada cono de caucho trabaja, pues, donde fue pensado para trabajar. El margen pasa del −25 % con una sola cuna a un <strong>+33 %</strong>, bicis eléctricas incluidas.</li>
<li><strong>El comportamiento: cierto, por una razón precisa.</strong> Dos ejes separados 80 cm se oponen al giro del remolque sobre sí mismo (la <em>guiñada</em>) mucho más que uno solo: el efecto de recuperación de los neumáticos se <strong>multiplica por 4,7</strong>. Es lo que calma un remolque tras una racha o el paso de un camión.</li>
<li><strong>El viento lateral: empate.</strong> El vuelco solo depende de dos cosas, el ancho de vía y la altura del centro de gravedad. El tándem gana porque sus ruedas de 10 pulgadas permiten un suelo 11 cm más bajo, y pierde otro tanto porque su vía sigue siendo más estrecha que la del Córdoba.</li>
<li><strong>«La carga se duplica»: sí para el eje, no para el remolque.</strong> Lo que limita la carga útil es la masa máxima declarada en la homologación: por encima de 750 kg hacen falta frenos y otro permiso. El tándem compra margen y vida útil, no kilos que llevar.</li>
</ul>
<p><img alt="Vista desde abajo del remolque sobre dos cunas de Mini en tándem: cuatro ruedas pequeñas de 10 pulgadas, dos travesaños negros, la caja más baja que en las otras versiones" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/11-tandem-mini.jpg" /></p>
<p><em>La variante con dos cunas de Mini. El resto del modelo se adaptó solo: caja de 1,46 m, suelo a 0,64 m, bicis a 2,82 m en lugar de 2,93.</em></p>
<p>Y tiene un precio. <strong>El arrastre lateral de los neumáticos</strong>, primero: para pivotar, un remolque de dos ejes tiene que hacer deslizar sus ruedas de lado. Con la dirección a tope hacen falta 52 kg de empuje lateral en la bola. La T5 ni se entera; yo sí, el día que quiera moverlo a mano en una parcela de camping. Después, un defecto conocido de este montaje, que encontré descrito por los fabricantes de ejes: dos suspensiones independientes <strong>no se reparten la carga por sí solas</strong>. Es la altura de la bola de la T5 la que fija el asiento — 5 cm de diferencia, y el eje delantero pierde 51 kg mientras el trasero gana 39 — y sobre un resalte un solo eje se lo lleva casi todo. Los fabricantes rebajan la capacidad de estos ejes en torno a un 20 % cuando los montan por parejas; aquí cada uno trabaja al 65 % de su carga, así que la regla se cumple. Por último, 43 kg más en vacío y cinco neumáticos de 10 pulgadas por encontrar, una medida que se ha vuelto rara.</p>
<h3 id="vent">El viento: tres objeciones y luego el método de los puentes</h3>
<p>El pasaje sobre el viento lateral, <a href="#autoroute">más arriba</a>, estaba mal. No en su conclusión — las bicis en el techo siguen siendo el punto débil — sino en sus cifras. La historia de la corrección me enseñó más que la corrección misma.</p>
<p>El primer cálculo era <strong>un modelo escrito a mano por la IA</strong>: el empuje del viento sobre el costado del remolque, como sobre un panel. Puse tres pegas.</p>
<p><em>«He visto remolques altos, sin suspensión, que no sufren con el viento.»</em> Comprobado: la misma caja, <strong>sin las bicis</strong>, aguanta una racha mucho más fuerte. El problema no es la altura de la caja, son las bicis: subidas a 2,30 m, suponen ellas solas el 41 % del esfuerzo que intenta tumbar el remolque. De paso, el modelo resultó demasiado optimista. Olvidaba que un remolque en marcha no recibe el viento de costado sino de tres cuartos, sumado a su propia velocidad, y que una caja atacada en diagonal recibe mucho más empuje que un panel atacado de frente.</p>
<p><em>«Una bici no es un panel macizo.»</em> Exacto. Contada pieza a pieza — neumáticos, llantas, radios, cuadro — una bici solo ofrece al viento el 34 % de su silueta. Y el aire pasa a través: sufre resistencia, no el efecto de ala que sufre la caja. Las dos bicis de sotavento quedan además resguardadas por la primera.</p>
<p><em>«Te olvidas de la T5 delante, que abre camino.»</em> Ahí me sorprendió ser yo quien lo pensara. Respuesta: la T5 sí resguarda el remolque… con viento flojo. Su estela se va con el viento, no por el eje de la carretera. A 110 km/h, el abrigo es completo por debajo de 20 km/h de viento de costado, se pierde a medias a 40 y es casi nulo a 60. Y las bicis sobresalen de su techo de todas formas.</p>
<p>Tres correcciones para tres objeciones: íbamos a tientas. Así que pregunté lo que debería haber preguntado desde el principio: <strong>¿cómo lo hace la gente que se dedica a esto?</strong> Bastaron diez minutos de búsqueda. El método existe, está publicado y en acceso abierto: es el de Baker y Soper (2018), que sirve para decidir a partir de qué racha se cierra un puente a los camiones. Cabe en tres líneas, se apoya en coeficientes <strong>medidos</strong> en túnel de viento y a escala real, y ya contenía mi tercera objeción: un remolque medido detrás de su camión solo gana alrededor de un 10 % de abrigo.</p>
<p>Rehecho con ese método, a la vuelta y con las bicis en el techo: <strong>basta una racha de 55 km/h para descargar la rueda de barlovento cuando se circula a 110 km/h</strong>, 61 km/h cuando se circula a 90. Remolque lleno y sin bicis: 85. Son velocidades de viento a la altura del remolque; la previsión anuncia rachas medidas a 10 m de altura, y en terreno despejado el viento es aproximadamente una cuarta parte más flojo a ras de carretera. El método clasifica cada vehículo por una «velocidad característica»: con sus bicis, mi remolque es más vulnerable que un <strong>autobús de dos pisos vacío</strong>, el primer vehículo que se detiene cuando se levanta el viento en el puente de Queensferry, en Escocia. La consigna práctica: a partir de 80 km/h de rachas previstas, se baja a 90, o las bicis viajan dentro de la T5.</p>
<p>El modelo casero daba 58 km/h en lugar de 55: el orden de magnitud correcto, alcanzado tras tres parches. Una parte del cálculo sigue siendo de cosecha propia, y así está señalada: el tratamiento de las bicis, a falta de medidas publicadas sobre bicis colocadas en un techo.</p>
<h3 id="limites">Cuándo se va</h3>
<p>Lo que quería saber, en el fondo, no es lo que dice el código de circulación: es <strong>dónde están los límites reales</strong>. El cálculo saca tres, reunidos en un gráfico.</p>
<p><a href="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/10-limites.png"><img alt="Tres gráficos: la racha límite en función de la velocidad de marcha para tres estados de carga, las aceleraciones laterales de vuelco comparadas con la adherencia de los neumáticos, y el amortiguamiento del culebreo en función de la velocidad" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/10-limites.png" /></a></p>
<p><em>Las tres maneras de irse, para la variante con dos cunas de Mini (rótulos del gráfico en francés: vent = viento, virage = curva, louvoiement = culebreo). El Córdoba da las mismas curvas con pocos km/h de diferencia. Pulsar para ampliar.</em></p>
<ul>
<li><strong>El viento.</strong> Lleno y sin bicis, nada se va con tiempo normal: harían falta rachas previstas de 110 km/h para inquietarlo a 130 km/h. Con las bicis, el margen se funde.</li>
<li><strong>La curva.</strong> El remolque vuelca entre 0,56 y 0,64 g de aceleración lateral, según la carga. Es antes de que los neumáticos deslicen en seco (0,8 g), pero después en mojado (0,5 g). Dicho de otro modo: en seco se tumba sin haber deslizado; en mojado, el conjunto desliza primero. Con las bicis, 0,58 g son 61 km/h en un ramal de 50 m de radio.</li>
<li><strong>El culebreo.</strong> No hay velocidad crítica detrás de la T5, ni siquiera con 120 kg mal colocados al fondo. La curva verde es el caso de control, una caravana de 1,5 t detrás de una berlina del mismo peso: cruza el cero hacia los 115 km/h.</li>
</ul>
<h3 id="cordoba-montage">El Córdoba, reducido a una cota</h3>
<p>Quedaba el problema que dejó abierto <a href="#correction">la corrección</a>: el conjunto muelle-amortiguador que sube hacia la caja. Al mirar qué hay en ese punto dentro del remolque, la restricción primero se endureció: el cajón del hornillo a un lado y la guía de la nevera al otro <strong>barren el suelo</strong> justo encima. No se tolera ningún saliente, ni siquiera un abombado.</p>
<p>Luego el cálculo la aflojó. Bajo la carga del remolque (290 kg por rueda), el muelle de origen se comprime y el conjunto ya solo mide unos 41 cm. Su cabeza puede alojarse entonces <strong>dentro del espesor del bastidor</strong>, 45 mm por debajo del suelo, sobre una simple pletina taladrada soldada entre dos largueros.</p>
<p>Con una condición, que es la única incógnita que queda: que el ojo inferior del conjunto esté a menos de 1,5 cm por encima del centro de la rueda. Lo he supuesto 3 cm por debajo; se mide en cinco minutos sobre el coche, antes de desmontarlo. Si la cota sale mal, existen conjuntos roscados, regulables en altura, homologados para este coche.</p>
<p><img alt="Vista desde abajo del remolque sobre el tren del Córdoba: el conjunto rojo y amarillo sube hasta el bastidor, dos soportes negros bajan del bastidor hasta las articulaciones de los brazos, unidos por un tubo" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/12-cordoba-montage.jpg" /></p>
<p><em>El montaje del Córdoba tal como lo dibuja ahora el cálculo: el conjunto termina dentro del bastidor, y dos soportes bajan a buscar las articulaciones de los brazos.</em></p>
<p>El verdadero trabajo de calderería está en otra parte, y no lo había visto. Como la caja pasa por encima de las ruedas, el bastidor queda a 67 cm del suelo, mientras que las articulaciones de los brazos del eje están a 33 cm. Hacen falta, pues, dos <strong>soportes descendentes de 35 cm</strong>, que aguantan alrededor de 1,6 kN·m en un bache cogido deprisa: cajones de chapa de 5 mm, un tirante hacia delante y un tubo entre los dos para los esfuerzos laterales.</p>
<p>Este montaje sigue siendo mucho más sencillo que el tándem: un tren, cuatro puntos de fijación, ningún ajuste, neumáticos que se encuentran en cualquier parte y un remolque que todavía se mueve a mano. El tándem tiene más margen y un suelo más bajo. No me he decidido.</p>
<h2 id="maj2">Segunda actualización del 21 de septiembre: todo baja</h2>
<p><em>El mismo día, unas horas más tarde. Dos preguntas de diseño han hecho más por el remolque que todos los refinamientos de cálculo de la mañana.</em></p>
<h3 id="surbaissee">Hundir el eje en la caja</h3>
<p>Desde el principio, la caja pasaba <strong>por encima</strong> de las ruedas. Eso le permitía ser más ancha que la vía, y también dejaba el suelo encaramado a 75 cm. De ahí mi pregunta: ¿por qué no hacer como el propio Seat, o como cualquier furgoneta? Bajar el suelo entre las ruedas, dejar que estas suban dentro de unos <strong>pasos de rueda</strong> en el interior de la caja, y construir los cajones alrededor.</p>
<p>El suelo puede bajar hasta casi rozar la viga que une las dos ruedas: 0,51 m en lugar de 0,75. Todo lo demás baja en bloque, 24 cm. Y las dos dificultades del montaje, las de la actualización de esta mañana, desaparecen de golpe:</p>
<ul>
<li>los <strong>soportes de 35 cm</strong> que debían bajar del bastidor hasta las articulaciones de los brazos se quedan en 10: los apoyos se atornillan casi directamente bajo los largueros, como en el coche;</li>
<li>la <strong>cabeza del conjunto</strong> muelle-amortiguador ya no tiene que caber bajo un suelo. Sube dentro del paso de rueda, exactamente como en el maletero del Seat. La famosa cota por medir ya no condiciona nada: solo fija la altura del paso de rueda.</li>
</ul>
<p>El precio es carpintería y bastidor. Dos pasos de rueda de 73 × 36 cm, de 20 cm de alto, se llevan un centenar de litros de 2 400. Cada portón lateral recibe una muesca a la altura de la rueda. Y el bastidor deja de ser un rectángulo: la rueda está en el camino de los largueros exteriores, así que dos largueros pasan por dentro de las ruedas y unos travesaños sostienen los costados por delante y por detrás.</p>
<p>La distribución se reorganiza con una regla sencilla: <strong>lo que se conforma con poca altura va encima de la rueda, lo que la necesita va delante o detrás.</strong> El cajón del hornillo mide 22 cm de alto. Ya estaba a la altura del eje, y ahí se queda, apoyado en el paso de rueda. El fregadero gana un cajón hondo, con sitio para un bidón de aguas grises debajo. La nevera deja la zona del eje y se va atrás; y como todo ha bajado, su tapa pasa de 1,27 m a 1,03 m: por fin se puede meter el brazo.</p>
<p><img alt="El remolque rebajado por el lado de la cocina, portón levantado: cajón del fregadero hondo atrás, cajón del hornillo bajo justo encima de la rueda, columna de agua alta delante" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/13-cuisine-surbaissee.jpg" /></p>
<p><em>Lado cocina. El cajón del hornillo va apoyado en el paso de rueda; el fregadero y la columna de agua, a un lado y a otro, bajan hasta el nuevo suelo.</em></p>
<p><img alt="El remolque rebajado por el lado de la nevera: nevera sacada sobre su guía atrás, mesa y sillas guardadas en plano encima de la rueda, cofre del gas delante" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/14-frigo-surbaisse.jpg" /></p>
<p><em>Lado nevera. La nevera ha pasado atrás; encima de la rueda, lo que se guarda en plano.</em></p>
<p>En carretera: el centro de gravedad baja 21 cm, el vuelco en curva pasa de 0,58 a 0,71 g, y la racha límite a 110 km/h de 55 a 66 km/h.</p>
<p>La idea no se suma a la de la mañana. Con dos ejes de Mini, los pasos de rueda medirían 1,45 m de largo, el 63 % de cada costado: casi no quedarían cajones bajos.</p>
<h3 id="velos-bas">Las bicis bajan del techo</h3>
<p>Segunda pregunta: ¿por qué empeñarse en subir tres bicis a casi 2 m? Podrían ir sobre un soporte detrás del remolque. O dos detrás y una delante, sobre la lanza.</p>
<p>En cuanto al viento, no hay color. Colocadas de través a un metro del suelo, el viento de costado las coge <strong>de punta</strong>, y ya no están encaramadas: casi no cuentan en el vuelco. Pero es el <strong>peso sobre la bola</strong> lo que decide entre las ubicaciones, y ahí el cálculo no dijo lo que yo esperaba.</p>
<p><a href="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/16-velos.png"><img alt="Tres gráficos: la racha límite según la velocidad para cuatro combinaciones, el peso sobre la lanza según dónde van las bicis, y la altura total" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/16-velos.png" /></a></p>
<p><em>En el centro, el peso sobre la bola para cada ubicación: un punto por estado de carga, entre los límites del 4 y el 10 % (rótulos del gráfico en francés). Pulsar para ampliar.</em></p>
<ul>
<li><strong>Tres bicis detrás</strong>: de 40 a 60 kg a metro y medio por detrás del eje. Según el remolque vaya lleno o vacío, con o sin bicis, el peso sobre la bola va del 3 al 10 % de la masa. Demasiado poco a la vuelta con bicis eléctricas, demasiado cuando se circula sin bicis. Es exactamente lo que los caravanistas reprochan al portabicis trasero.</li>
<li><strong>Tres bicis sobre la lanza</strong>: el defecto contrario. La bola se descarga en cuanto se circula sin bicis.</li>
<li><strong>Dos detrás, una delante</strong>: la bici de delante compensa las de detrás. El peso sobre la bola se mantiene entre el 5 y el 8 % en todos los casos, tan formal como con las bicis en el techo. La más pesada va delante.</li>
</ul>
<p>El culebreo no se mueve. Tres bicis al fondo aumentan un 17 % la inercia de giro del remolque, y detrás de una T5 cuatro veces más pesada eso no cambia nada. Detrás de una berlina sería otra historia.</p>
<p>El portabicis lo haré yo mismo, y es de una sencillez que da gusto: <strong>una plataforma</strong>, y <strong>una mordaza que desliza sobre un raíl en el eje del remolque</strong>. Se colocan las bicis de través, se avanza la mordaza hasta apretar los cuadros contra unos topes fijados a la caja, se pone el pasador, se cierra el candado — la mordaza hace de <strong>antirrobo</strong> — y luego se atan las ruedas con cinchas. El modelo sacó a la luz dos detalles. Hay que girar el manillar un cuarto de vuelta. Y aun con las bielas en vertical, el pedal sobresale 14 cm: por eso los topes van separados 15 cm de la caja, si no es el pedal el que toca antes que el cuadro.</p>
<p><img alt="Vista trasera: dos bicis de través sobre una plataforma, una mordaza vertical con dos mandíbulas de goma las aprieta contra la caja, candado en el carro, barra de luces y matrícula bajo la plataforma" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/17-porte-velos-arriere.jpg" /></p>
<p><em>El portabicis trasero. La mordaza desliza sobre el raíl perforado, en el eje; pasador naranja y candado en el carro; cinchas naranjas en las ruedas; luces y matrícula repetidas detrás de las bicis.</em></p>
<p><img alt="Vista delantera: una bici de través sobre una plataforma apoyada en la lanza, entre la caja y la rueda jockey, sujeta por la misma mordaza" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/18-porte-velos-timon.jpg" /></p>
<p><em>El mismo principio sobre la lanza, para la bici más pesada. Con la dirección a tope queda lejos de la T5.</em></p>
<p>Lo que esto cambia en el uso importa más que las cifras. El mástil, el pescante y el torno de la sección <a href="#velos">Subir tres bicis a casi 2 m</a> ya no existen: una bici se carga a la altura de la cintura. Y la primera lección del modelo — <em>las bicis van sobre la tapa, mientras estén ahí el cofre no se abre</em> — también cae.</p>
<p><img alt="Vista desde arriba: la tapa del cofre abierta del todo con dos bicis colocadas detrás y una delante" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/19-bac-ouvert-velos.jpg" /></p>
<p><em>El cofre se abre con las bicis cargadas.</em></p>
<h3 id="retenue">La versión elegida</h3>
<p>Esta vez me he decidido: <strong>tren de Córdoba, caja rebajada, dos bicis detrás y una sobre la lanza.</strong></p>
<p><img alt="El remolque elegido enganchado a la T5: caja baja, dos bicis detrás, todo el conjunto por debajo de la línea de techo de la furgoneta" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/20-retenue-attelee.jpg" /></p>
<p><em>Enganchado. Todo el conjunto pasa por debajo del techo de la T5.</em></p>
<div class="table-scroll"><table>
<thead>
<tr>
<th></th>
<th>Proyecto del 19 de septiembre</th>
<th>Versión elegida</th>
</tr>
</thead>
<tbody>
<tr>
<td>Suelo</td>
<td>0,75 m</td>
<td>0,51 m</td>
</tr>
<tr>
<td>Altura total, con las bicis</td>
<td>2,92 m</td>
<td>1,63 m</td>
</tr>
<tr>
<td>Longitud total</td>
<td>4,35 m</td>
<td>5,09 m</td>
</tr>
<tr>
<td>Vuelco en curva</td>
<td>0,58 g</td>
<td>0,79 g</td>
</tr>
<tr>
<td>Racha soportada a 110 km/h, a la vuelta</td>
<td>55 km/h</td>
<td>91 km/h</td>
</tr>
<tr>
<td>Peso sobre la bola, todos los estados de carga</td>
<td>5,5 a 7,6 %</td>
<td>5,1 a 8,2 %</td>
</tr>
<tr>
<td>Para cargar una bici</td>
<td>un mástil de 3,45 m, un pescante, un torno</td>
<td>apoyarla</td>
</tr>
</tbody>
</table></div>
<p>A 0,79 g, el umbral de vuelco alcanza el límite de adherencia de los neumáticos en seco: el remolque deslizaría antes de volcar. Y con 1,63 m, todo el conjunto pasa bajo el techo de la T5, es decir, bajo las mismas barreras de aparcamiento que ella.</p>
<p>El precio: 74 cm más de longitud, luces y matrícula que repetir detrás de las bicis, bicis expuestas a las salpicaduras de la carretera, y un bastidor más complicado de soldar que un rectángulo.</p>
<p><a href="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/15-architecture.png"><img alt="Tres gráficos que comparan la caja sobre las ruedas y la caja rebajada: racha límite, vuelco en curva, altura" src="https://pf.olibrio.fr/images/remorque-famille-cuisine-velos/15-architecture.png" /></a></p>
<p><em>Caja sobre las ruedas frente a caja rebajada, para el Córdoba y para los dos ejes de Mini (rótulos del gráfico en francés). Pulsar para ampliar.</em></p>
<h2 id="lo-que-me-llevo">Lo que me llevo</h2>
<p><strong>Un render no es una comprobación.</strong> Las primeras imágenes eran convincentes y descansaban sobre un eje sobrecargado un 20 %. Lo que hizo avanzar el proyecto no fue el modelo 3D, fue la pregunta «¿cuánto pesa, y dónde?».</p>
<p><strong>Desconfiar de un resultado demasiado cómodo.</strong> «Estable por encima de 400 km/h» podía ser un fallo. La única forma de saberlo era pasar el mismo cálculo por un caso con respuesta conocida. Es el mismo reflejo que con una suma de cotas que cuadra: la coherencia no es una prueba.</p>
<p><strong>Comprobar con la pieza real.</strong> El error de los muelles no vino de un cálculo ni de un render, sino de una generalización («en este tipo de eje, el muelle va apoyado en el brazo») que nunca se contrastó con el coche. Bastó con acordarse del coche para verlo, y una guía de desmontaje lo confirmó.</p>
<p><strong>Un error absurdo es una buena noticia.</strong> 164° de articulación se ve enseguida. Los errores peligrosos son los que dan una cifra plausible, como esos 55° que no dependían de la longitud de la lanza, y que solo ese detalle delataba.</p>
<p><strong>Parametrizarlo todo.</strong> Cambiar de eje costó una línea: la caja se ensanchó, el suelo subió, los cajones de cocina se acortaron para mantener la encimera a 0,95 m y el cálculo recolocó el eje. Sobre el papel, habría sido una semana de goma de borrar.</p>
<p><strong>Buscar el método publicado antes de escribir uno propio.</strong> <em>(Añadido el 21 de septiembre.)</em> El cálculo del viento se corrigió tres veces antes de que preguntara qué decía la bibliografía. La respuesta cabía en tres líneas y se apoyaba en medidas; el modelo casero, en hipótesis apiladas. Una IA escribe un modelo físico plausible en treinta segundos, y ahí está el peligro: nada la empuja a ir a ver si ya existe uno.</p>
<p><strong>Una objeción de quien ha visto la carretera vale una revisión de código.</strong> No sé calcular una sustentación lateral. Pero «he visto remolques altos que no sufren con el viento», «una bici no es un panel», «hay una furgoneta delante»: cada una de esas observaciones encontró un fallo real. Hay que hacerlas, y exigir que se comprueben con el cálculo en lugar de rebatirse con un argumento.</p>
<p><strong>La palanca era la arquitectura, no el cálculo.</strong> <em>(Añadido el 21 de septiembre por la tarde.)</em> Una mañana refinando el modelo de viento movió el resultado unos pocos km/h. Dos preguntas de diseño — por qué la caja es tan alta, por qué las bicis van en el techo — lo llevaron de 55 a 91. La IA optimizaba con aplicación el proyecto que yo le había dado; nunca lo puso en duda. Eso me tocaba a mí, y he tardado dos días.</p>
<h2 id="lo-que-queda-por-hacer">Lo que queda por hacer</h2>
<ul>
<li><strong>Medir dos cotas en el Córdoba</strong>, con el coche apoyado en sus ruedas: la altura de la viga del eje (fija los 43 cm bajo el bastidor, y con ello todo lo demás) y la del ojo inferior del conjunto muelle-amortiguador (fija la altura del paso de rueda). De paso, anotar la posición de las articulaciones de los brazos y la plantilla de taladros de sus soportes.</li>
<li><strong>Dibujar el bastidor de verdad</strong>: dos largueros por dentro de las ruedas, travesaños que sostienen los costados, un puente de tubos sobre cada rueda, y la estanqueidad de los pasos de rueda.</li>
<li><strong>Probar de verdad la bici de la lanza</strong>: tiene que convivir con la rueda jockey y con la puerta del cofre del gas.</li>
<li><strong>Leer la carga máxima del eje trasero</strong> en la placa del fabricante del Córdoba, y revisar silentblocks y rodamientos.</li>
<li><strong>Pesar.</strong> Las masas del cálculo son estimaciones. El remolque terminado pasará por una báscula, lanza y eje por separado, y el eje todavía podrá desplazarse unos centímetros sobre sus largueros antes de la soldadura definitiva.</li>
<li><strong>El papeleo</strong> (normativa francesa). Cargado, el remolque superará los 500 kg de MMA: necesitará su propio permiso de circulación y, por tanto, una homologación individual (RTI) ante la DREAL al ser de construcción artesanal. Quedándose por debajo de 750 kg, no son obligatorios los frenos y basta el permiso B. Queda por confirmar, junto con la masa remolcable y la MMC que figuran en la documentación de la T5.</li>
<li><strong>Construir ligero.</strong> Cada kilo ganado en la caja es un kilo de margen en el eje y un poco más de estabilidad con viento de costado.</li>
</ul>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="se-puede-usar-un-eje-de-mini-para-un-remolque">¿Se puede usar un eje de Mini para un remolque?</h3>
<p>Sí, para un remolque pequeño y ligero: es compacto, bajo, y las ruedas de 10 pulgadas permiten un suelo bajo. Pero es el tren trasero de un coche de 650 kg, previsto para del orden de 450 kg como máximo. Un remolque equipado (cocina, nevera, agua, bicis) supera con facilidad los 500 kg sobre el eje.</p>
<h3 id="cuanto-peso-sobre-la-lanza-hay-que-buscar">¿Cuánto peso sobre la lanza hay que buscar?</h3>
<p>Entre el 5 y el 10 % de la masa del remolque, nunca menos del 4 % ni más de lo que admite el enganche del coche (a menudo de 75 a 100 kg). Aquí, un 7 % a plena carga, unos 44 kg. Se consigue colocando el eje, no añadiendo lastre.</p>
<h3 id="un-eje-con-muelles-helicoidales-ocupa-mas-sitio">¿Un eje con muelles helicoidales ocupa más sitio?</h3>
<p>Depende del montaje. Un muelle separado, apoyado en el brazo, cabe bajo el bastidor cuando la caja pasa por encima de las ruedas. Un conjunto muelle-amortiguador, como en el Seat Córdoba 6K o el VW Polo 6N, sube por encima de la rueda: hay que hacerle sitio en la caja, subir el suelo o sustituirlo por un muelle y un amortiguador separados. Conviene comprobarlo antes de concluir: bajo carga el muelle se comprime, y en mi remolque el conjunto de origen acaba cabiendo dentro del espesor del bastidor, a falta de una cota.</p>
<h3 id="que-longitud-de-lanza-para-dar-marcha-atras-con-facilidad">¿Qué longitud de lanza para dar marcha atrás con facilidad?</h3>
<p>Lo que cuenta es la relación entre la distancia bola–eje del remolque y la distancia eje trasero–bola del coche. Por encima de 2,5, la marcha atrás se vuelve cómoda; aquí, 2,8 con una lanza de 2 m. La forma importa tanto como la longitud: una viga central única cerca de la bola evita que la V de la lanza toque el coche en los giros cerrados.</p>
<h3 id="puede-culebrear-un-remolque-ligero-detras-de-una-furgoneta">¿Puede culebrear un remolque ligero detrás de una furgoneta?</h3>
<p>Es muy poco probable si la furgoneta pesa bastante más: el cálculo no encuentra inestabilidad por debajo de 400 km/h con una T5 de 2,4 t y un remolque de 0,6 t. El riesgo práctico es el viento lateral, y sobre todo lo que se sube al techo.</p>
<h3 id="con-que-viento-puede-volcar-un-remolque">¿Con qué viento puede volcar un remolque?</h3>
<p>Depende de su masa, su vía, su altura y la velocidad a la que se circule. El método de referencia es el de Baker y Soper (2018), que se usa para las restricciones de tráfico en puentes. Para mi remolque de 0,6 t: 85 km/h de racha de costado a 110 km/h sin nada en el techo, 55 km/h con tres bicis. Son velocidades de viento a la altura del remolque; las rachas previstas, medidas a 10 m, son alrededor de un 40 % más fuertes.</p>
<h3 id="son-mejores-dos-ejes-que-uno-en-un-remolque-pequeno">¿Son mejores dos ejes que uno en un remolque pequeño?</h3>
<p>Cargan más y mantienen mejor el rumbo: los neumáticos se oponen casi cinco veces más a la guiñada. A cambio, el remolque arrastra las ruedas al maniobrar y ya no se mueve a mano, pesa más en vacío, y si los dos ejes son independientes (suspensión de caucho), es la altura de la bola la que fija el reparto de la carga: hay que remolcarlo bien nivelado.</p>
<h2 id="pequeno-glosario">Pequeño glosario</h2>
<p><strong>Bogie, tándem</strong> — Dos ejes próximos montados uno detrás de otro bajo el mismo remolque.</p>
<p><strong>Conjunto muelle-amortiguador</strong> — Un amortiguador con el muelle montado a su alrededor; los dos se montan y desmontan de una pieza. Su cabeza se fija en la carrocería del coche.</p>
<p><strong>Carga sobre la lanza</strong> — La carga vertical que el remolque ejerce sobre la bola de enganche. Demasiado baja o negativa, aligera la parte trasera del coche y favorece el culebreo.</p>
<p><strong>Culebreo</strong> — Oscilación del remolque de un lado a otro que, por encima de una velocidad crítica, crece en lugar de amortiguarse.</p>
<p><strong>Arrastre lateral (ripado)</strong> — Deslizamiento lateral forzado de los neumáticos cuando un remolque de dos ejes gira: sus dos ejes no pueden seguir el mismo círculo.</p>
<p><strong>Eje torsional</strong> — Eje en el que los dos brazos tirados están unidos por un travesaño que se retuerce cuando las ruedas no se mueven a la vez; hace de barra estabilizadora.</p>
<p><strong>Guiñada</strong> — Giro de un vehículo alrededor de un eje vertical: el morro va a la izquierda, la cola a la derecha.</p>
<p><strong>RTI</strong> — <em>Réception à titre isolé</em>: homologación individual, por la administración regional francesa (DREAL), de un vehículo construido o modificado como unidad.</p>
<p><strong>Lanza</strong> — La parte delantera del remolque, del chasis a la cabeza de enganche.</p>
<p><strong>Vía</strong> — Distancia entre los centros de las dos ruedas de un mismo eje.</p>
<h2 id="references">Referencias y copias locales</h2>
<ul>
<li>El modelo completo, regenerable: scripts de Blender y Python, <code>remorque.blend</code>, cálculo detallado (comentarios y nombres de archivo en francés) — <a href="https://pf.olibrio.fr/assets/remorque-famille-cuisine-velos/remorque-famille.zip"><code>remorque-famille.zip</code></a></li>
<li>El cálculo solo, legible en línea (en francés): <a href="https://pf.olibrio.fr/assets/remorque-famille-cuisine-velos/CALCULS.md"><code>CALCULS.md</code></a></li>
<li>Los gráficos, en vectorial (rótulos en francés): <a href="https://pf.olibrio.fr/assets/remorque-famille-cuisine-velos/limites.svg"><code>limites.svg</code></a>, <a href="https://pf.olibrio.fr/assets/remorque-famille-cuisine-velos/architecture.svg"><code>architecture.svg</code></a>, <a href="https://pf.olibrio.fr/assets/remorque-famille-cuisine-velos/velos.svg"><code>velos.svg</code></a></li>
<li><a href="https://pure-oai.bham.ac.uk/ws/files/56018864/Baker_and_Soper_Calculation_of_the_overturning_wind_speed_of_large_road_vehicles_ICEproceedings.pdf">Baker y Soper (2018), <em>The calculation of the overturning wind speed of large road vehicles at exposed sites</em></a> (en inglés, acceso abierto): el método de cálculo del viento, y la medida de un remolque detrás de su camión</li>
<li><a href="https://mechanicalelements.com/torsion-axles-in-tandem-or-triple/">Mechanical Elements: los ejes de suspensión de caucho montados por parejas</a> (en inglés): por qué no se reparten la carga</li>
<li><a href="https://club.autodoc.co.uk/manuals/how-to-change-rear-suspension-strut-on-vw-polo-6n1-replacement-guide-13252">Guía de Autodoc: cambiar el amortiguador trasero de un VW Polo 6N1</a> (en inglés): la fuente de la corrección sobre los muelles</li>
<li><a href="https://pf.olibrio.fr/es/posts//es/posts/vibe-design-ventouse-tpu.html">La entrada anterior</a>: otra pieza diseñada dialogando con una IA, y la trampa de la suma de cotas que cuadra</li>
</ul>]]></content:encoded>
    </item>
    <item>
      <title>El fallo que quería corregir ya estaba corregido — y la corrección era errónea</title>
      <link>https://pf.olibrio.fr/es/posts/premiere-contribution-libcamera.html</link>
      <guid isPermaLink="true">https://pf.olibrio.fr/es/posts/premiere-contribution-libcamera.html</guid>
      <pubDate>Tue, 08 Sep 2026 12:00:00 +0000</pubDate>
      <description>¿Cómo elegir en qué contribuir cuando uno empieza? Seguí el consejo habitual — buscar una tarea bien delimitada en un proyecto activo — y me topé con tres cosas que nadie había reportado: una entrada de tabla errónea en código fusionado hace dos meses y revisado por cuatro personas, un sensor ausente, y un defecto de rendimiento que el mantenedor del paquete había instrumentado él mismo sin que nadie lo reportara. El relato de una tarde con un Pixel 3a, con los callejones sin salida, la predicción que fallé, y qué escribir cuando no se ha logrado demostrar algo.</description>
      <category>contribución</category>
      <category>software libre</category>
      <category>libcamera</category>
      <category>postmarketos</category>
      <category>pixel 3a</category>
      <category>método</category>
      <category>revisión de código</category>
      <category>depuración</category>
      <category>primer parche</category>
      <category>upstream</category>
      <content:encoded><![CDATA[<p><img src="https://pf.olibrio.fr/images/pixel3a/og-pixel3a.jpg" alt="El fallo que quería corregir ya estaba corregido — y la corrección era errónea"></p>
<div class="tldr">
<p><strong>En dos minutos</strong></p>
<ul>
<li><strong>Punto de partida</strong>: quería contribuir y no sabía por dónde. Seguí el consejo estándar — una tarea bien delimitada, en un proyecto activo, sobre hardware que poseo.</li>
<li><strong>Primera sorpresa</strong>: la tarea que había elegido se había hecho seis semanas antes. El aviso que veía en mi teléfono no era una carencia, era un desfase de versión.</li>
<li><strong>Segunda sorpresa</strong>: la corrección reciente contenía un error. Dos valores intercambiados, en código revisado por cuatro personas incluido el mantenedor, y marcado como probado.</li>
<li><strong>El trabajo de verdad</strong>: un sensor ausente de las tablas. Valores tomados del aparato, salvo uno que no pude demostrar — y señalado como tal en el mensaje del commit.</li>
<li><strong>La predicción fallida</strong>: anuncié fotos más claras tras la corrección. Medido: 39,2 % antes, 38,1 % después. Nada. La explicación es aritmética, y es instructiva.</li>
<li><strong>El hallazgo real</strong>: buscando por qué se congelaba la aplicación, un defecto de rendimiento que el mantenedor del paquete había instrumentado él mismo, escribiendo que «indica problemas accionables en los controladores V4L2 o de GPU». Nadie lo había reportado.</li>
</ul>
<p><em>Este artículo trata de método más que de cámaras. Debería leerse aunque <code>libcamera</code> no le diga nada. La parte técnica está en <a href="https://pf.olibrio.fr/es/posts/pixel-3a-postmarketos-linux-mainline.html">el artículo anterior</a>.</em></p>
</div>
<h2 id="el-problema-de-la-primera-contribucion">El problema de la primera contribución</h2>
<p>Todo el mundo da el mismo consejo: «busca una incidencia etiquetada <em>good first issue</em>». Es un buen consejo y no funciona demasiado bien, por una razón sencilla: esas tareas son o bien triviales hasta el punto de no enseñar nada, o bien ya las ha cogido alguien más rápido.</p>
<p>Lo que funciona mejor, creo, es partir de lo que uno tiene <strong>y los demás no</strong>. En mi caso: un teléfono viejo que había decidido hacer funcionar con Linux, y por tanto hardware físico sobre el que ejecutar código que otros escriben a ciegas.</p>
<p>Es una ventaja más rara de lo que parece. Muchos desarrolladores trabajan sobre controladores de hardware que no poseen, fiándose de fichas técnicas y de informes de usuarios. Quien tiene el aparato conectado en su escritorio puede responder preguntas que nadie más puede zanjar.</p>
<h2 id="el-hilo-una-tarea-bien-delimitada">El hilo: una tarea bien delimitada</h2>
<p>El proyecto postmarketOS mantiene una lista de tareas por aparato. Para el mío, una incidencia paraguas titulada «Camera TODOs» enumeraba una docena de puntos, todos marcados salvo uno:</p>
<blockquote>
<p>imx355 driver (front camera) is missing features for libcamera, makes the later complain (e.g. when running <code>cam -l</code>)</p>
</blockquote>
<p>Alcance claro, síntoma reproducible, un comando para constatarlo. Exactamente lo que se busca.</p>
<p>Ejecuté el comando en el teléfono. Se quejó, tal como anunciaba. Abrí el repositorio de <code>libcamera</code> para escribir la corrección.</p>
<p>Y la entrada ya estaba ahí.</p>
<h2 id="primera-leccion-una-incidencia-abierta-no-esta-necesariamente-abierta">Primera lección: una incidencia abierta no está necesariamente abierta</h2>
<p>El soporte del sensor se había añadido el 17 de julio de 2026, por un ingeniero de Raspberry Pi. La versión instalada en mi teléfono era del 10 de julio.</p>
<p><strong>Siete días de diferencia.</strong> El aviso que veía no era una carencia del proyecto, era un desfase entre la versión publicada y el repositorio.</p>
<p>Es una confusión fácil de cometer, y merece un reflejo: antes de escribir código, comprobar que el problema sigue existiendo <strong>aguas arriba</strong>, no solo en la propia máquina. Se hace con dos peticiones.</p>
<details>
<summary>Para profundizar: comparar una versión publicada con el repositorio</summary>
<p>La mayoría de las forjas permiten recuperar un fichero en una referencia dada. Basta con comparar la versión que uno ejecuta con la rama principal:</p>
<pre><code class="language-bash">F=&quot;src/libcamera/sensor/camera_sensor_properties.cpp&quot;
for ref in v0.7.2 master; do
  echo -n &quot;$ref: &quot;
  curl -s &quot;.../repository/files/$(urlencode $F)/raw?ref=$ref&quot; | grep -c '&quot;imx355&quot;'
done
# v0.7.2: 0
# master: 1
</code></pre>
<p>Cero apariciones en la versión publicada, una en el repositorio: el trabajo está hecho pero aún no ha salido. No hay nada que escribir.</p>
<p>El mismo reflejo vale para el núcleo. El segundo punto de la lista se refería a un controlador que no respondía a cierta consulta; también allí la corrección ya existía aguas arriba — ausente de las versiones 6.18, 7.0 y 7.1, presente en la rama principal. Simplemente no se había publicado todavía.</p>
</details>
<p>Dos tareas de tres se habían evaporado. Podría haberme detenido ahí con la sensación de haber perdido la tarde. Salvo que, al leer la entrada recién añadida, algo no cuadraba.</p>
<h2 id="segunda-leccion-la-revision-no-ve-las-tablas">Segunda lección: la revisión no ve las tablas</h2>
<p>La entrada asociaba dos patrones de prueba a valores numéricos. Pero el controlador del sensor, en el núcleo, define esos valores en el orden inverso. «Color sólido» y «barras de color» estaban <strong>intercambiados</strong>.</p>
<p>Lo verifiqué tres veces, por caminos independientes:</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Fuente</th>
<th>Lo que dice</th>
</tr>
</thead>
<tbody>
<tr>
<td>El controlador en mi teléfono, consultado directamente</td>
<td><code>1 = color sólido</code>, <code>2 = barras de color</code></td>
</tr>
<tr>
<td>El código fuente del controlador en el núcleo oficial</td>
<td>mismo orden</td>
</tr>
<tr>
<td>Otros dos sensores con menú idéntico, descritos justo al lado</td>
<td>correspondencia correcta</td>
</tr>
</tbody>
</table></div>
<p>Y busqué activamente el contexto en el que el autor habría tenido razón: su empresa mantiene su propio núcleo, a veces con controladores distintos. Lo comprobé: mismo orden en ambos árboles. El error era real, también en su propio hardware.</p>
<p>Lo interesante de esta historia no es el error. Es que el commit había sido <strong>revisado por cuatro personas</strong>, incluido el mantenedor del proyecto, y llevaba la marca de «probado» de una quinta.</p>
<p>¿Cómo se les escapan a cinco personas competentes dos valores intercambiados?</p>
<p>Porque <strong>no hay lógica que revisar</strong>. Es una correspondencia entre dos documentos que no viven en el mismo repositorio: una tabla por un lado, una lista de cadenas en el núcleo por el otro. Para verificarla hay que abrir ambos ficheros lado a lado, o tener el aparato a mano. Y «probado» significaba aquí <em>la cámara funciona, apunto y obtengo una imagen</em> — lo cual es cierto, y nunca ejercita los patrones de prueba, que son una herramienta de diagnóstico.</p>
<p>El resto de la entrada era correcto. El tamaño del fotosito, los retardos del sensor: todo lo que se ejercita a diario estaba bien. Solo la parte que nadie hace funcionar estaba mal.</p>
<p><strong>Ahí es donde poseer el aparato se vuelve una ventaja decisiva.</strong> No porque yo sea mejor, sino porque era el único que podía plantearle la pregunta al hardware.</p>
<h2 id="lo-que-debe-contener-un-parche-de-dos-lineas">Lo que debe contener un parche de dos líneas</h2>
<p>El parche son dos líneas. Su mensaje de commit son treinta, deliberadamente.</p>
<p>Un revisor no debe tener que ir a buscar nada. Así que incluí la tabla del controlador del núcleo citada tal cual, la salida del comando que interroga a mi teléfono, la consecuencia concreta en una frase — <em>pedir un color sólido produce barras de color, y viceversa</em> — y el argumento de coherencia con los dos sensores correctamente descritos.</p>
<p>Y me adelanté a la pregunta que iba a llegar: «¿y las demás entradas, están mal también?». No, y lo verifiqué controlador por controlador: otros dos sensores sí usan el orden inverso, porque <strong>sus</strong> controladores lo definen así. Una frase en el mensaje ahorra un ida y vuelta de tres días.</p>
<details>
<summary>Para profundizar: la trampa del identificador de commit</summary>
<p>Estos proyectos usan una convención para designar el commit que se corrige:</p>
<pre><code>Fixes: a1db25dabaee (&quot;libcamera: camera_sensor: Add Sony IMX355 sensor properties&quot;)
</code></pre>
<p>El identificador tiene doce caracteres. Yo tenía siete delante y <strong>completé los cinco que faltaban de memoria</strong>. Estaban mal. Un identificador inventado que parece real es peor que uno ausente: nadie lo comprueba, y no apunta a nada.</p>
<p>La forma correcta se lo pregunta a la herramienta, no a la memoria:</p>
<pre><code class="language-bash">git rev-parse --short=12 &lt;referencia&gt;
</code></pre>
<p>Es una nimiedad. Y es exactamente el tipo de detalle por el que devuelven un primer parche.</p>
</details>
<h2 id="el-trabajo-de-verdad-y-el-valor-que-no-se-puede-demostrar">El trabajo de verdad, y el valor que no se puede demostrar</h2>
<p>Quedaba algo realmente ausente: el segundo sensor del teléfono no figuraba en ninguna parte. Ni en la biblioteca, ni en el núcleo oficial — su controlador se escribió en un fabricante de chips hace ocho años y nunca se envió aguas arriba.</p>
<p>Tomé los valores del aparato y del código del controlador. Tres se deducen con rigor. El cuarto no: es un parámetro que se lee en una ficha técnica, y las fichas técnicas de estos sensores no son públicas.</p>
<p>Intenté respaldarlo. Encontré un fichero de configuración, en mi propio teléfono, que declaraba exactamente el valor que había supuesto. Excelente noticia durante unos tres minutos — hasta que comprobé si era <strong>independiente</strong>. No lo era: los diez ficheros equivalentes del proyecto declaran el mismo valor, incluso para sensores de tres fabricantes distintos. No eran diez mediciones concordantes, era un valor por defecto copiado diez veces.</p>
<p><strong>Así que lo escribí tal cual en el mensaje del commit</strong>: este valor sigue lo documentado para los sensores de la misma familia. No «según la ficha técnica», ninguna formulación que sugiriera una medición. Un revisor que tenga la documentación lo corregirá en un mensaje, y está muy bien así.</p>
<p>Vestir una incertidumbre es la forma más eficaz de perder la confianza de un proyecto en el primer parche.</p>
<h2 id="la-prediccion-que-falle">La predicción que fallé</h2>
<p>Leyendo el código, había entendido qué provocaba la ausencia de ese sensor: sin él, la biblioteca deja de convertir la ganancia de la cámara. Escribe un número de ajuste donde debería escribir un factor de amplificación, y relee el número como si fuera el factor. El bucle de exposición automática queda falseado en ambos sentidos.</p>
<p>De ahí saqué una predicción: tras la corrección, las fotos con poca luz deberían mejorar. Monté un protocolo limpio — teléfono fijado y nunca movido, mediciones objetivas de luminancia y ruido, una serie antes y una serie después.</p>
<p>Resultado: <strong>39,2 % de luminancia antes, 38,1 % después.</strong> Nada.</p>
<p>La explicación es aritmética, y la había señalado como riesgo antes de lanzar la prueba — sin sacar la consecuencia, que fue el error.</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Ganancia pedida</th>
<th>Fórmula correcta</th>
<th>Fórmula errónea</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>1,0×</td>
<td>≈ 1,0×</td>
</tr>
<tr>
<td>50</td>
<td>1,1×</td>
<td>50×</td>
</tr>
<tr>
<td>300</td>
<td>2,4×</td>
<td>300×</td>
</tr>
</tbody>
</table></div>
<p>El error solo es enorme con ganancia alta. Mi escena de prueba tenía una zona blanca saturada: la exposición automática tenía luz de sobra, se mantenía cerca de cero de ganancia, y en ese punto <strong>ambas fórmulas dan el mismo resultado</strong>.</p>
<p>El parche sigue siendo correcto, y funciona — lo verifiqué de otro modo. Tras la instalación, la biblioteca no emite ningún aviso para ese sensor, mientras que el otro sensor del teléfono, sin corregir, los emite todos. Un testigo negativo limpio.</p>
<p><strong>Pero no demostré una mejora visible, así que no lo escribiré.</strong> La marca de «probado» que adjuntaré dirá que el sensor ya está reconocido. No que las imágenes sean mejores.</p>
<p>Es una distinción que suena quisquillosa y no lo es. Un razonamiento correcto sobre un mecanismo no dice nada de su magnitud en las condiciones de la prueba. Tenía el mecanismo; no tenía la magnitud.</p>
<h2 id="el-hallazgo-que-no-estaba-en-ninguna-lista">El hallazgo que no estaba en ninguna lista</h2>
<p>Durante todo este trabajo, la aplicación de cámara se congelaba con regularidad. Una molestia, que al principio sorteaba reiniciando.</p>
<p>Luego la instrumenté, a falta de algo mejor. Y resultó que una <strong>sola línea</strong>, emitida una vez en la inicialización, lo explicaba todo:</p>
<pre><code>Importing input DMABuf failed, falling back to upload
</code></pre>
<p>El procesamiento de imagen se hace en el procesador gráfico. Normalmente la imagen en bruto le llega sin copia, mediante memoria compartida. Aquí la importación falla — y la biblioteca pasa a modo copia: <strong>doce megapíxeles transferidos a la GPU en cada imagen</strong>. El bus de memoria se satura, la pantalla ya no obtiene ancho de banda para sus propias operaciones, y el pipeline acaba estrangulado.</p>
<p>No es un fallo abrupto. Es una asfixia, lo que explica que no dejara ningún rastro aprovechable.</p>
<p>Y aquí está lo que da todo su valor a esa línea. Viene de un parche añadido por el mantenedor del paquete, que la había <strong>restaurado deliberadamente</strong> después de que el proyecto aguas arriba la retirara. Su argumento:</p>
<blockquote>
<p>Las importaciones fallidas degradan enormemente el rendimiento e indican problemas accionables en los controladores V4L2 o de GPU.</p>
</blockquote>
<p>El mantenedor había colocado el detector, dejando por escrito que su disparo merece una investigación. Se disparó en mi teléfono. Nadie lo había reportado.</p>
<p>Todavía no he demostrado la causalidad — la correlación es clara, el mecanismo coherente, y una prueba sencilla lo zanjaría. Pero es con diferencia lo más útil que encontré aquella mañana, y no estaba en ninguna lista de tareas.</p>
<h2 id="lo-que-me-llevo-para-la-proxima">Lo que me llevo, para la próxima</h2>
<p><strong>Lo que uno aporta no es talento, es una posición.</strong> No fui mejor que nadie. Tenía el aparato conectado y cinco revisores competentes no. Eso es todo, y basta.</p>
<p><strong>Comprobar que el problema sigue existiendo antes de escribir.</strong> Dos tareas de tres se habían evaporado, corregidas aguas arriba pero aún sin publicar. Dos peticiones lo habrían dicho de entrada.</p>
<p><strong>Una fuente que confirma solo sirve si es independiente.</strong> Diez documentos que copian el mismo valor por defecto no valen más que uno.</p>
<p><strong>Separar lo demostrado de lo deducido</strong> — en un mensaje de commit como en una conversación. Tenía un mecanismo correcto y una predicción errónea; decir uno sin el otro habría sido una mentira educada.</p>
<p><strong>Y instrumentar lo que molesta.</strong> La congelación de la aplicación era una molestia que llevaba horas sorteando. Fue al dejar de sortearla cuando encontré lo único que nadie más buscaba.</p>
<p>Es realmente un ovillo: uno tira de un hilo de dos líneas, y salen tres cosas que no había pedido.</p>]]></content:encoded>
    </item>
    <item>
      <title>Vibe design: hacer que una IA modele una pieza que nunca verá</title>
      <link>https://pf.olibrio.fr/es/posts/vibe-design-ventouse-tpu.html</link>
      <guid isPermaLink="true">https://pf.olibrio.fr/es/posts/vibe-design-ventouse-tpu.html</guid>
      <pubDate>Tue, 08 Sep 2026 12:00:00 +0000</pubDate>
      <description>Cómo modelar una ventosa de TPU a partir de un croquis en papel, dialogando con una IA que no tiene ni la pieza ni el calibre. Por qué las preguntas abiertas dan vueltas, por qué un render equivocado avanza más que una buena pregunta, por qué unas cotas que cuadran no demuestran nada, y qué le impone al dibujo el TPU 95A cuando se imprime con extrusor remoto.</description>
      <category>impresion 3d</category>
      <category>tpu</category>
      <category>cad</category>
      <category>python</category>
      <category>manifold3d</category>
      <category>ia</category>
      <category>vibe coding</category>
      <category>flsun qq-s</category>
      <category>ventosa</category>
      <category>filamento flexible</category>
      <content:encoded><![CDATA[<p><img src="https://pf.olibrio.fr/images/vibe-design-ventouse-tpu/og.jpg" alt="Vibe design: hacer que una IA modele una pieza que nunca verá"></p>
<div class="tldr">
<p><strong>En dos minutos, si quieres que una IA modele una pieza sin abrir un programa de CAD</strong></p>
<ul>
<li><strong>La situación</strong>: una ventosa de goma que hay que reponer, un calibre, una hoja de papel — y una IA a la que le describo la pieza. No la ve, no la toca, no puede medir nada. Todas las cotas salen de mí.</li>
<li><strong>Lo que no funciona</strong>: preguntar. Envié un croquis acotado y correcto, la IA enumeró seis ambigüedades, las contesté una por una — y seis intercambios después seguía teniendo la geometría mal.</li>
<li><strong>Lo que sí funciona</strong>: <strong>hacer que enseñe</strong>. Un render equivocado, mostrado con sus hipótesis en color, se corrige en una frase: «el 6,5 es el fuste, no la altura total». Dos iteraciones bastaron donde seis preguntas abiertas ya no avanzaban.</li>
<li><strong>La trampa</strong>: mis cotas cerraban perfectamente — 1 + 3,5 + 2 = 6,5 — sobre una pieza completamente falsa. <strong>Una suma que cuadra no demuestra una lectura correcta.</strong> Véase <a href="#suma-cuadra">La trampa de la suma que cuadra</a>.</li>
<li><strong>Cuando lo que bloquea es una palabra</strong>: dije «hueco», mi interlocutor entendió «el agujero». Ninguna reformulación sirvió; un esquema donde se <strong>colorea el volumen</strong> del que se habla lo resolvió en un envío.</li>
<li><strong>La parte del material</strong>: dibujar una ventosa en TPU 95A no es dibujar una ventosa. La goma real está entre 40 y 60 Shore A, la impresión deja microcanales entre capas, y en una impresora de extrusor remoto el filamento flexible es el peor caso. Todo eso cambia el dibujo, no solo los ajustes.</li>
<li><strong>El código</strong>: la pieza es un script de Python de 120 líneas (<a href="https://pf.olibrio.fr/assets/vibe-design-ventouse-tpu/ventouse.py"><code>ventouse.py</code></a>), todas las cotas como constantes al principio. Cambiar un valor y regenerar el STL cuesta diez segundos — eso es lo que hace llevaderas las idas y venidas.</li>
</ul>
<p><em>No hace falta saber CAD. Continúa <a href="https://pf.olibrio.fr/es/posts//es/posts/flsun-qqs-delta-klipper-calibration.html">la calibración de la misma impresora</a>, pero se lee solo.</em></p>
</div>
<p><img alt="Croquis a mano alzada de una ventosa acotado a bolígrafo azul, vista superior, corte A-A y vista inferior, con la ventosa roja apoyada junto a la hoja" src="https://pf.olibrio.fr/images/vibe-design-ventouse-tpu/00-croquis.jpg" /></p>
<p><em>El punto de partida: tres vistas, siete cotas y la pieza original al lado. Esta foto es todo lo que la IA tendrá jamás de esta ventosa.</em></p>
<h2 id="el-problema-no-es-dibujar-es-entenderse">El problema no es dibujar, es entenderse</h2>
<p>Tenía una ventosa de goma que rehacer y una impresora recién calibrada. El modelado en sí no es el asunto: una ventosa es un disco, un cilindro, un tetón y un taladro. Cualquier programa de CAD la saca en diez minutos — siempre que sepas <strong>qué estás dibujando</strong>.</p>
<p>El asunto es que quería que la dibujara una IA. No por comodidad: porque quería ver dónde se rompe. Una IA que escribe código tiene el bucle de realimentación más corto posible — el código funciona o no. Una IA que dibuja una pieza mecánica <strong>no tiene ninguno</strong>: no ve el objeto, no puede medir nada, y su resultado solo se vuelve falso en el momento en que la pieza sale de la impresora y no entra en su alojamiento. Todo lo que ocurre en medio es conversación.</p>
<p>Así que hice un croquis. Tres vistas, acotado, limpio: lo que se enseña en dibujo técnico. Y ahí es donde se pone interesante, porque ese croquis es <strong>correcto</strong> — y no bastó.</p>
<h2 id="seis-preguntas-hechas-sobre-mi-propia-foto">Seis preguntas hechas sobre mi propia foto</h2>
<p>El primer reflejo de la IA, y fue el bueno: no adivinar. Cogió mi foto, le puso seis chapas numeradas en rojo y me devolvió la imagen con sus seis preguntas ancladas a puntos concretos del dibujo.</p>
<p><img alt="El mismo croquis con seis chapas rojas numeradas añadidas por la IA, cada una unida por una línea a una cota o detalle ambiguo del dibujo" src="https://pf.olibrio.fr/images/vibe-design-ventouse-tpu/01-questions.jpg" /></p>
<p><em>Las seis ambigüedades, señaladas sobre el propio croquis. Anotar la imagen en vez de describir con palabras: lo único que funcionó a la primera en toda esta historia.</em></p>
<p>Ese método ya lo conocía: viene del artículo anterior, donde describir un gesto de medida en prosa me bloqueó dos veces seguidas, y donde anotar mi propia foto lo desbloqueó en un solo envío. Funciona en los dos sentidos. Cuando la IA no entiende mi dibujo, tiene que enseñarme <strong>dónde</strong> no entiende, no pedirme que «precise las dimensiones».</p>
<p>Y aun así. Contesté a las seis, una línea cada una. «Es una vista en corte de la misma pieza, materializa el espesor de la ventosa.» «Es el agujero, debajo de la ventosa.» «Tiene 3 mm de diámetro y 4 de profundidad.» «Es ciego.» Seis respuestas exactas, sin ambigüedad. Tras lo cual la geometría <strong>seguía estando mal</strong>.</p>
<h2 id="lo-que-le-falta-a-un-croquis-no-son-las-cotas">Lo que le falta a un croquis no son las cotas</h2>
<p>Aquí está el nudo. Mi croquis llevaba todas las cotas necesarias. Lo que no llevaba es <strong>a qué se refiere cada cota</strong> — y eso es justamente lo que un dibujo a mano alzada no dice, mientras que un plano acotado en regla lo dice mediante la posición de las líneas de referencia.</p>
<p>Un ejemplo. Había escrito «6,5 mm» con una flecha vertical a la derecha del corte. Para mí, evidente: la altura del fuste. Para la IA, igual de evidente: la altura total, ya que la flecha va de un extremo a otro del dibujo. Ambas lecturas se sostienen en una foto tomada de lado, donde la flecha se pasa un poco.</p>
<p>Lo mismo con el agujero y el tetón, ambos de tres y pico milímetros, en los dos extremos de la pieza. Escribí «3» en uno y «3,5» en el otro sabiendo cuál era cuál. Nada en el papel lo decía.</p>
<h2 id="ensenar">Lo que funciona: hacer que enseñe, no que diga</h2>
<p>Tras el sexto intercambio, cambio de método: en vez de hacerme una séptima pregunta, la IA modeló la pieza <strong>con sus hipótesis</strong>, sacó un render y me lo envió — con un código de color explícito en el corte acotado: <strong>en rojo las cotas que venían de mí, en cian las que se había inventado</strong>.</p>
<p>Miré el render tres segundos y escribí: «de la punta del tetón al borde del labio, la ventosa mide 10,5 mm. 2 mm de tetón, 6,5 mm de fuste, 2 mm de cuerpo de ventosa.»</p>
<p><img alt="Dos cortes de ventosa uno al lado del otro: a la izquierda la versión falsa y aplastada, 6,5 de altura total; a la derecha la buena, fuste de 6,5 y 10,5 total" src="https://pf.olibrio.fr/images/vibe-design-ventouse-tpu/02-deux-lectures.png" /></p>
<p><em>La misma pieza, las mismas cotas, dos lecturas. A la izquierda lo que la IA había entendido; a la derecha lo que yo había dibujado. Ninguna pregunta habría producido esa frase — la produjo el dibujo equivocado.</em></p>
<p>Ahí está la inversión interesante. Una pregunta abierta («la cota 6,5, ¿qué mide?») me pide reconstruir mentalmente el contexto, recuperar lo que tenía en la cabeza tres días antes y formular una respuesta en el vacío. Un render equivocado me pone la geometría delante, y <strong>el ojo corrige más rápido que la memoria</strong>. La corrección ya no cuesta nada: veo que el fuste está aplastado, luego sé qué decir.</p>
<p>Hay una condición para que funcione, y no es menor: <strong>la IA tiene que señalar lo que inventa</strong>. Un render limpio, sin distinguir lo que viene de mí de lo que ha rellenado, me habría hecho validar una pieza con cinco valores salidos de la nada. El cian del corte es la confesión de ignorancia hecha visible. Es lo que convierte el render en instrumento de medida y no en ilustración.</p>
<h2 id="suma-cuadra">La trampa de la suma que cuadra</h2>
<p>Esta es la parte que me parece más instructiva, y merece detenerse.</p>
<p>Cuando la IA sacó su segunda versión — la del fuste, todavía equivocada — me explicó que por fin había conseguido colocar la última cota huérfana de mi croquis, el famoso 3,5. Su demostración: la copela mide 1,0, el fuste 3,5, el tetón 2,0, <strong>total 6,5</strong>, exactamente la altura total del dibujo. Todas las cotas cerraban entre sí. Escribió, y era sincera: «tus cinco cotas cierran entre ellas, lo cual es buena señal para mi lectura».</p>
<p>Salvo que era falso. El 6,5 no era la altura total, el 3,5 no era la altura del fuste, y la pieza reconstruida no se parecía a nada. La lectura correcta da 2 + 6,5 + 2 = 10,5, y el 3,5 es el diámetro del taladro — una cota que no tiene nada que ver con un apilamiento de alturas.</p>
<p><strong>Una suma que cuadra no es una prueba.</strong> Con siete cotas y una pieza de revolución hay bastantes grados de libertad para que combinaciones falsas cierren por azar. La coherencia aritmética es un indicio débil, y es justo el tipo de indicio débil que una IA presenta con aplomo porque <em>se parece</em> a una verificación. Es un razonamiento con la forma de una prueba y ninguna de su fuerza.</p>
<p>Lo que lo zanjó no fue un cálculo: fue que la pieza dibujada no se parecía a la pieza que había sobre la mesa. El único juez, en este asunto, es el objeto.</p>
<h2 id="cuando-lo-que-bloquea-es-una-palabra-hay-que-colorear">Cuando lo que bloquea es una palabra, hay que colorear</h2>
<p>Un último bloqueo, de otra naturaleza. Para que una ventosa agarre, su cara inferior no debe ser plana: sube ligeramente hacia el centro. A eso lo llamo, a falta de algo mejor, el «hueco». Aprietas, el aire atrapado escapa por el labio; sueltas, la goma quiere recuperar su forma, la presión baja en la cavidad y la presión atmosférica aplasta la pieza contra la superficie. Ese es todo el mecanismo.</p>
<p>Solo que mi pieza también tiene un agujero ciego en el centro. Así que cuando me hablaron del «hueco», respondí: «¿a qué llamas el hueco? en el centro de la ventosa hay un agujero de 3,5 mm por 4 mm de profundidad, ¿es el rebaje del centro de la ventosa?»</p>
<p>Reformular no habría servido de nada — la palabra ya estaba ocupada. Lo que funcionó cabe en una imagen:</p>
<p><img alt="Corte de la ventosa apoyada sobre una superficie rayada, con el volumen de aire atrapado bajo la copela en azul y el taladro que sube por el fuste en rojo" src="https://pf.olibrio.fr/images/vibe-design-ventouse-tpu/03-creux.png" /></p>
<p><em>El hueco es el azul. El agujero es el blanco, en el extremo opuesto. Colorear el volumen del que se habla resuelve en una imagen lo que tres párrafos no habrían resuelto.</em></p>
<p>La lección general: cuando un intercambio se atasca en una palabra, no es un problema de vocabulario sino de referente. No hay que definir mejor la palabra, hay que <strong>señalar la cosa</strong>. En geometría, señalar se hace con color.</p>
<p>Un detalle que cuenta: en sus primeros cortes, la IA dibujaba el taladro como un rectángulo blanco que sobresalía por debajo de la pieza y dentro del hueco, «para que se vea bien». Se lo dije — aquella vista era menos clara, porque un trazo que sobresale hace creer en una geometría que no existe, y sobresalía justo en la zona que intentábamos discutir. Un esquema técnico no mejora exagerando los trazos; mejora encuadrando la zona útil y coloreando los volúmenes.</p>
<h2 id="la-pieza">La pieza</h2>
<p><img alt="Tres vistas de la ventosa modelada: vista en tres cuartos superior con el fuste y el tetón, vista inferior con la copela y el taladro, y corte acotado" src="https://pf.olibrio.fr/images/vibe-design-ventouse-tpu/04-final.png" /></p>
<p><em>La pieza terminada: copela Ø19,5, cuerpo 2, fuste Ø9 × 6,5, tetón de centrado Ø3 × 2, taladro ciego Ø3,5 × 4. Total 10,5.</em></p>
<p>El modelo es un script de Python de 120 líneas que usa <a href="https://github.com/elalish/manifold">manifold3d</a>, una biblioteca de geometría sólida. Al ser una pieza de revolución, todo cabe en un perfil <code>(radio, altura)</code> que se hace girar:</p>
<pre><code class="language-python">def profil(n=80):
    &quot;&quot;&quot;Contorno cerrado (r, z) de la media seccion, sentido antihorario.&quot;&quot;&quot;
    p = []
    r = np.linspace(0, R_INT, n)                    # cara inferior: concavidad parabolica
    p += [(x, CREUX * (1 - (x / R_INT) ** 2)) for x in r]
    p += [(R_EXT, 0.0), (R_EXT, E_LEVRE)]           # labio: apoyo plano y flanco
    r = np.linspace(R_EXT, R_FUT, n)                # cara superior del cuerpo, algo abombada
    t = (r - R_FUT) / (R_EXT - R_FUT)
    p += [(x, E_LEVRE + (Z_FUT - E_LEVRE) * (1 - u) ** BOMBE) for x, u in zip(r, t)]
    p += [(R_FUT, Z_TET), (R_TETON, Z_TET), (R_TETON, H), (0.0, H)]
    return p

m = Manifold.revolve(CrossSection([profil()]), 128) - trou
</code></pre>
<p>Lo que hace viable el ejercicio no es la biblioteca: es que <strong>todas las cotas son constantes al principio del archivo</strong>, cada una comentada con su procedencia — croquis, deducción o hipótesis. Cambiar un valor y regenerar el STL lleva diez segundos. En cinco idas y venidas, esa es la diferencia entre una conversación y una faena.</p>
<details>
<summary>Para ir al fondo: por qué un perfil de revolución y no cilindros apilados</summary>
<p>Se podría dibujar esta pieza apilando primitivas: un cilindro para el cuerpo, otro para el fuste, otro para el tetón, un cilindro restado para el taladro. Funciona, y es lo que hace de forma natural una IA a la que se le pide «una ventosa».</p>
<p>El problema es la copela. Su cara inferior es una superficie curva, y su espesor varía del borde al centro — es lo que le permite deformarse bajo la presión del dedo y volver. Con primitivas habría que restar un casquete esférico o un elipsoide, y el espesor resultante pasaría a ser una consecuencia difícil de controlar.</p>
<p>Con un perfil de revolución se describen directamente las dos superficies — la inferior como parábola <code>z = hueco · (1 − (r/R)²)</code>, la superior como curva abombada de exponente ajustable — y el espesor es la diferencia entre ambas, visible y gobernable en cada punto. En una pieza flexible cuya función entera está en cómo se deforma, es la única parametrización que da agarre.</p>
<p><code>Manifold.revolve</code> toma una sección en el plano XY, la gira alrededor del eje Y y devuelve un sólido cuyo eje es Z. El taladro ciego se resta después como un cilindro — dibujado, en el corte de vista previa, <strong>exactamente</strong> entre su entrada y su fondo, sin sobresalir.</p>
</details>
<h2 id="dibujar-para-tpu-no-es-dibujar-una-ventosa">Dibujar para TPU no es dibujar una ventosa</h2>
<p><img alt="Bobina de TPU Overture naranja, etiqueta con boquilla 210-230 °C, cama 25-60 °C, velocidad 20-40 mm/s y un número de lote" src="https://pf.olibrio.fr/images/vibe-design-ventouse-tpu/05-bobine-tpu.jpg" /></p>
<p><em>La bobina que desencadenó todo esto. La etiqueta anuncia de 20 a 40 mm/s — precisando, un poco más arriba, que apunta a impresoras de extrusor directo.</em></p>
<p>Una ventosa de verdad es de silicona o PVC blando, en torno a <strong>40-60 Shore A</strong>. El TPU más corriente, el que tengo, es <strong>95A</strong>: más o menos la dureza de una rueda de carrito. No es un detalle de ajuste, es una restricción de diseño.</p>
<p>Un labio grueso en 95A no se adaptará a los microdefectos de la superficie: apoyará en tres puntos altos y tendrá fugas entre ellos. Hace falta pues un labio <strong>fino</strong>, de 0,6 a 0,8 mm, capaz de flexar — a costa de fragilizarlo. Y hay algo peor: una pieza impresa por deposición de hilo es un apilamiento de cordones soldados, y entre dos cordones quedan <strong>microcanales</strong>. En una pieza estética nadie los nota. En una pieza cuya función es sostener una depresión, son fugas. De ahí capas finas, temperatura alta y un ligero exceso de material — no por resistencia, sino para <strong>soldar las capas entre sí</strong>.</p>
<p>Es el tipo de compromiso que un diálogo con una IA saca bien a la luz, siempre que se le dé el material <strong>antes</strong> que la geometría. Si hubiera pedido «dibújame una ventosa» sin más, habría obtenido un labio de 2 mm: correcto en goma moldeada, inservible aquí.</p>
<h2 id="tpu-en-una-impresora-de-extrusor-remoto-el-peor-caso">TPU en una impresora de extrusor remoto: el peor caso</h2>
<p>Queda imprimirla, y ahí mi máquina se recuerda a sí misma. En una <strong>FLSun QQ-S</strong>, el motor que empuja el filamento no está en el cabezal: está en el bastidor, y el hilo recorre unos 700 mm dentro de un tubo guía antes de llegar a la boquilla. Es un montaje <strong>bowden</strong>. Con filamento rígido funciona: el hilo se comporta como una varilla que se empuja. Con filamento flexible se comporta como un muelle — empujas por un lado, no sale nada por el otro, y luego sale todo de golpe.</p>
<p>De ahí tres consecuencias, y se ven en el perfil de laminado:</p>
<ul>
<li><strong>La retracción.</strong> Mi perfil de PLA retrae 5 mm. En TPU, 5 mm aflojan el hilo hasta el punto de que puede enrollarse a la entrada del tubo y atascarse — es <em>el</em> modo de fallo del flexible en bowden. Bajada a 2 mm, a velocidad reducida.</li>
<li><strong>La velocidad.</strong> La etiqueta anuncia de 20 a 40 mm/s suponiendo extrusor directo. En bowden, de 15 a 25.</li>
<li><strong>La aceleración.</strong> En una delta rápida, los tirones los absorbe la elasticidad del hilo en vez de la boquilla: falta material en las esquinas. Rebajada de 1500 a 800 mm/s², restaurada al terminar.</li>
</ul>
<details>
<summary>Para ir al fondo: ¿hay que montar el extrusor en el cabezal?</summary>
<p>Es la pregunta que viene enseguida: si el tubo es el problema, ¿por qué no montar el extrusor en el cabezal y suprimirlo? Justamente tengo un extrusor de doble arrastre esperando, un OMG V2-S, que pesa <strong>64 g</strong> y se monta indistintamente en bowden o en directo.</p>
<p>La cuenta es menos favorable de lo que parece, porque <strong>el peso no está en el extrusor, está en el motor</strong>: unos 215 g con un motor plano, 365 g con uno estándar. Y en una delta el efector se mueve en los tres ejes, al contrario que en una cartesiana, donde un extrusor directo solo carga el eje X.</p>
<p>Ahora bien, la frecuencia de resonancia de una estructura sigue <code>f ∝ 1/√m</code>. Mi máquina ya resuena a 20 Hz, que es bajo; doblar la masa móvil la llevaría hacia 14 Hz. La documentación de Klipper considera que por debajo de 25 Hz hay que <strong>rigidizar la máquina en vez de compensar</strong> — por debajo, el filtro antivibraciones redondea los detalles. Pagaría la comodidad del TPU con una degradación en todo lo demás, en una máquina que acabo de calibrar.</p>
<p>La conclusión práctica: mantener el bowden y atacar el problema por el otro extremo. El verdadero culpable del flexible no es la longitud del tubo, es el extrusor de origen de <strong>un solo rodillo</strong>, bajo el cual el filamento blando se escapa de lado. Un doble arrastre lo sujeta por ambos lados. Y un tubo de 1,9 mm de diámetro interior en vez de 2,0 impide que el hilo pandee en la holgura. Dos piezas baratas que resuelven lo esencial sin tocar la dinámica de la máquina.</p>
</details>
<h2 id="lo-que-me-llevo">Lo que me llevo</h2>
<p><strong>Una IA que dibuja no tiene bucle de realimentación.</strong> No ve la pieza, no mide nada, y su error solo se hace visible al imprimir. Todo el trabajo consiste en fabricarle ese bucle a mano — y el render es eso.</p>
<p><strong>Enseñar gana a preguntar.</strong> Una pregunta abierta me pide reconstruir un contexto; un dibujo equivocado me pone la geometría delante y el ojo corrige solo. Seis preguntas no convergieron; dos renders sí.</p>
<p><strong>La IA debe señalar lo que inventa.</strong> El código rojo/cian — tus cotas, mis hipótesis — es lo que convierte un render bonito en instrumento de medida. Sin él habría validado cinco valores salidos de la nada.</p>
<p><strong>La coherencia aritmética no es una verificación.</strong> Mis cotas cerraban perfectamente sobre una pieza falsa. Una IA presenta ese tipo de indicio con el aplomo de una prueba, porque tiene su forma. El único juez es el objeto sobre la mesa.</p>
<p><strong>Cuando una palabra bloquea, señala la cosa.</strong> Nada de reformular: una imagen donde se colorea el volumen del que hablas.</p>
<p><strong>El material se da antes que la geometría.</strong> «Una ventosa» y «una ventosa de TPU 95A impresa por deposición de hilo» no son la misma pieza, y la segunda no se obtiene ajustando los parámetros de la primera.</p>
<p><strong>Y la parametrización hace todo esto llevadero.</strong> Cinco versiones sucesivas, diez segundos cada una. Si cada corrección hubiera supuesto rehacer un modelo de CAD, habría abandonado en el segundo render y dibujado la pieza yo mismo — lo cual, dicho sea de paso, habría sido perfectamente razonable.</p>
<h2 id="donde-estamos">Dónde estamos</h2>
<div class="status">
<p><strong>Situación a 8 de septiembre de 2026: modelo congelado, impresión pendiente.</strong> La geometría está validada sobre el corte acotado, el script saca el STL y su vista previa, el perfil de laminado para TPU está escrito. La impresión espera al montaje del extrusor de doble arrastre y luego a una prueba de humedad del filamento — la bobina es de noviembre de 2023, y el TPU absorbe agua aún más deprisa que el PETG. Queda una incógnita que solo se resolverá probando: el diámetro real del fuste impreso. Dibujado a Ø9, saldrá probablemente a Ø9,2; en TPU eso se recupera, la pieza entra comprimiéndose. En PLA habrían hecho falta tres intentos.</p>
</div>
<h2 id="para-reproducirlo">Para reproducirlo</h2>
<p><strong>Lo que hace falta</strong>: la pieza original, un calibre, con qué hacer un croquis y un entorno Python con <code>manifold3d</code>, <code>numpy</code> y <code>matplotlib</code>. Ningún programa de CAD.</p>
<p><strong>El croquis.</strong> Tres vistas valen más que una perspectiva. Pero sobre todo: <strong>escribe junto a cada cota qué mide</strong>, con todas las letras. «6,5 = altura del fuste», no «6,5». Queda feo en un plano en regla; es lo que aquí te ahorra cinco idas y venidas.</p>
<p><strong>El bucle.</strong> En cada iteración, exige tres salidas: el STL, una <strong>vista 3D</strong> (¿se parece al objeto?) y un <strong>corte acotado</strong> (¿están las cotas en los sitios correctos?). El corte es el que encuentra los errores; la 3D, la que encuentra los disparates.</p>
<p><strong>El código de color.</strong> Pide explícitamente que se distingan en pantalla las cotas tomadas de tu croquis y las inventadas por la IA. Es el punto más rentable de todo el método.</p>
<p><strong>Las reglas de dibujo</strong> que fueron surgiendo, para un esquema técnico legible: cada forma se detiene en su geometría real, nunca un trazo que sobresale «para que se vea»; el texto fuera de la pieza, nunca encima; encuadrar la zona en discusión — un hueco de 1 mm es invisible a la escala de una pieza de 20; y colorear los volúmenes en vez de engordar los trazos.</p>
<p><strong>Los archivos</strong>: el modelo <a href="https://pf.olibrio.fr/assets/vibe-design-ventouse-tpu/ventouse.py"><code>ventouse.py</code></a> y el <a href="https://pf.olibrio.fr/assets/vibe-design-ventouse-tpu/ventouse.stl">STL</a> que produce; el perfil de laminado <a href="https://pf.olibrio.fr/assets/vibe-design-ventouse-tpu/qqs-tpu.ini"><code>qqs-tpu.ini</code></a> (PrusaSlicer por línea de comandos, delta de 260 mm, boquilla 0,4); y <a href="https://pf.olibrio.fr/assets/vibe-design-ventouse-tpu/esp32-supermini-tray.py"><code>esp32-supermini-tray.py</code></a>, una pieza anterior hecha con la misma cadena, para comparar una geometría prismática con una de revolución.</p>
<p><strong>El perfil TPU en resumen</strong>, si imprimes flexible en bowden: retracción 2 mm a 25 mm/s, perímetros 15-20 mm/s, aceleración 800, boquilla 225-230, cama 45-50, ventilación 40-60 %, primera capa menos aplastada de lo habitual (el flexible refluye en vez de extenderse), y una barra de pegamento sobre el vidrio como <strong>desmoldeante</strong> — el TPU se adhiere lo bastante como para arrancar una lasca.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="se-puede-hacer-cad-de-verdad-dialogando-con-una-ia-sin-software">¿Se puede hacer CAD de verdad dialogando con una IA, sin software?</h3>
<p>Para una pieza sencilla y bien definida, sí, y el resultado es paramétrico, versionable y comentado — tres cosas que un archivo de CAD da mal. Para una pieza cuya forma aún no conoces, no: el diálogo cuesta más que el boceto. La frontera está más o menos donde puedes describir la pieza en una frase.</p>
<h3 id="por-que-no-basto-mi-croquis-acotado">¿Por qué no bastó mi croquis acotado?</h3>
<p>Porque un croquis a mano alzada lleva las cotas pero no sus anclajes. En un plano en regla, la posición de las líneas de referencia dice a qué se refiere la cota; a mano alzada, en una foto tomada de lado, esa información desaparece. Escribir con todas las letras qué mide cada cota la restituye.</p>
<h3 id="puede-una-ia-inventarse-cotas-sin-decirlo">¿Puede una IA inventarse cotas sin decirlo?</h3>
<p>Lo hace necesariamente — una pieza tiene más dimensiones de las que lleva un croquis. La cuestión es si lo señala. Exige que los valores inventados se marquen en el render y se comenten en el código; se comprueba de un vistazo y lo cambia todo.</p>
<h3 id="sirve-el-tpu-95a-para-una-ventosa">¿Sirve el TPU 95A para una ventosa?</h3>
<p>Es bastante más duro que la silicona de una ventosa real (40-60 Shore A). Puede funcionar sobre una superficie muy lisa con un labio fino y capas finas, pero no esperes el agarre de una pieza moldeada. Un TPU más blando, de 85A, iría mejor para el uso — y sería mucho más difícil de imprimir en bowden.</p>
<h3 id="hace-falta-extrusor-directo-para-imprimir-tpu">¿Hace falta extrusor directo para imprimir TPU?</h3>
<p>No para 95A; en la práctica sí para 85A y más blandos. En bowden, lo que más cuenta no es la longitud del tubo sino el extrusor: un doble arrastre sujeta el filamento por ambos lados, donde un solo rodillo lo deja escapar. Un tubo de 1,9 mm de interior lo completa bien.</p>
<h3 id="por-que-no-montar-el-extrusor-en-el-cabezal-de-una-delta">¿Por qué no montar el extrusor en el cabezal de una delta?</h3>
<p>Porque la masa móvil es ahí el parámetro crítico y penaliza los tres ejes a la vez. Doblar la masa del efector hace caer la frecuencia de resonancia en un factor √2; por debajo de 25 Hz, la compensación por software empieza a redondear los detalles. Véase el recuadro de la sección sobre el bowden.</p>
<h3 id="cuanto-tiempo-llevo-todo">¿Cuánto tiempo llevó todo?</h3>
<p>Una hora escasa de conversación, cinco versiones del modelo. La mayor parte de ese tiempo se fue en despejar seis ambigüedades del croquis — no en dibujar.</p>
<h2 id="pequeno-glosario">Pequeño glosario</h2>
<p><strong>Bowden (montaje)</strong> — El motor que empuja el filamento va fijado al bastidor, y el hilo llega a la boquilla por un tubo guía. Aligera el cabezal móvil, pero introduce elasticidad en el empuje.</p>
<p><strong>Direct drive</strong> — Lo contrario: el motor va en el cabezal. Mejor control del material, cabezal más pesado.</p>
<p><strong>Efector</strong> — En una impresora delta, la pieza móvil que sostiene la boquilla, suspendida de los tres pares de brazos.</p>
<p><strong>manifold3d</strong> — Biblioteca de geometría sólida que garantiza mallas siempre válidas; la pieza se describe en Python mediante operaciones booleanas y revoluciones.</p>
<p><strong>Pressure advance</strong> — Compensación por software del retardo entre la orden de extrusión y la salida de material, debido a la compresibilidad del filamento. Tanto mayor cuanto más elástico es el montaje.</p>
<p><strong>Retracción</strong> — Retroceso del filamento durante los desplazamientos sin extrusión, para evitar hilos. Larga en bowden, muy corta en directo.</p>
<p><strong>Shore A</strong> — Escala de dureza de los elastómeros. La silicona de una ventosa está en 40-60, una junta de puerta en 70, un TPU de impresión corriente en 95, una rueda de carrito en 98.</p>
<p><strong>STL</strong> — Formato de archivo que describe una superficie mediante una malla de triángulos. Lo que espera el laminador.</p>
<p><strong>Laminador (slicer)</strong> — El programa que convierte un STL en trayectorias de boquilla. Aquí PrusaSlicer, gobernado por línea de comandos con un archivo de perfil.</p>
<p><strong>TPU</strong> — Poliuretano termoplástico: el filamento flexible más corriente.</p>
<h2 id="referencias">Referencias y copias locales</h2>
<ul>
<li>El modelo y sus salidas: <a href="https://pf.olibrio.fr/assets/vibe-design-ventouse-tpu/ventouse.py"><code>ventouse.py</code></a>, <a href="https://pf.olibrio.fr/assets/vibe-design-ventouse-tpu/ventouse.stl"><code>ventouse.stl</code></a></li>
<li>El perfil de laminado para TPU: <a href="https://pf.olibrio.fr/assets/vibe-design-ventouse-tpu/qqs-tpu.ini"><code>qqs-tpu.ini</code></a></li>
<li>Una pieza prismática hecha con la misma cadena: <a href="https://pf.olibrio.fr/assets/vibe-design-ventouse-tpu/esp32-supermini-tray.py"><code>esp32-supermini-tray.py</code></a></li>
<li><a href="https://github.com/elalish/manifold">manifold3d</a> — la biblioteca de geometría sólida utilizada</li>
<li><a href="https://www.klipper3d.org/Measuring_Resonances.html">Documentación de Klipper — medida de resonancias</a> — sobre el umbral de 25 Hz y el compromiso masa/rigidez</li>
<li><a href="https://pf.olibrio.fr/es/posts//es/posts/flsun-qqs-delta-klipper-calibration.html">El artículo anterior</a> — la calibración de la misma máquina, donde nació el método de la foto anotada</li>
</ul>]]></content:encoded>
    </item>
    <item>
      <title>Un Pixel 3a europeo con Linux: lo que Google abandonó en 2022 hoy corre un núcleo de 2026</title>
      <link>https://pf.olibrio.fr/es/posts/pixel-3a-postmarketos-linux-mainline.html</link>
      <guid isPermaLink="true">https://pf.olibrio.fr/es/posts/pixel-3a-postmarketos-linux-mainline.html</guid>
      <pubDate>Mon, 07 Sep 2026 12:00:00 +0000</pubDate>
      <description>Un Pixel 3a europeo (G020F), última actualización de Google en mayo de 2022, restablecido de fábrica y con la pantalla rota. En una tarde: postmarketOS con un núcleo Linux mainline 7.1.3, Phosh, acceso SSH por el cable USB. El relato completo — por qué el núcleo mainline y no Ubuntu Touch, el desbloqueo del gestor de arranque, y la hora perdida culpando al cable cuando el responsable era la suspensión automática USB del núcleo, reaplicada por TLP. Y por qué no es solo un pasatiempo: Chat Control, la verificación de edad, y el documento de identidad que Google exigirá pronto a los desarrolladores para que podamos instalar sus aplicaciones.</description>
      <category>pixel 3a</category>
      <category>postmarketos</category>
      <category>linux mainline</category>
      <category>sdm670</category>
      <category>obsolescencia</category>
      <category>fastboot</category>
      <category>suspensión usb</category>
      <category>tlp</category>
      <category>libcamera</category>
      <category>phosh</category>
      <category>software libre</category>
      <category>derecho a reparar</category>
      <category>chat control</category>
      <category>verificación de edad</category>
      <category>soberanía digital</category>
      <category>grapheneos</category>
      <category>privacidad</category>
      <content:encoded><![CDATA[<p><img src="https://pf.olibrio.fr/images/pixel3a/og-pixel3a.jpg" alt="Un Pixel 3a europeo con Linux: lo que Google abandonó en 2022 hoy corre un núcleo de 2026"></p>
<div class="tldr">
<p><strong>En dos minutos</strong></p>
<ul>
<li><strong>Punto de partida</strong>: un Pixel 3a de 2019, modelo europeo G020F, última actualización de seguridad el 5 de mayo de 2022, pantalla rota, restablecido de fábrica. Oficialmente: un residuo.</li>
<li><strong>Punto de llegada</strong>, unas horas después: <strong>postmarketOS</strong> con un <strong>núcleo Linux 7.1.3 mainline</strong> — no un núcleo Android remendado, el de verdad —, el entorno Phosh, las dos cámaras detectadas y acceso <code>ssh</code> por el simple cable USB.</li>
<li><strong>La decisión que importa</strong>: Ubuntu Touch hace que todo funcione mejor, pero se apoya en controladores Android congelados. postmarketOS hace funcionar menos cosas, sobre código que se puede corregir y enviar aguas arriba. Para quien quiera contribuir, es la única opción.</li>
<li><strong>La hora perdida</strong>: <code>fastboot</code> se quedaba colgado sin un solo mensaje. Culpé sucesivamente a los permisos, al cable, al puerto USB y a la versión del binario. Las cuatro eran falsas. El responsable: <strong>el núcleo duerme la interfaz USB tras dos segundos</strong>, el gestor de arranque del Pixel no sabe despertar — y <strong>TLP</strong> deshacía mi corrección en silencio.</li>
<li><strong>Lo que eso revela</strong>: esta trampa no está documentada en ninguna parte. Quien la encuentra concluye que su cable está muerto y abandona. Una corrección de dos líneas lo resuelve, para todos los Pixel.</li>
<li><strong>Lo que viene</strong>: <code>cam -l</code> reproduce un fallo conocido de libcamera desde el primer arranque — y revela un segundo, más fácil, que nadie había reportado.</li>
<li><strong>¿Y tu teléfono?</strong> postmarketOS cubre 39 aparatos en <code>community</code> (catorce de ellos teléfonos) y 149 en <code>testing</code>; Ubuntu Touch anuncia 111. Las tablas completas, <a href="#y-tu-telefono">más abajo</a>.</li>
</ul>
<p><em>Este artículo pretende leerse sin saber nada de Android ni de Linux: cada término técnico se explica la primera vez que aparece. Los recuadros «Para profundizar» se despliegan para quien quiera los comandos exactos.</em></p>
</div>
<p><img alt="La parte trasera del Pixel 3a: grabados en el plástico blanco, el marcado CE, el contenedor con ruedas tachado, la mención «Model G020F» y la G de Google" src="https://pf.olibrio.fr/images/pixel3a/dos-g020f-ce-weee.jpg" /></p>
<p><em>La parte trasera del aparato. «Model G020F» — la variante europea. Al lado, el marcado CE y el contenedor tachado, ese pictograma que significa «no tirar con la basura doméstica». Han hecho falta siete años para que ese símbolo dejara de ser un trámite y se convirtiera en el tema.</em></p>
<h2 id="que-significa-realmente-fin-de-soporte">Qué significa realmente «fin de soporte»</h2>
<p>El Pixel 3a salió en mayo de 2019. Era el sensato de su generación: una cámara notable por 400 €, un conector de auriculares que los buques insignia ya habían suprimido, un procesador Snapdragon 670 sin pretensiones. Google lo actualizó hasta el <strong>5 de mayo de 2022</strong>. La última versión instalada en este lleva el número <code>SP2A.220505.008</code> — Android 12, parche de seguridad de mayo de 2022.</p>
<p>Desde entonces, nada. No porque el hardware haya fallado: funciona perfectamente. Porque una empresa decidió que un plazo se había cumplido.</p>
<p>«El dispositivo ya no tiene soporte» es una frase que se lee sin pensarla. Traduzcámosla. El procesador, la pantalla, las cámaras, el módem, la batería — todo eso sigue funcionando. Lo que se detiene es un servicio: alguien, en algún sitio, deja de compilar software para esa combinación concreta de chips. El teléfono no se vuelve defectuoso, se vuelve <strong>huérfano</strong>. Y como el software que ejecuta no lo puede modificar su propietario, huérfano significa condenado.</p>
<p>Salvo que este era un Pixel. Y los Pixel tienen una propiedad rara: Google, a diferencia de casi todos sus competidores, permite al propietario <strong>desbloquear el gestor de arranque</strong> — el pequeño programa que decide qué sistema operativo tiene derecho a iniciarse. Ese permiso, sobre el que volveré, es lo que separa un aparato recuperable de un ladrillo.</p>
<details>
<summary>Para profundizar: qué bloquea exactamente un gestor de arranque</summary>
<p>Cuando un teléfono se enciende, un programa diminuto grabado en el chip arranca primero, verifica una firma criptográfica sobre el sistema que viene a continuación y se niega a seguir si no coincide. Es el <em>arranque verificado</em> (<strong>verified boot</strong>), y es algo bueno: impide que un software malicioso reemplace tu sistema a tus espaldas.</p>
<p>El problema no es el mecanismo, es <strong>quién tiene la llave</strong>. En un aparato bloqueado, solo el fabricante puede firmar un sistema. El día en que deja de producirlos, la cerradura sigue ahí, pero ya nadie tiene la llave. La seguridad se convierte en una condena.</p>
<p>Google deja que el propietario desactive ese control, con un aviso bien visible y un borrado completo de los datos por el camino — que es la forma correcta de hacerlo, ya que un ladrón no puede desbloquear sin destruirlo todo. Las variantes vendidas por ciertos operadores estadounidenses, en cambio, están selladas de forma definitiva. La diferencia no es técnica: es comercial. En la trasera del mío, «G020F» significa <em>Rest of World</em>, la versión europea. Vendida sin operador, por tanto desbloqueable.</p>
</details>
<h2 id="tres-maneras-de-poner-linux-en-un-telefono-y-solo-una-que-cuenta-aqui">Tres maneras de poner Linux en un teléfono, y solo una que cuenta aquí</h2>
<p>Un teléfono Android ya ejecuta un núcleo Linux. Pero un núcleo Android es una versión antigua del núcleo oficial, a la que el fabricante del chip ha añadido miles de modificaciones que nunca publica aguas arriba. Ese código solo vive lo que dura el producto. Ahí está toda la diferencia entre las tres opciones que había:</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th></th>
<th>postmarketOS</th>
<th>Ubuntu Touch</th>
<th>Droidian</th>
</tr>
</thead>
<tbody>
<tr>
<td>Base</td>
<td><strong>núcleo Linux mainline</strong></td>
<td>controladores Android congelados (Halium)</td>
<td>controladores Android congelados</td>
</tr>
<tr>
<td>En el Pixel 3a</td>
<td>categoría <em>community</em></td>
<td>versión estable, muy pulida</td>
<td>funcional</td>
</tr>
<tr>
<td>Llamadas, cámara, huella</td>
<td>parcial</td>
<td><strong>todo funciona</strong></td>
<td>parcial</td>
</tr>
<tr>
<td>Esperanza de vida</td>
<td>la de Linux</td>
<td>la de los controladores de 2019</td>
<td>ídem</td>
</tr>
<tr>
<td>Corregible aguas arriba</td>
<td><strong>sí</strong></td>
<td>no</td>
<td>no</td>
</tr>
</tbody>
</table></div>
<p>Ubuntu Touch es objetivamente la mejor opción para <em>usar</em> este teléfono: llamadas, SMS, 4G, Bluetooth, NFC, las dos cámaras, el lector de huella — todo funciona. Pero lo consigue reutilizando los controladores binarios de Android 9. Es decir, embalsamando 2019. Nada de lo que allí se corrija beneficia a nadie más, y el día en que esa base se pudra, no habrá nada que hacer.</p>
<p>postmarketOS toma el camino inverso: hacer funcionar el <strong>núcleo Linux oficial</strong>, el que usa todo el mundo, sobre este chip. Es más difícil, faltan cosas, y ahí está precisamente el interés — lo que se escribe allí sube al núcleo que el mundo entero usará dentro de diez años. Un grupo de desarrolladores se dedica específicamente a este procesador, bajo el nombre <strong>sdm670-mainline</strong>.</p>
<p>La elección era pues sencilla, a condición de asumir lo que implica: este teléfono no será mi teléfono. Es un banco de pruebas.</p>
<h2 id="el-desbloqueo-y-la-trampa-del-telefono-restablecido">El desbloqueo, y la trampa del teléfono restablecido</h2>
<p>El aparato llegó restablecido de fábrica, lo que parecía simplificar las cosas. No fue así.</p>
<p>Para desbloquear el gestor de arranque hay que activar una opción llamada <strong>Desbloqueo de OEM</strong> en los ajustes de Android. Ahora bien, esa opción permanece atenuada mientras el teléfono no haya alcanzado la red al menos una vez: Google comprueba que el aparato no esté denunciado como robado. Hay que encender el teléfono, atravesar el asistente de configuración, conectar el Wi-Fi — y solo entonces activar la opción. En un aparato que uno se dispone a borrar por completo, es un rodeo absurdo pero obligatorio.</p>
<p>Segunda trampa, más traicionera: la combinación de teclas para entrar en modo <em>fastboot</em> — el modo de mantenimiento del gestor de arranque — es <strong>Bajar volumen + Encendido</strong>, pero <strong>únicamente desde un teléfono completamente apagado</strong>. En un aparato encendido, esa misma combinación hace una captura de pantalla. Uno pulsa, no ocurre nada de lo esperado, vuelve a intentarlo y empieza a dudar de su hardware. Hay que apagar, esperar dos segundos, mantener Bajar volumen <em>primero</em>, y luego pulsar Encendido.</p>
<p>El resto cabe en un comando, y un aviso rojo en pantalla que hay que confirmar con los botones físicos:</p>
<pre><code>fastboot flashing unlock
</code></pre>
<p><img alt="La pantalla rota del Pixel 3a en modo fastboot, mostrando la información del gestor de arranque: Product revision sargo MP1.0 (ROW), Secure boot PRODUCTION, y en rojo «Device state: unlocked»" src="https://pf.olibrio.fr/images/pixel3a/fastboot-unlocked.jpg" /></p>
<p><em>La pantalla de fastboot después de la operación. «Device state: unlocked» en rojo: el teléfono acepta ya arrancar un sistema que Google no ha firmado. Nótese «sargo MP1.0 (ROW)» — sargo es el nombre en clave del Pixel 3a, ROW confirma la variante internacional.</em></p>
<p>El teléfono lo borra todo y se reinicia. A partir de ahí, ya no pertenece del todo a Google.</p>
<h2 id="preparar-el-sistema-media-hora-de-preguntas">Preparar el sistema: media hora de preguntas</h2>
<p>Del lado del ordenador, postmarketOS se construye con una herramienta llamada <code>pmbootstrap</code>, disponible en los repositorios de la mayoría de las distribuciones. No descarga una imagen ya hecha: ensambla el sistema para tu aparato concreto, en un entorno aislado, haciéndote una veintena de preguntas.</p>
<p>La mayoría admiten la respuesta por defecto. Tres merecen reflexión, y resolví las tres con el mismo principio: <strong>ceñirse a lo que prueban los mantenedores.</strong></p>
<p>Es un principio que merece explicitarse, porque es contraintuitivo. Cuando uno instala un sistema para sí mismo, elige lo que prefiere. Cuando lo instala para contribuir, cada desviación respecto de la elección mayoritaria es una variable más que hará inservibles tus informes de fallo. Si reporto un problema de audio sobre una pila que nadie más usa, el mantenedor no puede ni reproducirlo ni compararlo. Mi informe se convierte en ruido.</p>
<p>Así que tomé <code>pulseaudio</code> en vez del más moderno <code>pipewire</code>, <code>wpa_supplicant</code> en vez de <code>iwd</code>, el entorno <strong>Phosh</strong> en vez del muy tentador <code>sxmo</code>, y — a regañadientes — systemd. Sobre esto último, postmarketOS es uno de los pocos sitios donde OpenRC sigue siendo un ciudadano de primera clase; mi reflejo no tenía nada de marginal. Pero cuatro de los quince fallos abiertos para este aparato están reportados bajo Phosh con systemd, y <code>journalctl</code> sigue siendo lo más cómodo para extraer una traza limpia.</p>
<p>Dos respuestas merecen una advertencia.</p>
<p><strong>No activar el cifrado del disco.</strong> La opción está ahí, es tentadora, y en este teléfono deja el aparato sin poder arrancar: un fallo abierto describe un sistema que no detecta la escritura de la contraseña durante el arranque. Uno acaba con una máquina que pide una frase de paso imposible de teclear.</p>
<p><strong>Mantener la configuración regional en inglés.</strong> Contraintuitivo para un blog francófono, pero los mensajes de error y los registros saldrán en inglés, y por tanto podrán pegarse directamente en un informe y compararse con los de los demás. No impide en absoluto tener un teclado AZERTY.</p>
<details>
<summary>Para profundizar: las respuestas exactas y los paquetes que llevar</summary>
<pre><code>Channel          edge          # donde se reportan los fallos y aterrizan las correcciones
Vendor           google
Device           sargo
UI               phosh
Audio backend    pulseaudio    # por defecto
WiFi backend     wpa_supplicant # por defecto
usb-moded        developer     # red USB SIEMPRE activa — el cabo de seguridad
Service manager  default       # systemd para Phosh
Locale           en_US
</code></pre>
<p>La elección <code>usb-moded: developer</code> merece subrayarse: mantiene una interfaz de red activa sobre el cable USB de forma permanente. Cuando la pantalla deje de responder — y ocurrirá —, <code>ssh</code> por el cable será la única manera de entrar a recoger los registros. La otra opción, <code>charging</code>, exigiría activar la red a mano desde un teléfono posiblemente inutilizable.</p>
<p>Como paquetes adicionales, llevé con qué trabajar desde el primer arranque:</p>
<pre><code>libcamera-tools,v4l-utils,evtest,tmux,vim,strace,usbutils
</code></pre>
<p><code>libcamera-tools</code> proporciona el comando <code>cam</code>, que es precisamente la herramienta citada en el fallo de cámara que quería reproducir. <code>v4l-utils</code> proporciona <code>v4l2-ctl</code>, el instrumento de medida de la corrección buscada. <code>evtest</code> sirve para los fallos táctiles. <code>tmux</code> permite que una sesión SSH sobreviva a la desconexión del cable.</p>
<p>Una observación de método: <strong>no adivines los nombres de los paquetes.</strong> Alpine, la distribución sobre la que se apoya postmarketOS, no siempre los nombra como tu distribución habitual. Un nombre erróneo hace fracasar la instalación tras varios minutos. El índice es público y se comprueba en diez segundos:</p>
<pre><code class="language-bash">curl -s -o idx.tar.gz \
  &quot;https://dl-cdn.alpinelinux.org/alpine/edge/community/aarch64/APKINDEX.tar.gz&quot;
tar xzf idx.tar.gz -O APKINDEX | grep '^P:' | sed 's/^P://' &gt; paquetes.txt
grep -qx &quot;libcamera-tools&quot; paquetes.txt &amp;&amp; echo presente
</code></pre>
<p>Así descubrí que <code>device-tree-compiler</code> se llama <code>dtc</code> en Alpine.</p>
<p><img alt="Beavis, con cara de perplejidad, diciendo «WHAT?»" src="https://pf.olibrio.fr/images/pixel3a/dtc-what.gif" /></p>
<p><em>Lo cual no dice nada en español. En argot francés, <code>dtc</code> es una abreviatura que no le dirías a tu madre, y sí, releí el comando dos veces antes de ejecutarlo.</em></p>
</details>
<p>Media hora después, el sistema estaba construido. Quedaba escribirlo en el teléfono. Ahí es donde la tarde se torció.</p>
<h2 id="una-hora-culpando-al-responsable-equivocado">Una hora culpando al responsable equivocado</h2>
<p>El teléfono estaba en modo fastboot, conectado, reconocido. El comando de escritura arrancaba — y se quedaba colgado. Indefinidamente. <strong>Sin el más mínimo mensaje de error</strong>, ni en la salida estándar ni en la de error. Un proceso dormido, para siempre.</p>
<p>Lo desconcertante era que el aparato parecía perfectamente presente:</p>
<pre><code>$ fastboot devices
058AY1WZGT     fastboot
</code></pre>
<p>Respondía. Estaba ahí. Y sin embargo toda escritura se bloqueaba.</p>
<p>Formulé cuatro hipótesis. Las cuatro eran falsas, y descartarlas me llevó una hora. Merece la pena enumerarlas, porque son exactamente las que formularía cualquiera.</p>
<p><strong>Un problema de permisos.</strong> La hipótesis clásica: el nodo USB pertenece a <code>root</code>, el usuario no tiene derecho a escribir en él. Verificado: el fichero llevaba una lista de control de acceso que concedía explícitamente el acceso a mi cuenta. Descartado por la medida, no por la suposición.</p>
<p><strong>Un cable o un puerto defectuosos.</strong> Es el reflejo siguiente, y el más extendido en los foros. Salvo que los registros del núcleo estaban impecables: enumeración a alta velocidad, ningún error, ninguna reinicialización, ninguna desconexión intempestiva. Un cable dañado deja rastro; no había ninguno.</p>
<p><strong>Un problema de controladora USB.</strong> Pista seria: los Pixel solo tienen USB 2.0, y las controladoras modernas tienen fama de caprichosas con ciertos gestores de arranque. El consejo habitual es «conéctalo a un puerto USB 2.0». Dos medidas lo descartaron: el teléfono ya negociaba a 480 megabits, es decir ya en USB 2.0, y la placa base de la máquina (una Raptor Lake de Intel) ya no tiene controladora de generación anterior — todo pasa por el mismo bloque. «Cambiar a un puerto USB 2.0» no tenía sentido.</p>
<p><strong>Una regresión del software.</strong> <code>pmbootstrap</code> ejecuta su propia copia de <code>fastboot</code>, en versión 37, mientras que mi sistema tenía la versión 35. Así que salté la herramienta y flasheé directamente con la del sistema. <strong>Se colgó exactamente igual.</strong> Hipótesis muerta.</p>
<p>Cuatro pistas, cuatro callejones sin salida. Y un detalle que debería haberme alertado mucho antes: en cada nueva entrada en modo fastboot, <strong>el primer comando pasaba</strong> — en trece milisegundos — y todos los siguientes se colgaban.</p>
<p>Tenía ese hecho delante desde el principio. Tardé una hora en escucharlo, porque seguía interrogando al aparato en lugar de interrogar al sistema.</p>
<h2 id="la-respuesta-cabia-en-un-fichero">La respuesta cabía en un fichero</h2>
<p>El modo fastboot es un diálogo: el ordenador pregunta, el gestor de arranque responde. Acabé mirando no lo que respondía el teléfono, sino <strong>lo que el núcleo Linux pensaba de él</strong>. Esa información vive en <code>/sys</code>, un sistema de ficheros virtual donde el núcleo expone su estado interno en forma de ficheros legibles.</p>
<pre><code>$ cat /sys/bus/usb/devices/1-9/power/control
auto
$ cat /sys/bus/usb/devices/1-9/power/autosuspend_delay_ms
2000
$ cat /sys/bus/usb/devices/1-9/power/runtime_status
suspended
</code></pre>
<p><strong>Dormido.</strong></p>
<p>Para ahorrar energía, el núcleo suspende los periféricos USB tras un plazo de inactividad — aquí, dos segundos. Es un comportamiento normal y deseable para la mayoría de aparatos, que saben despertar cuando se les vuelve a hablar. <strong>El gestor de arranque del Pixel no sabe.</strong> Una vez dormido, ya no responde nunca.</p>
<p>Todo encaja de golpe:</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Lo que observaba</th>
<th>Lo que ocurría</th>
</tr>
</thead>
<tbody>
<tr>
<td>El primer comando pasa, los siguientes se cuelgan</td>
<td>El teléfono se duerme en el intervalo</td>
</tr>
<tr>
<td><code>fastboot devices</code> lo lista igualmente</td>
<td>La enumeración está en caché, no requiere intercambio</td>
</tr>
<tr>
<td>El desbloqueo había funcionado</td>
<td>Era el primer comando tras entrar en fastboot</td>
</tr>
<tr>
<td>Salir y volver a entrar en fastboot «arreglaba»</td>
<td>Una nueva enumeración despierta el aparato, para un comando</td>
</tr>
<tr>
<td>Las dos versiones de <code>fastboot</code> fallaban igual</td>
<td>El binario no tenía nada que ver</td>
</tr>
<tr>
<td>Los registros del núcleo seguían limpios</td>
<td>La suspensión no es un error, es el funcionamiento normal</td>
</tr>
</tbody>
</table></div>
<p>La corrección es una regla de tres líneas, que pide al núcleo no dormir nunca los aparatos Google:</p>
<pre><code># /etc/udev/rules.d/52-fastboot-no-autosuspend.rules
ACTION==&quot;add&quot;, SUBSYSTEM==&quot;usb&quot;, ATTR{idVendor}==&quot;18d1&quot;, \
    TEST==&quot;power/control&quot;, ATTR{power/control}=&quot;on&quot;
</code></pre>
<p>Salvo que no cambió nada. Y la razón de ese fracaso es la parte más interesante de la historia.</p>
<h2 id="el-segundo-responsable-agazapado-tras-el-primero">El segundo responsable, agazapado tras el primero</h2>
<p>Mi regla era correcta — la herramienta de diagnóstico de udev confirmaba que se evaluaba y se aplicaba bien. Pero tras cada conexión, el ajuste volvía a <code>auto</code>.</p>
<p>Alguien pasaba detrás de mí. Ese alguien se llamaba <strong>TLP</strong>, un gestor de energía muy extendido en los portátiles Linux, que aplica sus propios ajustes de suspensión USB <em>después</em> de udev, y sobrescribe por tanto los tuyos en silencio. Mucha gente lo instala una vez para ganar autonomía y luego se olvida por completo.</p>
<p>TLP tiene precisamente una opción prevista para este caso:</p>
<pre><code># /etc/tlp.conf
USB_EXCLUDE_PHONE=1
USB_DENYLIST=&quot;18d1:4ee0 18d1:4ee1 18d1:4ee2 18d1:4ee3 18d1:4ee7&quot;
</code></pre>
<p>Esta vez el ajuste aguantó. Un detalle que conviene saber: <strong>aplicar la corrección no desbloquea un aparato ya dormido.</strong> El estado USB del gestor de arranque solo se repara al reenumerar. Hay que corregir, <em>y luego</em> salir y volver a entrar en modo fastboot.</p>
<p>Y para maximizar las probabilidades, agrupé las tres escrituras en una sola invocación, en lugar de tres procesos sucesivos:</p>
<pre><code class="language-bash">fastboot flash vbmeta   vbmeta.img \
         flash boot     boot.img \
         flash userdata google-sargo.img
</code></pre>
<pre><code>Sending 'vbmeta_b' (4 KB)                   OKAY [  0.120s]
Writing 'vbmeta_b'                          OKAY [  0.071s]
Sending 'boot_b' (28008 KB)                 OKAY [  0.747s]
Writing 'boot_b'                            OKAY [  0.194s]
Sending sparse 'userdata' 1/9 (258751 KB)   OKAY [  6.306s]
...
Finished. Total time: 94.883s
</code></pre>
<p>Noventa y cinco segundos. Tras una hora de bloqueo.</p>
<details>
<summary>Para profundizar: diagnosticar un fastboot que se cuelga</summary>
<p>Tres reflejos, en este orden:</p>
<p><strong>1. Comprobar que el aparato está realmente ahí antes de interpretar nada.</strong> Un <code>&lt; waiting for any device &gt;</code> significa a menudo que el teléfono simplemente ha salido del modo fastboot, no que haya un problema de acceso. Estuve a punto de concluir que había un problema de permisos invertido a partir de una prueba en la que el aparato estaba en realidad ausente.</p>
<pre><code class="language-bash">lsusb | grep 18d1
</code></pre>
<p><strong>2. Mirar el estado del núcleo, no solo la salida del comando.</strong></p>
<pre><code class="language-bash">cat /sys/bus/usb/devices/&lt;puerto&gt;/power/runtime_status
</code></pre>
<p><strong>3. Inspeccionar el proceso colgado.</strong> Dice si ha abierto el periférico — en cuyo caso espera una respuesta que no llegará — y en qué entorno se ejecuta:</p>
<pre><code class="language-bash">sudo readlink /proc/&lt;pid&gt;/root        # ¿se ejecuta en un chroot?
sudo ls -l /proc/&lt;pid&gt;/fd | grep usb  # ¿ha abierto el periférico?
</code></pre>
<p>Dos trampas del intérprete de comandos con las que tropecé, y que me costaron tiempo:</p>
<ul>
<li><code>rc=$?</code> después de una tubería captura el código del <strong>último eslabón</strong>, nunca el de <code>timeout</code>. Mi sonda de diagnóstico mostraba por tanto «OK» en comandos que se colgaban. Redirigir a ficheros y comprobar directamente, o usar <code>set -o pipefail</code>.</li>
<li><code>pkill -f 'un patrón'</code> mata al intérprete que lo llama cuando el patrón figura en su propia línea de comandos. Mejor un bucle sobre <code>pgrep -x</code>.</li>
</ul>
</details>
<h2 id="lo-que-arranco">Lo que arrancó</h2>
<p>Veinte segundos después del reinicio, la máquina vio aparecer una interfaz de red. El teléfono repartía él mismo las direcciones.</p>
<pre><code>$ ssh sam@172.16.42.1
$ uname -r
7.1.3-sdm670
$ df -h /
/dev/loop0p2   47.9G   2.2G   43.2G   5% /
</code></pre>
<p><strong>Núcleo 7.1.3.</strong> En un teléfono cuyo fabricante dejó de ocuparse en mayo de 2022, con un núcleo Android congelado en el 4.9. El sistema de ficheros se había agrandado solo en el primer arranque para ocupar los 48 gigabytes disponibles.</p>
<p><img alt="La pantalla de bienvenida de Phosh en el Pixel 3a con la pantalla rota: «Welcome — Get to know the features of your Phone and Phosh»" src="https://pf.olibrio.fr/images/pixel3a/phosh-welcome.jpg" /></p>
<p><em>Primer arranque. La pantalla lleva rota mucho tiempo; el aparato, en cambio, acaba de rejuvenecer cuatro años.</em></p>
<p><img alt="El panel de ajustes rápidos de Phosh: Wi-Fi activo, Bluetooth activo, batería al 94 %, y una notificación «USB Mode Selector — USB Developer mode»" src="https://pf.olibrio.fr/images/pixel3a/phosh-quicksettings.jpg" /></p>
<p><em>El panel de ajustes rápidos. Wi-Fi, Bluetooth, batería al 94 %. Y en las notificaciones, el selector «USB Developer mode» — exactamente el perfil elegido en la instalación, el que mantiene la red USB activa de forma permanente. El reloj marca «jueves 1 de enero, 4:12»: el reloj físico aún no está en hora, nadie le ha dicho todavía qué día es.</em></p>
<h2 id="la-camara-o-como-una-herramienta-bien-escrita-te-tiende-el-trabajo">La cámara, o cómo una herramienta bien escrita te tiende el trabajo</h2>
<p>Quedaba comprobar aquello a lo que venía. En postmarketOS, la gestión de las cámaras pasa por <strong>libcamera</strong>, una biblioteca libre que sustituye a la pila propietaria de Android. Un fallo conocido señala que el controlador del sensor frontal de este teléfono está incompleto, y que el comando <code>cam -l</code> — que lista las cámaras — se queja de ello.</p>
<p>Se quejó, en efecto. Pero mucho mejor de lo que esperaba:</p>
<pre><code>ERROR V4L2 'imx355 4-001a': Unable to get rectangle 2 on pad 0/0
ERROR V4L2 'imx355 4-001a': Unable to get rectangle 1 on pad 0/0
ERROR V4L2 'imx355 4-001a': Unable to get rectangle 0 on pad 0/0
 WARN  'imx355 4-001a': Failed to retrieve the sensor crop rectangle
 WARN  'imx355 4-001a': The sensor kernel driver needs to be fixed
 WARN  See Documentation/sensor_driver_requirements.rst
</code></pre>
<p>Hay algo reconfortante en un software que te dice literalmente «el controlador del núcleo del sensor necesita ser corregido» y te da la referencia del documento que explica cómo. Es exactamente lo contrario de <a href="https://pf.olibrio.fr/es/posts/erreur-4202-neato-obsolescence.html">un error 4202 en una aspiradora</a>.</p>
<p>Concretamente: el controlador no sabe responder cuando se le piden las dimensiones reales de su matriz de píxeles. libcamera se inventa entonces valores por defecto y trabaja sobre una geometría aproximada.</p>
<p>Pero la salida revelaba además esto, que no esperaba:</p>
<pre><code>WARN 'imx363': No static properties available — Please consider updating the database
WARN 'imx355': No static properties available
WARN IPASoft: Failed to create camera sensor helper for imx355 / imx363
</code></pre>
<p>Este segundo problema no está en el núcleo. Son dos tablas de datos, dentro de la propia libcamera, donde los sensores del Pixel 3a faltan — mientras que decenas de otros ya figuran allí y ofrecen un modelo que copiar. Datos puros, nada de algoritmia.</p>
<p><strong>Actualización, unas horas después.</strong> Al ir a escribir esa corrección, descubrí que la mitad acababa de hacerse: el sensor frontal, el <strong>imx355</strong>, se añadió aguas arriba <em>después</em> de la versión 0.7.2 que ejecuta este teléfono. El aviso de más arriba es pues un artefacto de versión, no una carencia — bastará con actualizar. El sensor trasero, el <strong>imx363</strong>, sigue ausente de todo el repositorio, y su controlador ni siquiera está en el núcleo oficial: se escribió en Intel, nunca se envió aguas arriba, y postmarketOS lo carga como módulo.</p>
<p>Y al comparar la entrada nueva del imx355 con lo que el controlador expone realmente en el aparato, algo no cuadra: asocia «barras de color» al valor 1 y «color sólido» al valor 2, cuando el controlador hace exactamente lo contrario. Otros dos sensores con menú idéntico, el imx258 y el imx471, están descritos correctamente justo al lado. Son pues dos correcciones en lugar de una — y la más sencilla es la que nadie esperaba.</p>
<p>Dicho de otro modo: la primera corrección que escribir no es la que venía buscando. Ha hecho falta encender el hardware real para darse cuenta. Es una lección bastante general — uno puede leer informes de fallos durante días sin ver lo que una máquina encendida te dice en tres segundos.</p>
<h2 id="por-que-esto-no-es-solo-un-pasatiempo">Por qué esto no es solo un pasatiempo</h2>
<p>La misma mañana en que este teléfono arrancó, la cuenta <code>balade.nomade</code> publicaba <a href="https://www.instagram.com/reel/Dc-vV23MGIi/">un reel</a> (<a href="https://pf.olibrio.fr/assets/pixel3a/refs/balade-nomade-reel-2026-09-07.md">copia local del texto y del hilo de comentarios</a>) que resume lo que se está jugando ahora mismo en Bruselas. Termina con una pregunta que me parece bien planteada:</p>
<blockquote>
<p>¿Estás dispuesto a escanear tu documento de identidad para usar Instagram?</p>
</blockquote>
<p>El tono es militante, así que verifiqué los tres puntos. Dos se sostienen sólidamente, el tercero merece un matiz — y el hilo de comentarios añadió un cuarto, más pertinente para este artículo que los otros tres.</p>
<p><strong>Chat Control.</strong> Exacto. El reglamento europeo llamado CSAR sigue bloqueado en trílogo, y las negociaciones se reanudan a finales de septiembre de 2026 bajo presidencia irlandesa del Consejo. El 9 de julio de 2026, el Parlamento Europeo votó 314 contra 276 por retirar el dispositivo — sin alcanzar el umbral de 360 votos necesario para bloquear la posición del Consejo. La excepción que autoriza el escaneo «voluntario» de los mensajes se prorrogó por tanto hasta 2028. El análisis en el lado del cliente se retiró de la última versión del texto, pero el propio servicio jurídico del Consejo, en un dictamen del 10 de junio de 2026, estima que ese escaneo voluntario sigue siendo un registro generalizado de las comunicaciones, incompatible con el artículo 7 de la Carta de los Derechos Fundamentales.</p>
<p><strong>El fin del anonimato.</strong> Exacto, con una novedad que el reel no menciona: la ley francesa del 21 de julio de 2026 que prohibía las redes sociales a los menores de quince años fue <strong>anulada el 14 de agosto por el Consejo Constitucional</strong> (decisión n.º 2026-911 DC), por vulneración desproporcionada de la libertad de expresión y de la vida privada. No entrará pues en vigor tal cual. Pero el movimiento de fondo continúa en otros frentes: la Comisión Europea anunció el 15 de abril de 2026 que su solución de verificación de edad estaba lista para el despliegue, y la cartera de identidad digital europea debe llegar a los Estados miembros antes de fin de año.</p>
<p><strong>Los metadatos.</strong> Aquí matizo. El EDPB sí adoptó el 7 de julio de 2026 unas nuevas directrices sobre anonimización, en consulta hasta el 30 de octubre, que sustituyen al dictamen de referencia de 2014. Pero es un trabajo de clarificación técnica, no un puñetazo en la mesa. Y la jurisprudencia reciente apunta más bien en sentido contrario: el Tribunal de Justicia de la Unión Europea, en septiembre de 2025, adoptó un enfoque <em>relativo</em> — un mismo dato seudonimizado puede ser anónimo para quien no tiene medio alguno de reidentificar, y personal para otro.</p>
<h3 id="el-cuarto-punto-el-que-habla-de-verdad-de-este-articulo">El cuarto punto, el que habla de verdad de este artículo</h3>
<p>En los comentarios, alguien señala que Google está cambiando su política de instalación de aplicaciones y teme que eso «ponga en peligro GrapheneOS». La respuesta del autor corrige con razón ese temor, y los hechos le dan la razón.</p>
<p>Desde agosto de 2025, Google exige que <strong>toda aplicación instalada en un dispositivo Android certificado provenga de un desarrollador verificado</strong> — incluso cuando se instala un archivo APK a mano, fuera de cualquier tienda. Las primeras restricciones visibles llegan el <strong>30 de septiembre de 2026</strong> a Brasil, Indonesia, Singapur y Tailandia, antes de una extensión mundial en 2027. Instalar la aplicación de un desarrollador no verificado pasará por un recorrido indirecto con un <strong>plazo de espera obligatorio de veinticuatro horas</strong>. Y para verificarse, un desarrollador debe abrir una cuenta, pagar veinticinco dólares y aportar un <strong>documento de identidad oficial</strong>.</p>
<p>Relee la pregunta del reel y sustituye al usuario por el desarrollador. Es el mismo gesto: un documento de identidad como condición de acceso. De un lado para leer, del otro para escribir.</p>
<p>El comentarista se equivocaba sin embargo en un punto, y es el que cuenta. La restricción afecta a los dispositivos <strong>certificados</strong> — los que incorporan los servicios de Google bajo licencia. GrapheneOS no los incorpora: queda fuera del perímetro. La restricción no pone pues en peligro a los sistemas desgooglizados, <strong>hace que su existencia sea más necesaria</strong>.</p>
<h3 id="instalar-tu-propio-software-esa-batalla">Instalar tu propio software, esa batalla</h3>
<p>Es lo que más me exaspera, y es anterior a toda esta actualidad. Tanto en Android como en iOS, instalar un software que uno mismo ha compilado, o recuperado de un repositorio Git, es una carrera de obstáculos.</p>
<p>En Android hay que autorizar un origen desconocido, pasar tres avisos, y pronto rebuscar en las opciones de desarrollador y esperar veinticuatro horas. En iOS es peor: una aplicación que compilas y firmas con una cuenta Apple gratuita <strong>deja de funcionar a los siete días</strong> y hay que reinstalarla desde un ordenador. Para que sobreviva, hay que pagar noventa y nueve euros al año. El reglamento europeo de mercados digitales entreabrió la puerta en 2024 — tiendas alternativas, distribución desde el propio sitio web — pero solo dentro de la Unión, y en las condiciones de Apple.</p>
<p>La justificación es siempre la misma: la seguridad. Merece tomarse en serio y, por tanto, examinarse.</p>
<p>Si la apertura causara inseguridad, se notaría. Linux permite instalar cualquier cosa desde cualquier sitio — un repositorio, un archivo comprimido, código compilado a mano — y no es un desastre de seguridad: es el sistema que hace funcionar la mayor parte de los servidores del planeta, bajo ataque permanente. Windows, en cambio, tuvo durante mucho tiempo el modelo más permisivo <strong>y</strong> la peor reputación. Si la teoría fuese buena, Android e iOS serían los sistemas más seguros jamás concebidos. Se observa más o menos lo contrario de lo que predice.</p>
<p>Lo que protege no es pues el cierre, sino <strong>una cadena de confianza verificable</strong>: repositorios firmados, mantenedores identificados, código fuente que cualquiera puede releer, compilaciones reproducibles. La seguridad viene de la transparencia, no del permiso. Y esa cadena ya existe en Android: F-Droid distribuye desde hace años aplicaciones libres compiladas a partir de fuentes públicas, sin peaje ni documento de identidad.</p>
<p>Mientras tanto, la tienda oficial deja pasar. En 2026, una familia de software malicioso llamada NoVoice se encontró en más de cincuenta aplicaciones de Play Store, sumando al menos 2,3 millones de descargas — con acceso root y capaz de sobrevivir a un restablecimiento de fábrica. El año anterior, la campaña SlopAds: 224 aplicaciones, 38 millones de descargas. Y Google baneó <strong>80 000 cuentas de desarrollador en 2025</strong>, bajo un régimen que ya exige verificación de identidad para publicar en Play Store.</p>
<p>Es esa cifra la que zanja la discusión. La verificación de desarrolladores ya existe allí donde se supone que protege, y aun así hay que banear ochenta mil cuentas al año. Extenderla a la instalación manual no detendrá las campañas industriales — entran por la puerta grande, y está documentado. Detendrá al desarrollador solitario que publica su código en un repositorio Git.</p>
<p>El riesgo, en sí, es real: quien instala un archivo recibido por SMS cae efectivamente en la trampa. Pero eso aboga por un aviso claro, no por un derecho de entrada. Se protege a alguien diciéndole lo que está haciendo; no se le protege cobrando a quien escribe.</p>
<p>Y hay un criterio que zanja la cuestión. Para operar una tienda alternativa en la Unión Europea, Apple exige, a partir del <strong>1 de octubre de 2026</strong>, cotizar en bolsa, o estar financiado por capital riesgo, o haber pasado una auditoría financiera, o sumar un millón de instalaciones anuales. Ninguno de esos criterios mide la seguridad de nada. Son criterios de <strong>tamaño</strong>.</p>
<p>Estoy dispuesto a conceder la buena fe en el principio. Me cuesta más cuando la misma empresa cierra la puerta y lleva la caja.</p>
<h3 id="lo-que-eso-cambia-para-un-telefono-viejo">Lo que eso cambia para un teléfono viejo</h3>
<p>El hilo común de todo esto es técnico, y es el que conecta esta actualidad con un Pixel de 2019.</p>
<p>El análisis en el lado del cliente consiste en inspeccionar los mensajes <strong>en el aparato, antes del cifrado</strong>. Un dispositivo así no se implementa en una aplicación: se implementa en el sistema. Ese es el desplazamiento decisivo. Mientras la garantía descansaba en el protocolo, podía auditarse desde fuera. En cuanto descansa en el aparato, la única pregunta que importa pasa a ser: <em>¿quién decide lo que hace este aparato?</em></p>
<p>En un teléfono cuyo sistema no puede reemplazarse, la respuesta es: el fabricante. Y a través de él, quienquiera que legisle sobre el fabricante. No es un escándalo, es una cadena de decisión perfectamente ordinaria — pero en ningún momento pasa por el propietario.</p>
<p>Las dos vías de escape existentes — GrapheneOS, postmarketOS — descansan exactamente en lo mismo: <strong>un gestor de arranque que se tiene derecho a desbloquear</strong>. La misma casilla en las opciones de desarrollador que abrió esta tarde. Toda la salida práctica, para Android, ha dependido hasta ahora de la buena voluntad de un solo fabricante sobre un solo ajuste. GrapheneOS solo está disponible en Pixel; habrá que esperar a los Motorola de gama alta de 2027 para que eso deje de ser cierto.</p>
<p>Y hay que decir lo que este artículo no demuestra. <strong>postmarketOS en un Pixel 3a no es una solución de privacidad.</strong> El módem sigue siendo una caja negra, un procesador autónomo que ejecuta software propietario al que el sistema no tiene acceso. Este aparato en concreto no es utilizable a diario, lo dije desde el principio. Para un uso real, la respuesta seria es la que el reel pone como etiqueta: GrapheneOS.</p>
<p>Lo que este artículo sí demuestra es más modesto, y basta: <strong>la capacidad existe, está al alcance de una tarde, y se ejerce.</strong> Una capacidad que nunca se ejerce acaba desapareciendo sin que nadie se dé cuenta — no por prohibición, simplemente porque un día ningún aparato la ofrece ya y nadie la habrá reclamado.</p>
<h2 id="y-tu-telefono">¿Y tu teléfono?</h2>
<p>Fue la primera pregunta que me hicieron, y es la buena. Esto es lo que la responde — las cifras vienen del repositorio <code>pmaports</code> a fecha del 5 de septiembre de 2026 y del sitio oficial de Ubuntu Touch, no de una lista copiada de algún sitio.</p>
<p>Primero, una advertencia sobre el vocabulario. postmarketOS clasifica sus aparatos en tres niveles, y significan algo:</p>
<ul>
<li><strong><code>community</code></strong> — funciona en general, con carencias identificadas. <strong>39 aparatos</strong>, de los cuales solo catorce son teléfonos.</li>
<li><strong><code>testing</code></strong> — desde «arranca, en cierto sentido» hasta «funciona casi todo». <strong>149 aparatos.</strong> Ahí está la mayoría del parque, y ahí está el trabajo.</li>
<li><strong><code>downstream</code></strong> — núcleo Android de origen, funcionalidades muy limitadas. <strong>20 aparatos</strong>, desaconsejados.</li>
</ul>
<p>Ningún aparato está hoy clasificado por encima de <code>community</code>. Eso sitúa honestamente el estado del ecosistema.</p>
<h3 id="los-catorce-telefonos-en-community">Los catorce teléfonos en <code>community</code></h3>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Año</th>
<th>Aparato</th>
</tr>
</thead>
<tbody>
<tr>
<td>2009</td>
<td>Nokia N900</td>
</tr>
<tr>
<td>2012</td>
<td>Samsung Galaxy S III</td>
</tr>
<tr>
<td>2014</td>
<td>Samsung Galaxy Core Prime VE LTE</td>
</tr>
<tr>
<td>2018</td>
<td>OnePlus 6 · OnePlus 6T · Samsung Galaxy S9 · Xiaomi Poco F1</td>
</tr>
<tr>
<td>2019</td>
<td><strong>Google Pixel 3a</strong> · Pixel 3a XL · Purism Librem 5</td>
</tr>
<tr>
<td>2020</td>
<td>SHIFT6mq</td>
</tr>
<tr>
<td>2021</td>
<td><strong>Fairphone 4</strong> · PinePhone Pro</td>
</tr>
</tbody>
</table></div>
<p>Dos sorpresas en esa lista. El <strong>Xiaomi Poco F1</strong> y los <strong>OnePlus 6 / 6T</strong> son excelentes candidatos: potentes para su edad, muy extendidos de segunda mano, y portados desde hace tiempo. Y el <strong>PinePhone original</strong>, diseñado para Linux, está en <code>testing</code> — es su sucesor Pro el que está en <code>community</code>.</p>
<p>El resto de la categoría no son teléfonos: una docena de <strong>Chromebooks</strong> ARM, el Lenovo ThinkPad X13s, la PineNote, la Odroid XU4, la RockPro64. Si lo que buscas es un pequeño ordenador ARM con Linux en lugar de un teléfono, es una vía muy infravalorada.</p>
<p>En <code>testing</code>, los 149 aparatos se reparten sobre todo entre <strong>Samsung</strong> (30), <strong>Xiaomi</strong> (18), <strong>Sony</strong>, <strong>OnePlus</strong>, <strong>LG</strong> y <strong>Google</strong> (5 cada uno), y <strong>Fairphone</strong> (4). Hay pues bastantes probabilidades de que tu teléfono esté ahí — con trabajo pendiente, que es precisamente el interés.</p>
<h3 id="si-quieres-un-telefono-que-funcione-no-un-banco-de-pruebas">Si quieres un teléfono que funcione, no un banco de pruebas</h3>
<p>Es otra necesidad, y tiene otras respuestas. <strong>Ubuntu Touch</strong> anuncia <strong>111 aparatos</strong> compatibles, con un porcentaje de funcionalidad por aparato. Los mejor servidos:</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Aparato</th>
<th>Funcional</th>
</tr>
</thead>
<tbody>
<tr>
<td>Lenovo Tab M10 HD 2.ª gen. (WiFi)</td>
<td>100 %</td>
</tr>
<tr>
<td>BQ Aquaris M10 HD / FHD</td>
<td>98,7 %</td>
</tr>
<tr>
<td><strong>Fairphone 5</strong> (2023)</td>
<td>97,4 %</td>
</tr>
<tr>
<td>Xiaomi Redmi Note 9 Pro · Poco X3 NFC</td>
<td>97,4 %</td>
</tr>
<tr>
<td>OnePlus Nord N10 5G · Nord N100</td>
<td>97,4 %</td>
</tr>
<tr>
<td><strong>Fairphone 4</strong> · Pixel 3a / 3a XL</td>
<td>97,3 %</td>
</tr>
<tr>
<td><strong>Nothing Phone (1)</strong> (2022)</td>
<td>95,6 %</td>
</tr>
<tr>
<td>Fairphone 3 / 3+</td>
<td>95,6 %</td>
</tr>
</tbody>
</table></div>
<p>El <strong>Fairphone 4</strong> es el punto de equilibrio de todo esto: está a la vez en <code>community</code> en postmarketOS <strong>y</strong> al 97,3 % en Ubuntu Touch, y es además el teléfono más reparable del mercado. Si alguien me preguntara qué comprar para hacer esto en serio, sería ese — o el Fairphone 5 si el objetivo es sobre todo usarlo.</p>
<p>Y si quieres quedarte en Android saliendo de la órbita de Google, <strong>GrapheneOS</strong> sigue siendo la respuesta más sólida — pero solo en Pixel 6 y posteriores, con siete años de actualizaciones garantizadas en los Pixel 8, 9 y 10. La alianza con Motorola anunciada en agosto de 2026 debería levantar esa exclusividad en 2027; la lista oficial, hoy, sigue siendo exclusivamente Pixel.</p>
<h3 id="como-comprobarlo-con-el-tuyo">Cómo comprobarlo con el tuyo</h3>
<p>Busca el nombre en clave de tu aparato — no su nombre comercial — en el wiki de postmarketOS y en <code>devices.ubuntu-touch.io</code>. El nombre en clave se lee con un solo comando, con el aparato conectado por USB:</p>
<pre><code class="language-bash">adb shell getprop ro.product.device
</code></pre>
<p>En el mío responde <code>sargo</code>. Y dos condiciones previas valen para todo el mundo, diga lo que diga la lista: <strong>el gestor de arranque debe poder desbloquearse</strong>, lo que excluye la mayoría de los aparatos vendidos por operadores estadounidenses; y la operación <strong>lo borra todo</strong>.</p>
<h2 id="lo-que-me-llevo">Lo que me llevo</h2>
<p>La parte técnica es casi anecdótica. Me quedan tres cosas.</p>
<p><strong>La trampa no está en ninguna parte.</strong> La suspensión automática USB no se menciona en ninguna guía de instalación. Quien la encuentra ve un comando que se cuelga sin mensaje, prueba otro cable, otro puerto, y concluye que su hardware tiene la culpa. Abandona. La corrección son dos líneas y vale para todos los Pixel. Es lo que voy a escribir primero — antes que cualquier código, antes que la cámara. Una tarde perdida por mí puede ahorrar muchas a otros, y es probablemente la contribución más rentable de toda la historia.</p>
<p><strong>Busqué en el sitio equivocado durante una hora.</strong> No por falta de método, sino porque seguía interrogando al aparato — reintentar el comando, cambiar un parámetro, volver a probar — en lugar de interrogar al sistema que gobernaba el aparato. La respuesta estaba en un fichero de texto de nueve caracteres. Cada vez que una herramienta calla en lugar de fallar, hay que dejar de relanzarla e ir a leer el estado de la capa de abajo.</p>
<p><strong>Y luego está el fondo.</strong> Este teléfono lleva grabado en la trasera un contenedor tachado, ese pictograma que significa que no se tira con la basura. El símbolo está ahí desde 2019, obligatorio, decorativo. Esta noche se ha vuelto exacto: el aparato no ha ido al vertedero, funciona, y funciona con un núcleo más reciente que el de muchas máquinas en servicio.</p>
<p>No es una proeza técnica — gente mucho más competente hizo el trabajo difícil, el de portar un núcleo moderno a este chip. Yo solo he seguido sus huellas y he tropezado con una trampa que no habían documentado. Pero es una demostración: el fin de soporte no es una propiedad del hardware. Es una decisión. Y cuando el fabricante deja la puerta abierta — como hace Google en los Pixel, hay que reconocérselo —, esa decisión puede retomarla otro.</p>
<p>Un Pixel 3a de segunda mano se encuentra por unas decenas de euros. Hay millones en los cajones.</p>
<p>Lo siguiente es la cámara.</p>]]></content:encoded>
    </item>
    <item>
      <title>Seis años de impresiones decepcionantes: lo que mi delta FLSun QQ-S tenía de verdad, y cómo la calibramos de una vez por todas</title>
      <link>https://pf.olibrio.fr/es/posts/flsun-qqs-delta-klipper-calibration.html</link>
      <guid isPermaLink="true">https://pf.olibrio.fr/es/posts/flsun-qqs-delta-klipper-calibration.html</guid>
      <pubDate>Sun, 06 Sep 2026 12:00:00 +0000</pubDate>
      <description>Una impresora delta FLSun QQ-S de 2020, «siempre un poco decepcionante» al lado de una Bambu Lab. Paso a Klipper, y una investigación: un extrusor que subextruía un 11,5 % desde el primer día, ángulos de torre nunca calibrados, una corriente de motor que la configuración oficial de Klipper no ajusta, un método de nivelado que mentía. El relato, las cifras, las herramientas y el procedimiento completo para reproducirlo — sin sonda, con una hoja de papel.</description>
      <category>impresión 3d</category>
      <category>delta</category>
      <category>flsun qq-s</category>
      <category>klipper</category>
      <category>calibración</category>
      <category>bed mesh</category>
      <category>pressure advance</category>
      <category>mks robin mini</category>
      <category>repetier</category>
      <category>diy</category>
      <category>ia</category>
      <content:encoded><![CDATA[<p><img src="https://pf.olibrio.fr/images/flsun/og-flsun.jpg" alt="Seis años de impresiones decepcionantes: lo que mi delta FLSun QQ-S tenía de verdad, y cómo la calibramos de una vez por todas"></p>
<div class="tldr">
<p><strong>En dos minutos, si tienes una delta que «imprime regular» y ningún ajuste cambia nada</strong></p>
<ul>
<li><strong>El síntoma</strong>: una FLSun QQ-S comprada en 2020, 233 horas y 970 m de filamento, nunca satisfactoria del todo. Paredes débiles, cotas desviadas un 2 %, una primera capa imposible de ajustar en todo el plato a la vez. Al lado de una Bambu Lab, daba pena.</li>
<li><strong>Lo que encontramos, en orden</strong>: un extrusor que empujaba <strong>un 11,5 % menos de material</strong> desde el primer día (un valor erróneo en la memoria del firmware); unos <strong>ángulos de torre nunca calibrados</strong> (+1,02° y +0,45°, todas las correcciones a cero en la EEPROM); y, al pasar a Klipper, una <strong>corriente de motor que la placa fija por PWM</strong> y que la configuración oficial de Klipper para esta impresora no fija — motores sin par, homing imposible.</li>
<li><strong>Lo que funcionó</strong>: recalibrarlo todo <strong>en caliente</strong>, en el estado en que la máquina imprime, con <strong>un solo método de medida</strong> (la hoja de papel), en el orden geometría → cero → malla del plato → primera capa. Treinta y cinco minutos. Una espiral de control uniforme de borde a borde, un cubo a 20,00 mm en Z.</li>
<li><strong>Lo que no funcionó</strong>, y costó dos días: corregir la malla del plato encima de una geometría errónea, con un método de micrómetro que se equivocaba justo donde la boquilla estaba demasiado cerca. El detalle está en <a href="#pista-falsa">La pista falsa</a>, porque es lo más instructivo.</li>
<li><strong>Para reproducirlo</strong>: <a href="#para-reproducir">el procedimiento completo</a>, los archivos de configuración, los scripts y las piezas de prueba están <a href="#referencias">al final del artículo</a>. Sin sonda, sin acelerómetro, una hoja de papel y un calibre.</li>
</ul>
<p><em>Este artículo pretende poder leerse sin saber nada de impresoras delta: cada término se explica la primera vez que aparece, y un glosario lo resume al final. Los recuadros «Para ir al fondo» se despliegan para quien quiera la cinemática, los valores y los comandos.</em></p>
</div>
<p><img alt="Banco de calibración de la FLSun QQ-S: calibre, micrómetro en pulgadas, cubo de 20 mm, marcos de primera capa y cuadrados de espesor numerados" src="https://pf.olibrio.fr/images/flsun/00-etabli.jpg" /></p>
<p><em>El banco el tercer día. Todo lo que sirvió de juez: el calibre, un viejo micrómetro en pulgadas, el cubo de 20 mm, los marcos de primera capa, los cuadrados de espesor numerados a rotulador y, detrás, la pieza de siete pilares de la calibración extendida.</em></p>
<h2 id="una-maquina-siempre-un-poco-decepcionante">Una máquina «siempre un poco decepcionante»</h2>
<p>Tengo una impresora delta FLSun QQ-S, comprada en enero de 2020. Una <strong>delta</strong> es esa impresora en forma de torre triangular en la que la boquilla cuelga de tres brazos articulados que suben y bajan por tres columnas; no hay ejes X, Y y Z separados como en una impresora cartesiana: la posición de la boquilla es el resultado de un cálculo a partir de la altura de los tres carros. Es rápida, silenciosa, elegante, y mucho más sensible a los errores de geometría que una máquina de ejes rectos: un brazo un milímetro demasiado largo o una columna desviada un grado no dan un error simple, sino una deformación en cuenco, en cúpula o en trébol que varía por todo el plato.</p>
<p>Poco usada, esta máquina siempre había sido un poco decepcionante. No catastrófica: las piezas salían. Pero las paredes no tenían consistencia, las cotas estaban desviadas unas décimas, la primera capa nunca agarraba en todas partes, y sobre todo <strong>ningún ajuste tenía un efecto claro</strong>. Había acabado imprimiendo con una boquilla más gruesa «para que fuera más rápido», cambiando las correas tras destruir un juego por sobretensión, y aparcando la máquina junto a una Bambu Lab que, ella sí, imprime bien sin que se le pida nada.</p>
<p>Esa comparación es lo que lanzó la investigación. No «cómo ajusto mi slicer», sino <strong>qué tiene exactamente esta máquina</strong>, y qué se puede recuperar. Este artículo cuenta tres días, del 4 al 6 de septiembre de 2026, llevados a cabo con una IA (Claude) que pilota la impresora, escribe las herramientas y lee los manuales, mientras yo sostengo el calibre, la hoja de papel y la cámara. Cuenta también un bonito error de método, el suyo y el mío, porque es lo que pasa cuando se busca de verdad.</p>
<h2 id="el-dispositivo">El dispositivo</h2>
<p>El firmware original iba a ser sustituido por <strong>Klipper</strong>. Klipper es un firmware de impresora 3D en dos partes: un programa minúsculo en la placa de la impresora, que solo pilota motores y calentadores en tiempo real, y un programa anfitrión, en un ordenador al lado, que hace todo lo demás: la cinemática, las calibraciones, las macros. Se pierde la pantalla táctil de la impresora (Klipper no sabe manejarla), se ganan herramientas de calibración que no existen en ningún otro sitio, en particular para las deltas.</p>
<p>Lo que Klipper aporta, en concreto, frente al Repetier original —o a un Marlin—:</p>
<ul>
<li><strong>El cálculo deportado.</strong> Un firmware clásico hace toda la cinemática delta en el pequeño microcontrolador de la placa, con las aproximaciones que eso impone; Klipper la hace en el ordenador anfitrión, en coma flotante, y solo envía a la placa instantes de paso precalculados. En una delta, donde cada movimiento es una raíz cuadrada por columna, se nota en la precisión de los movimientos y en la velocidad posible.</li>
<li><strong>Las herramientas de calibración</strong>: <code>DELTA_CALIBRATE</code>, que deduce la geometría completa a partir de siete puntos, con o sin sonda; la calibración extendida de los brazos; la malla del plato; y <code>TUNING_TOWER</code>, que hace variar un parámetro con la altura durante la impresión, para ajustar en una pieza lo que exigiría diez intentos.</li>
<li><strong>El pressure advance y el input shaper</strong>, la compensación de la presión en el bowden y la de las vibraciones, que el firmware original no tiene y que explican la mayor parte de la diferencia de calidad con una máquina moderna.</li>
<li><strong>Una configuración en archivo de texto</strong>, legible, comentable, versionable, donde cada valor tiene su procedencia; y un socket local desde el que se pilota todo con un script.</li>
</ul>
<p>Lo que no aporta: no eleva el techo de caudal del hotend, no sustituye una mecánica errónea, y necesita un ordenador al lado.</p>
<p>El anfitrión, de momento, es mi portátil conectado por USB; una Raspberry Pi tomará el relevo. Sin interfaz web por ahora: Klipper expone un socket local al que se envían comandos, y la IA escribió en una hora lo necesario para no teclear G-code a mano: un cliente para enviar un comando y leer la respuesta, un script de seguimiento de impresión y, sobre todo, <code>calib.py</code>, un control por teclado donde una tecla es un gesto: <code>h</code> para el homing, <code>s</code> para lanzar la calibración delta, <code>m</code> para la malla del plato, <code>d</code>/<code>u</code> para bajar o subir la boquilla 0,1 mm, <code>[</code>/<code>]</code> para ajustar la primera capa mientras se imprime.</p>
<p>El principio, desde el inicio, es el mismo que en la Bambu: <strong>se mide, no se inventa</strong>. Cada valor escrito en la configuración procede de una medida en la máquina, y cada corrección va seguida de una pieza de control.</p>
<details>
<summary>Para ir al fondo: qué hace un firmware delta y qué corrige cada ajuste</summary>
<p>En una delta, la posición de la boquilla se calcula a partir de siete números y medio: la <strong>longitud de los brazos</strong> (<code>arm_length</code>), el <strong>radio delta</strong> (<code>delta_radius</code>, la distancia horizontal entre el eje de una columna y el pivote del brazo en el carro, menos la del lado del efector), el <strong>ángulo</strong> de cada columna (nominalmente 210°, 330° y 90°) y la <strong>altura de tope</strong> de cada columna (<code>position_endstop</code>, donde el carro dispara su final de carrera). Cuando uno es erróneo, el error sobre el plato tiene una forma reconocible:</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Ajuste erróneo</th>
<th>Forma del error sobre el plato</th>
</tr>
</thead>
<tbody>
<tr>
<td>altura de un tope</td>
<td>un <strong>plano inclinado</strong> hacia la columna afectada</td>
</tr>
<tr>
<td>radio delta</td>
<td>un <strong>cuenco</strong> o una <strong>cúpula</strong> centrados, simétricos</td>
</tr>
<tr>
<td>longitud de los brazos</td>
<td>cuenco/cúpula también, más un <strong>error de escala</strong> en XY (piezas demasiado grandes o pequeñas)</td>
</tr>
<tr>
<td>ángulo de una columna</td>
<td>una distorsión en <strong>trébol</strong>, de tres lóbulos, y piezas alabeadas</td>
</tr>
</tbody>
</table></div>
<p>Klipper los mide todos con <code>DELTA_CALIBRATE</code>: se posa la boquilla en siete puntos del plato (con una sonda, o con papel), y ajusta los parámetros para que esos siete puntos queden en un plano. La versión <strong>extendida</strong> (<code>DELTA_ANALYZE</code>) añade las medidas de una pieza impresa para ajustar los brazos uno a uno. Sobre esta geometría, la <strong>bed mesh</strong> (malla del plato) corrige lo que queda —los defectos de planitud del propio cristal— interpolando entre puntos medidos. El orden importa: la malla solo puede corregir limpiamente lo que es <em>local</em>; un error de geometría no es local, y una malla que intenta compensarlo nunca lo consigue del todo. Ese es el corazón de este artículo.</p>
</details>
<h2 id="primero-la-mecanica-las-correas">Primero la mecánica: las correas</h2>
<p>Antes de tocar el firmware, una auditoría rápida de lo que se mueve. Las correas de esta máquina tienen historia: un primer juego destruido por sobretensión («había leído que nunca había que tensarlas, y es lo que me pasó»), en la época en que «ningún ajuste tenía efecto». Esa frase, con perspectiva, era la firma de un problema mecánico y no de slicer, y es lo que justifica empezar por ahí.</p>
<p>La IA propuso primero el método que se lee en todas partes: pellizcar la correa, medir la nota con una aplicación de guitarra, apuntar a una frecuencia. Tres rondas después, zanjé: «<em>no es una cuerda, si la tenso lo bastante para que suene lo romperá todo</em>». Ella lo comprobó, y yo tenía razón: en esta máquina el tramo libre mide 65 cm, la frecuencia objetivo estaría por debajo de 30 Hz, donde las aplicaciones saltan una octava (yo leía 70 Hz sin caer nunca en el mismo valor). Sobre todo, un artículo de Hackaday recuerda que la calidad de impresión apenas cambia con correas francamente flojas, mientras el eje no se retrase respecto al motor; en cambio, tensar de más rompe ejes de motor (un NEMA 17 admite 28 N de carga radial). No hay compromiso que buscar: <strong>ningún beneficio al apretar, un riesgo al apretar.</strong></p>
<p>El método elegido es el que uso desde hace años: aflojar francamente y volver a tensar justo hasta el umbral en que la correa empieza a vibrar blandamente en vez de flotar. Se llega por debajo, así que la sobretensión es imposible; el umbral es exactamente el límite bajo del sin-holgura; el mismo gesto en las tres columnas iguala por construcción. Las seis poleas giraban libres. Auditoría cerrada. <em>Veremos más adelante que este retensado, hecho en el momento equivocado, salió caro de todos modos.</em></p>
<h2 id="lo-que-la-maquina-tenia-dentro">Lo que la máquina tenía dentro</h2>
<p>Antes de flashear había que leer la memoria del firmware original: los valores que usaba son el punto de partida de la configuración Klipper, y una vez flasheada, ya no se pueden leer. Primera sorpresa, al conectar el USB: <strong>no es Marlin</strong>. Todo lo que se lee sobre la QQ-S da por hecho Marlin, y la IA había preparado los comandos Marlin (<code>M503</code> para leer la configuración, <code>M665</code>/<code>M666</code> para la geometría delta). Respuesta de la máquina: <code>Unknown command</code>. El firmware se anuncia como <code>FIRMWARE_NAME:Robin</code> y es <strong>Repetier</strong>, que vuelca su memoria con <code>M205</code>. Primera lección, no la última: comprobar antes de afirmar.</p>
<p>El volcado, 970 m de filamento y 233 horas de máquina, dio dos cosas.</p>
<p>Primero los valores reales: brazos 278,6 mm (la config Klipper de referencia dice 280), radio delta <strong>140,8</strong> (la referencia dice 130 — diez milímetros de diferencia, suficiente para una cúpula monstruosa si hubiéramos tomado la referencia), altura 376,03, 100 pasos/mm en las columnas y <strong>367 pasos/mm en el extrusor</strong> (recuerden esa cifra).</p>
<p>Después, una constatación que ya explicaba mucho: <strong>todos los términos de corrección por columna estaban a cero</strong>. Radio delta A/B/C, corrección de diagonal A/B/C, todo a cero. Esta máquina <strong>nunca</strong> había sido calibrada finamente como delta — o lo había sido en fábrica y lo perdió en una actualización del firmware, que reinicia la EEPROM: es mi hipótesis, y la EEPROM no guarda historial para zanjarla. En ambos casos, sus errores de geometría, fueran los que fueran, llevaban años intactos, y los pasos del extrusor probablemente venían del mismo reinicio.</p>
<details>
<summary>Para ir al fondo: leer la EEPROM de un Repetier, y qué se traslada a Klipper</summary>
<p><code>M205</code> devuelve una línea por valor, con el formato <code>EPR:&lt;tipo&gt; &lt;posición&gt; &lt;valor&gt; &lt;etiqueta&gt;</code>. El firmware responde <code>ok</code> <strong>antes</strong> de la respuesta, no después: un script que lee «hasta el ok» se lo pierde todo; hay que leer hasta el silencio. Lo que se traslada a Klipper: <code>Diagonal rod length</code> → <code>arm_length</code>, <code>Horizontal rod radius at 0,0</code> → <code>delta_radius</code>, <code>Z max length</code> → <code>position_endstop</code> de las tres columnas, <code>Max printable radius</code> → <code>print_radius</code>, y los pasos/mm → <code>rotation_distance</code> (para una correa GT2 en polea de 16 dientes, 32 mm por vuelta; para el extrusor, <code>rotation_distance = pasos_por_vuelta / pasos_por_mm</code>, es decir 3200 / 367 = 8,719). Los PID no se trasladan (escalas distintas), se rehacen. Los desfases de tope por columna (X 0, Y 7, Z 83 pasos en la EEPROM) no se trasladaron: la convención de signo de Repetier no es segura, y <code>DELTA_CALIBRATE</code> los vuelve a derivar de todos modos.</p>
<p>El volcado completo está en los archivos al final del artículo (<code>README-flsun.md</code> remite al <code>eeprom-repetier.txt</code> del repositorio).</p>
</details>
<h2 id="klipper-y-unos-motores-sin-fuerza">Klipper, y unos motores sin fuerza</h2>
<p>El flasheo en sí no tiene historia: Klipper compilado para el STM32F103 de la placa <strong>MKS Robin Mini</strong>, con un bootloader de 28 KB, un cristal de 8 MHz y el puerto serie USART3; el binario pasado por el pequeño script <code>update_mks_robin.py</code> de Klipper que lo codifica en el formato que espera el bootloader MKS; copiado en una tarjeta SD de 4 GB en FAT32, impresora apagada al insertarla. Un pitido, «complete» en verde, y Klipper responde <code>Klipper state: Ready</code>.</p>
<p>Y entonces el primer homing falló. <code>No trigger on stepper_b after full movement</code>: un carro no llegó a su interruptor. El segundo homing también, en otra columna. Los motores gruñían, subían a 5 mm/s, se calaban a 25, y bajaban «blandamente».</p>
<p>Lo que siguió es más una lección que un relato. La IA fue encadenando hipótesis —duración de los pulsos de paso, modo de micropasos, correas, un potenciómetro de corriente que no existe en esta placa—, cada una probada, cada una descartada, y cada prueba alargaba la conversación sin añadir información. Es un comportamiento que conviene conocer al trabajar con una IA: cuanto más se llena su ventana de contexto de intentos fallidos, más se desliza hacia el siguiente intento en vez de volver a los hechos. Lo que la detuvo cabe en una frase, una restricción fuerte: «antes del flasheo, todo funcionaba perfectamente». La víspera, con Repetier, la misma mecánica funcionaba; el hardware quedaba descartado por construcción, y la única pregunta válida pasaba a ser: <em>¿qué hacía el firmware antiguo que el nuevo no hace?</em></p>
<p>Entonces hizo lo que debería haber hecho primero: leer el archivo de pines de esta placa en las fuentes de Marlin, <code>pins_MKS_ROBIN_MINI.h</code>, y buscar <strong>todo</strong> lo que el firmware antiguo inicializaba al arrancar. Y ahí:</p>
<pre><code>MOTOR_CURRENT_PWM_XY_PIN  PA6
MOTOR_CURRENT_PWM_Z_PIN   PA7
MOTOR_CURRENT_PWM_E_PIN   PB0
MOTOR_CURRENT_PWM_RANGE   1500
DEFAULT_PWM_MOTOR_CURRENT { 800, 800, 800 }
</code></pre>
<p>En la Robin Mini, la tensión de referencia que fija la <strong>corriente de los motores</strong> no se ajusta con un potenciómetro: la <strong>genera el microcontrolador</strong>, como señal PWM en tres pines. Repetier las fijaba al arrancar. Klipper las dejaba flotando: referencia casi nula, par minúsculo, deriva con los minutos («se mueve mejor que al principio»). Y <strong>la configuración oficial de Klipper para esta impresora, <code>printer-flsun-qqs-2020.cfg</code>, no contiene esas líneas</strong> (en el momento de escribir esto). Quien siga esa configuración en una Robin Mini tiene los motores subalimentados.</p>
<p>La corrección son tres bloques de configuración: una salida PWM hardware por pin, 800 en una escala de 1500, a 1 kHz, el valor por defecto de Marlin. Homing inmediato, tres columnas disparadas, velocidad normal. «<em>¡Movimiento perfecto!</em>»</p>
<details>
<summary>Para ir al fondo: los tres bloques, y la lección de método</summary>
<pre><code>[output_pin motor_current_ab]
pin: PA6
pwm: True
hardware_pwm: True
cycle_time: 0.001
scale: 1500
value: 800

[output_pin motor_current_c]
pin: PA7
# ídem

[output_pin motor_current_e]
pin: PB0
# ídem
</code></pre>
<p>800/1500 corresponde a unos 1,28 V de referencia, es decir ~0,9 A eficaces en los drivers TMC2208 de la placa. Se puede ajustar en pasos de 50, sin pasar de ~1000 sin refrigeración. Los tres pines están en el mismo temporizador (TIM3), <code>hardware_pwm</code> se acepta sin error.</p>
<p>La lección va más allá de esta placa: cuando «antes funcionaba» con otro firmware, hay que inventariar <strong>todo</strong> lo que el firmware antiguo inicializaba: corriente, micropasos, modos de driver, no solo STEP/DIR/ENABLE. El error de la IA no fue equivocarse, sino razonar («la corriente viene de un potenciómetro, luego no ha cambiado») en vez de comprobar cómo produce su referencia esta placa en concreto.</p>
</details>
<h2 id="calibrar-una-delta-sin-sonda">Calibrar una delta sin sonda</h2>
<p>La sonda de la máquina no estaba. No importa: la documentación de Klipper recomienda de todos modos la calibración <strong>manual</strong> en una delta, porque una sonda montada al lado de la boquilla introduce su propio error cuando el efector se inclina. El método es la hoja de papel: <code>DELTA_CALIBRATE METHOD=manual</code> envía la boquilla a 2 mm sobre siete puntos del plato, uno en el centro y seis en círculo; en cada punto se baja la boquilla en pasos de 1 mm, luego 0,1, luego por bisección, hasta que una hoja de papel de 0,1 mm roza justo entre la boquilla y el cristal; se valida, la boquilla va al punto siguiente. Siete puntos, un cuarto de hora. Klipper calcula después los parámetros que ponen esos siete puntos en un plano.</p>
<p><img alt="Pieza calibrate_size.stl de Klipper sobre el plato de la FLSun QQ-S: anillo, seis radios, siete pilares hexagonales, letras A, B, C hacia las columnas" src="https://pf.olibrio.fr/images/flsun/04-calibrate-size.jpg" /></p>
<p><em>La pieza <code>calibrate_size.stl</code> que viene con Klipper, para la calibración extendida de los brazos. Se imprimirá pero no se usará: veremos por qué.</em></p>
<p>El primer resultado, el 4 de septiembre por la tarde: radio delta 141,18 (la EEPROM decía 140,8), y sobre todo <strong>ángulo de la columna A a 211,02° y de la columna B a 330,45°</strong>, en lugar de los 210° y 330° nominales. Un grado en A. Es enorme para una delta, y era el defecto «que ningún ajuste corregía»: un ángulo de columna erróneo alabea las piezas y deforma el plato en trébol, y ningún ajuste de slicer, ninguna malla de plato, lo compensa.</p>
<p>A continuación, la <strong>bed mesh</strong>, la malla del plato: <code>BED_MESH_CALIBRATE METHOD=manual</code>, el mismo gesto con papel en 13 puntos, para corregir lo que el cristal tiene de no plano. Rango 0,51 mm, dominado por los dos bordes del eje Y. Guardada, cargada al inicio de cada impresión. Calibración en frío terminada.</p>
<p><em>Fíjense en este detalle: la malla se midió en frío, y yo retensé las correas entre la calibración delta y su verificación. Volveremos a ello.</em></p>
<h2 id="el-extrusor-mentia-un-115">El extrusor mentía un 11,5 %</h2>
<p>La prueba más sencilla del mundo, y nunca la había hecho en seis años: una raya de rotulador en el filamento a 120 mm de la entrada del extrusor, se pide a la máquina que avance 100, se mide lo que queda. Esperado: 20 mm. Medido: <strong>31,5 mm</strong>. La máquina había empujado 88,5 mm de los 100 pedidos.</p>
<p>Los 367 pasos/mm de la EEPROM, trasladados fielmente a Klipper (<code>rotation_distance</code> 8,719), estaban mal en un 11,5 %. Corregido a 7,716, contrastado con una segunda prueba: 20,0 mm restantes, «<em>¡perfecto!</em>».</p>
<p>Midan lo que eso significa: <strong>a cada capa que esta máquina depositó le faltaba una décima parte de su material</strong>. Paredes débiles, uniones abiertas, superficies irregulares, mala adhesión entre capas: todo lo que yo achacaba a «la delta» o «el PETG». Y ningún ajuste de slicer compensa un error que se ignora: se puede subir el flujo al 110 % al azar, no se sabe por qué, y no se mantiene de un filamento a otro.</p>
<p>Con los ángulos de columna y la corriente de motor, son <strong>tres defectos de fábrica</strong> — de fábrica o de una actualización de firmware que lo puso todo a cero, la máquina no dirá cuál — nunca vistos.</p>
<h2 id="pid-petg-humedo-y-la-primera-impresion">PID, PETG húmedo y la primera impresión</h2>
<p>Las regulaciones de temperatura (PID) se recalibran en diez minutos, pero la de la boquilla hizo saltar la protección térmica de Klipper: <code>heater extruder not heating at expected rate</code>. La curva mostraba un calentamiento perfectamente sano (27 → 234 °C en 95 s), y luego una inercia inusual entre el bloque y su termistor que hace creer a la protección que el calentamiento se detiene. Sin desactivar nada: una ventana ampliada en <code>[verify_heater extruder]</code>, documentada en la configuración.</p>
<p>Luego la primera pieza, en PETG, el que vivía en la máquina desde hacía siglos. El cubo salió… así:</p>
<p><img alt="Cubo de 20 mm en PETG negro impreso en la FLSun QQ-S, paredes espumosas e irregulares, hilos colgando: filamento húmedo" src="https://pf.olibrio.fr/images/flsun/01-cube-petg-humide.jpg" /></p>
<p><em>El primer cubo, en PETG. Crepitaba en la boquilla durante la impresión: la bobina estaba saturada de agua. Las paredes son espuma.</em></p>
<p>No es la impresora: es el filamento. El PETG es higroscópico, y una bobina dejada al aire durante años crepita en la boquilla (el agua se vaporiza) y sale espumosa. Buena parte de la «fiabilidad decepcionante» de esta máquina era eso. Bobina de PLA nueva para toda la calibración; el PETG pasará por la secadora de filamento.</p>
<p>En PLA, el <code>square.stl</code> de Klipper (un marco de un milímetro de pared, cinco milímetros de alto, seis minutos): pared 1,00 mm, altura 5,00. Y el primer cubo de control: <strong>Z 20,00 · X 20,40 · Y 20,45</strong>. La altura es perfecta: las columnas están bien. El exceso del 2 % en XY lo resolveremos al final.</p>
<p><img alt="Prueba de primera capa square.stl de Klipper: dos marcos encajados en PLA blanco sobre el plato negro de la delta" src="https://pf.olibrio.fr/images/flsun/03-square.jpg" /></p>
<p><em><code>square.stl</code>: la prueba de primera capa y de caudal de Klipper. Pared de 1,00 mm clavada.</em></p>
<p><img alt="Primer plano del pie de un marco: un fino labio sobresale en la base de la pared" src="https://pf.olibrio.fr/images/flsun/02-square-levre.jpg" /></p>
<p><em>El pie de un marco, muy de cerca: el pequeño labio que sobresale en la base dice que la primera capa está un poco demasiado aplastada. Con esta prueba se ajusta el desfase de primera capa, en pasos de 0,05 mm, durante la impresión.</em></p>
<h2 id="pressure-advance">Pressure advance</h2>
<p>Último ajuste antes de atacar el plato: el <strong>pressure advance</strong>. En una máquina bowden (el motor del extrusor está en el chasis, un tubo largo lleva el filamento hasta la boquilla), la presión en el tubo tarda en subir y en bajar; sin compensación, las esquinas se hinchan y los finales de línea babean. Klipper compensa empujando un poco más antes de las aceleraciones y retirando antes de las deceleraciones, con un solo parámetro. Se mide con una torre de prueba en la que el parámetro aumenta con la altura (<code>TUNING_TOWER</code>), y se busca a ojo la altura en la que las esquinas son más nítidas.</p>
<p><img alt="Esquina de la torre de pressure advance square_tower de Klipper en PLA blanco, vista rasante: la arista cambia con la altura" src="https://pf.olibrio.fr/images/flsun/05-pa-tower.jpg" /></p>
<p><em>La torre <code>square_tower.stl</code>: abajo, poca compensación, las esquinas se hinchan; arriba, demasiada, se hunden. La mejor esquina está a 19 mm.</em></p>
<p>Mejor esquina a 19 mm, paso de 0,020 por milímetro: <strong>pressure advance 0,38</strong>, en el rango esperado para un bowden. Grabado.</p>
<h2 id="la-espiral-o-como-ver-la-primera-capa">La espiral, o cómo ver la primera capa</h2>
<p>Para juzgar el nivelado necesitaba algo mejor que la hoja de papel: recordaba un objeto en espiral que se imprime para ver la primera capa de un vistazo. En vez de buscar un archivo laminado para otra máquina, la IA generó el G-code directamente: una sola línea continua, en espiral de Arquímedes, del centro hasta 120 mm de radio, una vuelta cada 2,5 mm, una sola capa de 0,2. Doce minutos. Donde la boquilla está demasiado cerca, el cordón queda aplastado, plano, translúcido; donde está demasiado lejos, queda redondo, estrecho, mal pegado. En un plato redondo, es la prueba más legible que existe.</p>
<p><img alt="Espiral de nivelado sobre el plato redondo de la FLSun QQ-S: tres sectores brillantes alternando con tres oscuros, en trébol" src="https://pf.olibrio.fr/images/flsun/06-spirale-1-trefle.jpg" /></p>
<p><em>La primera espiral. Tres lóbulos brillantes a 120° uno de otro: la firma de una geometría delta, no de un plato alabeado.</em></p>
<p>La primera espiral mostraba un <strong>trébol de tres lóbulos</strong>. Un cristal alabeado no hace un trébol; una delta mal calibrada, sí. Y sin embargo la calibración acababa de hacerse. La conclusión correcta habría sido: <em>la geometría aún no está bien, repetir la calibración</em>. Tomamos el otro camino.</p>
<h2 id="pista-falsa">La pista falsa: dos días corrigiendo la malla</h2>
<p>Mi petición era razonable: «<em>una impresión con un espesor predeterminado sería más pertinente que la prueba de la hoja</em>». La IA construyó el método: imprimir un cuadrado de una capa en cada uno de los 13 puntos de la malla, medir su espesor, y corregir cada punto de la malla según su desviación de la media. Un cuadrado más grueso que los demás = la boquilla estaba más alta ahí = el plato está más bajo ahí de lo que la malla cree = se baja el punto. Escribió el script (<code>fix-mesh.py</code>) que hace el homing, coloca la boquilla a 100 mm sobre cada cuadrado para identificarlo («<em>¿cómo saber cuál es cuál?</em>» — el logo no es una referencia), registra las medidas, reescribe la malla. Como mi micrómetro está graduado en pulgadas, se introducen milésimas (<code>13t</code>).</p>
<p><img alt="Trece cuadrados de una capa en PLA impresos en los trece puntos de la bed mesh de Klipper, plato redondo de la delta" src="https://pf.olibrio.fr/images/flsun/07-carres-13.jpg" /></p>
<p><em>Pasada 1: trece cuadrados de 20 mm, una capa, uno por punto de la malla.</em></p>
<p><img alt="El cilindro de un viejo micrómetro: graduaciones de 0 a 7, una marca cada 25 milésimas de pulgada" src="https://pf.olibrio.fr/images/flsun/09-micrometre-pouces.jpg" /></p>
<p><em>El micrómetro, graduado en pulgadas: una marca del cilindro son 25 milésimas, el tambor da la unidad. 13 thou = 0,33 mm.</em></p>
<p><img alt="Un micrómetro Lufkin Rule Co. de Saginaw, Michigan, modelo n.º 1941, oxidado, con el husillo cerrado sobre un fragmento de primera capa de PLA translúcido" src="https://pf.olibrio.fr/images/flsun/09b-micrometre-lufkin.jpg" /></p>
<p><em>El instrumento en sí: un Lufkin Rule Co. de Saginaw, Michigan, n.º 1941. Tiene más años que yo y sigue midiendo a la milésima de pulgada. Entre sus topes, una capa de PLA.</em></p>
<p>Funcionaba. Pasada 1: rango de espesores 0,30 mm. Pasada 2: <strong>0,084 mm</strong>. La espiral siguiente era claramente mejor, el trébol se difuminaba. Luego pasamos a una malla más fina, 7×7 (29 puntos, paso de 40 mm en vez de 55), porque los defectos restantes parecían caer <em>entre</em> los puntos. Pasada 3, pasada 4, ganancia reducida para no oscilar. Y en cada espiral, <strong>volvían las mismas zonas</strong>, atenuadas pero en el mismo sitio.</p>
<p><img alt="Espiral 3 anotada: cinco zonas rodeadas en rojo y una en azul en el borde delantero derecho" src="https://pf.olibrio.fr/images/flsun/10-spirale-3-annotee.jpg" /></p>
<p><em>Espiral 3, anotada por mí: rojo = demasiado cerca (raspado), azul = demasiado lejos (no pegado). Cinco manchas, ya sin trébol claro.</em></p>
<p><img alt="Espiral 4 anotada: dos zonas rojas, una azul en el mismo borde" src="https://pf.olibrio.fr/images/flsun/11-spirale-4-annotee.jpg" /></p>
<p><em>Espiral 4, tras la malla 7×7: dos zonas rojas en vez de cinco, el azul siempre en la misma esquina.</em></p>
<p><img alt="Veintinueve cuadrados de una capa sobre la malla bed mesh 7×7 de la FLSun QQ-S, dos cuadrados a la izquierda arrancados" src="https://pf.olibrio.fr/images/flsun/12-carres-29.jpg" /></p>
<p><em>Malla 7×7, 29 cuadrados de 10 mm. Dos cuadrados de la izquierda están arrancados: demasiado cerca. El micrómetro, sin embargo, los medía «gruesos».</em></p>
<p>Ahí es cuando dije lo que había que decir: «<em>para mí el error es muy repetible en las tres últimas espirales. Falta material en las mismas zonas y las correcciones han mejorado las cosas pero no corrigen realmente el fondo del problema.</em>» Tres pasadas de corrección deberían haber bastado. Algo independiente del ajuste se resistía.</p>
<p><img alt="Espiral 5 anotada: dos zonas rojas, tres rosas, una azul" src="https://pf.olibrio.fr/images/flsun/13-spirale-5-annotee.jpg" /></p>
<p><em>Espiral 5: rojo, casi sin filamento; rosa, ligera falta; azul, no pegado. Las mismas zonas, otra vez.</em></p>
<p>Dos macros lo zanjaron. En la zona azul, el cordón es redondo, estrecho, depositado sin presionar, y la transición es progresiva a lo largo de 25 mm hacia el borde: la boquilla se aleja regularmente al ir hacia el borde. En la zona roja, los cordones son <strong>anchos, planos, translúcidos, aplastados hasta ser una película</strong>: se ven los puntos del plato a través. Demasiado cerca, de verdad.</p>
<p><img alt="Macro de la zona azul: cordones redondos y estrechos, ondulantes, con pequeños nudos" src="https://pf.olibrio.fr/images/flsun/14-macro-trop-loin.jpg" /></p>
<p><em>Zona azul: cordón redondo, sin presionar, que ondula y hace nudos donde ha agarrado. Demasiado lejos.</em></p>
<p><img alt="Macro de la transición hacia la zona roja: cordones anchos, planos y translúcidos, casi una película" src="https://pf.olibrio.fr/images/flsun/15-macro-trop-pres.jpg" /></p>
<p><em>Zona roja: cordones aplastados, translúcidos, se ve el plato a través. Demasiado cerca, sin discusión.</em></p>
<p>Y ahí está la contradicción: en esas zonas rojas, los cuadrados medían un espesor <em>normal</em>. La explicación, una vez que se ve: <strong>un cuadrado impreso demasiado cerca forma un labio levantado en todo su contorno</strong>, y los topes del micrómetro, seis milímetros de diámetro, se apoyan en ese labio. Lee «grueso» exactamente donde está aplastado. El método de los cuadrados estaba sesgado en la dirección precisa que impedía converger. Dos conclusiones de la IA construidas sobre esas medidas («la boquilla está a 0,4 mm del cristal de media», «hay que bajar el cero global») cayeron con él.</p>
<p>Quedaba la pregunta de fondo: ¿por qué zonas tan repetibles? Mi pista eran las correas. La IA escribió una prueba de repetibilidad (tecla <code>R</code>: mismo punto, cinco aproximaciones por caminos distintos, hoja de papel): <strong>repetible a 0,1 mm</strong> fuera cual fuera el camino. Correas y holgura descartadas. Pero esa prueba dio otra cosa: en esos puntos, la hoja rozaba a Z = +0,2 y <strong>+0,6 mm</strong> — la máquina creía que el plato estaba medio milímetro más bajo de lo que está. Y la propia malla llevaba una pendiente de 0,65 mm de delante atrás, que nada justifica en una delta calibrada.</p>
<p>La causa estaba en la secuencia del primer día. La calibración delta se había hecho <strong>en frío</strong>; <strong>entre</strong> esa calibración y su verificación, yo había retensado las correas; la verificación había mostrado un desfase, y la IA había aplicado <strong>+0,4 mm uniforme</strong> a los tres topes. Pero el retensado había desplazado las tres columnas <em>desigualmente</em>. El residuo, una pendiente inclinada, se fue a la malla, y una malla de delta nunca vuelve plana una pendiente: deja lóbulos, que cuatro pasadas de cuadrados al micrómetro persiguieron sin atraparlos.</p>
<details>
<summary>Para ir al fondo: por qué una malla no compensa un error de geometría</summary>
<p>Un error de tope en una columna no produce un plano inclinado exacto sino una superficie ligeramente curva, porque la inclinación del efector cambia con su posición; un error de ángulo produce un trébol. La malla muestrea esa superficie en 13 o 29 puntos e interpola (aquí en bicúbico) entre ellos: captura la tendencia, no la curvatura fina, y deja un residuo allí donde la superficie real se aparta de la interpolación. Cuanto mayor es el error de geometría, mayor es el residuo. Por eso Klipper pide la geometría primero y la malla después, y por eso «rehacer la malla» nunca sustituye a «rehacer la calibración delta». Y por eso hay que calibrar en el estado en que se imprime: un plato a 60 °C no está exactamente en el mismo sitio que a 20 °C (aquí, +0,36 mm en el centro), y la diferencia no es necesariamente uniforme.</p>
</details>
<h2 id="la-llegada-rehacerlo-todo-en-caliente-con-papel">La llegada: rehacerlo todo en caliente, con papel</h2>
<p>Plato a 60 °C, boquilla fría, malla vaciada. <code>DELTA_CALIBRATE</code> manual, siete puntos con papel, quince minutos. El veredicto está en los topes:</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Columna</th>
<th>Tope antes</th>
<th>Tope después</th>
<th>Diferencia</th>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
<td>376,252</td>
<td>376,075</td>
<td>−0,18</td>
</tr>
<tr>
<td>B</td>
<td>376,533</td>
<td>375,970</td>
<td><strong>−0,56</strong></td>
</tr>
<tr>
<td>C</td>
<td>377,204</td>
<td>376,859</td>
<td>−0,35</td>
</tr>
</tbody>
</table></div>
<p>Los ángulos apenas se movieron (A 211,02 → 210,93, B 330,45 → 330,33), el radio tampoco (141,18 → 141,29). La geometría aguantaba. Lo que estaba mal eran <strong>los topes, desigualmente</strong>: 0,38 mm de diferencia entre A y B. Exactamente la pendiente que llevaba la malla.</p>
<p>Guardar, homing, y luego la malla con papel en los 29 puntos, media hora. Centro plano a ±0,1 mm en 80 mm de radio; el borde delantero se hunde 0,6 mm a 120 mm del centro — es el propio cristal, o la delta al final de su alcance, y esta vez está medido directamente y la malla lo sabe. Luego la espiral:</p>
<p><img alt="Espiral de nivelado uniforme en la FLSun QQ-S tras la recalibración delta en caliente con Klipper: vueltas regulares de borde a borde" src="https://pf.olibrio.fr/images/flsun/16-spirale-6-uniforme.jpg" /></p>
<p><em>Espiral 6, la primera con geometría y malla coherentes, ambas medidas en caliente. Uniforme de borde a borde, borde delantero incluido.</em></p>
<p><img alt="Macro de la sexta espiral: cordones regulares, del mismo ancho de una vuelta a otra" src="https://pf.olibrio.fr/images/flsun/17-macro-spirale-6.jpg" /></p>
<p><em>El cordón, con lupa: regular, mismo ancho de una vuelta a otra, pegado en todas partes.</em></p>
<p>Seis espirales, y la buena fue aquella en la que dejamos de corregir y recalibramos, en treinta y cinco minutos, con un solo método.</p>
<p>Quedaba una última trampa, de la misma familia: el desfase de primera capa, +0,07 mm, se había ajustado el primer día sobre el cero <em>frío</em>. Sobre el nuevo cero, en caliente, el cubo de control no se pegó. <strong>Un cero nuevo implica reajustar el desfase de primera capa, nunca arrastrar el antiguo.</strong> Marco de prueba, ajuste en directo en pasos de 0,05: −0,10 apenas pega, −0,20 pega con un labio de 0,3 mm en el pie; grabado a <strong>−0,15</strong>.</p>
<p><img alt="Primera capa de un cubo de PLA despegada del plato: fragmento enroscado con hilos, desfase de primera capa demasiado alto" src="https://pf.olibrio.fr/images/flsun/18-cube-pas-colle.jpg" /></p>
<p><em>El cubo de control relanzado con el antiguo desfase de primera capa: no se pegó. El cero había cambiado, el desfase no.</em></p>
<p>Y el cubo, por fin: <strong>20,3 × 20,4 × 20,00</strong>, labio de 0,1 mm por lado. El primer día medía 20,40 × 20,45 × 20,00. El exceso en XY no se movió con la geometría, porque no es geometría: la pieza de siete pilares, medida con el calibre, daba una distancia entre ejes de 65,0 ± 0,4 mm sobre 65 nominales, es decir una escala correcta al 0,5 %; un error de brazos habría dado +1,3 mm ahí. Lo que queda es un <strong>exceso constante</strong> de ancho de cordón —esquinas que se hinchan, pared de 1,07 para 1,00— y eso se ajusta en el laminado como en cualquier máquina: multiplicador de extrusión 0,95, compensación XY −0,1 mm, compensación de pie de elefante 0,1 mm, en un perfil de producción separado del perfil bruto de pruebas. La calibración extendida de los brazos, larga y delicada, no era necesaria. Cubo de control con ese perfil: <strong>20,0 × 20,1 × 20,0</strong>.</p>
<h2 id="lo-que-me-llevo">Lo que me llevo</h2>
<p><strong>Calibrar en el estado en que se imprime.</strong> En caliente. Una máquina calibrada en frío describe un plato que ya no existe cuando llega el PLA.</p>
<p><strong>Un solo método de medida, de principio a fin.</strong> El papel para la geometría, el papel para la malla, el marco de prueba para la primera capa. Cada cambio de método introdujo un sesgo que nadie veía.</p>
<p><strong>La geometría primero, la malla después, nunca al revés.</strong> Una malla que no converge en dos pasadas no necesita más puntos: está compensando un error que no es suyo. Y cualquier retensado de correas pone la geometría de nuevo en juego: repetir <code>s</code> y luego <code>m</code>, sin atajos.</p>
<p><strong>Cuando dos medidas se contradicen, se va a mirar.</strong> La lupa sobre el cordón zanjó en un minuto lo que cuatro pasadas de micrómetro no habían resuelto. Una medida no es una verdad, es un instrumento con sus puntos ciegos.</p>
<p><strong>La IA sobreingenieriza cuando entiende mal.</strong> El script de corrección de malla por cuadrados al micrómetro era ingenioso, estaba bien hecho, era persistente, con reanudación y correcciones — y optimizaba una mala idea. Fui yo quien dijo «es repetible, no es el ajuste», y fue la macro la que zanjó. En cambio, ella encontró en una lectura lo que seis años de foros no habían encontrado: la corriente de motor por PWM, el extrusor desviado un 11,5 %, la calibración nunca hecha.</p>
<p><strong>«Antes funcionaba» es un dato.</strong> Dos veces en esta historia, mi juicio sobre mi máquina valió más que un método leído en otra parte: sobre la tensión de las correas, sobre el homing. Y dos veces, la IA acabó comprobándolo y dándome la razón, con fuentes. Ese es el reparto correcto: ella lee rápido, no mide por mí.</p>
<h2 id="donde-estamos">Dónde estamos</h2>
<div class="status">
<p><strong>Estado a 6 de septiembre de 2026: calibración de la máquina terminada.</strong> Geometría, cero y malla medidos en caliente con papel; primera capa a −0,15; extrusor a 7,716; pressure advance 0,38; PID rehechos; corriente de motor fijada. Espiral uniforme; cubo de control a 20,0 × 20,1 × 20,0 con el perfil de producción. Queda, por orden de interés: la compensación de resonancia (input shaper) con la torre de prueba de Klipper, un extrusor de doble arrastre en stock, y la Raspberry Pi como anfitrión para hacer la impresora autónoma. El PETG se está secando.</p>
</div>
<h2 id="para-reproducir">Para reproducir</h2>
<p><strong>Material</strong>: una FLSun QQ-S de 2020 (placa MKS Robin Mini) —el planteamiento vale para cualquier delta, los pines no—; un ordenador con Linux y un puerto USB; una tarjeta SD ≤ 8 GB en FAT32; una hoja de papel de 80 g; un calibre; una bobina de PLA <strong>seca</strong>. Sin sonda, sin acelerómetro.</p>
<p><strong>Antes de flashear</strong>, leer la memoria del firmware original (en Repetier: <code>M205</code>; en Marlin: <code>M503</code>) y guardar el volcado. Anotar en particular la longitud de los brazos, el radio delta, la altura y los pasos/mm del extrusor.</p>
<p><strong>Firmware</strong>: Klipper, <code>make menuconfig</code> → STM32F103, bootloader 28 KiB, cristal 8 MHz, USART3 (PB11/PB10), 250000 baudios; luego <code>scripts/update_mks_robin.py out/klipper.bin Robin_mini.bin</code>; el archivo en la raíz de la tarjeta SD, impresora apagada al insertarla, encender, esperar «complete». El bootloader renombra el archivo a <code>.CUR</code>. El script <a href="https://pf.olibrio.fr/assets/flsun/build-firmware.sh"><code>build-firmware.sh</code></a> lo hace todo.</p>
<p><strong>Configuración</strong>: <a href="https://pf.olibrio.fr/assets/flsun/printer.cfg"><code>printer.cfg</code></a>, con sus valores reales y sus comentarios. Los tres bloques <code>[output_pin motor_current_*]</code> son <strong>imprescindibles</strong> en una Robin Mini. El bloque <code>SAVE_CONFIG</code> al final del archivo contiene los resultados de las calibraciones; para empezar de cero, borrarlo y volver a poner los valores de la EEPROM en <code>[stepper_a/b/c]</code> y <code>[printer]</code>.</p>
<p><strong>Herramientas</strong>: <a href="https://pf.olibrio.fr/assets/flsun/start-klipper.sh"><code>start-klipper.sh</code></a> (arrancar el anfitrión), <a href="https://pf.olibrio.fr/assets/flsun/send-gcode.sh"><code>send-gcode.sh</code></a> y <a href="https://pf.olibrio.fr/assets/flsun/klippy-client.py"><code>klippy-client.py</code></a> (enviar un comando), <a href="https://pf.olibrio.fr/assets/flsun/calib.py"><code>calib.py</code></a> (control por teclado de las calibraciones), <a href="https://pf.olibrio.fr/assets/flsun/watch-print.py"><code>watch-print.py</code></a> (seguimiento de impresión), <a href="https://pf.olibrio.fr/assets/flsun/make-spiral.py"><code>make-spiral.py</code></a> (la espiral). Los perfiles de PrusaSlicer en línea de comandos están en <a href="https://pf.olibrio.fr/assets/flsun/slicer/"><code>slicer/</code></a>: <code>qqs-pla.ini</code> bruto para las pruebas, <code>qqs-pla-prod.ini</code> para las piezas.</p>
<p><strong>En orden, en caliente</strong> (plato a la temperatura de impresión, boquilla fría para el papel):</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Paso</th>
<th>Comando / tecla</th>
<th>Duración</th>
<th>Lo que se obtiene</th>
</tr>
</thead>
<tbody>
<tr>
<td>1. Homing</td>
<td><code>h</code></td>
<td>1 min</td>
<td>posición conocida</td>
</tr>
<tr>
<td>2. Geometría</td>
<td><code>s</code> (DELTA_CALIBRATE manual), 7 puntos con papel, luego <code>c c</code></td>
<td>15 min</td>
<td>radio, ángulos, topes</td>
</tr>
<tr>
<td>3. Verificación</td>
<td><code>v</code> (7 puntos a Z = 0,1)</td>
<td>5 min</td>
<td>±0,05 esperado; si no, repetir 2</td>
</tr>
<tr>
<td>4. Malla</td>
<td><code>m</code> (BED_MESH_CALIBRATE manual), luego <code>c c</code></td>
<td>20–30 min</td>
<td>perfil <code>default</code>, cargado por START_PRINT</td>
</tr>
<tr>
<td>5. Extrusor</td>
<td>raya a 120 mm, <code>M83</code> <code>G1 E100 F60</code>, medir</td>
<td>5 min</td>
<td><code>rotation_distance</code> × extruido/100</td>
</tr>
<tr>
<td>6. PID</td>
<td><code>PID_CALIBRATE HEATER=extruder TARGET=210</code>, ídem <code>heater_bed</code></td>
<td>15 min</td>
<td>ganancias, <code>SAVE_CONFIG</code></td>
</tr>
<tr>
<td>7. Primera capa</td>
<td><code>square.stl</code>, <code>[</code> <code>]</code> en directo, grabar en START_PRINT</td>
<td>7 min</td>
<td>desfase</td>
</tr>
<tr>
<td>8. Pressure advance</td>
<td><code>square_tower.stl</code> + <code>TUNING_TOWER … START=0 FACTOR=.020</code></td>
<td>50 min</td>
<td>altura de la mejor esquina × 0,020</td>
</tr>
<tr>
<td>9. Control</td>
<td>espiral, luego cubo de 20 mm</td>
<td>12 + 19 min</td>
<td>uniforme; 20,00 en Z</td>
</tr>
</tbody>
</table></div>
<p>Tres reglas, si se ponen a ello: <strong>en caliente</strong>, <strong>un solo método de medida</strong>, y <strong>cualquier intervención mecánica (correas, brazos, plato) devuelve al paso 2</strong>. Si una malla no converge en dos pasadas, no añadir puntos: rehacer la geometría.</p>
<p><strong>Leer la espiral</strong>: rojo = demasiado cerca (cordón plano, translúcido, raspado), azul = demasiado lejos (cordón redondo, mal pegado). Un trébol de tres lóbulos = geometría; manchas locales = plato o malla; un borde que se hunde progresivamente = el cristal o la delta al final de su alcance. En caso de duda, la lupa.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="hace-falta-una-sonda-para-calibrar-una-delta-con-klipper">¿Hace falta una sonda para calibrar una delta con Klipper?</h3>
<p>No. La documentación de Klipper recomienda la calibración manual con papel en las deltas, porque una sonda desplazada respecto a la boquilla introduce su propio error cuando el efector se inclina. Siete puntos para la geometría, de trece a veintinueve para la malla, media hora en total.</p>
<h3 id="mis-motores-grunen-y-el-homing-falla-tras-pasar-a-klipper-en-una-mks-robin-mini-por-que">Mis motores gruñen y el homing falla tras pasar a Klipper en una MKS Robin Mini. ¿Por qué?</h3>
<p>Porque la corriente de los motores se fija por PWM desde el microcontrolador (pines PA6, PA7, PB0) y la configuración oficial de Klipper para la QQ-S no lo hace. Tres bloques <code>[output_pin]</code> en PWM hardware, valor 800 sobre 1500, resuelven el problema. Ver <a href="#klipper-y-unos-motores-sin-fuerza">Klipper, y unos motores sin fuerza</a>.</p>
<h3 id="mi-flsun-qq-s-lleva-marlin">¿Mi FLSun QQ-S lleva Marlin?</h3>
<p>La QQ-S de 2020 no: lleva Repetier (<code>FIRMWARE_NAME:Robin</code>). <code>M503</code>, <code>M665</code>, <code>M666</code>, <code>M900</code> responden <code>Unknown command</code>; es <code>M205</code> el que lee la memoria. Los tutoriales de Marlin no aplican.</p>
<h3 id="mi-malla-del-plato-no-converge-ni-siquiera-tras-varias-pasadas-necesito-mas-puntos">Mi malla del plato no converge, ni siquiera tras varias pasadas. ¿Necesito más puntos?</h3>
<p>Casi nunca. Una malla que no converge suele estar compensando un error de geometría (topes desiguales, ángulo de columna) o una calibración hecha en frío. Rehacer <code>DELTA_CALIBRATE</code> en caliente, luego la malla, con el mismo método de medida.</p>
<h3 id="como-se-si-mi-extrusor-empuja-la-cantidad-correcta">¿Cómo sé si mi extrusor empuja la cantidad correcta?</h3>
<p>Una raya en el filamento a 120 mm de la entrada del extrusor, <code>M83</code> y luego <code>G1 E100 F60</code>, medir lo que queda: 20 mm esperados. Aquí quedaban 31,5: un 11,5 % de subextrusión desde siempre. Nuevo <code>rotation_distance</code> = antiguo × extruido / 100.</p>
<h3 id="es-bueno-el-metodo-de-los-cuadrados-de-espesor-al-micrometro">¿Es bueno el método de los cuadrados de espesor al micrómetro?</h3>
<p>Está sesgado donde la boquilla está demasiado cerca: el cuadrado aplastado forma un labio levantado en su contorno, y el micrómetro lo lee «grueso». Si se empeñan, cuadrados de 20 mm medidos en el centro, topes lejos del borde. La espiral y el papel son más fiables.</p>
<h3 id="hay-que-tensar-las-correas-de-una-delta-a-una-frecuencia-precisa">¿Hay que tensar las correas de una delta a una frecuencia precisa?</h3>
<p>No. La frecuencia depende de la longitud del tramo, de la masa y de la composición de la correa; una misma nota no significa una misma tensión de una máquina a otra, y en una QQ-S el tramo es demasiado largo para medirlo. Aflojar, y volver a tensar hasta el umbral en que la correa vibra blandamente en vez de flotar, en las tres columnas. Y rehacer la calibración delta después.</p>
<h3 id="el-cubo-mide-203-en-vez-de-2000-en-xy-debo-calibrar-los-brazos">El cubo mide 20,3 en vez de 20,00 en XY: ¿debo calibrar los brazos?</h3>
<p>No si el exceso es constante. Compruébenlo en una pieza mayor (la pieza de siete pilares de Klipper, 65 mm entre ejes): si la escala es correcta, el exceso viene del ancho de cordón y se corrige en el slicer (multiplicador de extrusión, compensación XY). La calibración de los brazos corrige un error de escala, no un exceso constante.</p>
<h3 id="que-hizo-exactamente-la-ia-y-que-hizo-el-humano">¿Qué hizo exactamente la IA, y qué hizo el humano?</h3>
<p>Claude leyó la EEPROM y el archivo de pines de la placa, compiló y preparó el firmware, escribió la configuración y todos los scripts, generó la espiral, condujo las calibraciones y redactó este artículo conmigo. Se equivocó sobre el firmware (Marlin), sobre la causa del homing (varias horas), sobre la tensión de las correas y sobre el método de los cuadrados. Yo sostuve la hoja de papel, el calibre, el micrómetro y la cámara; leí las espirales; dije «antes funcionaba», «no es una cuerda» y «es repetible, no es el ajuste». Las tres veces era la pista correcta.</p>
<h2 id="pequeno-glosario">Pequeño glosario</h2>
<ul>
<li><strong>Delta</strong>: impresora en la que la boquilla va sujeta por tres brazos articulados sobre tres carros verticales; la posición se calcula, no se mide eje por eje.</li>
<li><strong>Efector</strong>: la pieza central que lleva la boquilla, al extremo de los brazos.</li>
<li><strong>Brazos (<code>arm_length</code>)</strong>, <strong>radio delta (<code>delta_radius</code>)</strong>, <strong>ángulo de columna</strong>, <strong>tope (<code>position_endstop</code>)</strong>: los parámetros de la geometría; ver el recuadro «qué corrige cada ajuste».</li>
<li><strong>Homing</strong>: enviar los carros arriba hasta sus interruptores, para conocer su posición.</li>
<li><strong>Bed mesh (malla del plato)</strong>: mapa de alturas del plato, medido en unos pocos puntos, que el firmware interpola para corregir la boquilla en continuo.</li>
<li><strong>Prueba del papel</strong>: bajar la boquilla hasta que una hoja de 0,1 mm roza justo; el Z = 0 queda entonces 0,1 mm por encima del cristal.</li>
<li><strong>Desfase de primera capa</strong>: pequeño desplazamiento en Z aplicado al inicio de cada impresión para ajustar el aplastamiento de la primera capa.</li>
<li><strong>Rotation distance</strong>: en Klipper, la distancia recorrida (o de filamento empujado) por vuelta de motor; sustituye a los pasos/mm.</li>
<li><strong>Pressure advance</strong>: compensación de la presión en el tubo bowden, que limpia las esquinas.</li>
<li><strong>PID</strong>: la regulación de temperatura; se recalibra con <code>PID_CALIBRATE</code>.</li>
<li><strong>Bowden</strong>: configuración en la que el motor del extrusor está en el chasis y empuja el filamento por un tubo largo hasta la boquilla; ligero para el efector, pero elástico.</li>
<li><strong>Thou</strong>: milésima de pulgada, 0,0254 mm. Los micrómetros antiguos están graduados así.</li>
<li><strong>Labio / pie de elefante</strong>: reborde en la base de una pieza, señal de una primera capa demasiado aplastada.</li>
<li><strong>PWM</strong>: señal cuadrada cuya anchura se modula; sirve aquí para fabricar una tensión de referencia para la corriente de los motores.</li>
<li><strong>EEPROM</strong>: la memoria del firmware original donde guarda sus ajustes.</li>
</ul>
<hr />
<h2 id="referencias">Referencias y copias locales</h2>
<p>Para que este artículo siga siendo útil cuando los enlaces hayan desaparecido, los archivos del proyecto están alojados aquí.</p>
<ul>
<li><strong>Klipper</strong>, documentación: <a href="https://www.klipper3d.org/Delta_Calibrate.html">Delta Calibrate</a> · <a href="https://www.klipper3d.org/Bed_Mesh.html">Bed Mesh</a> · <a href="https://www.klipper3d.org/Bed_Level.html">Bed Level</a> · <a href="https://www.klipper3d.org/Manual_Level.html">Manual Level</a> · <a href="https://www.klipper3d.org/Pressure_Advance.html">Pressure Advance</a> · <a href="https://www.klipper3d.org/Resonance_Compensation.html">Resonance Compensation</a> · <a href="https://www.klipper3d.org/Config_Reference.html">Config Reference</a>. Las piezas de prueba (<code>square.stl</code>, <code>square_tower.stl</code>, <code>calibrate_size.stl</code>, <code>ringing_tower.stl</code>) están en <a href="https://github.com/Klipper3d/klipper/tree/master/docs/prints"><code>docs/prints/</code></a> del repositorio.</li>
<li><strong>Configuración Klipper de referencia</strong> para la QQ-S 2020 — <a href="https://github.com/Klipper3d/klipper/blob/master/config/printer-flsun-qqs-2020.cfg"><code>printer-flsun-qqs-2020.cfg</code></a> (sin las salidas de corriente de motor, a 6 de septiembre de 2026).</li>
<li><strong>Pines de la MKS Robin Mini</strong> en Marlin — <a href="https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.1.x/Marlin/src/pins/stm32f1/pins_MKS_ROBIN_MINI.h"><code>pins_MKS_ROBIN_MINI.h</code></a> (origen de los pines PWM de corriente).</li>
<li><strong>Hackaday</strong>, «Don&rsquo;t Tune Your 3D Printer To Middle &lsquo;C&rsquo; After All» — sobre la tensión de correas por frecuencia (<a href="https://hackaday.com/?s=belt+tension+middle+C">búsqueda en el sitio</a>).</li>
<li><strong>PrusaSlicer 2.8.1</strong>, última versión con AppImage para Linux — <a href="https://github.com/prusa3d/PrusaSlicer/releases/tag/version_2.8.1">releases</a>. Ejecutado en línea de comandos sin pantalla (<code>env -u DISPLAY</code>); añade sus propios comandos de calentamiento salvo si encuentra <code>M104</code>/<code>M140</code> reales en el G-code inicial.</li>
<li><strong>Los archivos del proyecto</strong>: <a href="https://pf.olibrio.fr/assets/flsun/printer.cfg"><code>printer.cfg</code></a> · <a href="https://pf.olibrio.fr/assets/flsun/calib.py"><code>calib.py</code></a> · <a href="https://pf.olibrio.fr/assets/flsun/klippy-client.py"><code>klippy-client.py</code></a> · <a href="https://pf.olibrio.fr/assets/flsun/send-gcode.sh"><code>send-gcode.sh</code></a> · <a href="https://pf.olibrio.fr/assets/flsun/start-klipper.sh"><code>start-klipper.sh</code></a> · <a href="https://pf.olibrio.fr/assets/flsun/watch-print.py"><code>watch-print.py</code></a> · <a href="https://pf.olibrio.fr/assets/flsun/build-firmware.sh"><code>build-firmware.sh</code></a> · <a href="https://pf.olibrio.fr/assets/flsun/make-spiral.py"><code>make-spiral.py</code></a> · perfiles <a href="https://pf.olibrio.fr/assets/flsun/slicer/"><code>slicer/</code></a> · <a href="https://pf.olibrio.fr/assets/flsun/README-flsun.md"><code>README-flsun.md</code></a> (el estado de la máquina y el manual del repositorio, en francés).</li>
<li><strong>Para memoria</strong>, la pista falsa: <a href="https://pf.olibrio.fr/assets/flsun/pour-memoire/fix-mesh.py"><code>fix-mesh.py</code></a>, <a href="https://pf.olibrio.fr/assets/flsun/pour-memoire/mesh-to-7.py"><code>mesh-to-7.py</code></a>, <a href="https://pf.olibrio.fr/assets/flsun/pour-memoire/first_layer_29.stl"><code>first_layer_29.stl</code></a>, y <a href="https://pf.olibrio.fr/assets/flsun/pour-memoire/analyze-delta.py"><code>analyze-delta.py</code></a> para la calibración extendida de los brazos, si algún día fuera necesaria.</li>
</ul>
<p><em>Fotos y medidas: mías. Firmware, configuración, scripts y redacción: con Claude. Este artículo también está disponible en <a href="https://pf.olibrio.fr/es/posts/flsun-qqs-delta-klipper-calibration.md">Markdown en bruto</a>.</em></p>]]></content:encoded>
    </item>
    <item>
      <title>Error 4202 en un Neato, “batería descargada”: el día en que mi aspiradora decidió que estaba muerta</title>
      <link>https://pf.olibrio.fr/es/posts/erreur-4202-neato-obsolescence.html</link>
      <guid isPermaLink="true">https://pf.olibrio.fr/es/posts/erreur-4202-neato-obsolescence.html</guid>
      <pubDate>Sat, 29 Aug 2026 12:00:00 +0000</pubDate>
      <description>Error 4202 en un Neato D8, D9, D10 o D800: la batería no está necesariamente muerta. Cómo hice hablar al chip bq40z50 del pack con un ESP32 de dos euros, lo que dijo, el giro del día siguiente y el nuevo intento.</description>
      <category>neato</category>
      <category>error 4202</category>
      <category>reparación</category>
      <category>batería</category>
      <category>bq40z50</category>
      <category>esp32</category>
      <category>smbus</category>
      <category>obsolescencia</category>
      <category>derecho a reparar</category>
      <category>diy</category>
      <content:encoded><![CDATA[<p><img src="https://pf.olibrio.fr/images/neato/pack-pads-da-cl.jpg" alt="Error 4202 en un Neato, “batería descargada”: el día en que mi aspiradora decidió que estaba muerta"></p>
<div class="tldr">
<p><strong>En dos minutos, si tu Neato parpadea en rojo con el error 4202</strong></p>
<ul>
<li><strong>El síntoma</strong>: luz roja, error 4202, «batería descargada», el robot se niega a cargar o a arrancar. En los D8, D9, D10 y D800, la aplicación (mientras existió) añadía que el <em>contador de cargas</em> de la batería estaba superado.</li>
<li><strong>Lo que significa</strong>: no necesariamente que la batería esté muerta. Contiene un chip que habla con el robot; es <strong>lo que ese chip cuenta</strong> lo que dispara el error. Cambiar las celdas (las «pilas» de dentro) no cambia lo que cuenta.</li>
<li><strong>Lo que encontramos</strong> al hacerlo hablar con un microcontrolador de dos euros: ninguna avería, ninguna protección activada, un contador en <strong>1547 ciclos</strong> y un «no me cargues» que no era más que su modo de reposo.</li>
<li><strong>Lo que hicimos</strong>: guardar una copia de su memoria y poner el contador a cero. El robot volvió a funcionar… un día. <strong>Actualización del 1 de septiembre</strong>: la causa real estaba en otra parte: una celda recuperada más débil que disparaba la protección de sobretensión en cada carga (240 veces en tres días). Tensión de carga bajada, medidor en modo aprendizaje, en observación (ver <a href="#ou-on-en-est">Dónde estamos</a>).</li>
<li><strong>Epílogo</strong>: las celdas originales «muertas», pasadas por el probador de capacidad, todavía dan de 1819 a 1916 mAh de los 2500 nominales. Tampoco tenían nada que reprocharse.</li>
<li><strong>Antes de comprar una batería</strong>: lee <a href="#pour-reproduire">Cómo reproducirlo</a>. Hacen falta un soldador, tres cables, un ESP32 y una tarde. Nada de programador del fabricante a 150 €, nada de contraseñas que romper.</li>
</ul>
<p><em>Este artículo pretende ser legible sin saber nada de electrónica: cada término técnico se explica la primera vez que aparece, y un glosario los recapitula al final. Los recuadros «Para ir al fondo» se despliegan para quienes quieran los registros, las direcciones y los bytes.</em></p>
</div>
<p><img alt="La placa electrónica del pack Neato, con la funda abierta: los pads C+ y C− en el centro y, a la derecha, los dos pequeños pads marcados DA y CL, con los cables amarillos ya soldados" src="https://pf.olibrio.fr/images/neato/pack-pads-da-cl.jpg" /></p>
<p><em>La placa del pack, una vez abierta la funda. Los dos pequeños pads marcados «DA» y «CL», a la derecha, son todo lo que necesitamos. Los grandes del centro, C+ y C−, son los que no se tocan.</em></p>
<h2 id="una-nube-apagada-y-luego-un-boton-que-muere">Una nube apagada, y luego un botón que muere</h2>
<p>Mi robot aspirador es un Neato D800. Un buen robot: un LIDAR giratorio (un pequeño radar láser que gira en la parte superior y mide las distancias a las paredes), un mapa de la casa, líneas prohibidas que se trazan en la aplicación, 600 € en su día. En 2023, Neato Robotics cerró. Vorwerk, la empresa matriz, mantuvo los servidores encendidos durante un tiempo —la «nube», es decir, los ordenadores remotos sin los cuales la aplicación, los mapas y la programación no funcionan— y luego anunció <a href="https://support.neatorobotics.com/support/solutions/articles/204000073686-announcement-6th-oct-2025">el 6 de octubre de 2025</a> (<a href="https://pf.olibrio.fr/assets/neato/refs/neato-announcement-2025-10-06.md">copia local</a>) que esa nube se apagaba. « <em>Your Neato robot will continue to function manually. Simply press the button once to launch a full house run.</em> » Un robot de 600 € degradado a aspiradora de un solo botón, por comunicado.</p>
<p>Y luego, unos meses más tarde, el propio botón dejó de responder. Luz roja, <strong>error 4202</strong>, «batería descargada». La aplicación, en sus últimos estertores, precisaba que el contador de cargas de la batería estaba superado y que había que sustituirla. Batería original: 90 €, cuando se encuentra. Compatible: de 30 a 50 €, con el riesgo, bien documentado en los foros, de que el robot la rechace.</p>
<p>Este artículo cuenta cómo pasamos de «robot muerto, batería muerta» a una batería que explica por sí misma lo que le pasa, sin comprar nada, con tres cables y un microcontrolador que cuesta lo que un café. Cuenta también una falsa esperanza, porque es lo que ocurre cuando se investiga de verdad. Se detiene en lo que esta investigación me habría costado hace tres años, antes de que una IA pudiera leerse un manual de 250 páginas por mí, y en el notable chip que gobierna esta batería. Y explica por qué esta historia me deja un regusto amargo sobre la manera en que fabricamos los objetos.</p>
<h2 id="primer-reflejo-las-celdas">Primer reflejo: las celdas</h2>
<p>Una batería de robot es una carcasa que contiene varias <strong>celdas</strong> —acumuladores de litio en formato 18650 (18 mm de diámetro, 65 mm de largo, el aspecto de una pila AA grande)— conectadas en serie y gestionadas por una pequeña placa electrónica. Una batería «descargada» que ya no se recarga son, clásicamente, celdas muertas. Así que hice lo que hace cualquier manitas: abrí el pack, desoldé las cuatro celdas, soldé en su lugar cuatro celdas recuperadas —desparejadas, lo que tendrá su importancia más adelante— y lo cerré.</p>
<p>Resultado: <strong>error 4202, igual que antes.</strong></p>
<p>Y sin embargo, multímetro en mano (el aparato que mide la tensión, es decir, la «presión» eléctrica, en voltios), todo era perfecto. 4,1 V en cada celda, que es una celda de litio llena; 16,4 V en los bornes del pack; 16,4 V <em>en el conector de salida</em>, lo que significa que el circuito de protección —el interruptor electrónico capaz de aislar las celdas en caso de peligro— dejaba pasar la corriente. El termistor (una resistencia cuyo valor cambia con la temperatura, que el robot lee para vigilar la batería) marcaba 6 kΩ, un valor normal para una habitación templada. El robot tenía entre manos una batería cargada al 95 % y en buen estado, y mostraba «batería descargada».</p>
<p>Es el momento en que uno comprende que el problema no es la batería. Es <strong>lo que la batería dice de sí misma</strong>.</p>
<details>
<summary>Para ir al fondo: medir sin quemarse</summary>
<p>El pack es de 14,4 V nominales (cuatro celdas en serie, «4S»), 16,8 V cargado. No es una tensión peligrosa para la piel, pero un <strong>cortocircuito</strong> —unir directamente el más y el menos— en unas 18650 deja pasar decenas de amperios: suficiente para soldar unas pinzas, fundir una funda o incendiar una celda. Reglas simples: ni pulsera ni anillo, una sola herramienta metálica a la vez, y se mide en los <strong>pads B+ / B−</strong> (lado celdas) o <strong>C+ / C−</strong> (lado conector) sin unirlos nunca. El termistor (una NTC de 10 kΩ a 25 °C: su resistencia <em>baja</em> cuando hace calor) se lee entre el cable de temperatura y el menos.</p>
<p>Si la tensión es buena del lado de las celdas pero nula en el conector, es que el circuito de protección ha cortado: ahí sí es el chip el que ha decidido, y estamos de lleno en el tema de este artículo.</p>
</details>
<h2 id="la-bateria-tiene-cerebro">La batería tiene cerebro</h2>
<p>Los packs de los Neato de última generación (D8, D9, D10, D800) son «baterías inteligentes» (<em>smart batteries</em>): junto a las celdas, la pequeña placa lleva un <strong>medidor de carga</strong> (<em>gas gauge</em>), un chip —un circuito integrado, una minúscula lámina de silicio que contiene un ordenador especializado— de Texas Instruments, el <strong>bq40z50-R2</strong>. Es él quien mide la corriente, suma lo que entra y lo que sale, deduce el estado de carga, corta en caso de sobretensión o sobrecalentamiento, y es él quien <em>habla con el robot</em> a través de un <strong>bus serie</strong>: dos cables por los que circulan mensajes digitales, uno para los datos y otro para el reloj que marca el ritmo de la conversación. El protocolo (el idioma que se habla en esos cables) se llama <strong>SMBus</strong>, primo industrial del I²C que conocen todos los aficionados a Arduino. Un cable azul adicional en el conector del pack lleva esa conversación hasta el robot.</p>
<p>El robot no mide la tensión de la batería. Le <em>pregunta</em> al medidor: «¿a cuánto estás cargada?», «¿qué corriente de carga quieres?», «¿qué tensión?», «¿cuántos ciclos llevas?». Y obedece a lo que responde. Si el medidor dice «0 %» o «no me cargues», el robot muestra «batería descargada», sea cual sea la realidad eléctrica a tres centímetros de ahí.</p>
<p>Esta arquitectura no es absurda: un medidor dentro del pack conoce el historial de las celdas, gestiona su equilibrado (mantener las cuatro celdas al mismo nivel de carga, sin lo cual la más débil se desgasta primero) y protege eficazmente contra la fuga térmica (la reacción en cadena que hace arder una celda de litio maltratada). Pero tiene una consecuencia: <strong>sustituir las celdas no pone el medidor a cero.</strong> El contador de ciclos, la capacidad aprendida, los indicadores de error (<em>flags</em>: casillas de «sí/no» que el chip marca cuando detecta un problema): todo eso vive en la memoria del chip, no en las celdas. Se cambia el corazón, el cerebro conserva sus recuerdos.</p>
<p>En los foros, la pista suele terminar aquí. Los chips de los packs D3–D7 son de un fabricante oscuro y están bloqueados; para los bq40z50 «hace falta un EV2400 y bqStudio» —el adaptador oficial de Texas Instruments, 150 €, y su software para Windows— y nadie sabe realmente qué datos comprueba el robot. Fin de la historia, compra una batería.</p>
<details>
<summary>Para ir al fondo: SMBus, SBS y lo que «smart battery» quiere decir</summary>
<p>El <em>Smart Battery System</em> (SBS) es una norma de los años noventa, nacida para los ordenadores portátiles. Una batería SBS es un periférico en la <strong>dirección</strong> SMBus <code>0x0B</code> —en un bus compartido, cada chip tiene un número para saber con quién se habla; la notación <code>0x…</code> significa que el número está escrito en hexadecimal, en base 16, la costumbre de los informáticos— que responde a un centenar de <strong>comandos</strong> estandarizados, cada uno designado por un número: <code>0x09</code> tensión, <code>0x0A</code> corriente, <code>0x0D</code> estado de carga relativo (RSOC, el «porcentaje de batería»), <code>0x10</code> capacidad a plena carga, <code>0x17</code> contador de ciclos, <code>0x14</code> / <code>0x15</code> corriente y tensión de carga <em>solicitadas</em>… Lo que devuelve un comando se llama <strong>registro</strong>: una pequeña casilla de memoria legible desde fuera. Un cargador «inteligente» lee esos dos últimos registros y suministra exactamente lo que se le pide. A cero, no suministra nada.</p>
<p>El bq40z50 añade por encima un comando comodín, <code>ManufacturerBlockAccess</code> (<code>0x44</code>), a través del cual se leen los registros de estado internos (estado de seguridad, fallos permanentes, estado de los transistores) y, con acceso suficiente, <strong>toda la memoria flash de configuración</strong> —la memoria que sobrevive al apagado, como una memoria USB—, 8 KB de direcciones <code>0x4000</code> a <code>0x5FFF</code>, donde viven el contador de ciclos, la capacidad nominal, los umbrales de protección y medio centenar de opciones.</p>
<p>Existen tres niveles de acceso: <em>Sealed</em> (sellado, solo lectura de los registros estándar), <em>Unsealed</em> (desbloqueado con una clave de 32 bits) y <em>Full Access</em> (todo, incluida la escritura en la flash, tras una segunda clave). TI recomienda sellar antes de salir de fábrica.</p>
</details>
<h2 id="tres-cables-y-un-esp32-de-dos-euros">Tres cables y un ESP32 de dos euros</h2>
<p>Solo que el bq40z50 es un chip documentado públicamente. Texas Instruments publica su <em>Technical Reference Manual</em>, el manual de referencia: 250 páginas que describen cada registro, cada comando, cada dirección de memoria (<a href="https://pf.olibrio.fr/assets/neato/refs/bq40z50-r2-trm-sluubk0b.pdf">copia local del PDF</a>, 1,6 MB). Y el SMBus lo sabe hablar cualquier <strong>microcontrolador</strong> —un ordenador completo en un chip, unos pocos euros, el que se encuentra en una placa Arduino— en cuanto tiene dos pines I²C.</p>
<p>Tengo un cajón lleno de ESP32-C3 «Super Mini»: una placa del tamaño de un sello, dos euros la unidad, que se conecta por USB y se programa como un Arduino.</p>
<p><img alt="La cara inferior de un ESP32-C3 Super Mini: de arriba abajo los pines 5V, G, 3.3, 4, 3, 2, 1, 0; usamos G, 4 y 5" src="https://pf.olibrio.fr/images/neato/esp32c3-supermini-pinout.jpg" /></p>
<p>En la placa del pack, dos <strong>pads de prueba</strong> —puntos de contacto dejados a propósito por el fabricante para conectar sus aparatos de control al final de la cadena de montaje— llevan serigrafiadas las marcas <strong>DA</strong> y <strong>CL</strong>: <em>data</em> y <em>clock</em>, los dos cables del SMBus. Un cable en DA, otro en CL, otro en el menos de las celdas, y al otro lado los pines GPIO 4, GPIO 5 (GPIO: los pines de entrada-salida numerados de un microcontrolador) y GND (la masa, el «cero voltios» común) del ESP32. Ningún componente que añadir, ninguna alimentación que suministrar: el medidor se alimenta de sus celdas y el ESP32 de su USB.</p>
<p><img alt="Esquema de cableado: GPIO 4 del ESP32-C3 al pad DA, GPIO 5 a CL, GND al menos de las celdas; C+ a 16,4 V no se toca nunca" src="https://pf.olibrio.fr/images/neato/cablage-esp32c3-bq40z50.svg" /></p>
<p>En cuanto al software, doscientas líneas en Arduino, escritas con una IA (Claude) que se leyó el manual por mí: se leen los registros estándar (tensión, corriente, estado de carga, contador de ciclos, tensiones por celda), luego los registros de estado internos —estado de seguridad, fallos permanentes, estado de los transistores de carga y descarga— y después se copia la memoria flash. <strong>No se escribe nada sin una orden explícita.</strong> Escuchamos.</p>
<details>
<summary>Para ir al fondo: el cableado, los pull-ups y el código</summary>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Pack (placa BMS)</th>
<th>ESP32-C3 Super Mini</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pad <strong>DA</strong> (SMBus data)</td>
<td>GPIO 4 (SDA)</td>
</tr>
<tr>
<td>Pad <strong>CL</strong> (SMBus clock)</td>
<td>GPIO 5 (SCL)</td>
</tr>
<tr>
<td>Cable negro (− de las celdas, pad B−)</td>
<td>G (GND)</td>
</tr>
</tbody>
</table></div>
<p>El SMBus necesita resistencias de polarización (<em>pull-up</em>: tiran suavemente de cada línea hacia 3,3 V cuando nadie habla, sin lo cual la señal flota) en ambas líneas. Las resistencias internas del ESP32 (≈ 45 kΩ) bastaron aquí a 100 kHz sobre diez centímetros de cable; si el chip no responde al escaneo I²C, añade dos de 4,7 kΩ entre cada línea y los 3,3 V del ESP32. El medidor tolera 3,3 V en sus líneas de bus; <strong>nunca</strong> se conectan los 3,3 V ni los 5 V del ESP32 al pack.</p>
<p>El sketch —así llama Arduino a un programa— (<a href="https://pf.olibrio.fr/assets/neato/bq40z50-reader.cpp"><code>bq40z50-reader.cpp</code></a>, <a href="https://pf.olibrio.fr/assets/neato/platformio.ini"><code>platformio.ini</code></a>) corre en bucle: cada diez segundos, una lectura completa por el <strong>puerto serie</strong> (el canal de texto entre la placa y el ordenador, que se lee en un «monitor serie») a 115200 baudios (la velocidad del enlace). Solo escribe en el medidor con tres letras tecleadas en el monitor: <code>r</code> (reinicio del chip), <code>c</code> (contador de ciclos a cero), <code>C</code> (contador restaurado a su valor original). Todo lo demás es lectura.</p>
</details>
<h2 id="lo-que-dijo-el-chip">Lo que dijo el chip</h2>
<p>Primera lectura, en el monitor serie:</p>
<pre><code>Voltage            : 16386 mV
RSOC               : 97 %
RemainingCapacity  : 2343 mAh
FullChargeCapacity : 2437 mAh
DesignCapacity     : 2500 mAh
CycleCount         : 1547
ChargingCurrent    : 0 mA
ChargingVoltage    : 0 mV
Cellules           : 4094 / 4097 / 4100 / 4095 mV
ManufacturerName   : BLUEWAY-
DeviceName         : bq40z50-
ManufactureDate    : 2022-01-09
OperationStatus    : PRES DSG CHG SEC0  -&gt; sécurité : FULL ACCESS
SafetyStatus       : (aucun flag)
PFStatus           : (aucun flag)
</code></pre>
<p>Para leer este informe: mV y mA son milivoltios y miliamperios (milésimas de voltio y de amperio); los mAh, miliamperios-hora, miden una cantidad de energía almacenada —2437 mAh es lo necesario para suministrar 2,4 A durante una hora—; RSOC es el porcentaje de batería que se muestra; <em>FullChargeCapacity</em> es lo que el medidor cree poder almacenar hoy, <em>DesignCapacity</em> lo que el pack almacenaba nuevo.</p>
<p>Tres cosas saltan a la vista.</p>
<p><strong>El medidor está en plena forma.</strong> Ningún fallo de seguridad, ningún fallo permanente, transistores de carga y descarga conduciendo (los <strong>transistores</strong>, o FET, son los interruptores electrónicos con los que el medidor autoriza o corta la carga y la descarga), estado de carga estimado en el 97 %, coherente con los 4,1 V por celda. No está «descargada», y lo sabe.</p>
<p><strong>Ni siquiera está bloqueado.</strong> El nivel de seguridad es <em>FULL ACCESS</em>: el modo más permisivo del chip, el que TI recomienda abandonar antes de salir de fábrica. Sin contraseña que romper, sin clave que adivinar. Toda la memoria es legible y escribible. El fabricante del pack entregó la casa con las llaves puestas en la puerta.</p>
<p><strong>Y sin embargo le dice al robot que no la cargue.</strong> <code>ChargingCurrent = 0 mA</code>, <code>ChargingVoltage = 0 mV</code>. Son los dos registros que un cargador inteligente lee para saber qué hacer. A cero, significan: «no envíes corriente».</p>
<p>Y el contador: <strong>1547 ciclos</strong>. Un ciclo, para un medidor, es una descarga acumulada equivalente a una batería entera: dos medias descargas hacen un ciclo. Para una batería fabricada en enero de 2022, es un ciclo al día durante cuatro años, plausible para un robot que pasa a diario. Es también el número que la aplicación me había reprochado.</p>
<details>
<summary>Para ir al fondo: leer los indicadores de estado</summary>
<p><code>OperationStatus</code> (comando <code>0x44</code> + <code>0x0054</code>) es una palabra de 32 <strong>bits</strong> —treinta y dos casillas que valen 0 o 1, cada una un indicador—. Los que cuentan aquí: <code>PRES</code> (el robot está detectado), <code>DSG</code> y <code>CHG</code> (transistores de descarga y carga conduciendo), <code>SEC1:SEC0</code> (nivel de seguridad: <code>01</code> = Full Access, <code>10</code> = Unsealed, <code>11</code> = Sealed), <code>PF</code> (fallo permanente: el pack se ha autocondenado), <code>XCHG</code> / <code>XDSG</code> (carga / descarga prohibidas), <code>SLEEP</code> (recuerda este). <code>SafetyStatus</code> (<code>0x0051</code>) enumera las protecciones activas —sobretensión, subtensión, sobrecorriente, temperatura—; <code>PFStatus</code> (<code>0x0053</code>), los fallos permanentes, los que ningún reinicio borra: celda abierta, fusible fundido, desequilibrio irrecuperable. Todo estaba a cero.</p>
</details>
<h2 id="diecisiete-mil-lineas-de-manual-y-una-falsa-esperanza">Diecisiete mil líneas de manual, y una falsa esperanza</h2>
<p>La pregunta pasa a ser: <em>por qué</em> el medidor rechaza la carga. El manual de TI enumera con precisión los casos en que <code>ChargingVoltage()</code> cae a cero: transistor de carga cortado por una protección, temperatura fuera de rango, fallo permanente, pack declarado «retirado», sobretensión del cargador detectada. Los comprobamos todos, registro a registro. Ninguno estaba activo. Temperatura 26 °C, región de temperatura «recomendada», región de tensión «alta», todo en verde.</p>
<p>Exploramos también una pista seductora: el bq40z50 tiene una función de <em>degradación por contador de ciclos</em>, que reduce voluntariamente la tensión y la corriente de carga a medida que el pack envejece: una obsolescencia programada en sentido literal, activable con un bit de configuración. Leímos ese bit en la memoria flash. <strong>Estaba a cero.</strong> Neato no la había activado. La tabla de carga decía 4,2 V por celda y 1,5 A en todos los rangos de temperatura. Sobre el papel, el medidor debía anunciar 16,8 V y 1500 mA. Anunciaba 0 y 0.</p>
<p>Antes de ir más lejos, hicimos lo que siempre hay que hacer antes de tocar una memoria que no se podrá volver a comprar: <strong>una copia de seguridad completa.</strong> 8 KB, 256 bloques de 32 bytes (un byte son ocho bits, la unidad mínima de memoria), leídos uno a uno y guardados en un archivo (<a href="https://pf.olibrio.fr/assets/neato/refs/bq40z50-df-backup-neato-blueway-20260829.txt">aquí está</a>, por si el tuyo es el mismo pack). Si una escritura sale mal, se puede restaurar todo.</p>
<p>Luego probamos la cosa más tonta del mundo. El manual documenta un comando <code>0x0041 : Reset</code> —reinicio del chip: su memoria RAM (la memoria de trabajo, que se borra en cada reinicio) se reconstruye desde la flash, no se escribe nada—. El equivalente de «¿has probado a apagarlo y volverlo a encender?». Una letra <code>r</code> enviada por el monitor serie, tres segundos de espera:</p>
<pre><code>&gt;&gt;&gt; Envoi MAC 0x0041 Reset
ChargingCurrent    : 1500 mA
ChargingVoltage    : 16800 mV
RSOC               : 97 %
FET DSG ON, FET CHG ON, PF inactif
</code></pre>
<p>Victoria, creímos. Pack montado de nuevo, robot en su base: se acabó el error, carga, anuncia que está listo. Escribí una primera versión de este artículo esa misma noche, con una conclusión triunfal sobre el contador de ciclos del que «el robot nunca se había preocupado».</p>
<p><strong>A la mañana siguiente, luz roja, error 4202.</strong></p>
<h2 id="el-sintoma-que-desaparece-cuando-se-le-mira">El síntoma que desaparece cuando se le mira</h2>
<p>Pack conectado de nuevo al ESP32. <code>ChargingCurrent : 0 mA</code>, otra vez. Reinicio: 1500 mA. Y ahí, en lugar de cantar victoria, lo dejamos correr y miramos el reloj.</p>
<p>A los 3 segundos: 1500 mA. A los 20 segundos: 1500 mA. A los 31 segundos: <strong>0 mA</strong>, y en la misma lectura un indicador que no estaba diez segundos antes: <code>SLEEP</code>. Dos intentos, dos lecturas completas comparadas línea a línea: entre los 20 y los 31 segundos, lo <em>único</em> que cambia es ese indicador.</p>
<p>El medidor <strong>se duerme</strong>. En cuanto casi no circula corriente (menos de 10 mA, umbral fijado en su configuración), pasa a reposo para ahorrar sus celdas, y en ese estado anuncia «corriente de carga: 0». El reinicio no reparaba nada: lo <em>despertaba</em> treinta segundos. En el banco de trabajo, con un ESP32 que no consume nada, se volvía a dormir enseguida. En el robot, que tira unos cientos de miliamperios, está despierto y anuncia 1500 mA. El «no me cargues» nunca fue el problema. Era un espejismo de laboratorio.</p>
<p><img alt="El laboratorio del día siguiente: en un sofá, el pack Neato bajo cinta kapton amarilla, unido por tres cables a un ESP32-C3, conectado a su vez por USB a un portátil cuya pantalla muestra las lecturas del medidor" src="https://pf.olibrio.fr/images/neato/labo-canape-esp32-pack.jpg" /></p>
<p><em>El laboratorio de la mañana siguiente: un sofá, el pack bajo kapton (la cinta adhesiva amarilla que aísla y resiste el calor), el ESP32 al extremo de tres cables y un terminal que compara las lecturas a diez segundos de intervalo.</em></p>
<p>Es una lección que ya conocía y que aun así tuve que reaprender: cuando un síntoma desaparece <em>en el momento en que se le observa</em>, probablemente es la observación la que lo ha hecho desaparecer. Hay que mirar lo que vuelve, no lo que se va.</p>
<details>
<summary>Para ir al fondo: la configuración de reposo, y una documentación imprecisa</summary>
<p>En la flash, <code>DA Configuration</code> (<code>0x4A7D</code>) vale <code>0x001F</code>: cuatro celdas, <strong>NR = 1</strong> (pack declarado no extraíble), <strong>IN_SYSTEM_SLEEP = 1</strong> y <strong>SLEEP = 1</strong>. <code>Sleep Current</code> (<code>0x48A3</code>) = 10 mA, <code>Bus Timeout</code> = 5 s. El TRM (§ 4.12, tabla de condiciones de <code>ChargingVoltage() = 0</code>) solo prevé la puesta a cero en reposo si <code>FET Options[SLEEPCHG] = 0</code>; aquí <code>FET Options</code> (<code>0x4887</code>) vale <code>0x7D</code>, así que SLEEPCHG = 1, y de hecho el transistor de carga sigue conduciendo en reposo. La puesta a cero de <code>ChargingCurrent()</code> / <code>ChargingVoltage()</code> se produce de todos modos. El comportamiento real tiene la última palabra sobre la documentación: una razón más para medir.</p>
<p>Esta configuración es la de fábrica, no se ha movido: el robot siempre ha vivido con un medidor que se duerme a la menor pausa. El Neato lo despierta simplemente consumiendo.</p>
</details>
<h2 id="el-contador">El contador</h2>
<p>Quedaba el sospechoso inicial, el que la aplicación había nombrado: <strong>1547 ciclos</strong>. Al medidor le da igual: la degradación por ciclos está desactivada, lo comprobamos. Pero el robot lee ese número (<code>CycleCount</code>, comando <code>0x17</code>), y un software embebido (un <strong>firmware</strong>: el programa grabado en el robot) que muestra «contador de cargas superado» tiene por fuerza un umbral en alguna parte.</p>
<p>El contador es un simple valor de dos bytes en la flash, en la dirección <code>0x4340</code>. En Full Access, se escribe como se ha leído: un comando de bloque, la dirección, dos bytes. Escribimos cero.</p>
<pre><code>&gt;&gt;&gt; CycleCount SBS avant = 1547 ; écriture DF 0x4340 = 0
&gt;&gt;&gt; relecture 0x4340 : 00 00  (OK)
&gt;&gt;&gt; CycleCount SBS après écriture = 0
</code></pre>
<p>Inmediato, sin reinicio, sin ningún indicador de seguridad activado. Una batería nueva, a ojos de quien solo mira ese número.</p>
<details>
<summary>Para ir al fondo: escribir en la data-flash</summary>
<p>TRM § 14.1.67: una escritura en flash es un <em>SMBus block write</em> (el envío de un paquete de bytes de una vez) sobre el comando <code>0x44</code>, cuyo bloque es la dirección de inicio (en <em>little-endian</em>: primero el byte de menor peso) seguida de 1 a 32 bytes de datos. Para <code>CycleCount = 0</code>: <code>0x44</code>, longitud 4, <code>0x40 0x43 0x00 0x00</code>. A continuación se relee el bloque (block write de la dirección sola, luego block read de <code>0x44</code>, que devuelve la dirección y 32 bytes) para verificar. El valor SBS <code>0x17</code> siguió sin reinicio. El comando <code>C</code> del sketch restaura <code>0x0B 0x06</code> (1547) si se quiere volver atrás.</p>
<p>Lo que <strong>no</strong> tocamos, y por qué: <code>Qmax</code> (la capacidad química de las celdas tal como el medidor la ha aprendido, <code>0x4306…0x430E</code>, cinco veces 2650 mAh) y la tabla de resistencias internas datan de las celdas originales; <code>Design Capacity</code> (<code>0x48E5</code>) vale 2500 mAh; el estado de salud que anuncia el medidor (<code>FullChargeCapacity / DesignCapacity</code>) oscila por tanto entre el 73 % y el 92 % según la hora. Se podría hacer trampa bajando <code>Design Capacity</code>, o forzar <code>Qmax</code>. Preferimos dejar que el medidor reaprenda honestamente sobre ciclos completos; ver más abajo. El mapa completo de la flash, decodificado, está <a href="https://pf.olibrio.fr/assets/neato/refs/bq40z50-df-map-neato.md">aquí</a>.</p>
</details>
<h2 id="rebondissement">El giro</h2>
<p>1 de septiembre por la noche: luz roja. Error 4202. El robot había aguantado un día.</p>
<p>Tercera vez que se repite el guion: se toca el pack, se vuelve a conectar, el robot arranca, y al día siguiente se para. Reiniciar el medidor había «funcionado» una noche; poner el contador a cero, un día y unos ciclos. Mirado de cerca, esas dos «victorias» tienen algo en común que no es la corrección: cada vez <strong>se desconectó y se volvió a conectar el pack</strong>. El robot se reinicia, olvida su estado «batería descargada», vuelve a intentarlo… y tropieza con la misma causa, que no habíamos encontrado.</p>
<p>Esta vez, antes de cualquier reinicio, el pack fue al ESP32 tal cual. Contador de ciclos: sigue en 0. Ninguna protección activa, ningún fallo permanente, medidor en plena forma: la misma lectura tranquilizadora de la primera noche. Solo que habíamos aprendido a desconfiar de las lecturas tranquilizadoras, y fuimos a leer una zona de la flash que nunca habíamos decodificado: los <strong>datos de vida</strong> (<em>Lifetimes</em>), el diario que el medidor lleva sobre sí mismo desde que salió de fábrica: tensiones extremas vistas por cada celda, cuántas veces ha saltado cada protección y en qué ciclo fue la última.</p>
<p>Comparada con la copia del 29 de agosto, decía esto:</p>
<pre><code>                              29 ago       1 sep
COV (sobretensión de celda)   6            246   (+240 en tres días)
Vmáx de por vida, celda 4     4213 mV      4293 mV   (umbral COV: 4225)
Terminaciones de carga válidas 21813       21813 (ninguna desde el cambio de celdas)
Celdas en reposo              —            3986 / 3986 / 3995 / 3939 mV
</code></pre>
<p>Doscientos cuarenta disparos de la protección de <strong>sobretensión</strong> en tres días, todos en la celda 4, y ni una sola carga llevada hasta el final. El pack original había visto seis en cuatro años.</p>
<p>La explicación cabe en una imagen. Cuatro celdas en serie son cuatro cubos que se llenan por la misma manguera: si uno es más pequeño, rebosa el primero. La celda 4 de mi juego de celdas recuperadas tiene menos capacidad que las otras tres: en reposo es la más baja (3,94 V frente a 3,99) y en carga es la primera en cruzar los 4,225 V. El medidor hace entonces su trabajo: corta el transistor de carga, espera a que la celda baje a 4,1 V, vuelve a abrir, vuelve a cortar un segundo después. Doscientas cuarenta veces. El cargador del robot, por su parte, ve una carga que nunca termina; al cabo de un rato su firmware saca la única conclusión que conoce: «batería descargada», 4202.</p>
<p>El contador de ciclos no tenía nada que ver, o no del todo. Para el pack original nunca lo sabremos: cambié dos cosas a la vez. Sus datos de vida, eso sí, muestran 67 subtensiones, la última en el ciclo 1547; la celda de 41 mΩ hundiéndose en plena aspiración es una explicación al menos tan buena como el contador. El código 4202 es un cajón de sastre.</p>
<p><strong>El nuevo intento.</strong> La solución limpia es pasar las cuatro celdas recuperadas por el probador, como las originales, y montar un pack con las cuatro celdas mejor emparejadas de las ocho. Mientras tanto, el medidor permite un parche sin soldador, siempre por los tres cables, y eso es lo que hicimos esa misma noche:</p>
<ul>
<li><strong>tensión de carga bajada de 4200 a 4100 mV por celda</strong>: el pack se detiene en 16,4 V en lugar de 16,8; la celda 4 se queda por debajo del umbral de sobretensión, a cambio de un 10 % de autonomía;</li>
<li><strong>capacidad de referencia reducida a 2100 mAh</strong> (se había quedado en 2500, la del pack nuevo), capacidad química de las celdas alineada con ella;</li>
<li><strong>medidor puesto de nuevo en modo aprendizaje</strong>: sus valores aprendidos (capacidad química, tabla de resistencias) databan de las celdas de 2022; un bit le dice que lo reaprenda todo en los próximos ciclos.</li>
</ul>
<p>Reinicio: el medidor anuncia 16 400 mV y 1500 mA, una capacidad a plena carga estimada de 1792 mAh, ningún fallo. Pack cerrado, robot en su base. Esta vez no cantamos victoria: esperamos unos días y volveremos a abrir el diario del medidor. Si el contador de sobretensiones sigue en 246, era eso.</p>
<details>
<summary>Para ir al fondo: los datos de vida, y lo que escribimos</summary>
<p>La zona <em>Lifetimes</em> ocupa la flash de <code>0x4380</code> a <code>0x43F7</code> (TRM cap. 18): tensiones mín/máx de cada celda (<code>0x4380</code>), luego para cada protección un contador de eventos y el contador de ciclos en el último evento —COV en <code>0x43A0</code>/<code>0x43A2</code>, CUV en <code>0x43A4</code>/<code>0x43A6</code>, etc.—, después las terminaciones de carga válidas (<code>0x43D0</code>), las actualizaciones de Qmax/Ra (<code>0x43D4</code>…), el tiempo de funcionamiento. El umbral COV está en <code>0x494E</code> (4225 mV aquí, retardo 1 s, recuperación 4100 mV en <code>0x4959</code>).</p>
<p>Escrituras del 1 de septiembre, todas releídas después: tensión de carga por celda en las cinco regiones de temperatura del algoritmo de carga (<code>0x4A19</code>, <code>0x4A21</code>, <code>0x4A29</code>, <code>0x4A31</code>, <code>0x4A39</code>: 4200 → 4100); <em>Design Capacity</em> <code>0x48E5</code> = 2100 mAh y <code>0x48E7</code> = 3024 cWh; <em>Qmax</em> celdas 1–4 y pack <code>0x4306</code>–<code>0x430E</code> = 2100; <em>Qmax Cycle Count</em> <code>0x4310</code> = 0; <em>Update Status</em> <code>0x4312</code> = 0x04 (Impedance Track activo, «aún no aprendido»: el medidor rehará Qmax y luego la tabla Ra en los próximos ciclos, TRM 15.13.8.2 y 6.4.6); después reinicio <code>0x0041</code>. Comprobado antes de escribir: las banderas de «carga completa» (FC/TC) se activan aquí por terminación de carga válida (corriente por debajo de 130 mA, celda a menos de 75 mV de la tensión de carga), no por un umbral fijo de 4200 mV; bajar la tensión no las rompe. Margen en la celda 4: unos treinta milivoltios por debajo del umbral; el sketch tiene un comando para bajar a 4050 si no basta. Comandos: <code>v</code>/<code>w</code>/<code>V</code> (tensión 4100 / 4050 / 4200), <code>d</code>/<code>D</code> (capacidad y aprendizaje / valores de fábrica).</p>
</details>
<h2 id="ou-on-en-est">Dónde estamos</h2>
<div class="status">
<p><strong>Estado a 1 de septiembre de 2026: en observación.</strong> El error 4202 volvió el 1 de septiembre tras un día de funcionamiento; la causa real es una celda recuperada más débil que disparaba la protección de sobretensión en cada carga, 240 veces en tres días (ver <a href="#rebondissement">El giro</a>). Parche aplicado esa misma noche por los tres cables: tensión de carga 4100 mV por celda, capacidad de referencia 2100 mAh, medidor en reaprendizaje. El robot está en su base; veredicto en unos días, al reabrir el diario del medidor: si el contador de sobretensiones no se ha movido, era eso. Sigue sin comprarse ninguna pieza.</p>
</div>
<p>Y luego está el epílogo que no vi venir. Las cuatro celdas <em>originales</em>, las que había desoldado al principio porque «la batería estaba muerta», andaban por el banco de trabajo. Por descargo de conciencia, las medí: <strong>3,6 V cada una.</strong> Ninguna está por debajo del umbral en el que una celda de litio se condena. Así que las pasé por el probador de capacidad: un Liitokala Lii-500, un cargador-analizador de unos treinta euros, en modo «NOR TEST»; carga la celda a tope, la descarga después a corriente constante contando los miliamperios-hora que salen, y vuelve a cargarla. Es la única forma honesta de saber lo que vale una celda: vaciarla con el cronómetro en marcha.</p>
<p>Veredicto, sobre celdas dadas por <strong>2500 mAh</strong> cuando eran nuevas:</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Celda</th>
<th>Capacidad medida</th>
<th>Porcentaje del nominal</th>
</tr>
</thead>
<tbody>
<tr>
<td>A</td>
<td>1916 mAh</td>
<td>77 %</td>
</tr>
<tr>
<td>B</td>
<td>1912 mAh</td>
<td>76 %</td>
</tr>
<tr>
<td>C</td>
<td>1855 mAh</td>
<td>74 %</td>
</tr>
<tr>
<td>D</td>
<td>1819 mAh</td>
<td>73 %</td>
</tr>
</tbody>
</table></div>
<p>El probador da también la <strong>resistencia interna</strong> de cada celda: la «fricción» eléctrica de la química, en miliohmios (mΩ). Cuanto más alta, más se hunde la tensión cuando el robot tira corriente, y más se calienta la celda en lugar de entregar. Tres celdas oscilan entre <strong>16 y 19 mΩ</strong>, un buen valor para unas 18650 de esa edad. La cuarta está en <strong>41 mΩ</strong>: más del doble. Es el eslabón débil del pack, la que se desploma primero en plena aspiración, arrastra a las demás hacia el umbral de corte y por tanto acorta la autonomía mucho más de lo que sus 1819 mAh dejarían suponer.</p>
<p>Pero ninguna está muerta. Tras algo así como 1547 ciclos, estas celdas todavía entregan tres cuartas partes de su capacidad original: una pérdida normal, la que se espera de un litio que llega al final de su vida anunciada. En la práctica, la autonomía habría pasado de la hora y media larga a poco más de una hora. Una aspiradora algo menos resistente, no una aspiradora muerta.</p>
<p>Ahí es donde la historia cobra sentido. El pack que desencadenó todo esto no estaba averiado: estaba <strong>gastado un 25 %</strong>, y algo —un contador, o más probablemente su celda de 41 mΩ hundiéndose en plena aspiración— decidió que se había acabado. El cambio de celdas que hice por primer reflejo probablemente no era necesario, y hecho con celdas recuperadas nunca medidas, añadió un problema (ver <a href="#rebondissement">El giro</a>); al menos me deja cuatro celdas originales en funcionamiento, medidas y documentadas, listas para servir de recambio el día en que las recuperadas fallen.</p>
<h2 id="lo-que-me-habria-costado-hace-tres-anos">Lo que me habría costado hace tres años</h2>
<p>Seamos honestos sobre el escalón que subí sin verlo.</p>
<p>Hace tres años, esta historia se habría detenido en el párrafo «Primer reflejo: las celdas». Celdas cambiadas, error todavía ahí, multímetro tajante: la batería está bien. ¿Y después? Después, un <strong>callejón sin salida</strong>. Habría buscado en los foros, encontrado los mismos hilos que todo el mundo —«hace falta un EV2400 y bqStudio», «el chip está bloqueado», «compra una batería»— y habría comprado, o guardado el robot en un armario a la espera de un valor que nunca llega.</p>
<p>Porque el resto del proceso, que aquí cabe en unos pocos párrafos, representa un trabajo que yo no habría podido aportar en tardes de aficionado. Pongámoslo sobre la mesa:</p>
<ol>
<li><strong>Identificar el chip</strong> y encontrar su manual: fácil.</li>
<li><strong>Leer el manual</strong>: 250 páginas, 17 000 líneas de inglés técnico denso, escritas para ingenieros de baterías que ya dominan el vocabulario. No se trata de hojearlo: hay que encontrar <em>las</em> tres tablas que dicen cuándo la corriente de carga cae a cero, el procedimiento de escritura en la flash, el mapa de las 400 direcciones de configuración, el significado de cada bit de una decena de registros de estado.</li>
<li><strong>Aprender el SMBus</strong> a nivel de protocolo (el <em>block read</em>, el <em>block write</em>, el comando <code>0x44</code> y su eco, el autoincremento de dirección) y escribir un programa que lo hable sin errores.</li>
<li><strong>Interpretar</strong> una lectura de cuarenta indicadores y 8 KB de bytes en bruto, cruzándolos con el manual.</li>
<li><strong>Diseñar los experimentos</strong>: el reinicio y luego —tras la falsa esperanza— la idea de comparar dos lecturas completas a diez segundos de intervalo para aislar <em>la</em> línea que cambia.</li>
<li><strong>Escribir</strong> en la flash sin romper nada.</li>
</ol>
<p>Para un desarrollador competente que no es ingeniero de baterías, son varias semanas de tardes, con un riesgo real de abandono en el punto 2, que es exactamente donde se detienen los hilos de los foros. No es que sea <em>difícil</em> en el sentido intelectual; es que es <em>largo</em>, y nada garantiza, de entrada, que esas semanas lleven a alguna parte.</p>
<p>Con Claude, los puntos 2 a 6 llevaron dos tardes y una mañana. La IA absorbió el manual en unos segundos, escribió el sketch de una pasada, decodificó los registros a medida que llegaban, propuso el reinicio y luego —cuando el reinicio mintió— propuso repetirlo grabándolo todo, y encontró el indicador <code>SLEEP</code> en la comparación. Lo que yo conservaba: el soldador, el multímetro, las fotos, las decisiones («no tocamos Qmax, dejamos que aprenda») y, sobre todo, la duda: fue la prueba de una noche en el robot de verdad la que desmintió la victoria, no una lectura más.</p>
<p>Dos matices, para no convertirlo en un cuento. Primero, la IA cofirmó la falsa esperanza: tenía la misma conclusión errónea que yo la primera noche, porque teníamos los mismos datos incompletos. Lee rápido, pero no mide por mí. Segundo, encontró un error en el propio manual (el reposo que pone la corriente a cero cuando la documentación dice lo contrario) únicamente porque <em>medimos</em> lo contrario; sin el ESP32 conectado, habría defendido la documentación.</p>
<p>Pero el desplazamiento es real, y me parece importante para la reparación en general: <strong>un saber que estaba encerrado en un manual de 250 páginas, y por tanto reservado a los profesionales, se vuelve accesible a alguien que sabe sostener un soldador y formular una pregunta.</strong> Los fabricantes cuentan, sin decirlo, con que nadie leerá el manual. Esa hipótesis acaba de caer.</p>
<h2 id="enfoque-el-bq40z50-el-chip-que-gestiona-tu-bateria">Enfoque: el bq40z50, el chip que gestiona tu batería</h2>
<p>Ya que hemos pasado dos días con él, presentémoslo. El bq40z50-R2 es lo que Texas Instruments llama un <em>battery pack manager</em>: un único chip, del tamaño de una uña (encapsulado QFN de 32 pines, con los contactos bajo el encapsulado), que hace todo lo que un pack de litio de 1 a 4 celdas en serie necesita. Se encuentra en buena parte de las baterías de portátiles de los últimos diez años, en herramientas eléctricas, robots, drones, baterías médicas.</p>
<h3 id="lo-que-hace">Lo que hace</h3>
<ul>
<li><strong>Medir</strong>: mide la corriente a través de una resistencia de medida (un <em>shunt</em>, unos pocos miliohmios) y la tensión de cada celda, y deduce el estado de carga con un algoritmo propio, <em>Impedance Track</em>: en lugar de limitarse a contar lo que entra y sale (lo que deriva con el tiempo), <strong>aprende</strong> la capacidad química real de las celdas (Qmax) y su resistencia interna en cada ciclo, y corrige permanentemente. Es lo que da los porcentajes precisos de los portátiles recientes.</li>
<li><strong>Proteger</strong>: integra el <em>AFE</em> (<em>analog front-end</em>: la parte analógica que vigila tensiones y corrientes en tiempo real, con independencia del software) y gobierna directamente los transistores de carga y descarga. Sobretensión y subtensión por celda, sobrecorriente en carga y en descarga, cortocircuito, sobrecalentamiento y baja temperatura, cada una con sus umbrales, sus retardos y sus condiciones de vuelta a la normalidad.</li>
<li><strong>Condenarse</strong>: una segunda familia de protecciones, los <em>fallos permanentes</em> (PF), corta definitivamente el pack —si hace falta, fundiendo un <strong>fusible químico</strong> irreversible— en caso de celda abierta, desequilibrio incorregible, transistor quemado o demasiadas sobretensiones repetidas.</li>
<li><strong>Equilibrar</strong>: durante la carga, descarga ligeramente las celdas adelantadas para que todas lleguen llenas a la vez.</li>
<li><strong>Recordar</strong>: contador de ciclos, temperaturas y tensiones extremas vistas a lo largo de su vida (<em>lifetime data</em>), y una <strong>caja negra</strong> que registra los últimos eventos de seguridad antes de un fallo permanente: material para hacer la autopsia de un pack muerto.</li>
<li><strong>Hablar</strong>: SMBus, todo el estándar SBS, más los comandos del fabricante. Y <strong>autenticarse</strong>: un mecanismo criptográfico (SHA-1 con una clave secreta) permite al aparato verificar que el pack es original. Es lo que bloquea las baterías compatibles en algunos aparatos.</li>
</ul>
<h3 id="sus-puntos-fuertes">Sus puntos fuertes</h3>
<ul>
<li><strong>Completo y documentado.</strong> Todo está en un solo encapsulado, y el manual lo describe todo: es lo que ha hecho posible esta investigación. Muchos chips de la competencia están documentados bajo acuerdo de confidencialidad, o no lo están en absoluto.</li>
<li><strong>Preciso.</strong> Impedance Track sigue siendo la referencia en medición de carga para el gran público; el error de estimación baja al 1 % en un pack bien configurado.</li>
<li><strong>Seguro por construcción.</strong> El AFE protege incluso si el software se cuelga; los fallos permanentes no se negocian.</li>
<li><strong>Ubicuo.</strong> Decenas de millones de unidades en packs de portátiles: abundan las placas, los archivos de configuración y las experiencias compartidas.</li>
<li><strong>Abrible.</strong> El software oficial bqStudio y el adaptador EV2400 existen, pero, como hemos visto, un microcontrolador de dos euros basta para leer, y a menudo para escribir.</li>
</ul>
<h3 id="sus-puntos-debiles">Sus puntos débiles</h3>
<ul>
<li><strong>Complejo de configurar.</strong> Más de 400 parámetros en flash. Hacer funcionar correctamente Impedance Track exige una «imagen de referencia» (<em>golden image</em>) construida en laboratorio: identificación de la química de las celdas, calibración, ciclo de aprendizaje completo. Un pack DIY mal configurado mide mal, y el <em>aprendizaje</em> que hemos elegido lleva varios ciclos.</li>
<li><strong>La seguridad depende del fabricante del pack.</strong> TI proporciona las cerraduras; es el ensamblador quien decide cerrarlas. El pack Neato se entregó en Full Access. Una batería de portátil de marca, en cambio, casi siempre está sellada, y sin las claves solo se leen los registros estándar.</li>
<li><strong>La seguridad, a la inversa, puede ser un muro.</strong> La autenticación SHA-1 y el sellado son precisamente lo que hace irreparables algunos packs: un fallo permanente en un pack sellado es basura, sea cual sea el estado de las celdas.</li>
<li><strong>No más de 4 celdas en serie.</strong> Para una bicicleta eléctrica (de 10 a 13 celdas en serie) hace falta su hermano mayor, el bq40z80 (hasta 7 en serie), u otra arquitectura.</li>
<li><strong>Difícil de cablear uno mismo.</strong> El encapsulado QFN se suelda en horno o con aire caliente, no con soldador; las placas de desarrollo de TI cuestan un centenar de euros. En la práctica, el DIY pasa por placas recuperadas.</li>
</ul>
<h3 id="lo-que-se-puede-hacer-con-el-fuera-del-neato">Lo que se puede hacer con él, fuera del Neato</h3>
<ul>
<li><strong>Diagnosticar una batería de portátil antes de tirarla.</strong> Un pack Dell, HP o Lenovo «muerto» contiene muy a menudo un bq40z50 (o un primo: bq30z55, bq40z80) y seis celdas de las que tres están bien. El ESP32 y el sketch de este artículo leen el estado de salud, el contador, los fallos, y dicen si son las celdas o el chip. En un pack sellado se lee menos, pero se lee.</li>
<li><strong>Rearmar un pack tras un cambio de celdas.</strong> Exactamente este artículo: contador, eventualmente fallo permanente (<code>PFStatus</code> se pone a cero por comando, en Full Access o con la clave), y luego ciclo de aprendizaje.</li>
<li><strong>Construir una «batería inteligente» para tus propios proyectos.</strong> Una placa BMS recuperada con su bq40z50, cuatro celdas 18650 nuevas, y se obtiene un pack de 14,4 V que se autoprotege, se equilibra y anuncia su porcentaje: para un robot DIY, una radio de campo, un SAI de respaldo para un servidor doméstico, una lámpara de obra.</li>
<li><strong>Vigilar una batería a distancia.</strong> El ESP32 tiene Wi-Fi: el mismo sketch puede publicar tensión, corriente, temperatura y estado de carga por MQTT (un protocolo de mensajes ligero, el estándar de la domótica) hacia Home Assistant o una base de datos. Un pack que avisa antes de fallar.</li>
<li><strong>Aprender.</strong> El bq40z50 es un curso completo de gestión de baterías de litio, con un manual gratuito y un chip que se encuentra en la basura. Todo lo que hace el BMS de un coche eléctrico, él lo hace en pequeño, y se deja mirar mientras lo hace.</li>
</ul>
<p>Una reserva: todo esto supone un pack <strong>abierto</strong> (no sellado) o del que se tienen las claves. Los fabricantes de portátiles sellan; los fabricantes de packs para robots, herramientas y juguetes, a menudo, se olvidan. Compruébalo antes de lanzarte: es la primera lectura, y no cuesta nada.</p>
<h2 id="lo-que-esto-cuenta">Lo que esto cuenta</h2>
<p>No creo que nadie, en Neato ni en su proveedor de baterías, <em>decidiera</em> que este robot moriría en 2026. Creo algo peor: nadie decidió que <em>viviría</em>.</p>
<p>Observemos las capas.</p>
<p><strong>La nube.</strong> El robot fue diseñado para no hacer nada sin un servidor. Cuando el servidor se apaga, solo queda el botón. En los D3 a D7, una comunidad consiguió conectar un ESP32 al puerto serie de la placa base y devolver a los robots su autonomía (<a href="https://github.com/vacuula/fang">vacuula/fang</a>, <a href="https://github.com/renjfk/OpenNeato">OpenNeato</a>). En los D8 a D10, ese puerto está <em>bloqueado con contraseña</em>. Una generación más tarde, la puerta se cerró con llave. No por la seguridad del usuario: por nada, al parecer, salvo para que no la toque.</p>
<p><strong>La batería autenticada.</strong> El robot verifica la identidad del pack. Los foros están llenos de D5 bloqueados tras insertarles una batería compatible. El fabricante lo llama seguridad; también es, muy concretamente, un peaje sobre la pieza de desgaste número uno.</p>
<p><strong>El contador.</strong> 1547 ciclos, y una aplicación que dice «a sustituir». No porque la batería esté fuera de uso —el propio medidor la daba cargada al 97 %, y las celdas originales, medidas desde entonces, todavía entregan del 73 al 77 % de su capacidad de fábrica—, sino porque un número ha cruzado un umbral que nadie te muestra. El robot fue puesto fuera de servicio por un cuarto de autonomía de menos.</p>
<p><strong>Y la ausencia de camino.</strong> Un chip perfectamente documentado, dejado en acceso total, cuyo contador se pone a cero con un comando. Ningún camino, en el producto, lleva a ese comando. El diagnóstico entregado al usuario es «batería descargada», que es falso, y la solución propuesta es «comprar», que es cara.</p>
<p>La obsolescencia, aquí, no es una bomba de relojería programada por un ingeniero cínico. Es una suma de no-decisiones: nadie presupuestó la función «reiniciar la batería», nadie escribió el mensaje de error honesto, nadie dejó un puerto abierto. Cada elección se justifica por separado. Su suma fabrica un residuo de 600 € con una batería cargada dentro.</p>
<p>La buena noticia es que las mismas no-decisiones dejan grietas. El chip no se bloqueó. El fabricante del pack dejó sus pads de prueba. TI publica su manual. Y un microcontrolador de dos euros, más una IA que acepta leer 17 000 líneas de documentación sin quejarse, bastan para colarse por ellas.</p>
<p>A partir del 18 de febrero de 2027, el artículo 11 del <a href="https://eur-lex.europa.eu/eli/reg/2023/1542/oj">reglamento europeo sobre baterías</a> (<a href="https://pf.olibrio.fr/assets/neato/refs/eu-regulation-2023-1542-article-11.md">extracto local</a>) exigirá que las baterías portátiles de los aparatos sean « <em>readily removable and replaceable by the end-user</em> ». Es un avance. Pero esta historia muestra que «sustituible» no basta: mi batería <em>era</em> sustituible, y precisamente la sustitución era lo que me vendían como única salida. Lo que habría que exigir es que los objetos <strong>digan la verdad sobre su estado</strong>, y que dejen un camino para corregirlo. Un botón «reiniciar la batería» en una aplicación cuesta una tarde de desarrollo. El silencio, en cambio, cuesta una batería a cada cliente.</p>
<h2 id="pour-reproduire">Cómo reproducirlo</h2>
<p><strong>Material</strong>: un ESP32-C3 Super Mini (o cualquier ESP32/Arduino con I²C), tres cables, un soldador y, eventualmente, dos resistencias de 4,7 kΩ. El pack debe estar abierto a la altura de su placa electrónica: la funda va pegada, un cúter la raja sin forzar.</p>
<p><strong>Seguridad</strong>: las celdas permanecen conectadas durante toda la operación. <strong>Ninguna herramienta metálica cerca de los pads C+ y C−</strong>, que llevan 16 V y varias decenas de amperios de cortocircuito posible. Ni pulsera, ni anillo. Los pads DA y CL, en cambio, están a 3,3 V y no corren ningún riesgo.</p>
<p><img alt="La otra cara de la placa del pack: los pads de prueba T1, T3, T6, T7 y HEAT, el cable rojo del más y el cable negro del menos" src="https://pf.olibrio.fr/images/neato/pack-bplus-bminus.jpg" /></p>
<p><em>La otra cara de la placa: no se toca, pero muestra que el fabricante previó muchos más puntos de prueba que los dos que nos interesan.</em></p>
<p><strong>Cableado</strong>:</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Pack (placa BMS)</th>
<th>ESP32-C3</th>
</tr>
</thead>
<tbody>
<tr>
<td>Pad <strong>DA</strong></td>
<td>GPIO 4 (SDA)</td>
</tr>
<tr>
<td>Pad <strong>CL</strong></td>
<td>GPIO 5 (SCL)</td>
</tr>
<tr>
<td>Cable negro (− celdas)</td>
<td>G (GND)</td>
</tr>
</tbody>
</table></div>
<p><strong>Software</strong>: <a href="https://pf.olibrio.fr/assets/neato/bq40z50-reader.cpp"><code>bq40z50-reader.cpp</code></a> y <a href="https://pf.olibrio.fr/assets/neato/platformio.ini"><code>platformio.ini</code></a> (PlatformIO es la herramienta que compila y sube el programa; entorno Arduino, destino <code>esp32-c3-devkitm-1</code>). Monitor serie a 115200 baudios. Los registros esenciales, en la dirección SMBus <code>0x0B</code>:</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Registro</th>
<th>Contenido</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>0x09</code> / <code>0x0A</code></td>
<td>tensión / corriente del pack</td>
</tr>
<tr>
<td><code>0x0D</code></td>
<td>estado de carga (RSOC, %)</td>
</tr>
<tr>
<td><code>0x10</code> / <code>0x18</code></td>
<td>capacidad a plena carga / capacidad nominal</td>
</tr>
<tr>
<td><code>0x14</code> / <code>0x15</code></td>
<td>corriente / tensión de carga solicitadas (0 en reposo: normal)</td>
</tr>
<tr>
<td><code>0x17</code></td>
<td>contador de ciclos</td>
</tr>
<tr>
<td><code>0x3C</code>–<code>0x3F</code></td>
<td>tensiones de las celdas 4 a 1</td>
</tr>
<tr>
<td><code>0x44</code> + <code>0x0054</code></td>
<td>OperationStatus (seguridad, FET, PF, SLEEP)</td>
</tr>
<tr>
<td><code>0x44</code> + <code>0x0053</code></td>
<td>PFStatus (fallos permanentes)</td>
</tr>
<tr>
<td><code>0x00</code> ← <code>0x0041</code></td>
<td>reinicio del medidor</td>
</tr>
<tr>
<td><code>0x44</code> ← <code>0x40 0x43</code> + 2 bytes</td>
<td>escritura del contador de ciclos (flash <code>0x4340</code>)</td>
</tr>
<tr>
<td><code>0x44</code> ← <code>0x80 0x43</code> … <code>0xE0 0x43</code></td>
<td>lectura de los datos de vida (flash <code>0x4380</code>–<code>0x43FF</code>): contadores COV/CUV, terminaciones de carga</td>
</tr>
<tr>
<td><code>0x44</code> ← <code>0x19 0x4A</code> + 2 bytes (×5)</td>
<td>tensión de carga por celda (flash <code>0x4A19</code>…<code>0x4A39</code>)</td>
</tr>
</tbody>
</table></div>
<p><strong>En orden</strong>: (1) conectar, leer, comprobar que <code>DeviceType</code> responde <code>0x4500</code> y que el nivel de seguridad es Full Access —si no, harán falta las claves del fabricante, y este artículo no las tiene—; (2) guardar la flash (el sketch lo hace al arrancar) y poner el archivo a buen recaudo; (3) leer <code>PFStatus</code> y <code>SafetyStatus</code> —un fallo permanente es otra historia—; (4) leer los datos de vida (<code>0x4380</code>…) y compararlos con la copia tras unos días en el robot: un contador COV o CUV que sube señala a una celda, no a un contador; (5) solo entonces, teclear <code>c</code>, y esperar varios días antes de concluir.</p>
<p>Tres reglas, si te pones a ello: leer primero, guardarlo todo después, escribir solo al final. Un medidor en <em>Full Access</em> se deja reparar tan fácilmente como destruir.</p>
<h2 id="preguntas-frecuentes">Preguntas frecuentes</h2>
<h3 id="que-significa-el-error-4202-en-un-neato">¿Qué significa el error 4202 en un Neato?</h3>
<p>Es el error «batería descargada» de los D8, D9, D10 y D800. La aplicación (cuando funcionaba) precisaba que el contador de cargas de la batería estaba superado y que había que sustituirla. Aparece incluso con celdas en perfecto estado: lo que lo dispara es lo que el chip del pack le cuenta al robot; en particular, según lo que hemos observado, un contador de ciclos demasiado alto.</p>
<h3 id="cambiar-las-celdas-del-pack-resuelve-el-error-4202">¿Cambiar las celdas del pack resuelve el error 4202?</h3>
<p>No por sí solo. El contador de ciclos y el estado de salud viven en el chip bq40z50 del pack, no en las celdas. Tras el cambio de celdas, el error persistía en mi caso con celdas a 4,1 V.</p>
<h3 id="hace-falta-un-ev2300ev2400-y-bqstudio-para-hablar-con-el-medidor">¿Hace falta un EV2300/EV2400 y bqStudio para hablar con el medidor?</h3>
<p>No. Un ESP32 (o un Arduino) con dos pines I²C, tres cables y el manual de TI bastan: el chip está documentado y, en los packs Neato que he visto, se deja en Full Access, sin contraseña. bqStudio es más cómodo, no necesario.</p>
<h3 id="una-bateria-compatible-del-mercado-resuelve-el-problema">¿Una batería compatible del mercado resuelve el problema?</h3>
<p>A veces, y a veces el robot la rechaza: los foros documentan D5 bloqueados tras insertar un pack compatible. Antes de comprar, cuesta una tarde comprobar que la batería original no ha superado simplemente un umbral de ciclos.</p>
<h3 id="es-peligroso">¿Es peligroso?</h3>
<p>Las líneas DA y CL están a 3,3 V y no entrañan riesgo. El peligro está en otra parte: los pads C+/C− y B+/B− a 16 V, capaces de decenas de amperios en cortocircuito. Una sola herramienta metálica a la vez, nada de joyas, y no se toca nada más que DA, CL y el menos.</p>
<h3 id="por-que-el-medidor-anuncia-0-ma-de-corriente-de-carga">¿Por qué el medidor anuncia 0 mA de corriente de carga?</h3>
<p>Porque duerme. En cuanto la corriente baja de 10 mA durante una treintena de segundos, entra en reposo y pone ChargingCurrent y ChargingVoltage a cero. En el robot, que consume permanentemente, se mantiene despierto. No es una avería, y un reinicio no «repara» nada: lo despierta treinta segundos.</p>
<h3 id="funciona-en-un-d3-d4-d5-d6-o-d7">¿Funciona en un D3, D4, D5, D6 o D7?</h3>
<p>Los packs de esas generaciones usan un chip diferente, bloqueado, y las investigaciones de la comunidad no han dado fruto. En cambio, su puerto serie está abierto, y vacuula/fang u OpenNeato devuelven a esos robots su autonomía sin la nube.</p>
<h3 id="se-puede-reutilizar-el-chip-bq40z50-de-una-bateria-vieja-en-otro-proyecto">¿Se puede reutilizar el chip bq40z50 de una batería vieja en otro proyecto?</h3>
<p>Sí, si el pack no está sellado o si se tienen sus claves. Una placa BMS recuperada con sus celdas sustituidas hace una batería inteligente de 1S a 4S para un robot, una radio o un SAI DIY; un ESP32 conectado a ella puede publicar su estado por MQTT hacia la domótica. Ver la sección «Enfoque: el bq40z50».</p>
<h3 id="que-hizo-exactamente-la-ia-y-que-hizo-el-humano">¿Qué hizo exactamente la IA, y qué hizo el humano?</h3>
<p>Claude leyó el manual de 250 páginas, escribió el programa de lectura, decodificó los registros, propuso el reinicio y luego el experimento de comparación que reveló el modo de reposo, y redactó este artículo conmigo. Yo soldé, medí, fotografié, decidí no tocar Qmax y dejé que el robot pasara una noche en su base, lo que desmintió la primera conclusión, la suya tanto como la mía.</p>
<h3 id="esta-reparado-el-robot">¿Está reparado el robot?</h3>
<p>Todavía no con certeza. Poner el contador a cero (30 de agosto) le dio un día, y luego el error 4202 volvió: la causa real era una celda recuperada más débil que disparaba la protección de sobretensión en cada carga. Corrección aplicada el 1 de septiembre (tensión de carga de 4100 mV por celda, reaprendizaje del medidor), en observación. Sigue sin comprarse ninguna pieza. Ver <a href="#ou-on-en-est">Dónde estamos</a>.</p>
<h2 id="pequeno-glosario">Pequeño glosario</h2>
<ul>
<li><strong>Celda</strong>: el acumulador elemental, aquí en formato 18650 (18 mm × 65 mm). Un pack ensambla varias.</li>
<li><strong>BMS</strong> (<em>battery management system</em>): la placa electrónica del pack, que protege, equilibra y mide las celdas. Aquí está construida en torno al bq40z50.</li>
<li><strong>Medidor de carga (gas gauge)</strong>: el chip que cuenta lo que entra y sale de la batería y deduce el estado de carga.</li>
<li><strong>Chip / circuito integrado</strong>: un ordenador o un circuito completo grabado en unos milímetros de silicio.</li>
<li><strong>Microcontrolador</strong>: un pequeño ordenador completo en un chip, programable; el ESP32-C3 lo es.</li>
<li><strong>Bus serie / SMBus / I²C</strong>: dos cables (datos y reloj) por los que los chips intercambian mensajes digitales; SMBus es la variante que usan las baterías.</li>
<li><strong>Dirección, registro, comando</strong>: el número de un chip en el bus, una casilla de memoria que se puede leer, el número que la designa. <code>0x…</code>: número escrito en hexadecimal.</li>
<li><strong>Bit, byte</strong>: la casilla elemental (0 o 1) y el grupo de ocho; un <strong>indicador</strong> (<em>flag</em>) es un bit que señala un estado.</li>
<li><strong>Firmware</strong>: el programa grabado en un aparato. <strong>Flash</strong>: la memoria que sobrevive al apagado; <strong>memoria RAM</strong>: la de trabajo, borrada al reiniciar.</li>
<li><strong>Ciclo</strong>: una descarga acumulada equivalente al 90 % de la capacidad (umbral ajustable). El contador se limita a sumar.</li>
<li><strong>RSOC</strong>: estado de carga relativo, el «porcentaje de batería»; <strong>FCC</strong>: capacidad a plena carga, tal como la estima el medidor; <strong>Qmax</strong>: capacidad química aprendida de las celdas; <strong>mAh</strong>: miliamperio-hora, unidad de cantidad de energía almacenada.</li>
<li><strong>Resistencia interna</strong>: la «fricción» eléctrica de una celda, en miliohmios (mΩ). Cuanto más alta, más cae la tensión bajo carga y más se calienta la celda; sube con la edad y delata a una celda cansada antes de que su capacidad se desplome.</li>
<li><strong>FET / transistor</strong>: interruptor electrónico con el que el medidor autoriza o corta la carga y la descarga.</li>
<li><strong>Pull-up</strong>: resistencia que mantiene una línea del bus a 3,3 V cuando nadie habla.</li>
<li><strong>PF (Permanent Failure)</strong>: un fallo que el medidor juzga irrecuperable; se condena y nada lo borra. No había ninguno.</li>
<li><strong>COV / CUV (Cell Over-/Under-Voltage)</strong>: protecciones de sobretensión y subtensión por celda. El medidor corta la carga (COV) o la descarga (CUV), reanuda cuando la tensión vuelve al rango y cuenta cada disparo en sus datos de vida.</li>
<li><strong>Impedance Track</strong>: el algoritmo de TI que aprende la capacidad y la resistencia de las celdas para medir con precisión.</li>
<li><strong>Full Access / Unsealed / Sealed</strong>: los tres niveles de acceso al chip, del más abierto al más cerrado.</li>
</ul>
<hr />
<h2 id="referencias-y-copias-locales">Referencias y copias locales</h2>
<p>Para que este artículo siga siendo útil cuando los enlaces hayan desaparecido, los documentos citados se alojan aquí, con su fuente original.</p>
<ul>
<li><strong>TI bq40z50-R2 Technical Reference Manual</strong>, SLUUBK0B (junio de 2017, rev. octubre de 2018) — <a href="https://www.ti.com/lit/pdf/sluubk0">fuente</a> · <a href="https://pf.olibrio.fr/assets/neato/refs/bq40z50-r2-trm-sluubk0b.pdf">copia local (PDF, 1,6 MB)</a>.</li>
<li><strong>Mapa de la data-flash del pack Neato, decodificado</strong> — <a href="https://pf.olibrio.fr/assets/neato/refs/bq40z50-df-map-neato.md">bq40z50-df-map-neato.md</a> · <strong>copia de seguridad en bruto</strong> del 29 de agosto de 2026 — <a href="https://pf.olibrio.fr/assets/neato/refs/bq40z50-df-backup-neato-blueway-20260829.txt">bq40z50-df-backup-neato-blueway-20260829.txt</a>.</li>
<li><strong>El sketch y su configuración</strong> — <a href="https://pf.olibrio.fr/assets/neato/bq40z50-reader.cpp">bq40z50-reader.cpp</a> · <a href="https://pf.olibrio.fr/assets/neato/platformio.ini">platformio.ini</a>.</li>
<li><strong>Neato Robotics, «Announcement – 6th Oct 2025»</strong> (fin de los servicios en la nube) — <a href="https://support.neatorobotics.com/support/solutions/articles/204000073686-announcement-6th-oct-2025">fuente</a> · <a href="https://pf.olibrio.fr/assets/neato/refs/neato-announcement-2025-10-06.md">copia en texto</a>.</li>
<li><strong>Reglamento (UE) 2023/1542 sobre baterías</strong>, artículo 11 (aplicable a partir del 18 de febrero de 2027) — <a href="https://eur-lex.europa.eu/eli/reg/2023/1542/oj">fuente EUR-Lex</a> · <a href="https://pf.olibrio.fr/assets/neato/refs/eu-regulation-2023-1542-article-11.md">extracto local</a>.</li>
<li><strong>vacuula/fang</strong> (firmware ESP32 que libera los Neato D3–D7 de la nube) — <a href="https://github.com/vacuula/fang">fuente</a> · <a href="https://pf.olibrio.fr/assets/neato/refs/vacuula-fang-README-20260830.md">README del 30 de agosto de 2026</a>.</li>
<li><strong>renjfk/OpenNeato</strong> — <a href="https://github.com/renjfk/OpenNeato">fuente</a> · <a href="https://pf.olibrio.fr/assets/neato/refs/renjfk-OpenNeato-README-20260830.md">README del 30 de agosto de 2026</a>.</li>
<li><strong>Hilo de laptopu.ro sobre los chips de los packs Neato</strong> (acceso Full Access mediante bqStudio) — <a href="https://www.laptopu.ro/community/laptop-battery-chip-reset-and-repair/robot-neato-battery-nlba-reads-it-but-can-not-recognize-chip/">fuente</a> (sin copia: el sitio rechaza el archivado).</li>
</ul>
<p><em>Fotos y mediciones: mías. Lectura del manual, código y redacción: con Claude. Este artículo también está disponible en <a href="https://pf.olibrio.fr/es/posts/erreur-4202-neato-obsolescence.md">Markdown en bruto</a>.</em></p>]]></content:encoded>
    </item>
    <item>
      <title>El fuego, el modelo y lo que otra política habría cambiado</title>
      <link>https://pf.olibrio.fr/es/posts/ce-quune-autre-politique-aurait-change.html</link>
      <guid isPermaLink="true">https://pf.olibrio.fr/es/posts/ce-quune-autre-politique-aurait-change.html</guid>
      <pubDate>Tue, 28 Jul 2026 12:00:00 +0000</pubDate>
      <description>Seis días de megaincendio en la Gironda y las Landas, un modelo que aprende a representar la lucha y una pregunta incómoda: ¿qué habría cambiado otra política?</description>
      <category>incendio</category>
      <category>gironda</category>
      <category>landas</category>
      <category>simulación</category>
      <category>lucha contra el fuego</category>
      <category>política</category>
      <content:encoded><![CDATA[<p><img src="https://pf.olibrio.fr/images/kokusho/boucle-25-juillet.png" alt="El fuego, el modelo y lo que otra política habría cambiado"></p>
<p>La <a href="https://pf.olibrio.fr/es/posts/mon-modele-faisait-bruler-latlantique.html">primera entrada</a> contaba la construcción de la herramienta y terminaba con su enseñanza más incómoda: el modelo no predice lo que el incendio va a hacer, predice lo que haría <em>si nadie se le opusiera</em>. La diferencia entre ambas cosas &mdash; un factor 1,7 el día en que el fuego corría libremente, un factor 12 el día en que los equipos de extinción mantenían el frente &mdash; es la lucha contra el fuego, y el modelo no la representaba en absoluto.</p>
<p>Esta entrada cuenta cuatro cosas: lo que el fuego ha hecho desde entonces, lo que el modelo ha aprendido al intentar representar a los equipos de extinción, lo que la lucha real debe a un ejército que nadie presupuesta &mdash; los vecinos y los agricultores &mdash;, y lo que este modelo permite decir &mdash; con prudencia &mdash; sobre una pregunta política que me han hecho: <strong>si el programa de l&rsquo;Avenir en commun (« el Porvenir en común », el programa de La France insoumise) se hubiera aplicado durante dos mandatos, ¿qué habría cambiado en un episodio como este?</strong></p>
<p><strong>Cómo se califica un modelo sobre el pasado</strong> &mdash; tres términos que volverán a lo largo de todo el texto. La <strong>repetición retrospectiva</strong> (<em>rejeu rétrospectif</em>): uno se sitúa en un instante pasado, no le da al modelo más que lo que se sabía en ese momento, simula hacia adelante y compara con lo real. El <strong>sesgo de superficie</strong>: la relación entre la superficie predicha y la superficie observada &mdash; un sesgo de 7,5 significa que el modelo quema siete veces y media de más. El <strong>AUC</strong>: tomen al azar una celda que ardió y otra que no ardió; el AUC es la probabilidad de que el modelo haya dado una puntuación más alta a la primera. A 0,95, rara vez se equivoca sobre el <em>dónde</em> &mdash; incluso cuando se equivoca gravemente sobre el <em>cuánto</em>.</p>
<hr />
<h3 id="seis-dias-cuarenta-y-cinco-mil-hectareas">Seis días, cuarenta y cinco mil hectáreas</h3>
<p>Primero los hechos, porque dan la escala. El incendio principal no empezó en Biscarrosse: empezó el <strong>22 de julio</strong> en Saumos, en la Gironda (<em>Gironde</em>, el departamento de Burdeos), en una obra de desbroce &mdash; 1 400 hectáreas esa misma noche. El de Biscarrosse, una furgoneta en llamas, siguió al día siguiente. A partir de ahí, las jornadas se cuentan en decenas de miles de hectáreas:</p>
<ul>
<li><strong>24 de julio</strong> &mdash; 19 000 ha en la Gironda, 110 000 personas evacuadas, entre ellas la península del Cap Ferret por tierra <em>y por mar</em>;</li>
<li><strong>25 de julio</strong> &mdash; más de 32 000 ha, 167 000 evacuados, primera descarga de retardante &mdash; un producto que no se evapora como el agua, sino que recubre la vegetación para volverla ininflamable &mdash; desde un A400M del Ejército del Aire francés;</li>
<li><strong>26 de julio</strong> &mdash; 42 000 ha, cinco municipios a las puertas de Burdeos evacuados mediante <em>FR-Alert</em> (el sistema francés de alerta por teléfono móvil): alrededor de <strong>220 000 personas desplazadas en total</strong>, una de las mayores evacuaciones francesas en tiempos de paz;</li>
<li><strong>27-28 de julio</strong> &mdash; tregua, cortafuegos ampliados con bulldozer, incendio « contenido pero no fijado », luego « estabilizado »&hellip; y una nueva ola de calor anunciada por <em>Météo-France</em> (el servicio meteorológico nacional).</li>
</ul>
<p><a href="https://pf.olibrio.fr/images/kokusho/chronologie-2026.svg" title="Abrir el gráfico en grande"><img alt="Gráfico de barras de la superficie total recorrida por el fuego, día a día del 22 al 28 de julio de 2026: 1 400 hectáreas el 22, 4 800 el 23, 21 600 el 24 con la evacuación del Cap Ferret por tierra y mar, 35 500 el 25 con la primera descarga del A400M, 45 500 el 26 con FR-Alert y unos 220 000 evacuados en total, y luego estabilización los días 27 y 28, bajo el anuncio de una nueva ola de calor" src="https://pf.olibrio.fr/images/kokusho/chronologie-2026.svg" /></a></p>
<p>Hagan clic en las figuras para abrirlas en grande.</p>
<p>Según el último balance que he podido documentar: 42 000 ha en la Gironda, 3 500 en las Landas (<em>Landes</em>, el departamento vecino, al sur), 88 bomberos heridos, más de 2 750 bomberos y cerca de 3 000 gendarmes y militares desplegados, refuerzos europeos (Canadair croatas, Air Tractor portugueses, helicópteros pesados checo y eslovaco), un dron Reaper para la cartografía térmica. EDF ha indicado que la central del Blayais, a unos cincuenta kilómetros de las llamas, no está amenazada &mdash; la pregunta que había puesto en marcha todo este proyecto tiene por tanto, de momento, una respuesta tranquilizadora. El Laser Mégajoule del CEA (el organismo francés de energía atómica), en cambio, ha visto cómo se abrían cortafuegos de urgencia alrededor de sus instalaciones.</p>
<p>📡 Del lado de la herramienta: el mapa <a href="https://kokusho.ss2i.ca">kokusho.ss2i.ca</a> sigue rastreando los dos focos. Esta mañana, el modelo ha puesto la base aérea de Cazaux en vigilancia reforzada frente al foco secundario &mdash; el frente observado está a 7,3 km y un tercio de los escenarios <em>sin lucha</em> alcanzan la zona de los 6 km en menos de 48 h. Precisión por honestidad: ninguna fuente de prensa documenta amenaza alguna sobre Cazaux; es una salida del modelo, y una salida <em>contrafactual</em>. Es exactamente el matiz que esta entrada va a pasarse todo el tiempo haciendo.</p>
<hr />
<h3 id="lo-que-funciono-en-el-modelo">Lo que funcionó en el modelo</h3>
<p>Desde la primera entrada, el modelo ha superado dos pruebas y ha ganado un piso.</p>
<p><strong>Primera prueba: la hipótesis de la falta de combustible.</strong> La sobrepredicción del 25 de julio (factor 12) tenía una explicación rival a la de la lucha: quizá el fuego estaba simplemente atrapado entre el océano, las lagunas y su propia cicatriz, sin nada más que quemar. La prueba es sencilla y se la recomiendo a todos los modelizadores: mirar <em>dónde</em> hace arder el modelo sus hectáreas sobrantes. Veredicto inapelable &mdash; <strong>el 94 % de la superficie predicha cae sobre pinar intacto</strong> que el fuego real nunca tocó. El combustible estaba ahí. El fuego no lo tomó. Lo que se lo impidió fue, en efecto, la lucha contra el fuego, y había que modelizarla.</p>
<p><strong>Segunda prueba: dos intentos de modelo de lucha, dos fracasos instructivos.</strong> El primero sorteaba, celda por celda, si los equipos aguantaban: habría hecho falta ganar el 93 % de las escaramuzas, y se ganaba el 15 %. El segundo mantenía tramos enteros de pista &mdash; una treintena de kilómetros defendidos&hellip; que el fuego rodeaba tranquilamente. La lección merece escribirse en negrita: <strong>un incendio no se contiene defendiendo mucha línea, se contiene defendiendo un bucle cerrado</strong>, anclado en barreras que el fuego no franquea. El confinamiento es un problema de topología, no de física local.</p>
<p><strong>El piso ganado: modelizar el razonamiento del jefe de operaciones.</strong> Encontrar el mejor bucle cerrado alrededor de un incendio, apoyándose al máximo en el agua, las zonas ya quemadas y las carreteras existentes, es un problema que las matemáticas saben resolver de forma exacta, y la idea se cuenta sin ecuaciones. Todo camino que lleve del fuego al exterior debe atravesar la línea de defensa &mdash; si no, el bucle no está cerrado, y el fuego encontrará el agujero. Buscar el mejor bucle es, por tanto, buscar el conjunto de celdas <em>más barato de defender</em> que corte <em>todos</em> los caminos: es lo que se llama un <strong>corte mínimo</strong>. Un teorema clásico &mdash; <a href="https://doi.org/10.4153/CJM-1956-045-5">Ford y Fulkerson, 1956</a> &mdash; dice que ese corte se calcula resolviendo un problema de flujo: imaginen que intentamos empujar un fluido desde el fuego hacia el exterior, dejando pasar cada celda un caudal igual a su coste de defensa; el caudal máximo que consigue circular es <em>exactamente</em> el precio de la mejor barrera, y las celdas que se saturan <em>son</em> la barrera. Es lo que calcula el algoritmo de Dinitz, implementado en <a href="https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csgraph.maximum_flow.html">SciPy</a>. El agua es gratis, una pista cuesta la mitad, el pinar abierto cuesta tarifa completa &mdash; y cada kilómetro se factura según la probabilidad de que un equipo pueda realmente defenderlo, de acuerdo con los umbrales operativos documentados: por debajo de 2 000 kW por metro de frente, el ataque directo es posible; por encima de 10 000, <em>nada aguanta</em>, medios aéreos incluidos.</p>
<p><strong>Intensidad de Byram</strong> (Byram, 1959): la potencia liberada por metro lineal de frente, en kW/m &mdash; el producto del poder calorífico del vegetal, la masa consumida por metro cuadrado y la velocidad de avance del frente. Es la magnitud que lo decide todo: un pinar landés que corre a 600 m/h libera unos 6 000 kW/m &mdash; ya fuera del alcance de un ataque directo por tierra. La altura de las llamas se deduce de ella casi directamente (unos 4 m en este caso).</p>
<p><strong>Dos detalles de implementación</strong>, para quien quiera rehacer el cálculo. Primero, los algoritmos de flujo hacen que las capacidades las lleven los <em>enlaces</em> entre casillas, mientras que aquí lo que se compra es la casilla misma: se desdobla entonces cada casilla en una « entrada » y una « salida » unidas por un arco interno al precio de la casilla &mdash; la técnica llamada <em>node splitting</em> (Ahuja, Magnanti y Orlin, <em>Network Flows</em>, 1993, § 2.4). Después, el corte debe separar las casillas contando sus <em>ocho</em> vecinas, diagonales incluidas &mdash; el « vecindario de Moore » de los autómatas celulares &mdash; porque el fuego también se propaga en diagonal: una barrera que solo bloquea las cuatro vecinas cardinales deja que el fuego se cuele entre dos casillas dispuestas al tresbolillo.</p>
<p><a href="https://pf.olibrio.fr/images/kokusho/coupe-minimale.svg" title="Abrir el esquema en grande"><img alt="Esquema de principio del confinamiento como corte mínimo. En el centro, la cicatriz ya recorrida y el frente activo, rodeados de una franja de retirada concedida de antemano. El bucle de defensa se apoya en una laguna al oeste, coste nulo, sigue una pista DFCI al sur, mitad de precio, y atraviesa el pinar en el resto, tarifa completa. Al nordeste, una brecha: un arco perdido o nunca financiado, por el que se escapa una lengua de fuego" src="https://pf.olibrio.fr/images/kokusho/coupe-minimale.svg" /></a></p>
<p>El bucle del jefe de operaciones, en principio: cada tipo de terreno tiene su precio, y el corte más barato que cierra el círculo <em>es</em> la estrategia.</p>
<p>La puesta a punto fue una lección de humildad por iteraciones, cada una pagada con una repetición retrospectiva de unos veinte minutos:</p>
<ul>
<li>sin precio para la superficie concedida, el corte « óptimo » se iba a buscar las lagunas a treinta kilómetros y abandonaba 150 000 hectáreas &mdash; matemáticamente mínimo, operativamente absurdo;</li>
<li>una línea defendida a las 3 de la madrugada no está defendida a las 15 h: hubo que añadir el <em>desbordamiento</em>, la nueva puesta a prueba de las líneas cuando el frente se intensifica claramente &mdash; es el repunte del mediodía el que hace ceder las líneas establecidas de noche;</li>
<li>y los medios son finitos: la defensa siempre se intenta, pero las unidades se agotan arco tras arco, y los huecos de financiación se convierten en las brechas por las que desbordan los grandes incendios.</li>
</ul>
<p><a href="https://pf.olibrio.fr/images/kokusho/boucle-25-juillet.png" title="Abrir el mapa en grande"><img alt="Mapa generado por el modelo: el bucle de confinamiento calculado por el corte mínimo sobre la repetición del 25 de julio a las 4 de la madrugada. Sobre un fondo de ocupación del suelo de OpenStreetMap, la gran cicatriz gris parda del incendio se extiende entre el océano al oeste y las lagunas; el bucle naranja de los arcos a defender, 187 kilómetros para 159 unidades, lo rodea lo más cerca posible, completado con segmentos negros allí donde el océano, las lagunas y la cicatriz cierran el círculo gratis. Al este, varios anillos pequeños ciñen los focos satélite" src="https://pf.olibrio.fr/images/kokusho/boucle-25-juillet.png" /></a></p>
<p>Y el mismo bucle en la realidad: el plan calculado por el corte mínimo sobre el incendio del 25 de julio, anclado en el océano, las lagunas y la cicatriz. Cada islote naranja al este ciñe un foco secundario detectado a distancia del incendio principal.</p>
<p>El resultado, en las dos jornadas de referencia: el día contenido, el sesgo cae de 12 a 7,5 &mdash; mejor, no bien; el resto se reparte entre los rincones de la cicatriz que el satélite no vio arder, los saltos de fuego que el modelo todavía no combate, y la humedad de los combustibles, que sigue calculándose con una fórmula instantánea sin memoria (Simard, 1968): solo mira la temperatura y la humedad de la hora, de modo que una tarde a 39,8 °C puede parecer <em>más húmeda</em> que la víspera. El remedio conocido es el índice meteorológico de incendios forestales canadiense (Van Wagner, 1987) y sus componentes acumulativas DMC y DC &mdash; dos « depósitos » que se llenan con cada lluvia y se vacían día tras día con el calor, guardando así la memoria de las semanas de sequía acumulada. Es la próxima obra. El día en que el fuego se escapó, en cambio, el modelo predice ahora una superficie media con un margen del <strong>14 %</strong> respecto a lo observado, y sabiendo <em>por qué</em>: las líneas defendidas por la mañana ceden en el pico térmico. En ambos casos, el AUC se mantiene por encima de 0,95 &mdash; el modelo sigue sabiendo adónde va el fuego.</p>
<hr />
<h3 id="el-experimento-que-un-modelo-permite-hacer-variar-los-medios">El experimento que un modelo permite: hacer variar los medios</h3>
<p>Y es aquí donde la modelización se convierte en un instrumento político &mdash; en el sentido noble. La v3 parametriza la lucha en « unidades desplegadas », donde una unidad defiende aproximadamente un kilómetro de línea, y el efectivo se sortea alrededor de una media calibrada sobre las movilizaciones reales (de 2 000 a 2 750 bomberos en los grandes incendios girondinos de 2022 y 2026). Nada impide entonces girar el mando: <strong>¿qué pasa con un 30 % menos de medios? ¿Con un 50 % más?</strong></p>
<p>Repetí las dos jornadas de referencia a tres niveles de despliegue, veinte sorteos cada uno:</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Medios desplegados</th>
<th>25 de julio (frente defendible) &mdash; superficie nueva mediana</th>
<th>24 de julio (frente indefendible) &mdash; superficie nueva mediana</th>
</tr>
</thead>
<tbody>
<tr>
<td>−70 % (« tres megaincendios a la vez »)</td>
<td>22 067 ha</td>
<td>8 244 ha</td>
</tr>
<tr>
<td>−30 % (« la austeridad continúa »)</td>
<td>18 352 ha</td>
<td>6 154 ha</td>
</tr>
<tr>
<td>Nominal (movilización real)</td>
<td>18 324 ha</td>
<td>6 154 ha</td>
</tr>
<tr>
<td>+50 % (« el servicio público reconstruido »)</td>
<td>18 324 ha</td>
<td>6 154 ha</td>
</tr>
</tbody>
</table></div>
<p>Repeticiones retrospectivas a +12 h, 20 sorteos por nivel de despliegue. « Mediana »: la mitad de los sorteos queman más, la otra mitad menos &mdash; más robusta que una media frente a los sorteos extremos. Observado: 1 645 ha el 25, 4 642 ha el 24. Órdenes de magnitud de un modelo experimental, no previsiones.</p>
<p>Esperaba una bonita curva decreciente &mdash; más medios, menos hectáreas. El modelo me respondió otra cosa, y es el resultado más interesante de la semana: <strong>los medios no compran hectáreas, compran un bucle</strong>. Por debajo del umbral en que el bucle deja de ser financiable &mdash; aquí, alrededor del −70 %, el equivalente de un dispositivo repartido entre tres megaincendios simultáneos, que es exactamente el temor de los veranos que vienen &mdash; se pierden miles de hectáreas de golpe. Por encima del umbral, el rendimiento marginal se desploma: entre el nominal y el +50 %, <em>ni una hectárea de diferencia</em>. Y el 24 de julio, la columna entera lo dice: se alineen 34 o 168 unidades, el fuego pasa &mdash; las líneas ceden ante la intensidad, no ante el número.</p>
<p><a href="https://pf.olibrio.fr/images/kokusho/sensibilite-moyens.svg" title="Abrir el gráfico en grande"><img alt="Dos curvas lado a lado, a la misma escala, de la superficie nueva quemada en doce horas según los medios desplegados. El 25 de julio, frente defendible: 22 067 hectáreas a menos 70 por ciento, luego una meseta en torno a 18 300 desde menos 30 por ciento --- el umbral en que el bucle se vuelve financiable, y después la saturación. El 24 de julio, frente indefendible: 8 244 y luego 6 154 hectáreas, la curva ya no se mueve sea cual sea el nivel de medios. En azul discontinuo, lo observado: 1 645 y 4 642 hectáreas" src="https://pf.olibrio.fr/images/kokusho/sensibilite-moyens.svg" /></a></p>
<p>La forma de la curva es el resultado: un umbral, luego una saturación &mdash; y el 24 de julio, una curva que los medios ya no mueven.</p>
<p>Una reserva importante antes de sacar conclusiones políticas: esta tabla minimiza el efecto real de los medios, porque el modelo no representa ni el <em>ataque a los incendios incipientes</em> &mdash; sofocar un conato en la primera hora, allí donde cada Canadair disponible cuenta doble &mdash; ni la rapidez de las rotaciones aéreas, ni el reparto del dispositivo entre varios incendios. Lo que establece es la forma de la curva: un umbral, luego una saturación. No la inutilidad de los medios.</p>
<hr />
<h3 id="el-otro-ejercito-la-logistica-que-se-resquebraja-y-quienes-la-sostienen">El otro ejército: la logística que se resquebraja, y quienes la sostienen</h3>
<p>Hay algo que ni la tabla ni la curva muestran, y que salta a la vista en cuanto se leen los partes de situación y la prensa local: <strong>la cuestión no era solo cuántas unidades, sino cómo se mantenían en pie</strong>. La logística &mdash; el agua, los vehículos, los aviones, el avituallamiento de los hombres &mdash; fue el eslabón débil de principio a fin, y ya se resquebrajaba antes del episodio.</p>
<p>Los hechos, con fecha. Durante los incendios, <strong>siete Canadair de doce</strong> estaban operativos, los demás inmovilizados por el mantenimiento de aparatos con treinta años de servicio &mdash; y el pedido de dos aparatos adicionales había sido anulado en 2024, antes de volver a cursarse en junio de 2026 para entrega&hellip; en 2032. El parque nacional de camiones cisterna forestales pasó de <strong>5 117 en 2002 a 3 845 en 2020</strong>, con una tasa de obsolescencia que subió del 51 al 61 %; la federación de bomberos estima que harían falta 10 000. Tres semanas antes del episodio, el 6 de julio, un sindicato de bomberos profesionales alertaba de que faltaban <strong>más de 300 vehículos</strong> para cubrir las necesidades de una temporada que ya iba por 7 000 conatos de incendio. Sobre el terreno, un jefe de batallón pedía un camión de 13 000 litros para « mantener una permanencia de agua », las columnas de refuerzo llegaban desde Île-de-France, y un bombero voluntario de Bouches-du-Rhône murió en la carretera &mdash; <em>en misión de avituallamiento</em>. Un suboficial lo dice sin rodeos en la prensa: « no tenemos medios suficientes, ni humanos ni materiales, para responder a catástrofes de una dimensión tan importante ». No son accidentes: la <em>Cour des comptes</em> (el Tribunal de Cuentas francés, 2022) hablaba de « falta de anticipación » en la flota aérea, el <em>Sénat</em> (2022) de « subinversión crónica » en los camiones, y las federaciones de bomberos de un « modelo agotado ». Cuatro años después, el episodio de 2026 se jugó con esas mismas carencias, conocidas, escritas y no corregidas.</p>
<p>Y sin embargo las líneas aguantaron los días defendibles. En parte porque se levantó un segundo ejército, que nadie presupuesta. El 24 de julio a las 7 de la mañana, la <em>préfecture</em> de las Landas (la delegación del Gobierno en el departamento) lanza oficialmente « un llamamiento a la solidaridad de los agricultores para aportar cubas de agua » &mdash; esas cisternas de decenas de miles de litros que se remolcan detrás de un tractor y que reabastecen a los camiones lo más cerca posible del frente. En pocas horas, la <em>chambre d&rsquo;agriculture</em> (la cámara agraria) de la Gironda registra <strong>más de 500 voluntarios</strong> &mdash; viticultores del Médoc, comerciantes con sus camiones cisterna, empresas de obras públicas con gradas, palas y bulldozers &mdash; de los que un centenar intervendrán efectivamente en el incendio de Saumos, hasta el punto de que el llamamiento se <em>suspende</em> el 27, desbordado por la afluencia. El sector maderero tumbó <strong>22 kilómetros de pinos en veinticuatro horas</strong> para abrir cortafuegos &mdash; 103 km de cortafuegos y pistas de acceso creados en total, dice el parte de la prefectura del 27. Detrás del frente: voluntarios que sostienen los centros de avituallamiento de los 2 750 bomberos, restauradores que preparan miles de comidas, veterinarios que atienden gratis a los animales evacuados, el recinto ferial de Bordeaux-Lac abierto para 10 000 personas. Nada de esto se improvisa desde cero: ya en 2022, en Landiras, las cubas de purín de los agricultores habían hecho ganar « hasta tres horas al día » a los bomberos, según la cámara agraria &mdash; y es precisamente esa experiencia la que la Gironda había empezado a formalizar, un mes antes del episodio, censando el material agrícola movilizable.</p>
<p>Releamos esto con las gafas del modelo, porque ilumina a ambos. El modelo cuenta « unidades que defienden un kilómetro » sin preguntar quién las dota: en realidad, una parte de esas unidades eran tractores. El reabastecimiento de agua, las tres horas al día de 2022, los cortafuegos labrados &mdash; en el vocabulario del modelo, eso es <em>resistencia</em>: arcos que siguen defendidos en lugar de ceder por falta de agua, unidades que se quedan en la línea en lugar de hacer viajes de ida y vuelta. Dicho de otro modo, <strong>el margen bajo el umbral, ese margen del que la curva muestra que lo decide todo, lo aportó en parte la sociedad misma</strong> &mdash; en el momento en que el Estado, que tenía sobre su mesa desde hacía cuatro años los informes que cifraban lo que faltaba, no lo tenía. Hay que decir las dos mitades de esta frase: la ayuda mutua fue magnífica, y es el síntoma de una carencia. Una cuba de purín no sustituye a un Canadair en mantenimiento; quinientos voluntarios en veinticuatro horas no se encargan, no se planifican, y se suspenden cuando la afluencia desborda la coordinación; y un sistema que necesita estructuralmente los tractores de sus vecinos para mantener sus líneas no es un sistema dimensionado &mdash; es exactamente lo que el informe parlamentario sobre el « valor de lo salvado », presentado diez días antes del episodio, intentaba decir en lenguaje presupuestario.</p>
<hr />
<h3 id="y-si-lavenir-en-commun-se-hubiera-aplicado-durante-dos-mandatos">¿Y si l&rsquo;Avenir en commun se hubiera aplicado durante dos mandatos?</h3>
<p>Vayamos a ello. La pregunta me la plantearon así: las medidas propuestas por La France insoumise (LFI, el partido de Jean-Luc Mélenchon), aplicadas desde 2017, ¿habrían cambiado algo en un episodio como este? El ejercicio es un contrafactual: no se verifica, se argumenta. Voy a empezar, pues, por lo que el programa contiene <em>de verdad</em>, porque la primera sorpresa está ahí.</p>
<p><strong>Lo que el programa contiene &mdash; y lo que no contiene.</strong> He buscado. Ni la edición de 2017 ni la de 2022 de l&rsquo;Avenir en commun incluyen un capítulo de protección civil. Ningún número de bomberos que reclutar, ningún presupuesto para los <em>SDIS</em> (los servicios departamentales de incendios y salvamento, es decir, los cuerpos de bomberos), ningún número de Canadair. Las medidas que tocan nuestro tema están en otra parte:</p>
<ul>
<li>la <strong>sección 27</strong> (« Defender el bosque »): reforzar los medios y las plantillas de la <em>ONF</em> (Office national des forêts, la agencia forestal pública), prohibir las cortas a hecho &mdash; la tala de una parcela entera de una sola vez &mdash;, promover bosques <em>diversificados en especies y en edades</em> frente a los monocultivos, y « reforzar los medios de prevención y de lucha contra los incendios » &mdash; formulación sin cifra;</li>
<li>el <strong>cuaderno temático Bosque</strong>: duplicación de la plantilla de la ONF (unos 8 400 agentes hoy, 16 000 a mediados de los años ochenta), adquisición pública de 100 000 ha, medios contra incendios considerados « notoriamente insuficientes »;</li>
<li>la <strong>sección 79</strong>: una fuerza mediterránea de intervención y de protección civil contra los incendios &mdash; la medida más directamente « fuego » del programa;</li>
<li>la <strong>sección 68</strong>: un servicio ciudadano obligatorio de nueve meses que incluye misiones de protección civil, y una guardia nacional bajo mando civil.</li>
</ul>
<p><strong>En el Parlamento, en cambio, las cifras existen.</strong> He vaciado los archivos de las dos últimas legislaturas (2022-2026), y el cuadro es más preciso &mdash; y más modesto &mdash; de lo que dejaría creer un eslogan en un sentido o en otro:</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Propuesta</th>
<th>Cifra</th>
<th>Destino</th>
</tr>
</thead>
<tbody>
<tr>
<td>Inversión estructural en los SDIS (enmienda II-CF1334, PLF 2023, F. Chauche, ponente especial)</td>
<td>15 M€/año durante 5 años, es decir, 75 M€</td>
<td>Rechazada en comisión, octubre de 2022</td>
</tr>
<tr>
<td>Recursos permanentes para los SDIS mediante el impuesto sobre los contratos de seguro (I-CF594, PLF 2025)</td>
<td>≈ +10 % del presupuesto total de los SDIS</td>
<td>No adoptada</td>
</tr>
<tr>
<td>Parte « protección civil » de la tasa turística asignada a los SDIS (PLF 2026)</td>
<td>0,10 a 0,50 €/pernoctación</td>
<td>No adoptada</td>
</tr>
<tr>
<td>Financiación de los dos Canadair previstos al 100 % por la UE en lugar del 90 % (CL265, LOPMI 2022)</td>
<td>2 aparatos, 10 % del coste</td>
<td>No adoptada</td>
</tr>
<tr>
<td>Flota de dieciséis Canadair &mdash; <em>objetivo gubernamental de 2022, cuya ejecución reclama LFI</em> (pregunta escrita de C. Lejeune, julio de 2025)</td>
<td>12 → 16 aparatos</td>
<td>No realizado (entregas 2028-2033)</td>
</tr>
<tr>
<td>Aviones anfibios alternativos franceses a la espera de los DHC-515 (trabajos Maudet, PLF 2026)</td>
<td>≈ 30 M€ la unidad</td>
<td>Exploratorio</td>
</tr>
</tbody>
</table></div>
<p>Enmiendas y preguntas del grupo LFI, XVI y XVII legislaturas (PLF: <em>projet de loi de finances</em>, el proyecto de ley de presupuestos; LOPMI: la ley de programación del Ministerio del Interior de 2022). Enlaces al final del artículo. La cifra de 220 000 bomberos voluntarios en 2027 que a veces se cita es un objetivo <em>gubernamental</em>, que LFI apoyó y sobre el que preguntó &mdash; no una propuesta de LFI.</p>
<p>Dos observaciones de honestidad sobre esta tabla. La primera: la fórmula « LFI proponía tantos bomberos y tantos Canadair » sería <strong>engañosa</strong> &mdash; los archivos muestran mecanismos de financiación (75 M€ de inversión, ~+10 % de recursos permanentes, el « valor de lo salvado » del informe Maudet&ndash;Pantel presentado diez días antes del episodio) y la exigencia de cumplir objetivos gubernamentales ya existentes, no metas propias de plantilla o de flota. La segunda: todo fue rechazado, retirado o dejado sin curso, y los presupuestos pasaron después por el 49.3 (el artículo de la Constitución que permite al Gobierno aprobar una ley sin votación). Frente a eso, la realidad: las plantillas de la ONF se han fundido un <strong>40 % en veinte años</strong>, la flota francesa cuenta con doce Canadair de más de treinta años, el Tribunal de Cuentas denunciaba ya en julio de 2022 una « falta de anticipación » en su renovación &mdash; y los dos aparatos encargados en junio de 2026 se entregarán <em>en 2032</em>.</p>
<p><strong>Ahora, hagamos trabajar al modelo.</strong> En kokusho, una política pública solo puede actuar por tres canales, y no tienen en absoluto el mismo peso:</p>
<p><em>Canal 1 &mdash; las unidades disponibles.</em> Más bomberos, más vehículos, una flota aérea de dieciséis aparatos en lugar de doce: en el modelo, es la media de despliegue la que sube. Y ahí, el cotejo de las dos tablas de esta entrada es instructivo: las propuestas parlamentarias reales &mdash; +10 % de presupuesto para los SDIS, 75 M€ de inversión &mdash; son de un orden de magnitud que, trasladado a mi curva de sensibilidad, cae <em>en la zona de saturación</em>. En una jornada defendible, con todo el dispositivo nacional concentrado en un solo incendio, un +10 % no habría cambiado la superficie quemada. Su valor está en otra parte, y es doble: <strong>margen bajo el umbral</strong> para el día en que los medios estén dispersos &mdash; tres conatos simultáneos, una flota medio clavada en tierra, columnas a ocho horas de carretera &mdash; y <strong>material que sale más rápido</strong> hacia los incendios incipientes, el canal que mi modelo todavía no representa y donde cada aparato disponible cuenta doble. Es exactamente el terreno de los dieciséis Canadair y de los aviones complementarios a 30 M€: no ganar la batalla del 24 de julio, sino hacer que no tenga lugar.</p>
<p><em>Canal 2 &mdash; la anchura de los cortafuegos.</em> La <em>DFCI</em> &mdash; <em>défense de la forêt contre l&rsquo;incendie</em>, defensa del bosque contra el incendio &mdash; es esa red de pistas arenosas, cortafuegos y puntos de agua que cuadricula el macizo landés precisamente para ofrecer a los equipos de extinción líneas de apoyo ya preparadas. Mantenida, desbrozada, ampliada &mdash; trabajo de la ONF y de entidades locales financiadas &mdash;, es, en el modelo, cortafuegos más anchos, y por tanto probabilidades de aguante más altas a igual intensidad. Es el canal del 40 % de plantilla de la ONF perdida: el mantenimiento de la red es precisamente el trabajo que se ha desmantelado. Difícil de cifrar, pero el mecanismo es el correcto.</p>
<p><em>Canal 3 &mdash; el combustible mismo.</em> Y es el canal decisivo, porque es el único que actúa sobre la <strong>intensidad</strong>. El macizo landés es un monocultivo de pino marítimo de un millón de hectáreas &mdash; nuestro mapa de combustible es monocromo, y esa monocromía es una política pública con ciento setenta años de antigüedad. Un bosque diversificado en especies y en edades, salpicado de frondosas menos inflamables, es una intensidad de frente más baja; y la intensidad es la única magnitud que decide si una línea es defendible. Por debajo de 2 000 kW/m, todo el mundo aguanta. Por encima de 10 000, nadie. <strong>Las medidas lentas son las únicas que desplazan los umbrales.</strong> Pero seamos honestos con el horizonte: dos mandatos no transforman un pinar industrial &mdash; diez años de diversificación son lindes, parcelas de prueba, interfaces mejor defendidas. El efecto en 2026 habría sido marginal; el efecto en 2046 sería estructural.</p>
<p><strong>¿Y el 24 de julio?</strong> Es la pregunta que decide la honestidad de un contrafactual. Respuesta del modelo: ese día, nada de lo anterior bastaba. Con un 50 % más de medios, la superficie simulada del 24 no se mueve ni una hectárea: las líneas ceden ante la intensidad, no ante el número. Cuando el frente supera los 10 000 kW/m, la aritmética de los medios ya no se aplica &mdash; no se hace frente con bulldozers a una tormenta de fuego. La única victoria posible el 24 estaba <em>aguas arriba</em>: que el fuego nunca hubiera alcanzado ese tamaño. Ataque a los incendios incipientes en la primera hora &mdash; lo que la flota aérea envejecida hace cada vez más despacio &mdash; y prevención para que el conato accidental de una obra de desbroce no se encuentre con 40 °C, viento del este y un pinar continuo. Dicho de otro modo: en las jornadas extremas, solo existe la política <em>de antes del incendio</em>. Y las jornadas extremas son precisamente las que fabrican los megaincendios.</p>
<p><strong>Los límites del ejercicio, sin los cuales no vale nada:</strong> el programa en sí no cifra ni bomberos ni aviones, y las cifras parlamentarias reales (75 M€, +10 %) son mucho más modestas que los ±50 % de mi tabla, que siguen siendo una hipótesis de lectura; el modelo es experimental y su sesgo residual está documentado; la ola de calor, el viento y siglo y medio de monocultivo no se gobiernan en dos mandatos; y un contrafactual nunca se verifica. Lo que el ejercicio establece es más modesto y más sólido: <em>por qué canales</em> actúa una política sobre un megaincendio, y cuáles de esos canales estaban saturados el 24 de julio.</p>
<hr />
<h3 id="lo-que-me-llevo-de-todo-esto">Lo que me llevo de todo esto</h3>
<p>La primera entrada terminaba con una lección de modelización: el modelo no respondía a la pregunta que yo creía hacerle. Esta termina con la lección simétrica, del lado político: <strong>« más medios » no es una respuesta única, porque « el fuego » no es un problema único.</strong> Están las jornadas defendibles, en las que cada unidad adicional compra hectáreas &mdash; ahí, los Canadair de 2032 encargados en 2026 son un escándalo de aritmética presupuestaria. Y están las jornadas indefendibles, en las que la única política que todavía existe se jugó diez años antes, en la composición del bosque, el mantenimiento de los cortafuegos y la velocidad de ataque a los incendios incipientes.</p>
<p>Un programa político que quiera pesar sobre los megaincendios se juzga, pues, con la vara de esos dos regímenes a la vez. Sobre el primero, el programa da la dirección y es en el Parlamento donde se encuentran las cifras: modestas &mdash; 75 millones, +10 % &mdash;, sistemáticamente rechazadas o aprobadas por el 49.3, pero puestas en los dos lugares que el modelo señala como las verdaderas palancas del régimen defendible, la financiación permanente de los SDIS y la flota de ataque inicial. Sobre el segundo &mdash; el bosque, sus plantillas, su diversidad &mdash; l&rsquo;Avenir en commun plantea el problema en el lugar donde se desplazan los umbrales. Y hay que apuntar en el balance lo que ni los programas ni mi modelo cuentan: el margen aportado por la sociedad misma &mdash; las cubas de agua de los agricultores, los voluntarios de los centros de avituallamiento &mdash;, que aguantó una vez más, y que ningún Estado seriamente dimensionado debería inscribir en su presupuesto como algo adquirido.</p>
<p>Hay que terminar diciéndolo sin rodeos: lo que acaba de pasar no es una anomalía, es un anticipo. El informe del Senado de 2022 &mdash; el mismo que cifraba la subinversión &mdash; lo escribía negro sobre blanco: de aquí a 2050, las superficies quemadas podrían aumentar un 80 %, y cerca de la mitad de las landas y bosques de la Francia metropolitana quedar expuestos a un riesgo de incendio elevado. Cuatro años después de Landiras, el mismo bosque ha vuelto a arder &mdash; más grande, más rápido, más cerca de Burdeos. Dos « incendios del siglo » en cuatro años no constituyen una excepción: constituyen un régimen. <strong>Es la nueva normalidad</strong>, y su firma es precisamente la más inquietante de las dos columnas de mi curva: las jornadas indefendibles del tipo 24 de julio, aquellas en las que la aritmética de los medios ya no se aplica, serán cada verano más numerosas.</p>
<p>Conocen la escena: el gato al borde de la mesa, la pata sobre el vaso, los ojos clavados en los de uno &mdash; y empuja. Nos reímos del gato. Deberíamos mirar al observador: quien ve el vaso deslizarse y no se mueve no es un testigo, es coautor de la rotura. Hace cuatro años que ese vaso se desliza ante los ojos de todos nosotros. Los informes estaban sobre la mesa &mdash; el Tribunal de Cuentas en 2022, el Senado en 2022, las federaciones de bomberos año tras año. Las enmiendas estaban presentadas &mdash; 75 millones para los camiones en 2022, <em>rechazados</em>; los créditos para los Canadair, <em>rechazados y luego aprobados por el 49.3</em>; el pedido de aparatos, <em>anulado en 2024</em> para volver a cursarse en 2026, con entrega en 2032. Las supresiones de puestos en la ONF <em>continúan en 2026</em>, el mismo verano en que arde el bosque. A estas alturas, la palabra « carencias » es demasiado suave: son decisiones, tomadas con conocimiento de causa, por gente que tenía las cifras. Y esta entrada ha pasado suficiente tiempo midiendo como para ganarse el derecho a decirlo: no seré el observador que no le dice nada al gato.</p>
<p>Y no me crean solo a mí: en pleno episodio, el medio independiente <a href="https://bonpote.com/quels-partis-politiques-ont-vote-pour-la-lutte-anti-incendie/">Bon Pote rehízo la cuenta, votación por votación</a>, de los votos de la Asamblea Nacional sobre la lucha contra los incendios. El cuadro no deja lugar a dudas: dos bloques. De un lado comunistas, insumisos, ecologistas y socialistas, que votan los medios y la prevención; del otro, desde el partido presidencial hasta el Rassemblement national (la extrema derecha de Marine Le Pen), que votan lo contrario &mdash; la tasa turística para los SDIS, rechazada dos veces; la contribución de las aseguradoras, rechazada cuando la enmienda esperaba de ella « al menos 800 millones de euros »; el programa de reclutamiento de bomberos profesionales, votado únicamente por la izquierda junto con LIOT (el grupo de independientes de centro); y el decreto firmado por Gabriel Attal en 2024 que anula 50 millones de créditos de protección civil, llevándose por delante el pedido de dos Canadair. La única unanimidad del expediente: 3 millones para la DFCI &mdash; así se mide el orden de magnitud de los consensos. Y la medida que se parece rasgo por rasgo al canal del combustible de mi modelo &mdash; cortafuegos de <em>frondosas</em> entre las parcelas de coníferas, para romper la continuidad del pinar &mdash; solo la votaron los insumisos, los socialistas y los ecologistas. Los umbrales de los que habla esta entrada tienen un color político en el Parlamento, y es verificable voto por voto.</p>
<p>Así que sí, esta entrada toma partido. De todo lo que he leído y cotejado, l&rsquo;Avenir en commun es hoy el <strong>único</strong> programa nacional que responde a los dos regímenes a la vez &mdash; y las votaciones citadas muestran que, cuando esas medidas llegan al pleno, es la izquierda entera la que las vota: el combustible y el bosque &mdash; diversificación de especies, fin de las cortas a hecho, plantilla de la ONF duplicada, allí donde se desplazan los umbrales que deciden si una línea es defendible &mdash; y el dimensionamiento de la protección civil &mdash; financiación permanente de los SDIS mediante el « valor de lo salvado », flota de ataque inicial ahora y no en 2033. Que no me respondan que le faltan cifras: fueron presentadas, enmienda tras enmienda, con los números que cita esta entrada &mdash; y son quienes las rechazaron los que hoy deben rendir cuentas. El resto de la oferta política, cuando habla del fuego, solo habla de aviones &mdash; el régimen defendible &mdash; y nunca del combustible &mdash; el régimen que mata. Pero los Canadair de 2033 no cambiarán nada en las jornadas en que nada vuela, y esas jornadas son las que hacen los megaincendios. <strong>Un programa que no habla del bosque no habla del problema.</strong> Los tractores de los agricultores aguantaron la línea esta vez. La próxima vez &mdash; y la nueva normalidad garantiza que la habrá &mdash; me gustaría que la República estuviera allí antes que ellos.</p>
<p>El fuego, por su parte, no espera al final del debate: Météo-France anuncia una nueva ola de calor. El mapa sigue girando.</p>
<hr />
<p>🔥 <strong><a href="https://kokusho.ss2i.ca">Ver la herramienta en línea &mdash; kokusho.ss2i.ca</a></strong></p>
<p>Experimental, sin valor oficial. En caso de incendio, la única fuente fidedigna es la prefectura: <a href="https://www.landes.gouv.fr/">landes.gouv.fr</a> · <a href="https://www.gironde.gouv.fr/">gironde.gouv.fr</a>.</p>
<h3 id="fuentes">Fuentes</h3>
<ul>
<li>Cronología y balance: <a href="https://fr.wikipedia.org/wiki/Feux_de_for%C3%AAt_de_2026_en_Gironde_et_dans_les_Landes">Wikipedia, Incendios forestales de 2026 en la Gironda y en las Landas</a>; comunicados de la <a href="https://www.gironde.gouv.fr/Actualites/Communiques-de-presse/Communiques-de-presse-2026/Juillet-2026/Incendie-en-Gironde-declenchement-de-FR-Alert-pour-l-evacuation-des-nouvelles-communes">prefectura de la Gironda</a> y de la <a href="https://www.landes.gouv.fr/Actualites/Salle-de-presse/Communiques-de-presse/2026/Incendie-en-cours-a-Biscarrosse-point-de-situation-a-07h">prefectura de las Landas</a>; partes de situación de <a href="https://www.franceinfo.fr/environnement/evenements-meteorologiques-extremes/incendies-et-feux-de-foret/incendies-en-gironde/incendies-en-gironde-et-dans-les-landes-le-point-sur-la-journee-du-lundi-27-juillet_8124539.html">franceinfo (27 de julio)</a> y <a href="https://www.franceinfo.fr/replay-jt/france-2/20-heures/incendie-en-gironde-des-prochaines-heures-decisives_8124449.html">France 2 (28 de julio)</a>.</li>
<li>Blayais: <a href="https://montelnews.com/fr/news/964487e1-b5d4-4dc1-a05c-134cc576314b/feux-en-gironde-pas-d-impact-sur-les-re-acteurs-du-blayais">Montel News, 27 de julio de 2026</a>. Emplazamientos estratégicos: <a href="https://armees.com/incendie-gironde-sites-surveillance/">armees.com</a>.</li>
<li>Programa: <a href="https://laec.fr/section/27/defendre-la-foret-poumon-de-la-planete">l&rsquo;Avenir en commun, sección 27</a>; <a href="https://melenchon2027.fr/livrets-2022/foret/">cuaderno Bosque</a>; secciones 68 y 79 en <a href="https://laec.fr/">laec.fr</a>.</li>
<li>Los votos de la Asamblea, votación por votación: <a href="https://bonpote.com/quels-partis-politiques-ont-vote-pour-la-lutte-anti-incendie/">Bon Pote, « Quels partis politiques ont voté pour la lutte anti-incendie ? » (« ¿Qué partidos políticos votaron a favor de la lucha contra los incendios? »), Sophie Kloetzli, 27 de julio de 2026</a> &mdash; tasa turística SDIS (votaciones 302 y 4074, XVII legislatura), contribución de las aseguradoras (4076), reclutamiento de bomberos profesionales (133, XVI legislatura), plan de adaptación del bosque (1509), cortafuegos de frondosas entre coníferas (1556), decreto de anulación de 50 M€ de créditos de protección civil (2024).</li>
<li>Parlamento y presupuesto: enmiendas <a href="https://www.assemblee-nationale.fr/dyn/16/amendements/0273C/CION_FIN/CF1334">II-CF1334 (PLF 2023, 75 M€ SDIS)</a>, <a href="https://www.assemblee-nationale.fr/dyn/17/amendements/0324A/CION_FIN/CF594">I-CF594 (PLF 2025, TSCA ≈ +10 % SDIS)</a>, <a href="https://www.assemblee-nationale.fr/dyn/17/amendements/AMANR5L17PO838901B1906P1D1N003166">I-3166 (PLF 2026, tasa turística)</a>, <a href="https://www.assemblee-nationale.fr/dyn/16/amendements/0343/CION_LOIS/CL265">CL265 (LOPMI 2022, Canadair 100 % UE)</a>, <a href="https://www.assemblee-nationale.fr/dyn/17/amendements/1906C/CION_FIN/CF2221">II-CF2221 (PLF 2026, aviones complementarios ≈ 30 M€)</a>; preguntas escritas <a href="https://questions.assemblee-nationale.fr/q16/16-2391QE.htm">n.º 2391 (F. Chauche, voluntarios)</a> y <a href="https://questions.assemblee-nationale.fr/q17/17-9156QE.htm">n.º 9156 (C. Lejeune, dieciséis Canadair)</a>; <a href="https://nosparlementaires.fr/actualites/canadair-securite-civile-ce-que-le-parlement-a-vote">nosparlementaires.fr, « Canadair : ce que le Parlement a voté » (« Canadair: lo que votó el Parlamento »)</a>; <a href="https://www.lagazettedescommunes.com/club-prevention-securite/securite-civile/sapeurs-pompiers-et-sdis/budget-des-sdis-la-valeur-du-sauve-fait-recette-a-lassemblee-nationale.MNCLJM6YOFHRZEW765AU42AXUE.html">La Gazette des communes, informe « valor de lo salvado »</a>.</li>
<li>Contexto: <a href="https://basta.media/face-aux-incendies-l-onf-en-premiere-ligne-malgre-la-baisse-des-effectifs">Basta!, plantillas de la ONF</a>; <a href="https://www.ccomptes.fr/fr/publications/la-flotte-aerienne-de-la-securite-civile">Cour des comptes, informe del 26 de julio de 2022</a>; <a href="https://www.usinenouvelle.com/aero-spatial/aeronautique/aviation-civile/en-attendant-un-modele-made-in-france-letat-rachete-deux-canadair-supplementaires-au-canadien-de-havilland-pour-200-millions-deuros.TAX5FDHQOZGURDPUXWS7BRRU6E.html">L&rsquo;Usine nouvelle, pedido de Canadair (junio de 2026)</a>; <a href="https://www.senat.fr/rap/r21-856/r21-856_mono.html">Sénat, informe n.º 856 (2022)</a>.</li>
<li>Logística y ayuda mutua, episodio 2026: <a href="https://fr.wikipedia.org/wiki/Feux_de_for%C3%AAt_de_2026_en_Gironde_et_dans_les_Landes">siete Canadair de doce operativos (Le Monde, vía Wikipedia)</a>; <a href="https://www.landes.gouv.fr/Actualites/Salle-de-presse/Communiques-de-presse/2026/Incendie-en-cours-a-Biscarrosse-point-de-situation-a-07h">llamamiento de la prefectura a las cubas de agua (Landas, 24 de julio, 7 h)</a>; <a href="https://www.vitisphere.com/actualite-107124-100-agriculteurs-intervenus-contre-lincendie-500-volontaires-au-total-la-chambre-dagriculture-suspend-son-appel.html">Vitisphere: 100 agricultores intervinieron, 500 voluntarios, llamamiento suspendido</a>; <a href="https://gironde.chambres-agriculture.fr/actualites-33/detail-de-lactualite/feux-en-gironde">coordinación por la cámara agraria de la Gironda</a>; <a href="https://www.gironde.gouv.fr/Actualites/Communiques-de-presse/Communiques-de-presse-2026/Juillet-2026/Incendie-de-Saumos-point-de-situation-a-22h30-ce-lundi-27-juillet">parte de la prefectura del 27 de julio: balance, 103 km de cortafuegos</a>; <a href="https://www.franceinfo.fr/faits-divers/incendies-en-gironde/en-gironde-le-ravitaillement-des-pompiers-s-organise_8122952.html">franceinfo: el avituallamiento sostenido por voluntarios</a>; <a href="https://www.franceinfo.fr/environnement/evenements-meteorologiques-extremes/incendies-et-feux-de-foret/on-n-a-pas-suffisamment-de-moyens-ni-humains-ni-materiels-secouristes-et-sinistres-en-colere-face-au-niveau-bilan-des-incendies-en-gironde_8123675.html">franceinfo: « no tenemos medios suficientes »</a>; <a href="https://france3-regions.franceinfo.fr/nouvelle-aquitaine/gironde/arcachon/je-voulais-etre-utile-le-bel-elan-de-solidarite-face-a-l-incendie-en-gironde-et-dans-les-landes-3391921.html">France 3: « Quería ser útil »</a>; <a href="https://www.bordeaux-metropole.fr/actualites/incendies-en-gironde-accueil-personnes-evacuees-collecte-dons">Bordeaux Métropole: acogida en Bordeaux-Lac, recogida de donativos</a>; <a href="https://cnews.fr/france/2026-07-27/incendies-les-pompiers-recensent-beaucoup-de-points-chauds-en-gironde-une-reprise">CNEWS: un bombero voluntario muerto en misión de avituallamiento</a>; <a href="https://snspp-pats.com/feux-despaces-naturels-le-snspp-pats-alerte-une-nouvelle-fois/">SNSPP-PATS, 6 de julio de 2026: más de 300 vehículos que faltan</a>; <a href="https://viralmag.fr/incendies-en-gironde-pompiers-en-course-contre-un-feu-imprevisible/">reportaje: « corremos detrás del fuego », el camión de 13 000 litros</a>; <a href="https://mesinfos.fr/ile-de-france/incendie-en-gironde-la-colonne-de-renfort-commandee-par-un-essonnien-335962.html">la columna de refuerzo de Île-de-France, los 22 km de pinos cortados en 24 h</a>.</li>
<li>El precedente de 2022 y las constataciones estructurales: <a href="https://www.reussir.fr/feux-en-gironde-les-agriculteurs-apportent-leur-aide-aux-pompiers">Réussir: las cubas de purín de Landiras (50 000 litros aportados)</a>; <a href="https://www.reussir.fr/face-aux-incendies-comment-la-precieuse-aide-des-agriculteurs-sorganise">Réussir: más de 100 tractores y cubas censados en la Gironda (agosto de 2022)</a>; <a href="https://www.pleinchamp.com/actualite/les-agriculteurs-un-peu-plus-que-des-porteurs-d-eau-dans-la-lutte-contre-les-incendies-de-foret">Pleinchamp: « hasta tres horas al día » ganadas, y la formalización de 2026</a>; <a href="https://agriculture.gouv.fr/incendies-en-gironde-le-monde-agricole-se-mobilise-aux-cotes-des-services-de-secours">Ministerio de Agricultura, 2022</a>; <a href="https://www.europe1.fr/societe/un-elan-de-solidarite-que-jai-rarement-vu-en-gironde-les-habitants-ravitaillent-les-pompiers-4123813">Europe 1: la población avitualla a los bomberos (La Teste, 2022)</a>; <a href="https://www.assemblee-nationale.fr/dyn/16/amendements/0273C/CION_FIN/CF1327.pdf">parque de camiones cisterna: 5 117 (2002) → 3 845 (2020), obsolescencia 61 %, objetivo FNSPF de 10 000 (datos DGSCGC citados en anexo presupuestario)</a>; <a href="https://www.senat.fr/rap/l22-115-329-2/l22-115-329-24.html">Sénat, PLF 2023: « subinversión crónica », y los pactos de capacidad</a>; <a href="https://www.fosis.org/index.php/2022/08/16/un-modele-de-securite-civile-a-bout-de-souffle/">FO-SIS: « un modelo de protección civil agotado »</a>.</li>
<li>Física del fuego: Byram G.M. (1959), « Combustion of forest fuels », en K.P. Davis (dir.), <em>Forest Fire: Control and Use</em>, McGraw-Hill &mdash; la intensidad de frente <em>I = H·w·R</em> y la relación de longitud de llama <em>L = 0,0775·I^(0,46)</em>; <a href="https://www.fs.usda.gov/rm/pubs_int/int_rp115.pdf">Rothermel R.C. (1972), <em>A Mathematical Model for Predicting Fire Spread in Wildland Fuels</em>, USDA Forest Service INT-115</a> &mdash; la amortiguación por la humedad de los combustibles finos; Simard A.J. (1968), <em>The Estimation of Moisture Content of Fine Fuels</em>, Forest Fire Research Institute, Ottawa, FF-X-14 &mdash; la fórmula de humedad instantánea utilizada (y criticada) aquí; <a href="https://ostrnrcan-dostrncan.canada.ca/entities/publication/9505b1a8-2b34-40f2-a67a-42d1cf2f2b7d">Van Wagner C.E. (1987), <em>Development and Structure of the Canadian Forest Fire Weather Index System</em>, Servicio Forestal Canadiense, informe técnico 35</a> &mdash; los índices con memoria DMC/DC.</li>
<li>Umbrales operativos de aguante: <a href="https://doi.org/10.1071/WF9960199">Hirsch K.G. &amp; Martell D.L. (1996), « A Review of Initial Attack Fire Crew Productivity and Effectiveness », <em>International Journal of Wildland Fire</em> 6(4)</a>; <a href="https://doi.org/10.1007/978-3-319-51727-8_52-1">Alexander M.E. &amp; Cruz M.G. (2019), « Fireline Intensity », en <em>Encyclopedia of Wildfires and Wildland-Urban Interface (WUI) Fires</em>, Springer</a> &mdash; ataque directo posible por debajo de 2 000 kW/m, vehículos hasta ~4 000, nada aguanta por encima de 10 000; la regla « un cortafuegos aguanta a partir de dos longitudes de llama » es una regla del arte de la ordenación DFCI, tratada aquí como transición suave y no como umbral neto.</li>
<li>Algorítmica del confinamiento: <a href="https://doi.org/10.4153/CJM-1956-045-5">Ford L.R. &amp; Fulkerson D.R. (1956), « Maximal Flow Through a Network », <em>Canadian Journal of Mathematics</em> 8</a> &mdash; el teorema corte mínimo/flujo máximo; <a href="https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csgraph.maximum_flow.html">scipy.sparse.csgraph.maximum_flow</a> (algoritmo de Dinitz); el paso de capacidades de nodos a capacidades de aristas (<em>node splitting</em>) se describe en Ahuja R.K., Magnanti T.L. &amp; Orlin J.B. (1993), <em>Network Flows</em>, Prentice Hall, § 2.4; panorama de los modelos de propagación (autómatas celulares incluidos): <a href="https://doi.org/10.1071/WF06144">Sullivan A.L. (2009), « Wildland surface fire spread modelling, 1990&ndash;2007 », <em>IJWF</em> 18, tres partes</a>.</li>
<li>Puntuaciones de validación: Brier G.W. (1950), « Verification of Forecasts Expressed in Terms of Probability », <em>Monthly Weather Review</em> 78; AUC calculada mediante el estadístico de Mann-Whitney; diagramas de fiabilidad y puntuaciones espaciales (Sørensen-Dice, Jaccard): Wilks D.S. (2019), <em>Statistical Methods in the Atmospheric Sciences</em>, 4.ª ed., Elsevier. La comparación con la persistencia como referencia nula es la salvaguarda clásica de la predicción.</li>
<li>Datos del modelo: <a href="https://firms.modaps.eosdis.nasa.gov/">NASA FIRMS</a>, detecciones activas VIIRS 375 m (<a href="https://doi.org/10.1016/j.rse.2013.12.008">Schroeder W. et al. (2014), <em>Remote Sensing of Environment</em> 143</a>); <a href="https://open-meteo.com/">Open-Meteo</a> (modelos de Météo-France, y altimetría Copernicus DEM GLO-90); ocupación del suelo y viario: <a href="https://www.openstreetmap.org/copyright">© colaboradores de OpenStreetMap (ODbL)</a> vía la API Overpass. Cargas de combustible y velocidades base por clase: órdenes de magnitud asumidos, documentados en el código, no un inventario medido.</li>
</ul>]]></content:encoded>
    </item>
    <item>
      <title>Mi modelo incendiaba el Atlántico</title>
      <link>https://pf.olibrio.fr/es/posts/mon-modele-faisait-bruler-latlantique.html</link>
      <guid isPermaLink="true">https://pf.olibrio.fr/es/posts/mon-modele-faisait-bruler-latlantique.html</guid>
      <pubDate>Mon, 27 Jul 2026 12:00:00 +0000</pubDate>
      <description>Un incendio en las Landas: ¿y si va hacia la central del Blayais? Dos días para improvisar una herramienta que responde, y todo lo que tenía mal.</description>
      <category>incendio</category>
      <category>landas</category>
      <category>simulación</category>
      <category>validación</category>
      <category>ia</category>
      <content:encoded><![CDATA[<p><img src="https://pf.olibrio.fr/images/kokusho/carte-kokusho-grand.jpg" alt="Mi modelo incendiaba el Atlántico"></p>
<p>El jueves 23 de julio, una furgoneta se incendia en una carretera departamental en Biscarrosse (en las Landas, departamento del suroeste de Francia). A las 15:45 las llamas pasan al macizo forestal, y en tres días se evacúa a 30 000 personas. Como todo el mundo, sigo aquello en mapas de puntos rojos, y una pregunta se instala &mdash; el tipo de pregunta que uno no se atreve a formular del todo mientras no sabe responderla: <strong>¿y si fuera hacia el Blayais?</strong></p>
<p>El Blayais es la central nuclear situada en la orilla derecha del estuario de la Gironda, a unos cincuenta kilómetros al norte de Burdeos. Un mapa de puntos rojos no responde a esa pregunta. Muestra dónde <em>está</em> el fuego. Nunca adónde <em>va</em>.</p>
<p>Entre ambas cosas hace falta un modelo. Quise ver hasta dónde se podía improvisar uno honesto en dos días. El resultado existe, funciona y se puede consultar aquí:</p>
<p>👉 <strong><a href="https://kokusho.ss2i.ca">kokusho.ss2i.ca</a></strong> &mdash; el mapa es público y se actualiza con cada nuevo cálculo.</p>
<p>Herramienta experimental, sin ningún valor oficial. En caso de incendio, la única fuente que da fe es la prefectura (la representación del Estado en cada departamento francés).</p>
<p>Pero esa no es la parte interesante de la historia. La parte interesante es la lista de todo lo que tuvo mal &mdash; y sobre todo, con qué se dejó atrapar cada error.</p>
<hr />
<h3 id="la-primera-decision-es-moral-no-tecnica">La primera decisión es moral, no técnica</h3>
<p>Una herramienta como esta puede mostrar dos cosas muy distintas. La primera:</p>
<p><em>«El fuego alcanzará la central dentro de 17 horas.»</em></p>
<p>Es nítido. Es accionable. Y es una estafa. Para escribir una frase así, habría que conocer la posición exacta del frente, el viento de las próximas diecisiete horas, la sequedad real de los combustibles y la eficacia de los equipos de extinción. No conozco ninguno de esos cuatro elementos. Nadie los conoce.</p>
<p>La segunda se parece más bien a esto:</p>
<p><em>«De 200 escenarios simulados, 6 llevan el fuego a la zona ampliada alrededor de la central, como muy pronto dentro de 29 horas. El viento previsto es transversal al eje del emplazamiento. Confianza baja: última detección satelital hace 5 horas.»</em></p>
<p>Es bastante menos satisfactorio de leer. Es verdad.</p>
<p>Todo lo demás se deriva de esa elección. La herramienta nunca traza una trayectoria; dibuja <strong>envolventes</strong> &mdash; el término consagrado para esos contornos que delimitan la zona alcanzable &mdash; a 6, 12, 24 y 48 horas, en tres niveles de plausibilidad decreciente: la zona alcanzada en más de un escenario de cada dos, la alcanzada en uno de cada diez, y la envolvente extrema que solo se cruza en un escenario de cada cien, aquel en el que todo sale mal a la vez.</p>
<p>Y se niega a resumir la situación en una única cifra. Da tres, por separado: <strong>el nivel de amenaza</strong>, <strong>la confianza</strong> que se puede otorgar a ese juicio, y <strong>la frescura</strong> de la última observación. Porque un «verde» calculado con datos de cuatro horas de antigüedad no es una buena noticia: es un vacío de información. Un satélite que no ve nada no demuestra que el fuego se haya detenido &mdash; demuestra que no ve nada.</p>
<hr />
<h3 id="los-ladrillos-y-lo-que-hacen-de-verdad">Los ladrillos, y lo que hacen de verdad</h3>
<p><a href="https://pf.olibrio.fr/images/kokusho/pipeline.svg" title="Abrir el esquema en grande"><img alt="Esquema de la cadena de tratamiento. Las detecciones térmicas de los satélites NASA FIRMS, sensores VIIRS a 375 metros, se agrupan por incendio y luego se reducen al frente activo visto en las últimas doce horas. La meteorología AROME de Météo-France, la vegetación de OpenStreetMap y el modelo digital del terreno alimentan un autómata celular, tablero de celdas de 150 metros, repetido doscientas veces por el método de Montecarlo. De ahí salen las envolventes a 6, 12, 24 y 48 horas, y luego un nivel de amenaza acompañado de la confianza y de la frescura del dato" src="https://pf.olibrio.fr/images/kokusho/pipeline.svg" /></a></p>
<p>Haz clic en las figuras para abrirlas en grande.</p>
<p><strong>Ver el fuego: FIRMS y VIIRS.</strong> La NASA difunde gratuitamente, casi en tiempo real, las detecciones térmicas de sus satélites &mdash; el servicio se llama <strong>FIRMS</strong>, y los sensores que uso, <strong>VIIRS</strong>, dividen el suelo en píxeles de 375 metros. Los prefiero a MODIS, más antiguo y cuatro veces más grueso.</p>
<p>Hay que entender bien qué es una detección FIRMS: <strong>un píxel cuya temperatura de superficie es anómala</strong>. No un contorno de incendio. Con retraso, con huecos cuando no pasa ningún satélite, y nada en absoluto cuando el humo o las nubes tapan la vista. Este matiz gobierna todo el resto del artículo.</p>
<p><strong>Saber qué lo empuja: AROME, OSM, MDT.</strong> Tres ingredientes hacen avanzar un fuego. El viento en primer lugar, que pesa mucho más que el resto: lo tomo de <strong>AROME</strong>, el modelo de malla fina de Météo-France (el servicio meteorológico nacional francés), y no en un único punto sino muestreado sobre todo el dominio &mdash; un incendio de este tamaño atraviesa varias mallas, y el viento puede girar localmente. La vegetación después, extraída de <strong>OpenStreetMap</strong>: un pinar seco arde, un estanque no, una viña apenas. El relieve por último, a través de un <strong>modelo digital del terreno</strong> &mdash; un archivo de altitudes, sencillamente &mdash; porque un fuego sube una pendiente mucho más deprisa de lo que la baja.</p>
<p><strong>Hacerlo avanzar: el autómata celular.</strong> El corazón del cálculo lleva un nombre erudito para una idea sencilla.</p>
<p><strong>Autómata celular</strong> &mdash; se divide el espacio en celdas regulares, aquí cuadrados de 150 metros, y se da una regla que dice cómo el estado de una celda depende de sus vecinas. Se aplica la regla en todas partes, se avanza un paso de tiempo, se vuelve a empezar. El <em>Juego de la vida</em> de Conway es el ejemplo más conocido.</p>
<p>Mi regla: una celda en llamas intenta prender a sus ocho vecinas, tanto más deprisa cuanto más inflamable es la vegetación, más sube la pendiente y más empuja el viento en esa dirección. El frente adopta espontáneamente una forma <strong>elíptica</strong> alargada a sotavento &mdash; lo que los bomberos observan sobre el terreno, y lo que los modelos reproducen desde los años 1980.</p>
<p><strong>Aceptar que no se sabe: Montecarlo.</strong> Es el punto que lo cambia todo.</p>
<p><strong>Método de Montecarlo</strong> &mdash; en lugar de calcular una sola vez con los mejores valores posibles, se rehace el cálculo cientos de veces sorteando, cada vez, los parámetros que se conocen mal. Después se mira la distribución de los resultados. El nombre viene del casino, y el método, de la bomba atómica &mdash; Ulam y von Neumann, 1946.</p>
<p>Lanzo pues <strong>200 sorteos</strong>. Cada vez perturbo lo que es realmente incierto: el error de previsión del viento &mdash; que crece con el plazo y se mantiene correlacionado en el tiempo, porque una previsión equivocada lo es de forma duradera y no una hora de cada dos &mdash; el error de mi propio modelo de velocidad, la sequedad real de los combustibles y la aparición de <strong>saltos de fuego</strong>, esas brasas proyectadas por delante del frente que cruzan una carretera o un cortafuegos.</p>
<p>Lo que se muestra después ya no es una previsión sino un recuento: esta celda ardió en 150 de mis 200 mundos posibles, aquella en 3. Es la misma lógica que el cono de incertidumbre de las trayectorias de los ciclones.</p>
<p>Una precisión que importa: esas frecuencias <em>no</em> son probabilidades en el sentido actuarial. Son frecuencias <strong>condicionadas a mis hipótesis</strong>. Si mis hipótesis son malas, mis porcentajes también lo son. Tenlo en cuenta &mdash; el resto del artículo no habla prácticamente de otra cosa.</p>
<hr />
<h3 id="primer-resultado-un-fuego-perfectamente-inmovil">Primer resultado: un fuego perfectamente inmóvil</h3>
<p>Primer lanzamiento con los datos reales. Cae el informe: superficie nueva quemada al cabo de 6 horas, 103,5 hectáreas. Al cabo de 12 horas: 103,5 hectáreas. Con precisión de una décima de hectárea.</p>
<p>Un fuego que no gana ni un metro en seis horas bajo 17 km/h de viento es falso. Y mis 200 sorteos, que se suponía que exploraban mundos distintos, daban todos rigurosamente el mismo resultado &mdash; lo que es aún más sospechoso.</p>
<p>La causa estaba en una elección de índice. Cuando calculaba la velocidad de paso de una celda a su vecina, tomaba la velocidad de la celda <strong>fuente</strong>, la que ya arde. Ahora bien, marco toda la superficie ya recorrida como «cicatriz», con una velocidad de propagación casi nula &mdash; lo cual es correcto: una zona ya quemada no vuelve a arder fácilmente.</p>
<p>Salvo que el fuego parte forzosamente de la superficie ya quemada. Todas mis celdas fuente eran cicatrices, y por tanto incapaces de transmitir nada. <strong>El fuego era prisionero de su propio perímetro.</strong></p>
<p>La corrección cabe en una palabra: tomar la velocidad de la celda <strong>objetivo</strong>, aquella cuyo combustible está a punto de consumirse. Además es físicamente más justo &mdash; un fuego avanza a la velocidad que le permite lo que ataca, no lo que ya ha quemado. Bonificación inesperada: también corrige el cruce de las masas de agua, que una celda fuente combustible podía atravesar.</p>
<hr />
<h3 id="luego-mire-el-mapa-mas-de-cerca">Luego miré el mapa más de cerca</h3>
<p>La herramienta funcionaba, las envolventes se extendían con elegancia, las cifras parecían plausibles. Las miré un rato antes de hacer lo que debería haber hecho desde el principio: abrir el mapa de entrada, el que usa el modelo, y mirarlo de verdad.</p>
<p>Había un problema. <strong>El modelo hacía arder el mar.</strong></p>
<p>Y era cierto. Aquí está el <strong>mapa de combustible</strong> &mdash; la imagen que le dice al autómata, para cada celda, a qué velocidad puede avanzar el fuego allí. A la izquierda lo que veía mi programa, a la derecha la realidad:</p>
<p><a href="https://pf.olibrio.fr/images/kokusho/mer-avant-apres.png" title="Abrir la comparación en grande"><img alt="Dos mapas de combustible uno junto a otro, sobre la misma zona alrededor de Biscarrosse. A la izquierda, el océano Atlántico aparece enteramente en verde oscuro, el color del pinar: el modelo lo trata como combustible. A la derecha, tras la corrección, el océano aparece en azul, netamente separado del litoral, y se distinguen los grandes lagos de Cazaux-Sanguinet y de Biscarrosse-Parentis" src="https://pf.olibrio.fr/images/kokusho/mer-avant-apres.png" /></a></p>
<p>Toda la masa verde oscuro de la izquierda es el Atlántico. Clasificado como pinar.</p>
<p>La razón es casi divertida. <strong>OpenStreetMap no cartografía el océano como una superficie.</strong> No existe ningún polígono «Atlántico»: los contribuidores han trazado la <strong>línea de costa</strong> &mdash; en la jerga de OSM, un camino etiquetado <code>natural=coastline</code> &mdash; es decir, una línea, no una superficie. Mi consulta, en cambio, buscaba superficies. Recuperaba concienzudamente los lagos, los estanques y los ríos, todos polígonos, y el mar abierto no correspondía a nada.</p>
<p>Ahora bien, fuera de un polígono reconocido, mi programa supone pinar. Era una elección deliberada: en el macizo forestal de las Landas domina el pino marítimo, y equivocarse del lado de «esto arde» sesga el modelo hacia el lado prudente. Salvo que aplicar esa prudencia al 40 % del dominio de cálculo ya no se llama prudencia. En este mapa, el agua pasa del 3,4 % al 40,7 % una vez corregido: <strong>más de un tercio de mi zona de trabajo era océano inflamable</strong>.</p>
<p>Mi primera corrección recuperaba la línea de costa y recortaba el dominio con ella &mdash; perfecto en mi prueba aislada. En condiciones reales, fracaso: tres consultas de doce al servidor de OpenStreetMap volvieron con error, la línea quedó agujereada, y una línea agujereada no recorta nada. El mar volvió a ser combustible.</p>
<p>La buena solución estaba en otra parte, y explota una convención de OpenStreetMap: cuando se traza una costa, <strong>la tierra está siempre a la izquierda del sentido de trazado</strong>. Basta entonces, para cada celda, con encontrar el segmento de costa más cercano y mirar de qué lado cae &mdash; un simple producto vectorial. A la izquierda la tierra, a la derecha el mar. Un hueco en los datos ya solo cuesta la precisión local alrededor del hueco.</p>
<p>Solo supe que mi primera corrección había fracasado porque me había tomado la molestia de hacer gritar al programa. Cuando no conseguía reconstituir el mar, escribía negro sobre blanco en su informe: <em>«línea de costa presente pero imposible deducir de ella la extensión del mar: el mar abierto corre el riesgo de tratarse como combustible»</em>. Un modelo que falla en silencio miente. Un modelo que falla ruidosamente se deja reparar.</p>
<hr />
<h3 id="la-pregunta-incomoda-funciona">La pregunta incómoda: ¿funciona?</h3>
<p>A estas alturas, la herramienta producía bonitos mapas. Un bonito mapa nunca ha demostrado nada.</p>
<p>Y tenía a mano con qué ponerla en evidencia: el incendio duraba ya varios días, así que su propio pasado estaba disponible. En lugar de esperar a ver si las próximas previsiones acertaban, mejor repetir las que se habrían podido hacer dos días antes y mirar cuánto valían. Es un método conocido, y tiene nombre: la <strong>retroprevisión</strong>.</p>
<p><strong>Retroprevisión</strong> (o <em>hindcast</em>) &mdash; uno se sitúa en un instante del pasado, conserva solo los datos disponibles en esa fecha, simula hacia delante y luego compara con lo que ocurrió realmente. Es la manera estándar de evaluar un modelo de previsión cuando uno no puede permitirse esperar.</p>
<p>Me sitúo pues en la mañana del 24 de julio, descarto todo lo observado después, simulo doce horas y comparo con lo que realmente ardió. Luego vuelvo a empezar el 25. Dos ejecuciones, un puñado de minutos de cálculo &mdash; y con mucha diferencia la mejor relación entre el esfuerzo invertido y lo que me enseñó.</p>
<p><a href="https://pf.olibrio.fr/images/kokusho/validation.svg" title="Abrir el gráfico en grande"><img alt="Gráfico de barras que compara, a la misma escala, la superficie realmente quemada en doce horas y la producida por el modelo. El 24 de julio, cuando el fuego corría libremente, 4 642 hectáreas observadas frente a 10 008 simuladas, es decir, un sesgo de superficie de 1,7. El 25 de julio, cuando los equipos de extinción contenían el frente, 1 645 hectáreas observadas frente a 22 758 simuladas, es decir, un sesgo de 12,3" src="https://pf.olibrio.fr/images/kokusho/validation.svg" /></a></p>
<p>La mañana del 24, cuando el fuego corría libremente, el modelo sobrepredice por un factor de 1,7. Para un modelo de propagación es honorable &mdash; se está en el orden de magnitud correcto. El 25, cuando los equipos de extinción retomaban el control del frente: factor 12,3.</p>
<p>Lo interesante no es que el modelo se equivoque. Es <strong>por dónde pasa la diferencia entre las dos jornadas</strong>. El modelo no se volvió malo de un día para otro: mismo código, mismo viento, mismo bosque. Lo que cambió entre el 24 y el 25 fueron los medios de lucha.</p>
<p>Mi programa no los ve. No sabe nada de los efectivos desplegados, ni de las <strong>líneas de apoyo</strong> &mdash; esos cortes que los bomberos abren con bulldozer para detener el frente &mdash; ni de las descargas aéreas. Calcula por tanto, sin que yo lo haya decidido explícitamente, <strong>un contrafactual sin lucha</strong>: lo que haría el incendio si nadie se le opusiera. El 25, la física sola daba 22 758 hectáreas; el fuego solo recorrió 1 645, porque hubo gente que se lo impidió.</p>
<p>Hay un consuelo en esas cifras, y es importante. Cabe en una medida que se llama <strong>AUC</strong>.</p>
<p><strong>AUC</strong>, por <em>área bajo la curva ROC</em> &mdash; mide la calidad de una <em>clasificación</em>, independientemente de los valores absolutos. Si tomo al azar una celda que ardió y una que no ardió, el AUC es la probabilidad de que el modelo haya clasificado mejor la primera. 0,5 = cara o cruz, 1 = clasificación perfecta.</p>
<p>Mi AUC vale <strong>entre 0,96 y 0,98</strong> en ambos casos &mdash; mientras el sesgo de superficie, por su parte, varía por un factor de siete. Dicho de otro modo: <strong>el modelo sabe muy bien adónde va el fuego, y se equivoca gravemente sobre cuánto</strong>. Es el mejor modo de fallo posible, porque un error de escala se calibra, mientras que un error de dirección condena la herramienta.</p>
<p>Lo que me lleva a la decisión menos intuitiva de todo este bricolaje. Tenía un factor de ajuste listo: frenar la propagación lo justo para volver a caer en el 25 de julio. <strong>No lo apliqué.</strong> Sería grabar en el modelo la hipótesis «la lucha siempre tiene éxito» &mdash; precisamente aquella de la que no hay que fiarse delante de una central nuclear. La herramienta, por lo demás, se niega por sí misma a publicar un factor global cuando sus casos de validación son demasiado heterogéneos, y explica por qué en lugar de promediar dos regímenes incomparables.</p>
<hr />
<h3 id="lo-que-no-hace-y-es-lo-mas-grave">Lo que no hace &mdash; y es lo más grave</h3>
<p>La peor limitación no es ninguna de las que acabo de contar. Cabe en una palabra: <strong>el acoplamiento es de sentido único</strong>. La meteorología gobierna el fuego; el fuego nunca modifica la atmósfera.</p>
<p>Ahora bien, un gran incendio fabrica su propia meteorología. Es la <strong>piroconvección</strong>: la columna de aire sobrecalentado que envía hacia el cielo puede subir varios kilómetros y formar un <strong>pirocumulonimbo</strong>, una auténtica nube de tormenta nacida del propio fuego. Produce rayos secos que encienden focos a decenas de kilómetros, y puede colapsar de golpe, abatiendo contra el suelo una ráfaga violenta, en una dirección cualquiera.</p>
<p>Es exactamente lo que hace escapar a los fuegos que se creían contenidos, y es <em>independiente del viento sinóptico</em> &mdash; el viento de gran escala, el que prevé AROME. Por tanto, invisible para mi modelo. Existe un verdadero acoplamiento fuego-atmósfera, lleva nombres como Meso-NH/ForeFire o WRF-SFIRE, y exige medios de cálculo de laboratorio. Fuera de alcance.</p>
<p>El compromiso: no simular el fenómeno, sino evaluar su <em>potencial</em>. Existe para ello un indicador, el <strong>índice de Haines continuo</strong>, que combina la inestabilidad del aire en altura y su sequedad &mdash; en suma, dice si el cielo «hace chimenea» ese día. Cruzado con la potencia radiativa del fuego, me da una puntuación. Una fracción de mis 200 sorteos, igual a esa puntuación, pasa entonces a <strong>régimen piroconvectivo</strong>: dirección mucho más incierta, propagación aumentada, saltos de fuego más numerosos y más lejanos. Esos sorteos alimentan naturalmente la envolvente extrema.</p>
<p>Un potencial elevado se lee entonces como «las envolventes amplias se vuelven creíbles», nunca como «va a ocurrir esto».</p>
<p>Otro punto ciego, descubierto viendo llegar la ola de calor de esta semana. Mi humedad de los combustibles finos procede de una fórmula clásica de peligro meteorológico, la de Simard, que solo mira la temperatura y la humedad relativa <em>instantáneas</em>. No tiene ninguna memoria. Ahora bien, tres días a 38 °C secan la hojarasca en profundidad, y el suelo con ella. De ahí este resultado absurdo: mi modelo muestra una humedad de los combustibles que <em>sube</em> el día en que hará 39,8 °C. Subestima por tanto el efecto de una ola de calor. Harían falta índices con memoria, del tipo DMC y DC del <strong>índice meteorológico de incendios forestales canadiense</strong>, que acumulan el déficit hídrico a lo largo de días y semanas. Es el próximo frente de trabajo.</p>
<hr />
<h3 id="entonces-el-blayais">Entonces, ¿el Blayais?</h3>
<p><a href="https://pf.olibrio.fr/images/kokusho/carte-kokusho-grand.jpg" title="Abrir la captura en grande"><img alt="Captura de la herramienta en línea. A la izquierda un mapa del litoral aquitano: la superficie ya recorrida en gris, el frente activo en naranja, y las envolventes a 48 horas en contornos amarillos alrededor de dos focos. A la derecha un panel que da, para cada emplazamiento sensible, el nivel de amenaza, la confianza, la distancia al frente y las distancias mínimas simuladas" src="https://pf.olibrio.fr/images/kokusho/carte-kokusho.jpg" /></a></p>
<p>Haz clic para ampliar &mdash; o ve a ver la versión viva en <a href="https://kokusho.ss2i.ca">kokusho.ss2i.ca</a>.</p>
<p>La respuesta se mantuvo igual del primer al último cálculo: <strong>frente observado a 36 kilómetros, ninguno de los 200 escenarios se acerca a menos de 10 kilómetros, viento que empuja en sentido opuesto</strong>. La central nunca estuvo amenazada. Y la herramienta lo dice con sus motivos, no con un veredicto.</p>
<p>El emplazamiento realmente expuesto estaba en otra parte: la base aérea de Cazaux, a 7 kilómetros del foco de Biscarrosse, con hasta un 6,7 % de los escenarios alcanzando su zona ampliada.</p>
<p>Y luego hubo esa última mañana en que Cazaux pasó bruscamente a naranja, con un 96,7 % de los escenarios alcanzando esa misma zona. Espectacular. Y falso.</p>
<p>El satélite no había visto nada desde hacía quince horas. Mi programa había recurrido a su hipótesis de repliegue: a falta de saber dónde se encuentra el frente activo, considerar que <em>todo</em> el perímetro recorrido está activo. El incendio se propagaba, pues, en todas las direcciones a la vez, y mi 96,7 % ya no medía una convergencia hacia Cazaux &mdash; medía mi ignorancia. La velocidad de aproximación realmente observada, en cambio, era nula.</p>
<p>Desde ahora, en ese caso concreto, el nivel vuelve a caer en «incertidumbre elevada, ninguna aproximación observada» en lugar de gritar ¡fuego! &mdash; salvo si se mide realmente una aproximación, en cuyo caso la alerta se mantiene. Es quizá la corrección de la que estoy más contento: impide que la herramienta convierta una ausencia de información en alerta.</p>
<hr />
<h3 id="lo-que-me-llevo-de-todo-esto">Lo que me llevo de todo esto</h3>
<p>Todo esto se improvisó en dos días, y el código no lo tecleé yo: lo hice escribir por una IA. El mismo método que para el descapotable checo hace tres semanas, pero esta vez sobre un tema en el que equivocarse no es anodino.</p>
<p>Lo que no se delega, en cambio, es el resto: decidir que se mostrarían envolventes y nunca una trayectoria, elegir las fuentes, exigir que el modelo se pusiera a prueba con el pasado del incendio y no con pruebas de laboratorio, y volver a abrir el mapa de entrada cuando un resultado olía a falso. La máquina escribe rápido y bien. No sabe qué hay que verificar.</p>
<p>Se encontraron cinco errores de fondo en el modelo. Lo que más me sorprendió fue mirar <em>por medio de qué</em>:</p>
<ul>
<li>el fuego prisionero de su cicatriz: por una cifra inverosímil en un informe;</li>
<li>la rasterización que se atascaba: por un cálculo que ya no devolvía el control;</li>
<li>el mar combustible: <strong>porque acabé mirando el mapa de entrada</strong>, el que nadie piensa en abrir;</li>
<li>la reconstrucción del litoral que no aguantaba en condiciones reales: por un aviso que me había tomado la molestia de escribir para ese caso concreto;</li>
<li>la falsa alerta naranja: confrontando lo que decía la simulación con lo que decía la observación.</li>
</ul>
<p>Ninguno fue encontrado por las pruebas automáticas. Tengo sesenta y cuatro, y cada uno de esos bugs tiene ahora la suya &mdash; impedirán la regresión. Pero ninguna prueba podía adivinar que OpenStreetMap no cartografía el océano. <strong>Las pruebas verifican aquello en lo que ya se ha pensado. Callan sobre el resto.</strong></p>
<p>Lo que funcionó fue el roce con lo real: los datos verdaderos, el mapa verdadero, el pasado verdadero del incendio. La retroprevisión me enseñó más en dos ejecuciones que dos días de desarrollo.</p>
<p>Y su enseñanza principal no era «el modelo se equivoca en tanto». Era: <strong>el modelo no responde a la pregunta que yo creía hacerle</strong>. Le preguntaba qué iba a hacer este incendio. Me respondía qué haría si nadie se le opusiera.</p>
<p>Es una información útil &mdash; es incluso exactamente la que hace falta para saber de qué es capaz un incendio. Pero no es la que uno cree leer en un mapa.</p>
<hr />
<p>🔥 <strong><a href="https://kokusho.ss2i.ca">Ver la herramienta en línea &mdash; kokusho.ss2i.ca</a></strong></p>
<p>Experimental, sin valor oficial. En caso de incendio, la única fuente que da fe es la prefectura: <a href="https://www.landes.gouv.fr/">landes.gouv.fr</a> · <a href="https://www.gironde.gouv.fr/">gironde.gouv.fr</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>La noche trabaja para nosotros</title>
      <link>https://pf.olibrio.fr/es/posts/la-nuit-travaille-pour-nous.html</link>
      <guid isPermaLink="true">https://pf.olibrio.fr/es/posts/la-nuit-travaille-pour-nous.html</guid>
      <pubDate>Mon, 13 Jul 2026 12:00:00 +0000</pubDate>
      <description>37,7 °C fuera, 30 °C en el cuarto de baño y la ventilación sin funcionar en toda la semana. Cómo una casa instrumentada evacúa su calor por la noche.</description>
      <category>ola de calor</category>
      <category>free cooling</category>
      <category>vmc</category>
      <category>sensores</category>
      <category>aislante</category>
      <category>desajuste climático</category>
      <content:encoded><![CDATA[<p><img src="https://pf.olibrio.fr/images/nuit/semaine-canicule.png" alt="La noche trabaja para nosotros"></p>
<p>Son las 16 h, fuera hace 37,7 °C en el momento más caluroso de las últimas veinticuatro horas, y mi cuarto de baño marca 30 °C. No el cuarto de baño después de una ducha: el cuarto de baño vacío, con las persianas bajadas, sin nadie dentro. Eso es lo que una ola de calor le hace a una casa &mdash; la va llenando despacio, grado a grado, por el tejado, por las paredes, por cada cristal, y al caer la tarde la casa se ha convertido en un radiador que le devuelve a uno la jornada entera mientras intenta dormir.</p>
<p>Contra eso, en el momento, poco se puede hacer. Pero la ola de calor tiene un defecto: <strong>la noche</strong>. Hacia las 4 h de la madrugada, el aire exterior baja a 20 °C, a veces menos. Durante unas horas hay fuera una reserva de frescor gratuita, inmensa, renovada cada noche &mdash; y la única pregunta que importa es: ¿cómo hacerla entrar?</p>
<hr />
<h3 id="un-extractor-de-cuarto-de-bano-como-caballo-de-tiro">Un extractor de cuarto de baño como caballo de tiro</h3>
<p>La casa ya tenía todo lo necesario, en realidad. Bastaba con mirarlo de otra manera.</p>
<p>Abajo, una toma de aire fresco, instalada en su día para alimentar la estufa de leña. Arriba, en la planta superior, el cuarto de baño &mdash; el punto más caliente de la casa, física elemental. Y entre ambos, una modesta VMC (la sigla francesa de la ventilación mecánica controlada) que desde hace años solo se ocupa de la humedad: se enciende cuando la ducha empaña, se apaga cuando está seco.</p>
<p>Ahora bien, si se hace funcionar ese extractor por la noche, ocurre algo más interesante: aspira el aire caliente acumulado arriba, lo expulsa fuera, y la depresión tira del aire fresco de la noche por la toma de aire de abajo. Toda la casa se convierte en un circuito: el aire fresco entra por la planta baja, la atraviesa, sube y vuelve a salir por arriba llevándose el calor del día. El beneficio no es local, del cuarto de baño &mdash; es un <strong>tiro térmico a escala de la casa</strong>, con un ventilador de unas decenas de vatios como único motor.</p>
<p>Los anglófonos lo llaman <em>free cooling</em>. A mí me gusta más decirlo a mi manera: la noche trabaja para nosotros.</p>
<hr />
<h3 id="la-regla-y-las-trampas-que-evita">La regla, y las trampas que evita</h3>
<p>Quedaba por escribir la regla de decisión. El pequeño ordenador que gobierna el extractor consulta ahora la meteorología y solo enciende la extracción si se cumplen <strong>cuatro condiciones</strong> a la vez:</p>
<ol>
<li>el <strong>máximo exterior de las últimas 24 horas</strong> supera los 22 °C &mdash; estamos de verdad en temporada cálida;</li>
<li>el cuarto de baño supera los 24 °C &mdash; arriba hace calor de verdad;</li>
<li>el salón supera los 20 °C &mdash; la casa no está ya refrescada;</li>
<li>el aire exterior está <strong>al menos 3 °C más fresco</strong> que el interior &mdash; si no, removeríamos aire para nada.</li>
</ol>
<p>La sutileza está en la primera condición. Uno podría pensar que basta con comparar dentro y fuera. Error &mdash; y un error que saldría caro en enero: una casa calentada con la estufa a 24 °C con 5 °C fuera muestra una diferencia de 19 °C, más que suficiente para disparar una regla ingenua&hellip; que entonces tiraría el calor de la leña por la ventana, aspirando aire helado por la toma de aire. La misma que alimenta la estufa. El sistema se sabotearía a sí mismo.</p>
<p>De ahí el criterio de <em>temporada</em>: el <strong>máximo exterior en 24 h deslizantes</strong>. Mis registros de enero no pasan de 14,6 °C; los del verano nunca bajan de 22 °C. Entre ambos, un abismo &mdash; la barrera es infranqueable por accidente. Y sobre todo, no mira la temperatura del instante: una noche a 13 °C después de un día a 32 °C es precisamente el momento de extraer, y un umbral instantáneo lo habría prohibido.</p>
<hr />
<h3 id="lo-que-dicen-las-cifras">Lo que dicen las cifras</h3>
<p>Antes de conectar nada, reproduje la regla sobre los datos reales de la semana anterior &mdash; la casa lo registra todo desde hace años, que sirva de algo.</p>
<p><img alt="Una semana de ola de calor: la temperatura exterior oscila entre 20 y 38 °C mientras el cuarto de baño se instala en torno a los 28-30 °C; en el extremo derecho, la orden del ventilador pasa a ON" src="https://pf.olibrio.fr/images/nuit/semaine-canicule.png" /></p>
<p><em>La semana en una imagen: el exterior (azul) respira de 20 a 38 °C, el cuarto de baño (rosa) encaja el golpe y se instala en torno a los 28-30 °C. Y en el extremo derecho, ese trazo que sube: la orden del ventilador que pasa a ON &mdash; el sistema acaba de armarse, a unas horas de su primera noche.</em></p>
<p>Veredicto: en la semana del 6 al 13 de julio, la regla habría disparado <strong>48 horas de extracción</strong>. Diferencia media entre dentro y fuera en el momento de los disparos: <strong>4,9 °C</strong>. Franjas: concentradas entre <strong>la 1 h y las 9 h de la mañana</strong>, nunca por la tarde &mdash; la regla ha encontrado por sí sola el ritmo de las noches.</p>
<p>Y la cifra que más me ha divertido: durante esa misma semana de ola de calor, el extractor no funcionó <strong>ni un solo minuto</strong>. El aire estaba tan seco (del 29 al 37 % de humedad en el cuarto de baño, con un umbral de disparo del 60 %) que su misión histórica nunca lo despertó. Un motor perfectamente funcional, instalado, cableado, alimentado &mdash; y dormido al 100 %, justo la semana en que más tenía que ofrecer. Es exactamente el tipo de yacimiento que me gusta: cero material que comprar, solo una regla que escribir.</p>
<p>Esta noche es la primera en condiciones reales. La incógnita es franca: la toma de aire se dimensionó para la combustión de una estufa, no para ventilar una casa. Si su sección es demasiado justa, el ventilador tirará sobre todo de las fugas de estanqueidad y el caudal real será decepcionante. Será la curva de mañana por la mañana la que decida &mdash; si el cuarto de baño se desmarca claramente de las noches anteriores, está ganado.</p>
<hr />
<h3 id="acontecimientos-notables-7-c-y-417-c-el-mismo-ano">Acontecimientos notables: −7 °C y +41,7 °C, el mismo año</h3>
<p>Una casa que lo registra todo acumula su pequeña mitología. La tabla de récords exteriores de 2026, por su parte, casi no necesita comentario:</p>
<ul>
<li><strong>6 de enero de 2026: −7,0 °C.</strong> El día más frío jamás anotado por la estación. La estufa funcionó sin parar, la toma de aire de abajo aspiraba escarcha.</li>
<li><strong>23 de junio de 2026: 41,7 °C.</strong> El más caluroso &mdash; antes incluso del verano oficial. Tres horas seguidas por encima de los 41 °C.</li>
</ul>
<p><img alt="Llanura cubierta de nieve bajo un sol rasante, cielo despejado, durante el episodio de frío de enero de 2026" src="https://pf.olibrio.fr/images/nuit/janvier-neige.jpg" /></p>
<p><em>La mañana del récord: la llanura bajo la nieve, cielo límpido &mdash; el mismo cielo despejado que, seis meses después, dejará que el sol empuje el termómetro hasta los 41,7 °C.</em></p>
<p><strong>48,7 grados de amplitud en menos de seis meses</strong>, en el mismo lugar, medidos por la misma cadena de sensores. La media, en cambio, se desliza sin hacer ruido &mdash; y ahí está precisamente la trampa.</p>
<p>Me recordó a Mélenchon, en su primera campaña presidencial, que ya se irritaba con la palabra «calentamiento»: una palabra demasiado suave, casi una promesa de primavera temprana, dos grados más sobre una media, ¿quién lo notaría? Y que le prefería, con insistencia, «<strong>desajuste climático</strong>». El matiz no es cosmético, es toda la cuestión: lo que estropea las casas, las cosechas y a las personas no es la media que se desliza &mdash; son <strong>los extremos que se separan en ambos sentidos</strong>. Las heladas más mordientes <em>y</em> las olas de calor más tempranas. Una máquina climática que no ha ganado simplemente un grado: que ha perdido su termostato.</p>
<p><img alt="Tendencia climática del 13 de julio en Puilboreau desde 1970: mínimas, medias y máximas en ±7 días, con una pendiente de +0,32 °C por década" src="https://pf.olibrio.fr/images/nuit/tendance-13-juillet.png" /></p>
<p><em>El 13 de julio a lo largo de los años, desde 1970 (agregados de Open-Meteo para mi casa). La media sube </em><em>+0,32 °C por década</em><em> &mdash; 19,5 °C en los primeros años de la serie, 21,5 °C en los diez últimos. Dos grados en medio siglo: eso es el «calentamiento», y en este gráfico parece inofensivo. Lo que solo se ve entornando los ojos es la curva rosa de las máximas, que se desboca &mdash; los picos recientes revientan el techo de los años 70. El desajuste es ella.</em></p>
<p>Mis dos récords de 2026 sostienen la demostración por sí solos. Y exactamente por eso se instrumenta una casa: uno no se prepara para una media, se prepara para los extremos &mdash; en ambos sentidos.</p>
<hr />
<h3 id="bajo-el-capo-para-quien-quiera-construirlo">Bajo el capó, para quien quiera construirlo</h3>
<p>Todo lo anterior se sostiene con material de fondo de cajón &mdash; ese es el punto importante, y la razón de ser de esta entrada: cualquiera puede montarlo un domingo.</p>
<ul>
<li><strong>En el cuarto de baño: una Raspberry Pi Zero W</strong> (~15 €), un sensor de temperatura/humedad <strong>DHT11</strong> de 2 € en un GPIO, y un <strong>emisor de radio de 433 MHz</strong> de 2 € en otro.</li>
<li><strong>El extractor no se modifica ni en un cable.</strong> Está enchufado a un <strong>enchufe con mando a distancia de 433 MHz</strong> de supermercado (~10 €): la Pi se limita a reproducir los códigos ON/OFF del mando original (biblioteca <code>rpi-rf</code>, protocolo 1, pulso de 350 µs &mdash; los valores se capturan escuchando el mando con un receptor de 1 €). Ningún cableado a 230 V, reversible en treinta segundos.</li>
<li><strong>Un pequeño servidor en alguna parte</strong> &mdash; aquí un VPS de unos pocos euros, pero un NAS o una segunda Pi harían exactamente lo mismo: una página PHP, una base <strong>SQLite</strong>, y nada más.</li>
</ul>
<p><img alt="Raspberry Pi Model B Revision 2, la placa de 2012" src="https://pf.olibrio.fr/images/nuit/pi-model-b.jpg" /> <img alt="Raspberry Pi Zero, la placa diminuta que gobierna el extractor" src="https://pf.olibrio.fr/images/nuit/pi-zero.jpg" /> <img alt="Sensor de temperatura y humedad DHT11, la cajita azul estriada" src="https://pf.olibrio.fr/images/nuit/dht11.jpg" /></p>
<p><em>Los obreros de la casa. Arriba, el veterano: una Raspberry Pi Model B de 2012 &mdash; 14 años de servicio, gobierna la calefacción del salón en Ruby. En medio, la Pi Zero del cuarto de baño, que acaba de aprender el free cooling. Abajo, sus ojos: el DHT11, el sensor de temperatura/humedad de 2 € &mdash; la cajita azul estriada con la que cualquier aficionado a la electrónica se ha cruzado alguna vez. (Fotos: Gareth Halfacree CC BY-SA 2.0; Evan-Amos, dominio público; Crackopl CC BY-SA 3.0.)</em></p>
<p><strong>La caza de vatios</strong> forma parte del juego, para máquinas que funcionan las 24 h del día. La Pi Zero consume ~0,6 W. La vieja Model B se lleva ~2,5 &mdash; por culpa de sus reguladores lineales de 2012, que queman el exceso de tensión en puro calor, y de su chip USB/Ethernet alimentado permanentemente. Contra la arquitectura no se puede hacer nada, pero sí se puede recortar la grasa del software: hurgando en el veterano esta semana, encontré un MySQL y un Apache de 2017 que llevaban nueve años funcionando para nada, una salida HDMI activa en NTSC sin pantalla al otro extremo, un Bluetooth nunca emparejado y un demonio que esperaba los atajos de un teclado fantasma. Todo apagado: dos grados menos en el procesador en plena ola de calor, 38 MB de RAM devueltos y, sobre todo, se acabaron las escrituras inútiles en la tarjeta SD &mdash; ella sí que es la verdadera asesina. A escala de la factura es anecdótico (2,5 W ≈ 22 kWh/año ≈ 5 €), pero un sistema que uno quiere ver durar diez años tiene que ser magro.</p>
<p>Las decisiones de arquitectura las dicta todas la misma obsesión: sobrevivir a las averías, a los reinicios del router y a los años.</p>
<ul>
<li><strong>Nada de demonio: un cron.</strong> El controlador se lanza cada 5 minutos, vive veinte segundos, mide, decide, envía su código de radio y se apaga. Un proceso que no está en ejecución no puede tener fugas ni bloquearse &mdash; la Pi va por 267 días de uptime sin pensar en ello.</li>
<li><strong>Siempre es la Pi la que tira, nunca el servidor el que empuja.</strong> La Pi vuelve a descargar su configuración (un YAML) cada minuto con un simple <code>curl</code>, y consulta la meteorología en el momento de decidir. Detrás de cualquier router, NAT o cambio de IP, funciona &mdash; y la casilla «Activar» marcada en la página web es efectiva sobre el terreno al minuto siguiente.</li>
<li><strong>La meteorología viene de Open-Meteo</strong> (open-meteo.com): API gratuita, sin clave, con histórico. Un cron horario la archiva del lado del servidor, y la Pi recibe un JSON mínimo: temperatura actual, máximo en 24 h deslizantes, temperatura del salón. Servir únicamente lo observado &mdash; nunca la previsión &mdash; tiene su importancia: la línea de las 23 h anunciaba 24 °C mientras fuera hacía 35, y una regla alimentada con previsiones habría aspirado el aire del horno.</li>
<li><strong>Una tabla única para todo</strong>: <code>observations (source, metric, value, unit, metadata)</code>. Sensores, consignas, órdenes, meteorología &mdash; todo entra en el mismo molde. Añadir un sensor es añadir una <em>source</em>, cero migraciones. Es esta tabla la que permitió reproducir la regla sobre los archivos antes de conectarla.</li>
<li><strong>Fallo cerrado.</strong> Servidor inalcanzable o meteorología con más de dos horas de antigüedad → la Pi vuelve a su lógica de humedad original. Sin máximo de 24 h → sin extracción (la barrera de temporada no se salta por accidente). El peor escenario de una avería es el comportamiento de antes.</li>
<li>Las curvas de la página las traza <strong>uPlot</strong>, una biblioteca de ~50 KB que aguanta decenas de miles de puntos sin inmutarse.</li>
</ul>
<p>Y una palabra sobre lo que, a mis ojos, no es negociable: <strong>estos datos nunca salen de mi perímetro</strong>. Lo que miden estos sensores es el interior de una casa &mdash; cuándo uno se ducha, cuándo la calienta, cuándo está vacía. Las Pis empujan sus lecturas por SSH hacia un servidor <em>que administro yo</em>, la página que las muestra pide una contraseña, y el bucle se detiene ahí. Nada de nube del fabricante, nada de «skill» de Alexa, nada de SaaS domótico que cierra dentro de tres años llevándose el histórico, ni un byte en las analíticas de nadie. La única dependencia exterior va en el otro sentido: la casa <em>descarga</em> la meteorología pública de Open-Meteo, no envía nada. El día que cambie el servidor &mdash; un NAS, otro VPS, una caja de zapatos &mdash; se mueve un archivo SQLite y todo vuelve a arrancar.</p>
<p>Presupuesto total por habitación instrumentada: <strong>menos de 30 €</strong>. El lujo no está en el material &mdash; está en los años de datos que se acumulan, que se pueden consultar el día en que se tiene una idea, y que no pertenecen a nadie más que a uno mismo.</p>
<hr />
<h3 id="lo-que-viene-entrar-en-el-espesor-de-las-cosas">Lo que viene: entrar en el espesor de las cosas</h3>
<p>Hasta ahora, todos mis sensores miden <em>habitaciones</em>. El siguiente paso es más íntimo: entrar <strong>en el aislante</strong>.</p>
<p>El proyecto: una varilla clavada verticalmente en el aislante del desván, con cuatro sondas de temperatura escalonadas &mdash; superficie, un tercio, dos tercios, fondo contra la placa de yeso. Encima, una quinta sonda en el aire bajo las tejas, que en estos días sube a 60-70 °C. Debajo, el termostato del salón, ya instalado. Una columna de medida completa, del sol a la sala de estar.</p>
<p>Lo que contará, día tras día:</p>
<ul>
<li><strong>El desfase real</strong>: ¿cuántas horas tarda el pico de calor bajo las tejas en atravesar el aislante? El fabricante anuncia un valor teórico; el aislante apelmazado y envejecido hace lo que le da la gana. Quiero la cifra verdadera, en mi casa.</li>
<li><strong>La amortiguación</strong>: ¿cuánto se aplasta la amplitud día/noche entre la superficie y el fondo?</li>
<li><strong>El efecto de las chimeneas de tiro</strong> que instalé en el tejado para evacuar el calor bajo las tejas: con meteorología comparable, la superficie del aislante debe estar más fresca si el tiro hace su trabajo. Dos columnas de sondas &mdash; una cerca de las chimeneas, otra lejos &mdash; y la respuesta caerá por sí sola.</li>
<li>Y a largo plazo, un <strong>detector de envejecimiento</strong>: un desfase que se acorta año tras año es un aislante que se degrada. Más vale saberlo antes de que lo diga la factura de calefacción.</li>
</ul>
<p>En cuanto al material, nada heroico: sondas estancas de unos pocos euros en un bus de un par de hilos, un microcontrolador que duerme el 99,9 % del tiempo con dos baterías recuperadas &mdash; lo bastante para aguantar unos dos años sin cambiar las pilas. La electrónica se queda al fresco en la parte baja del desván; solo las sondas suben al frente.</p>
<hr />
<h3 id="y-en-invierno-se-invierte-todo">Y en invierno, se invierte todo</h3>
<p>La ola de calor terminará. Y la misma fontanería intelectual volverá a servir, vuelta del revés como un guante.</p>
<p>La próxima obra que me ronda la cabeza: <strong>paneles térmicos de aire en la fachada exterior</strong> &mdash; captadores solares de lo más simple, una caja negra acristalada en la que el aire se calienta al sol de invierno. Incluso con 5 °C fuera, un panel bien orientado saca aire a 30 o 40 °C a mediodía. Conectado a la toma de aire de la casa, se convierte en <strong>precalentamiento gratuito</strong>: en lugar de aspirar aire a 5 °C para alimentar la estufa y compensar la extracción, se aspira aire ya templado por el sol.</p>
<p>Y el bucle se cierra con elegancia: es la misma lógica de decisión que el free cooling, invertida. En verano se extrae de noche cuando <em>fuera \&lt; dentro</em>. En invierno se inyectará de día cuando <em>panel &gt; dentro</em>. Los mismos sensores, la misma meteorología, la misma regla de cuatro condiciones con sus barreras &mdash; solo cambia el signo. Las sondas del aislante dirán incluso si el precalentamiento se nota en el gradiente del desván.</p>
<p>Una casa, en el fondo, es un sistema térmico que se ignora a sí mismo. La mía apenas empieza a conocerse &mdash; y esta noche, por primera vez, va a intentar refrescarse sola mientras duermo. Mañana les cuento si lo ha conseguido.</p>
<hr />
<h3 id="post-scriptum-la-manana-del-14-de-julio">Post scriptum, la mañana del 14 de julio</h3>
<p>La primera noche ha tenido lugar. El ventilador extrajo durante cerca de <strong>doce horas</strong>, de las 19 h a las 8 h, con una pausa de una hora hacia la 1 h de la madrugada &mdash; la diferencia había vuelto a caer por debajo del umbral de parada, la regla hizo exactamente lo que se le enseñó.</p>
<p>Resultado en bruto: cuarto de baño de <strong>31 °C al acostarse a 26 °C al levantarse</strong>. La mejor noche de la semana. Pero la cifra que me gusta está en otra parte. Las noches anteriores, el exterior bajaba a 23-24 °C y el cuarto de baño se quedaba clavado en 28: cuatro o cinco grados de diferencia al levantarse, la firma de una casa que no intercambia nada con la noche. Esta vez, el controlador mantuvo la diferencia entre <strong>1,4 y 2,4 °C hasta la mañana</strong> &mdash; el interior <em>siguió</em> al exterior en su descenso, hora tras hora. La renovación del aire está ahí, y la incógnita de la toma de aire queda despejada: da caudal.</p>
<p>Transparencia obligada: las ventanas estuvieron abiertas esa noche, ola de calor obliga &mdash; imposible separar su parte de la del ventilador. La próxima noche se hará <strong>con las ventanas cerradas, solo el extractor</strong>. Si por la mañana el cuarto de baño sigue pegado al exterior a dos grados de diferencia, la demostración será completa. La ciencia doméstica avanza una noche cada vez.</p>
<hr />
<p><em>Episodio siguiente: las curvas de la primera noche con las ventanas cerradas, y lo que 48 horas de tiro nocturno cambian (o no) en una ola de calor.</em></p>]]></content:encoded>
    </item>
    <item>
      <title>Ingeniería inversa de un sofá cama de 1970, con una IA a los mandos de Blender</title>
      <link>https://pf.olibrio.fr/es/posts/retro-ingenierie-convertible-1970.html</link>
      <guid isPermaLink="true">https://pf.olibrio.fr/es/posts/retro-ingenierie-convertible-1970.html</guid>
      <pubDate>Sun, 05 Jul 2026 12:00:00 +0000</pubDate>
      <description>Un sofá cama checoslovaco visto en internet, una IA que pilota Blender y tres teorías equivocadas antes de la buena. Una reconstrucción paramétrica.</description>
      <category>blender</category>
      <category>ia</category>
      <category>mueble</category>
      <category>mid-century</category>
      <category>paramétrico</category>
      <category>mecánica</category>
      <content:encoded><![CDATA[<p><img src="https://pf.olibrio.fr/images/sofa/00-illustration-manga.png" alt="Ingeniería inversa de un sofá cama de 1970, con una IA a los mandos de Blender"></p>
<p><img alt="El sofá cama OPP Drevovyroba, en versión tinta y tramas" src="https://pf.olibrio.fr/images/sofa/00-illustration-manga.png" /></p>
<p><em>Ilustración: reinterpretación al estilo manga de una foto del vendedor &mdash; el original está en <a href="https://justchairs.eu/products/mid-century-convertible-sofa-by-opp-drevovyroba-1970s">justchairs.eu</a>.</em></p>
<p>Me crucé en internet con un sofá cama checoslovaco de los años 70, firmado OPP Drevovyroba, <a href="https://justchairs.eu/products/mid-century-convertible-sofa-by-opp-drevovyroba-1970s">a la venta en una tienda de Budapest</a>. Línea baja, reposabrazos esculturales en contrachapado de teca curvado, y un mecanismo despachado en una frase: «el sofá se transforma en cama con un solo gesto». 1 550 €, a 1 500 km de mi casa, y unas dimensiones que no encajan en mi salón. La conclusión se imponía: en lugar de comprarlo, volver a dibujarlo &mdash; y aprovechar para entenderlo.</p>
<p>Esta entrada cuenta el ejercicio, llevado a cabo con una IA (Claude) que pilota Blender en directo. Spoiler: la IA se equivocó tres veces sobre el mecanismo, y eso es precisamente lo que hace interesante la historia.</p>
<h2 id="el-montaje">El montaje</h2>
<p>En cuanto a herramientas, la cosa se ha vuelto casi rutinaria: Blender, un pequeño addon que abre un servidor en la máquina (<a href="https://github.com/ahujasid/blender-mcp">BlenderMCP</a>) y la IA que se conecta a él. Diez minutos de instalación. A partir de ahí, escribe Python dentro de Blender, construye geometría, hace capturas del viewport para comprobar su trabajo y vuelve a empezar. Yo miro el modelo girar en directo en mi pantalla y comento.</p>
<p>La apuesta desde el principio: un modelo <strong>paramétrico</strong>. Nada de esculpir con el ratón, sino un script con un bloque de parámetros en cabecera &mdash; anchura, altura de asiento, grosor de los cojines, inclinación del respaldo &mdash; y toda la geometría, mecanismo incluido, que se recalcula al cambiar un valor. Veremos que esta decisión salvó la partida más de una vez.</p>
<p><img alt="El modelo en posición sofá" src="https://pf.olibrio.fr/images/sofa/04-canape-34.png" /></p>
<h2 id="tres-teorias-para-un-mecanismo">Tres teorías para un mecanismo</h2>
<p>El vendedor aporta unas quince fotos, ninguna del mecanismo en acción. Así que hubo que deducir.</p>
<p><strong>Teoría n.º 1: la bisagra simple.</strong> Primera interpretación de la IA: el respaldo bascula hacia atrás sobre una bisagra, como un clic-clac. Modelado, animado&hellip; y demolido al mirar mejor las fotos: en posición cama, la franja delantera del colchón queda <em>delante</em> del asiento, no detrás. El respaldo pasa, por tanto, por encima del asiento. Adiós a la bisagra.</p>
<p><strong>Teoría n.º 2: la cinemática de cuatro barras.</strong> Si el respaldo tiene que sobrevolar el asiento sin chocar con él, me decía yo, tiene que girar <em>y</em> trasladarse &mdash; o sea, dos pivotes y unas bieletas. La IA se tomó la idea en serio, muy en serio incluso: escribió un solver que coloca los pivotes por búsqueda numérica a lo largo de las mediatrices de las dos poses, maximizando la holgura entre respaldo y asiento durante el vuelco. Resultado: un mecanismo de cuatro barras perfectamente funcional, con 17 mm de holgura verificados en todo el recorrido. Elegante. Y completamente falso.</p>
<p><strong>Teoría n.º 3: el pivote único.</strong> Fue un primer plano del reposabrazos lo que zanjó la cuestión: los tornillos que unen el brazo al respaldo son una fijación <em>rígida</em>, no un pivote. El brazo y el respaldo forman una sola pieza móvil, que gira alrededor del espárrago redondo visible en el costado del cajón. Un solo pivote por lado. Y ahí todo se ilumina: como el pivote está bajo y centrado, el arco de rotación <em>sube</em> por encima del asiento. Nunca hubo ningún problema de colisión que resolver. Los diseñadores checos no necesitaban bieletas &mdash; simplemente habían colocado bien un eje.</p>
<p>La lección merece enmarcarse: <strong>cuando la IA entiende mal la realidad, no se equivoca tímidamente &mdash; sobreingenieriza.</strong> El mecanismo de cuatro barras era la respuesta brillante a un problema que no existía.</p>
<p><img alt="A mitad de vuelco: el respaldo sobrevuela el asiento" src="https://pf.olibrio.fr/images/sofa/02-mi-bascule.png" /></p>
<p>El bonito gesto matemático sobrevivió al naufragio de la teoría n.º 2: dos poses de un sólido en el plano determinan un centro de rotación único &mdash; la intersección de las mediatrices. Ya no hace falta búsqueda numérica: el pivote se <em>calcula</em>, exactamente. Y cuando se le da la geometría de entrada correcta, cae a pocos milímetros de la ubicación del espárrago original. Una bonita validación cruzada, cincuenta años después.</p>
<h2 id="el-reposabrazos-que-se-convierte-en-pata">El reposabrazos que se convierte en pata</h2>
<p>Otro hallazgo de las fotos en posición cama: el respaldo sobresale 46 cm en voladizo por delante del cajón, y es <em>el reposabrazos</em> el que lo sostiene &mdash; al bascular, la rama del reposabrazos apunta al suelo y su extremo se apoya en él, como un puntal improvisado. La pequeña bandeja donde uno apoyaba el codo se convierte en un patín.</p>
<p>En el modelo paramétrico invertimos la lógica: en lugar de dibujar el reposabrazos y luego constatar dónde aterriza, la IA calcula sus puntos de apoyo <strong>por rotación inversa a partir de su objetivo en el suelo</strong>. La punta del reposabrazos se define como «el punto que, tras una rotación de 110°, toca el suelo en y = -47 cm». Comprobación en el frame final: z = 0,0 mm. De paso se entiende también <em>por qué</em> el reposabrazos original es tan corto y está tan retrasado: su posición no es una elección estética, es la restricción de aterrizaje. La forma sigue al mecanismo.</p>
<p><img alt="Posición cama: voladizo sostenido por el reposabrazos" src="https://pf.olibrio.fr/images/sofa/03-lit-profil.png" /></p>
<h2 id="donde-superamos-al-original">Donde superamos al original</h2>
<p>Entender está bien; mejorar está mejor. Tres defectos del mueble original pasaron por el tamiz.</p>
<p><strong>El colchón con dos firmezas.</strong> En el original, el asiento grueso y el respaldo más fino dan una cama con dos zonas. Corrección: grosor común de 14,5 cm en todas partes, superficie de descanso de 126 × 200 cm perfectamente uniforme.</p>
<p><strong>El asiento de 65 cm de profundidad.</strong> Imposible recostarse manteniendo los pies en el suelo. Mirando mejor, el original ya hace trampa: su respaldo no está en el borde trasero sino <em>adelantado</em> sobre la plataforma, y la zona muerta que queda detrás se convierte en cama al desplegar. Lo parametrizamos como es debido: <code>prof_utile = 50 cm</code>, y el pivote se recalcula solo.</p>
<p><strong>La cara mullida en el lado equivocado.</strong> El verdadero rompecabezas. El vuelco hacia delante expone el <em>dorso</em> del respaldo como superficie de descanso: si la cara delantera es mullida para sentarse, se duerme sobre la cara firme. El original tomó partido y peor para el asiento. Nuestra solución: un <strong>eje central</strong> que atraviesa el respaldo por su mitad. Durante el vuelco, el respaldo da media vuelta sobre sí mismo &mdash; y la misma cara mullida sirve de respaldo de día y de cama de noche. Consecuencia en cascada: el brazo ahora se detiene a media altura del respaldo para sostener ese cojinete&hellip; justo a la altura del reposabrazos. El reposabrazos <em>es</em> el cojinete.</p>
<p>Quedaba impedir que el respaldo girase libremente a su antojo. Primera idea: un pestillo. Segunda idea, mucho mejor: un <strong>tetón que corre por una ranura semicircular de 180°</strong>, concéntrica al eje, fresada en la cara interior del brazo. Los extremos de la ranura son los topes de las dos posiciones &mdash; el recorrido de la ranura <em>es</em> el recorrido de la media vuelta. Cero cerrojos que manipular, indexación automática, y en ambas poses las cargas aprietan el tetón contra su tope. Verificado en el modelo: el tetón está exactamente en el extremo de la ranura en las dos posiciones.</p>
<p><img alt="La ranura de 180° y su tetón, en la cara interior del brazo" src="https://pf.olibrio.fr/images/sofa/06-gorge-teton.png" /></p>
<p><img alt="Posición cama: la cara mullida queda arriba" src="https://pf.olibrio.fr/images/sofa/05-lit-34-face-moelleuse.png" /></p>
<h2 id="lo-que-me-llevo-de-esto">Lo que me llevo de esto</h2>
<p><strong>Una foto vale más que mil tokens.</strong> Las tres correcciones decisivas vinieron de primeros planos que le envié a la IA: los tornillos rígidos, el reposabrazos-pata, el respaldo adelantado. Razona notablemente bien &mdash; pero sobre lo que se le muestra.</p>
<p><strong>La IA sobreingenieriza cuando entiende mal.</strong> El solver de cuatro barras era magnífico e inútil. Desconfíen de las soluciones brillantes: comprueben primero el problema.</p>
<p><strong>Lo paramétrico abarata los errores.</strong> Tres rediseños completos del mecanismo, y cada vez unos minutos de recálculo en lugar de horas de remodelado. Como los puntos de anclaje (pivote, apoyos en el suelo, cojinete) se calculan en lugar de colocarse a mano, todo sigue.</p>
<p><strong>La colaboración tiene sentido.</strong> Ella calcula intersecciones de mediatrices y verifica holguras al milímetro; yo veo que un asiento de 65 cm de profundidad es invivible y que un tornillo no es un pivote. Ninguno de los dos habría producido este diseño por su cuenta.</p>
<p>Continuará en el próximo episodio: planos 2D acotados, detalle del cojinete y de la ranura, y fabricación en contrachapado de 18. El script y el modelo ya funcionan &mdash; solo faltan las dimensiones de mi salón.</p>
<h2 id="los-archivos">Los archivos</h2>
<p>Todo se puede descargar, sírvanse:</p>
<ul>
<li><a href="https://pf.olibrio.fr/assets/sofa/sofa_parametrique.py"><code>sofa_parametrique.py</code></a> &mdash; el script completo: parámetros, cálculo del pivote, construcción, animación. Para abrir en Blender (pestaña Scripting) y volver a ejecutar después de cambiar los <code>PARAMS</code>.</li>
<li><a href="https://pf.olibrio.fr/assets/sofa/canape_convertible.blend"><code>canape_convertible.blend</code></a> &mdash; la escena de Blender con la animación de vuelco (frame 1 = sofá, frame 61 = cama).</li>
<li><a href="https://pf.olibrio.fr/assets/sofa/canape_convertible.glb"><code>canape_convertible.glb</code></a> &mdash; el modelo en formato glTF, animación incluida, legible en cualquier parte (visores 3D en línea, motores de juego, RA).</li>
</ul>
<hr />
<p><em>Fotos del sofá original: <a href="https://justchairs.eu/products/mid-century-convertible-sofa-by-opp-drevovyroba-1970s">justchairs.eu</a>. Modelo 3D: Blender 5.1 + <a href="https://github.com/ahujasid/blender-mcp">BlenderMCP</a>.</em></p>]]></content:encoded>
    </item>
    <item>
      <title>Mi hijo, el brainrot y yo: la investigación de un padre dentro de la máquina de dopamina</title>
      <link>https://pf.olibrio.fr/es/posts/brainrot-machine-a-dopamine.html</link>
      <guid isPermaLink="true">https://pf.olibrio.fr/es/posts/brainrot-machine-a-dopamine.html</guid>
      <pubDate>Tue, 09 Jun 2026 12:00:00 +0000</pubDate>
      <description>Mi hijo se ponía irritable tras sus vídeos de Roblox. En lugar de especular, analicé las transcripciones de sus 10 vídeos favoritos. Esto dicen los datos.</description>
      <category>crianza</category>
      <category>pantallas</category>
      <category>dopamina</category>
      <category>roblox</category>
      <category>brainrot</category>
      <category>atención</category>
      <content:encoded><![CDATA[<h3 id="acto-i-el-sintoma">Acto I &mdash; El síntoma</h3>
<p>Todo empezó con una discusión tonta.</p>
<p>«Apaga, ya es la hora.» Una frase de lo más corriente. Salvo que aquella noche la respuesta no fue el suspiro normal de un adolescente. Fue seca, a flor de piel, casi hostil &mdash; como si acabara de arrancarle algo. Diez minutos después volvía a ser él mismo. Pero entre medias hubo ese <strong>momento</strong>: un chaval que no reconocía, irritable, cerrado, en otra parte.</p>
<p>Y no era la primera vez. El patrón se repetía: veía vídeos de Roblox &mdash; un youtuber llamado <strong>Kevko</strong>, <em>Steal a Brainrot</em>, <em>Lucky Block</em> &mdash; y cuando lo interrumpía en pleno vídeo, la cosa se descontrolaba. No después. <strong>En pleno vídeo.</strong></p>
<p>Podría haberlo dejado ahí. Decretar «las pantallas son malas», poner una regla y agotarme haciéndola cumplir. Pero tenía una intuición más precisa, y un hijo demasiado inteligente como para tragarse una prohibición sin explicación. Necesitaba entender <em>exactamente</em> qué pasaba en su cabeza. Y para eso necesitaba <strong>datos</strong>, no impresiones.</p>
<hr />
<h3 id="acto-ii-la-investigacion">Acto II &mdash; La investigación</h3>
<p>Primera hipótesis, la más inquietante: ¿y si el problema fuera el contenido en sí? Muchos vídeos de Roblox giran en torno a <em>robar, vencer, tender trampas, trolear, ganar a los demás</em>. ¿Estaba mi hijo pasando las tardes interiorizando una lógica de competición y dominación?</p>
<p>El problema es que no tenía ni idea. Yo <em>sentía</em>. Y el sentimiento, en materia de educación, es el camino más corto hacia la injusticia.</p>
<p>Así que decidí hacer lo que haría un periodista: <strong>leer las fuentes</strong>. No mirar distraídamente un par de vídeos &mdash; recuperar las <strong>transcripciones completas</strong> de los vídeos más grandes del canal y analizarlas, palabra por palabra.</p>
<p>Identifiqué sus <strong>10 vídeos más vistos</strong> (de 426 000 a 786 000 visualizaciones), extraje los subtítulos automáticos en francés y lo limpié todo: <strong>48 437 palabras</strong> de transcripción. Luego conté. Clasifiqué el vocabulario en grandes familias &mdash; urgencia, competición, recompensa, acumulación, conflicto, burla &mdash; y medí su frecuencia por cada 1 000 palabras.</p>
<p>Ahí las cifras empezaron a hablar. Y no dijeron lo que yo creía.</p>
<div class="table-scroll"><table>
<thead>
<tr>
<th>Tema (sobre 10 vídeos, 48 000 palabras)</th>
<th>Frecuencia /1000 palabras</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Escasez / acumulación</strong> (<code>encore</code>, <code>obtenir</code>, <code>débloquer</code>, <code>rare</code>)</td>
<td><strong>11,4</strong></td>
</tr>
<tr>
<td><strong>Urgencia / rapidez</strong> (<code>vite</code>, <code>vitesse</code>, <code>allez</code>, <code>go</code>)</td>
<td><strong>10,1</strong></td>
</tr>
<tr>
<td>Recompensa / dinero (<code>robux</code>, <code>million</code>, <code>argent</code>)</td>
<td>6,3</td>
</tr>
<tr>
<td>Competición / ganancia</td>
<td>5,0</td>
</tr>
<tr>
<td>Excitación / superlativos</td>
<td>3,3</td>
</tr>
<tr>
<td>Robo («steal»)</td>
<td>2,3</td>
</tr>
<tr>
<td><strong>Conflicto / dominación</strong></td>
<td><strong>0,4</strong></td>
</tr>
<tr>
<td><strong>Burla / troll</strong></td>
<td><strong>0,5</strong></td>
</tr>
</tbody>
</table></div>
<p>El contenido agresivo que yo temía &mdash; la dominación, la burla, el troleo &mdash; era <strong>casi inexistente</strong>: 0,4 y 0,5 por cada 1 000 palabras, básicamente ruido estadístico. Mi hijo no estaba aprendiendo a aplastar a los demás.</p>
<p>Lo que dominaba era otra cosa muy distinta: <strong>la acumulación y la urgencia.</strong> <em>Siempre un objeto más. Siempre más rápido.</em> Las dos palabras-tema más frecuentes de todo el canal eran «encore» («más», «otra vez») y «vite» («rápido»). Y al medir las interjecciones y las risas &mdash; un indicio de la intensidad &mdash; algunos vídeos subían hasta <strong>23 marcadores de excitación por cada 1 000 palabras</strong>, sin un solo respiro.</p>
<p>Me había equivocado de culpable. El peligro no era <em>ideológico</em>. Era <strong>fisiológico</strong>.</p>
<hr />
<h3 id="acto-iii-lo-que-encontramos">Acto III &mdash; Lo que encontramos</h3>
<p>Quedaba confrontar mis cifras con la ciencia. Y ahí todo encajó.</p>
<p><strong>1. La máquina de recompensa imprevisible.</strong> El corazón de <em>Steal a Brainrot</em> es el azar: el Lucky Block que <em>puede</em> soltar un brainrot raro, el ingreso pasivo que corre sin parar y empuja a volver a conectarse. Es exactamente el <strong>refuerzo de razón variable</strong> &mdash; el mecanismo que los casinos explotan desde hace un siglo porque es el más adictivo que existe. El cerebro libera dopamina <strong>al anticipar</strong> la recompensa, no al recibirla. Uno se queda en tensión permanente: <em>¿y si el próximo es el bueno?</em></p>
<p><strong>2. No es la violencia, es el ritmo.</strong> La pieza clave la encontré en un estudio publicado en la revista <em>Pediatrics</em> en 2011. Unas investigadoras mostraron a unos niños <strong>9 minutos</strong> de un dibujo animado simplemente <em>rápido</em> &mdash; cortes cada once segundos &mdash; sin ninguna violencia. Justo después, su capacidad de concentración y de paciencia estaba <strong>degradada de forma medible</strong>, en comparación con niños que habían visto un dibujo animado lento. Nueve minutos. El formato Kevko es precisamente eso: caudal verbal saturado, montaje picado, cero respiración. <strong>No es lo que cuenta lo que actúa sobre mi hijo. Es la velocidad.</strong></p>
<p><strong>3. Y por eso explotaba en casa.</strong> Cuando yo cortaba en pleno vídeo, el cerebro de mi hijo seguía «arriba». Y la Academia Americana de Pediatría lo dice explícitamente: al apagar la pantalla, <strong>la dopamina cae, y esa caída nos deja gruñones e irritables.</strong> La irritabilidad que me llevaba en plena cara no era insolencia. Era un <strong>estado químico previsible</strong> &mdash; la resaca de un estado de excitación al que no se había dejado bajar.</p>
<p>Lo más cruel es el efecto relacional. El contenido lo ponía en un estado en el que <strong>rechazaba, sin quererlo, a las personas presentes en la misma habitación.</strong> Y la trampa del <em>«siempre uno más»</em> es que nunca hay un buen momento para parar &mdash; así que nunca había realmente un momento en el que estuviera <em>presente</em> con nosotros. El verdadero coste no era el tiempo de pantalla. Eran los momentos reales, con personas reales, que desaparecían.</p>
<p><strong>El matiz, porque hay que ser honesto.</strong> No, el brainrot no «pudre el cerebro» en sentido literal &mdash; fue la palabra del año del diccionario Oxford en 2024, pero es un marcador cultural, no un diagnóstico. No, la famosa «desintoxicación de dopamina» no es un concepto científico real: uno no «reinicia» su dopamina apagando las pantallas. Y sí, el brainrot es también humor de chavales, un lenguaje generacional. Mi hijo no está en peligro. Pero está, por construcción, <strong>manipulado</strong> &mdash; y eso sí tiene arreglo.</p>
<hr />
<h3 id="acto-iv-lo-que-intentamos-hacer-al-respecto">Acto IV &mdash; Lo que intentamos hacer al respecto</h3>
<p>Decidí hacer una apuesta: la de su inteligencia.</p>
<p>Nada de prohibición frontal &mdash; un chaval listo se la salta y te guarda rencor. En su lugar, cambié de bando. El mensaje ya no era <em>«papá te lo prohíbe»</em> sino <em>«hay ingenieros a los que pagan millones que están jugando con tu cerebro, y yo estoy en tu equipo contra ellos»</em>. Nada irrita más a un adolescente que ser manipulado. Era mi mejor palanca.</p>
<p>Luego le propuse un <strong>experimento</strong>, porque le gusta la ciencia:</p>
<blockquote>
<p>«Durante una semana, observa simplemente tu estado de ánimo en los 10 minutos después de apagar. Puntúalo sobre 10. Y compara: cuando te cortan en pleno vídeo, frente a cuando <em>tú</em> eliges el momento de parar. Si me equivoco, lo reconoceré. Pero mira los datos tú mismo.»</p>
</blockquote>
<p>Devolverle el control es precisamente lo que la investigación identifica como el factor que más reduce las crisis de fin de pantalla. Y convertir una discusión recurrente en una <strong>investigación compartida</strong> es sacarlo de la posición defensiva.</p>
<p>Por último, vimos vídeos <strong>juntos</strong> &mdash; nada de sermones, sino análisis hechos por gente a la que un adolescente respeta:</p>
<ul>
<li><strong>Serie « Dopamine » &mdash; ARTE, episodio TikTok</strong> (~9 min): desmonta, técnica por técnica, la aplicación que él conoce. Tono clínico, cero moralina, el clic de «me están manipulando». → https://www.youtube.com/watch?v=-pOWdBpVR3s</li>
<li><strong>« Et tout le monde s&rsquo;en fout » &mdash; #59 Les algorithmes</strong> (~7 min): divertido, cómplice, nunca aleccionador. → https://www.youtube.com/watch?v=5NiVg4DBJrI</li>
<li><strong>Tracks ARTE &mdash; « Brainrot : est-ce qu&rsquo;internet fait pourrir nos cerveaux ? »</strong>: aborda de frente su universo. <em>(Conviene verlo antes uno mismo.)</em> → https://www.youtube.com/watch?v=ubT8hS0lAlg</li>
<li><strong>Stupid Economics &mdash; « L&rsquo;économie de l&rsquo;attention »</strong>: el enfoque «tu atención es el producto que se vende». → https://www.youtube.com/watch?v=rMV1WaWGb3I</li>
<li><strong>Tristan Harris &mdash; TED Talk (subtítulos en francés)</strong>: el exingeniero de Google que dio la primera voz de alarma. Credibilidad máxima. → https://www.ted.com/talks/tristan_harris_how_a_handful_of_tech_companies_control_billions_of_minds_every_day?language=fr</li>
</ul>
<p>El plan: empezar por el primero (9 minutos, reconoce su aplicación), dejarle comentar, no sacar conclusiones en su lugar. El formato corto y factual hace el trabajo por sí solo.</p>
<hr />
<h3 id="epilogo">Epílogo</h3>
<p>No he «ganado». No es una batalla que se gane en una noche, y nunca fue ese el objetivo. Pero algo ha cambiado: mi hijo ha dejado de ver a un padre que confisca y ha empezado a ver un mecanismo que lo manipula. Ahora tiene un vocabulario para nombrarlo. Y entre nosotros, la conversación ha sustituido a la discusión.</p>
<p>El contenido que ve no es el mal. Ni siquiera es ideológico &mdash; mis propios datos me lo demostraron. Es solo una máquina, muy bien diseñada, para mantener el cerebro de un niño en estado de excitación máxima y hacerlo volver. Entender la máquina ya es liberarse a medias de ella.</p>
<p>Y esa es una apuesta que estoy dispuesto a hacer por la inteligencia de mi hijo.</p>
<hr />
<h2 id="fuentes-y-referencias">Fuentes y referencias</h2>
<p><strong>Sobre la dopamina y la irritabilidad tras la pantalla</strong> - American Academy of Pediatrics &mdash; <em>Screen Time and Temper Tantrums</em> (la caída de dopamina al apagar vuelve irritable): https://www.healthychildren.org/English/family-life/Media/Pages/screen-time-and-temper-tantrums-helpful-tips-for-parents.aspx</p>
<p><strong>Sobre el ritmo/montaje que degrada la atención</strong> - Lillard, A. S., &amp; Peterson, J. (2011). <em>The Immediate Impact of Different Types of Television on Young Children&rsquo;s Executive Function.</em> <strong>Pediatrics</strong>, 128(4), 644-649. (El estudio «SpongeBob».) Resumen accesible (NPR): https://www.npr.org/sections/health-shots/2011/09/12/140401099/spongebob-may-be-too-speedy-for-preschool-brains - Metaanálisis reciente sobre los efectos a corto plazo de los medios en la atención y las funciones ejecutivas de los niños (PMC, 2024): https://pmc.ncbi.nlm.nih.gov/articles/PMC12412071/</p>
<p><strong>Sobre los bucles de recompensa y el diseño adictivo</strong> - <em>The Vegas Effect of Our Screens</em> &mdash; Psychology Today (refuerzo de razón variable): https://www.psychologytoday.com/us/blog/tech-happy-life/201901/the-vegas-effect-of-our-screens - <em>Why We Can&rsquo;t Stop</em> &mdash; Communication Research / Taylor &amp; Francis (elementos recompensantes de los juegos y juego problemático en adolescentes): https://www.tandfonline.com/doi/full/10.1080/15213269.2023.2242260 - <em>Debunking the Dopamine Detox Trend</em> &mdash; The Scientist (la «desintoxicación de dopamina» es un mito): https://www.the-scientist.com/debunking-the-dopamine-detox-trend-72036</p>
<p><strong>Sobre el «brainrot» y <em>Steal a Brainrot</em></strong> - <em>« Brain rot » named Oxford Word of the Year 2024</em> &mdash; Oxford University Press: https://corp.oup.com/news/brain-rot-named-oxford-word-of-the-year-2024/ - <em>Steal a Brainrot</em> &mdash; ficha enciclopédica (ingreso pasivo, bucle de juego, monetización): https://en.wikipedia.org/wiki/Steal_a_Brainrot</p>
<p><strong>Sobre el uso de las pantallas como regulador emocional</strong> - <em>Using screens to calm kids may hurt their emotional regulation</em> &mdash; CNN (eco de un estudio publicado en JAMA Pediatrics): https://edition.cnn.com/2022/12/12/health/tantrum-distraction-screens-parenting-wellness</p>
<p><strong>Recursos de vídeo divulgativos (citados en el artículo)</strong> - Serie <em>Dopamine</em> &mdash; ARTE (lista de reproducción): https://www.youtube.com/playlist?list=PL8Ax_z5vzflwdvoTnARE5FiYl42Sg-fYb - <em>Et tout le monde s&rsquo;en fout</em> &mdash; #59 Les algorithmes: https://www.youtube.com/watch?v=5NiVg4DBJrI - <em>Brainrot : est-ce qu&rsquo;internet fait pourrir nos cerveaux ?</em> &mdash; Tracks / ARTE: https://www.youtube.com/watch?v=ubT8hS0lAlg - <em>L&rsquo;économie de l&rsquo;attention</em> &mdash; Stupid Economics: https://www.youtube.com/watch?v=rMV1WaWGb3I - Tristan Harris &mdash; TED (subtítulos en francés): https://www.ted.com/talks/tristan_harris_how_a_handful_of_tech_companies_control_billions_of_minds_every_day?language=fr</p>
<hr />
<p><em>Nota metodológica: el análisis léxico se basa en las transcripciones automáticas (subtítulos de YouTube en francés) de los 10 vídeos más vistos del canal, es decir, ~48 000 palabras. Límite asumido: una transcripción mide las palabras, no el volumen sonoro ni el ritmo de montaje &mdash; y es precisamente ese ritmo el que la ciencia identifica como el factor más determinante. Las cifras son, por tanto, un indicio convergente, no una medida directa de la sobreestimulación.</em></p>]]></content:encoded>
    </item>
  </channel>
</rss>
