
Chismes del Lince 46: pi pico y números aleatorios
Anochecía sobre Sierra Bermeja y el Lince de la Noche subía por el sendero con una mochila que parecía un armario. Dentro llevaba el Arduino Mega, tres protoboards, un montón de cables y una tarjeta microSD.
Su plan era colgar una estación de medidas de un pino y dejarla trabajando toda la noche.
—¿Eso es una estación o te mudas? —preguntó la Gata Montesa, sentada en una roca, sin levantarse.
—Es lo que hay —resopló el Lince—. La Heltec cabe, pero lleva su pantalla y sus antenas. El Mega no cabe en ningún sitio. Necesito algo más pequeño. Un ordenador de verdad, pero en una plaquita.
—¿Y no conoces la Raspberry Pi?
—Claro que sí. Un ordenador del tamaño de una tarjeta de crédito. Hay que enchufarle pantalla, teclado, ratón…
—Esa es la grande. Yo hablo de su hermana pequeña.
La Gata abrió la zarpa. Encima tenía una placa verde y alargada, de poco más de cinco centímetros.
—Se llama Pico W. No tiene sistema operativo, ni pantalla, ni teclado. Pero tiene Bluetooth.
—¿Sin pantalla? ¿Y cómo voy a ver lo que mide?
—Con el móvil, Lince. Para eso lo llevas en el bolsillo.
El Lince se rascó una oreja. Ya estaba imaginando una red de sensores repartida por toda la sierra.
—Pues vamos a empezar por algo sencillo —cortó la Gata—. Que la placa te mande un número de dado cada cinco segundos.
—¿Un dado? Yo pensaba en un sistema de alerta temprana…
—Y yo en que primero funcione. Un paso cada vez.
Introducción
En este chisme estrenamos la Raspberry Pi Pico W, una placa diminuta que se programa con Python y habla Bluetooth con el móvil.
Hasta ahora hemos trabajado con la micro:bit en el cuentapasos con Bluetooth y con la Heltec en el letrero del Lince. La Pico W es otra pieza para la caja de herramientas: más pequeña y barata, y con el mismo tipo de comunicación.
Qué es la Raspberry Pi Pico W
No es un ordenador como el que tienes en casa. Es un microcontrolador: un chip pequeño que ejecuta un solo programa, el que tú le grabas.
Lleva el chip RP2040, que tiene dos núcleos, y un módulo inalámbrico con Wi-Fi y Bluetooth de baja energía. Puedes consultar todos los datos en la documentación oficial de Raspberry Pi.
Para programarla usaremos MicroPython, una versión de Python hecha para placas pequeñas.
Qué vamos a construir
El primer proyecto con la Raspberry Pi Pico W será un dado Bluetooth. Cada cinco segundos, la placa tirará un dado y enviará el número al móvil.
Parece poca cosa, pero tiene todo lo importante: una placa nueva, un programa en Python y una comunicación inalámbrica que funciona. Cuando eso esté en marcha, conectar sensores es cuestión de añadir cables.
Empezamos por lo primero: preparar la placa en Windows.
Poner en marcha la Raspberry Pi Pico W en Windows
Necesitas una Raspberry Pi Pico W, un cable USB de datos (algunos cables solo cargan y no sirven) y un ordenador con Windows.
Paso 1: instalar Thonny
Thonny es el programa con el que escribiremos el código en Python y lo enviaremos a la placa. Descárgalo de su web, ejecuta el instalador y acepta las opciones por defecto.
Paso 2: descargar MicroPython
Entra en la página de MicroPython para la Pico W y descarga el archivo .uf2 de la versión marcada como latest. Se guardará en tu carpeta de Descargas.
Fíjate en que sea el de Pico W y no el de la Pico normal. El segundo no tiene Bluetooth.
Paso 3: instalar MicroPython en la placa
La Pico W no trae Python de fábrica. Hay que grabarlo una vez.
- Desenchufa la placa del ordenador.
- Mantén pulsado el botón blanco BOOTSEL.
- Con el botón pulsado, enchufa el cable USB al ordenador.
- Suelta el botón. En el Explorador aparecerá una unidad nueva llamada RPI-RP2, como si fuera un pendrive.
- Arrastra el archivo
.uf2a esa unidad. - La unidad desaparecerá sola. Eso significa que MicroPython está instalado.
Si la unidad RPI-RP2 no aparece, lo más probable es que hayas pulsado el botón después de enchufar. Hay que pulsarlo antes y mantenerlo unos segundos.
Paso 4: decirle a Thonny dónde está la placa
Desenchufa la Pico y vuelve a enchufarla sin pulsar BOOTSEL. Después:
- Abre Thonny.
- En la esquina inferior derecha, pulsa donde pone el intérprete y elige Configure interpreter.
- En Intérprete elige MicroPython (Raspberry Pi Pico).
- En Puerto elige el que aparezca, por ejemplo COM5.
- Pulsa Aceptar.
Si Thonny no encuentra la placa, es porque aún no sabe qué puerto usar. Este paso se hace una sola vez.
Paso 5: la primera prueba
Pulsa el botón rojo de parar. En la consola de abajo debe aparecer algo parecido a esto:
MicroPython v1.29.0 on 2026-08-24; Raspberry Pi Pico W with RP2040
>>>
Escribe esto en la consola y pulsa Intro:
print("Hola Lince")
Si responde Hola Lince, la placa ya habla contigo. Para ver algo con tus propios ojos, pega este programa en la ventana de arriba y pulsa el triángulo verde:
from machine import Pin
import time
led = Pin("LED", Pin.OUT) # el LED verde de la placa
while True:
led.toggle() # cambia: si estaba apagado lo enciende y al revés
time.sleep(0.5) # espera medio segundo
El LED verde de la Pico W debe parpadear. Para pararlo, pulsa el botón rojo.
Si algo falla
- No aparece RPI-RP2: cambia de cable o de puerto USB, y pulsa BOOTSEL antes de enchufar.
- Thonny no encuentra la placa: revisa el puerto en Configure interpreter.
- Sale un programa antiguo al enchufarla: la placa ya tenía uno guardado que arranca solo. Para dejarla en blanco, descarga
flash_nuke.uf2de Raspberry Pi, cópialo a la unidad RPI-RP2 y repite el paso 3.
Cuando el LED parpadee, la Raspberry Pi Pico W está lista para el dado.
El programa de la Pico
La placa ya habla con Thonny. Ahora vamos a que hable con el móvil.
El programa tiene dos partes. La primera prepara el Bluetooth y es igual en todos los chismes: la copias y no la tocas. La segunda es la que importa: tira un dado y envía el número.
Pega todo esto en Thonny y guárdalo en la Pico como main.py (Archivo → Guardar como → Dispositivo MicroPython).
# Chisme 46 - Dado Bluetooth del Lince
# Raspberry Pi Pico W + MicroPython
# Cada 5 segundos tira un dado y envía el número al móvil por Bluetooth.
import bluetooth, random, struct, time
from machine import Pin
from micropython import const
# --- Cosas del Bluetooth (igual que en la micro:bit): no hace falta tocarlas ---
_IRQ_CENTRAL_CONNECT = const(1)
_IRQ_CENTRAL_DISCONNECT = const(2)
NOMBRE = "Pico-Lince" # el nombre que verás en el móvil
_UART_UUID = bluetooth.UUID("6E400001-B5A3-F393-E0A9-E50E24DCCA9E")
_UART_TX = (bluetooth.UUID("6E400003-B5A3-F393-E0A9-E50E24DCCA9E"), bluetooth.FLAG_NOTIFY)
_UART_RX = (bluetooth.UUID("6E400002-B5A3-F393-E0A9-E50E24DCCA9E"),
bluetooth.FLAG_WRITE | bluetooth.FLAG_WRITE_NO_RESPONSE)
_UART_SERVICE = (_UART_UUID, (_UART_TX, _UART_RX))
led = Pin("LED", Pin.OUT) # el LED verde de la placa: encendido = móvil conectado
conexiones = set()
def anuncio(nombre=None, uuid=None):
# Construye el paquete con el que la Pico se "anuncia" para que el móvil la encuentre
datos = bytearray()
def anade(tipo, valor):
datos.extend(struct.pack("BB", len(valor) + 1, tipo) + valor)
if nombre:
anade(0x01, struct.pack("B", 0x06)) # visible para cualquier móvil
anade(0x09, nombre.encode()) # nombre completo
if uuid:
anade(0x07, bytes(uuid)) # servicio UART (128 bits)
return datos
def irq(evento, datos):
if evento == _IRQ_CENTRAL_CONNECT: # un móvil se conecta
conn, _, _ = datos
conexiones.add(conn)
led.on()
elif evento == _IRQ_CENTRAL_DISCONNECT: # el móvil se va
conn, _, _ = datos
conexiones.discard(conn)
led.off()
publicitar() # volver a ser visible
def publicitar():
ble.gap_advertise(100_000, adv_data=anuncio(nombre=NOMBRE),
resp_data=anuncio(uuid=_UART_UUID))
ble = bluetooth.BLE()
ble.active(True)
ble.irq(irq)
((tx, rx),) = ble.gatts_register_services((_UART_SERVICE,))
publicitar()
# --- LO IMPORTANTE: tirar el dado y enviarlo ---
while True:
dado = random.randint(1, 6) # número al azar del 1 al 6
for conn in conexiones:
ble.gatts_notify(conn, tx, str(dado) + "\n") # "4" + salto de línea
time.sleep(5) # esperar 5 segundos
Lee y predice
Antes de ejecutarlo, intenta responder:
- ¿Qué pasa si cambias
time.sleep(5)portime.sleep(1)? - ¿Y si cambias
random.randint(1, 6)porrandom.randint(1, 20)? La página del dado no entenderá los números mayores que 6. ¿Por qué? - ¿Para qué sirve el
"\n"al final del número?
Cambia el nombre Pico-Lince por el tuyo si hay varios compañeros en clase. Si no, en la lista de Bluetooth saldrán todas las placas con el mismo nombre.
La página web del dado
La Pico ya manda números. Ahora necesitamos algo que los reciba y los dibuje.
Esta página se conecta a la placa por Bluetooth, dibuja el dado y cuenta cuántas veces sale cada cara. Es el mismo Bluetooth que usamos con la micro:bit, así que la parte de la conexión te sonará.
Guárdala como chisme-46-dado-pico.html (codificación UTF-8) y ábrela desde una dirección https://, por ejemplo subiéndola a tu web. Si la abres haciendo doble clic en el archivo, el navegador no dejará usar el Bluetooth.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>Chisme 46 · El dado de la Pico W</title>
<style>
:root{
--bg:#eef2ef; --ink:#10201c; --soft:#4d625b; --card:#ffffff; --line:#cfdad5;
--pine:#1f5b4a; --sel:#7b3fa0; --barra:#2563a8; --dado:#fffdf6; --punto:#10201c;
}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]){
--bg:#0f1a17; --ink:#e8f1ed; --soft:#9db3aa; --card:#172622; --line:#2a3d37; --pine:#5fc4a2; --sel:#c79bff;
--barra:#7db3ee; --dado:#f3efe2; --punto:#10201c;}}
*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--ink);font:17px/1.45 "Trebuchet MS","Segoe UI",system-ui,sans-serif;
padding-top:env(safe-area-inset-top,0px);padding-bottom:env(safe-area-inset-bottom,0px)}
main{max-width:30rem;margin:0 auto;padding:1.2rem 1rem 2rem}
h1{font-size:1.3rem;margin:.2rem 0 .1rem}
h2{font-size:1.05rem;margin:0 0 .5rem}
.sub{color:var(--soft);margin:0 0 1rem;font-size:.95rem}
button{font:inherit;font-weight:700;border:2px solid var(--pine);background:var(--pine);color:var(--bg);
border-radius:.8rem;padding:.65rem 1rem;min-height:3rem;cursor:pointer}
button:disabled{opacity:.5;cursor:not-allowed}
button.alt{background:transparent;color:var(--pine)}
button:focus-visible{outline:3px solid var(--sel);outline-offset:2px}
.botones{display:flex;gap:.6rem;flex-wrap:wrap}
#estado{margin:.8rem 0 .2rem;color:var(--soft);min-height:1.5em}
#ayuda{margin:0 0 .6rem;color:var(--soft);font-size:.9rem;min-height:1.2em}
.card{background:var(--card);border:1px solid var(--line);border-radius:.9rem;padding:.9rem;margin:1rem 0}
.nota{color:var(--soft);font-size:.9rem}
/* el dado: una cuadrícula de 3x3 con puntos que se encienden o no */
#dado{width:9rem;height:9rem;margin:.4rem auto 1rem;background:var(--dado);border:3px solid var(--punto);
border-radius:1.4rem;display:grid;grid-template:repeat(3,1fr)/repeat(3,1fr);padding:.9rem;gap:.2rem}
#dado i{border-radius:50%;background:transparent;margin:.15rem}
#dado i.on{background:var(--punto)}
#dado.tira{animation:giro .45s ease-out}
@keyframes giro{0%{transform:rotate(-40deg) scale(.8)}60%{transform:rotate(15deg) scale(1.08)}100%{transform:none}}
.fila{display:flex;gap:.8rem}
.dato{flex:1;background:var(--bg);border:1px solid var(--line);border-radius:.8rem;padding:.5rem .8rem}
.dato b{display:block;font-size:1.6rem;font-variant-numeric:tabular-nums}
.lbl{color:var(--soft);font-size:.88rem}
#ultimas{display:flex;flex-wrap:wrap;gap:.3rem;min-height:2rem}
#ultimas span{background:var(--bg);border:1px solid var(--line);border-radius:.5rem;padding:.1rem .5rem;font-weight:700;font-variant-numeric:tabular-nums}
#barras{display:grid;grid-template-columns:repeat(6,1fr);gap:.4rem;height:9rem;align-items:end;position:relative;margin-top:.6rem}
.col{display:flex;flex-direction:column;justify-content:flex-end;align-items:center;height:100%}
.col .b{width:100%;background:var(--barra);border-radius:.3rem .3rem 0 0;min-height:2px}
.col .n{font-size:.85rem;font-variant-numeric:tabular-nums}
#esperado{position:absolute;left:0;right:0;border-top:2px dashed var(--sel);display:none}
#etq{display:grid;grid-template-columns:repeat(6,1fr);gap:.4rem;text-align:center;font-weight:700}
details{background:var(--card);border:1px solid var(--line);border-radius:.9rem;padding:.2rem .9rem;margin:1rem 0}
summary{cursor:pointer;font-weight:700;color:var(--pine);padding:.6rem 0}
details p,details li{font-size:.95rem;margin:.3rem 0}
</style>
</head>
<body>
<main>
<h1>El dado de la Pico W</h1>
<p class="sub">La placa tira un dado cada 5 segundos y te manda el número por Bluetooth.</p>
<div class="botones">
<button id="conectar">Conectar Pico W</button>
<button id="demo" class="alt">Probar sin la placa</button>
</div>
<div id="estado" role="status">Sin conectar.</div>
<div id="ayuda"></div>
<div class="card">
<div id="dado" aria-label="Dado" role="img"></div>
<div class="fila">
<div class="dato"><span class="lbl">Tiradas</span><b id="total">0</b></div>
<div class="dato"><span class="lbl">Media</span><b id="media">–</b></div>
</div>
<p class="nota">Con un dado justo, la media tiende a 3,5.</p>
</div>
<div class="card">
<h2>Últimas tiradas</h2>
<div id="ultimas"></div>
</div>
<div class="card">
<h2>¿Sale cada cara por igual?</h2>
<div id="barras"><div id="esperado"></div></div>
<div id="etq"><span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span></div>
<p class="nota" id="notaBarras">La línea discontinua marca lo esperado: tiradas ÷ 6. Se verá a partir de la tirada 6.</p>
<div class="botones">
<button id="csv" class="alt">Guardar CSV</button>
<button id="borrar" class="alt">Borrar</button>
</div>
</div>
<details>
<summary>Cómo usarlo</summary>
<ol>
<li>Enchufa la Pico W con el programa del dado.</li>
<li>Pulsa «Conectar Pico W» y elige <b>Pico-Lince</b> en la lista.</li>
<li>Cada 5 segundos llegará una tirada. Con 60 tiradas ya se nota cómo se reparten las caras.</li>
</ol>
<p>Necesita Chrome o Edge y abrirse con <b>https://</b>. Los datos viven solo en esta página: no se envían ni se guardan en ningún servidor.</p>
</details>
</main>
<script>
const $ = id => document.getElementById(id);
/* ============ DATOS ============ */
let tiradas = []; // cada tirada: {n: 1..6, t: hora}
let demoOn = false, demoId = null;
/* ============ EL DADO ============ */
// qué puntos se encienden en la cuadrícula 3x3 (0..8) para cada número
const PUNTOS = {1:[4], 2:[0,8], 3:[0,4,8], 4:[0,2,6,8], 5:[0,2,4,6,8], 6:[0,2,3,5,6,8]};
const dado = $("dado");
for (let i = 0; i < 9; i++) dado.appendChild(document.createElement("i"));
function pintaDado(n){
[...dado.children].forEach((p, i) => p.classList.toggle("on", (PUNTOS[n] || []).includes(i)));
dado.setAttribute("aria-label", n ? "Dado: " + n : "Dado");
}
pintaDado(0);
/* ============ PANTALLA ============ */
function pinta(){
const n = tiradas.length;
$("total").textContent = n;
$("media").textContent = n ? (tiradas.reduce((s, x) => s + x.n, 0) / n).toFixed(2).replace(".", ",") : "–";
$("ultimas").innerHTML = tiradas.slice(-20).reverse().map(x => "<span>" + x.n + "</span>").join("");
const cuenta = [0, 0, 0, 0, 0, 0];
tiradas.forEach(x => cuenta[x.n - 1]++);
const max = Math.max(1, ...cuenta, n / 6);
const cajas = $("barras");
[...cajas.querySelectorAll(".col")].forEach(c => c.remove());
cuenta.forEach(c => {
const col = document.createElement("div"); col.className = "col";
col.innerHTML = '<span class="n">' + c + '</span><div class="b" style="height:' + (c / max * 85) + '%"></div>';
cajas.appendChild(col);
});
const esp = $("esperado");
if (n >= 6){
esp.style.display = "block";
// la altura útil de las barras es el 85 % de la caja menos el número de arriba (aprox.)
esp.style.bottom = "calc(" + (n / 6 / max * 85) + "% )";
} else esp.style.display = "none";
}
function nuevaTirada(n){
if (!(n >= 1 && n <= 6)) return;
tiradas.push({n, t: new Date().toLocaleTimeString("es-ES")});
dado.classList.remove("tira"); void dado.offsetWidth; dado.classList.add("tira");
pintaDado(n);
pinta();
}
/* ============ RECIBIR DATOS ============ */
// La Pico envía una línea de texto por tirada: «4» + salto de línea.
// Puede llegar cortada en trozos, así que guardamos lo recibido y cortamos por líneas.
let buffer = "";
function recibir(ev){
buffer += new TextDecoder().decode(ev.target.value);
const lineas = buffer.split("\n");
buffer = lineas.pop(); // lo que quede sin salto de línea espera al siguiente trozo
lineas.forEach(l => { const m = l.match(/[1-6]/); if (m) nuevaTirada(Number(m[0])); });
}
/* ============ SIN LA PLACA (para probar la página) ============ */
$("demo").onclick = () => {
if (demoOn){ clearInterval(demoId); demoOn = false; $("demo").textContent = "Probar sin la placa"; estado("Prueba parada."); return; }
demoOn = true; $("demo").textContent = "Parar la prueba";
estado("Prueba: tiradas inventadas por la página, no por la Pico.");
demoId = setInterval(() => nuevaTirada(1 + Math.floor(Math.random() * 6)), 800);
};
$("borrar").onclick = () => { tiradas = []; pintaDado(0); pinta(); };
$("csv").onclick = () => {
if (!tiradas.length) return;
const txt = "tirada,numero,hora\n" + tiradas.map((x, i) => (i + 1) + "," + x.n + "," + x.t).join("\n") + "\n";
const a = document.createElement("a"); a.href = URL.createObjectURL(new Blob([txt], {type: "text/csv"}));
a.download = "dado-pico.csv"; a.click(); URL.revokeObjectURL(a.href);
};
/* ============ BLUETOOTH (el mismo UART de Nordic que la micro:bit, chismes 19 a 22 y 45) ============ */
const UART_SERVICE = "6e400001-b5a3-f393-e0a9-e50e24dcca9e";
const UART_TX = "6e400003-b5a3-f393-e0a9-e50e24dcca9e"; // la Pico envía por aquí
let paso = "", conectando = false;
const espera = ms => new Promise(r => setTimeout(r, ms));
function estado(t, ayuda){ if (!/^Error/.test(t)) paso = t; $("estado").textContent = t; $("ayuda").textContent = ayuda || ""; }
function explicar(e){
const nombre = e && e.name ? e.name : "Error", msg = e && e.message ? e.message : String(e);
let ayuda = "";
if (nombre === "NotFoundError" && /cancel/i.test(msg)) ayuda = "No has elegido ningún dispositivo. Pulsa Conectar y elige Pico-Lince.";
else if (nombre === "NotFoundError") ayuda = "La Pico no tiene el servicio UART. Comprueba que está ejecutando el programa del dado.";
else if (nombre === "NetworkError") ayuda = "No se ha podido abrir la conexión. Desenchufa y enchufa la Pico y vuelve a intentarlo.";
else if (nombre === "SecurityError") ayuda = "La página debe abrirse con https://.";
else if (nombre === "NotAllowedError") ayuda = "Permiso denegado. Permite el Bluetooth y los dispositivos cercanos para el navegador.";
estado("Error (" + nombre + "): " + msg, "Falló en el paso: «" + paso + "». " + ayuda);
}
$("conectar").onclick = async () => {
if (conectando || demoOn) return;
if (!navigator.bluetooth){ estado("Este navegador no permite Bluetooth.", "Usa Chrome o Edge (ordenador o Android). Safari y Firefox no sirven."); return; }
conectando = true; $("conectar").disabled = true;
try {
estado("Buscando la Pico…");
const dev = await navigator.bluetooth.requestDevice({acceptAllDevices: true, optionalServices: [UART_SERVICE]});
dev.addEventListener("gattserverdisconnected", () => estado("Desconectado.", "Pulsa Conectar para volver a empezar."));
estado("Conectando…");
const srv = await dev.gatt.connect();
await espera(600);
estado("Buscando el servicio UART…");
const svc = await srv.getPrimaryService(UART_SERVICE);
const tx = await svc.getCharacteristic(UART_TX);
buffer = "";
tx.addEventListener("characteristicvaluechanged", recibir);
estado("Activando notificaciones…");
await tx.startNotifications();
estado("Conectado a " + (dev.name || "la Pico") + ". La primera tirada llegará en menos de 5 segundos.");
} catch (e){ explicar(e); }
finally { conectando = false; $("conectar").disabled = false; }
};
pinta();
</script>
</body>
</html>
Qué parte es la importante
La página es larga, pero casi todo es el dibujo del dado y las barras. Lo esencial está en la función recibir: junta los trozos que llegan por Bluetooth, los corta por líneas y se queda con el número. El resto es decoración y el Bluetooth de siempre.


Cómo probar la Pico y el dado
Prueba en dos pasos. Así, si algo falla, sabes si el problema está en la placa o en la página.
Paso 1: la placa, con nRF Connect
Instala la aplicación gratuita nRF Connect en el móvil.
- Enchufa la Pico con el programa del dado.
- En nRF Connect, pulsa Scan y busca Pico-Lince.
- Conecta. El LED verde de la placa se enciende.
- Abre el servicio UART y activa las notificaciones del TX, con el icono de las tres flechas hacia abajo.
- Cada 5 segundos debe llegar un número del 1 al 6.
Cuando funcione, cierra nRF Connect del todo. La Pico solo admite una conexión a la vez.
Paso 2: la página
- Abre la página del dado en Chrome (Android o ordenador), desde
https://. - Pulsa Conectar Pico W y elige Pico-Lince.
- Espera menos de 5 segundos. Aparecerá la primera tirada.
Si quieres enseñar la página sin la placa, pulsa Probar sin la placa. Verás tiradas inventadas por el propio navegador.
Si algo falla
- La Pico no sale en la lista: comprueba que el programa se está ejecutando, sin mensajes en rojo en Thonny.
- Conecta pero no llegan números: en nRF Connect, activa las notificaciones del TX.
- La página no la encuentra: cierra nRF Connect y desconecta cualquier otro móvil de la Pico.
Qué es realmente un número aleatorio
La Pico no tira ningún dado. Hace una cuenta que parece azar.
Se llama generador de números pseudoaleatorios. Parte de un número inicial, la semilla, y aplica una fórmula que da una secuencia de números desordenados. Si dos placas empiezan con la misma semilla, sacan exactamente la misma serie. Por eso se dice que son pseudo: falsos, pero suficientes para un dado.
Para que cada arranque sea distinto, la semilla debe cambiar. En la Pico W suele tomarse de ruido del propio chip, que es difícil de predecir. Puedes comprobarlo en la documentación de MicroPython.
¿Por qué las barras no salen iguales?
Con 60 tiradas esperamos unos 10 de cada número. Pero es normal que una cara salga 6 veces y otra 14. El azar no reparte con regla.
Cuantas más tiradas, más se acercan las barras a la línea discontinua. Con 6 tiradas no te dice nada. Con 600 empieza a ser fiable.
Dato no es lo mismo que medida
Un sensor de temperatura mide algo que existe fuera de la placa. El dado no mide nada: inventa el número. Es un dato, pero no una medida.
Esa diferencia es la que lo hace útil. Como sabemos exactamente cómo se genera, podemos usarlo para probar el resto del sistema.
¿Qué sale del dispositivo?
Nada. La tirada se hace en la placa, viaja por Bluetooth al móvil y se queda en la página. No hay internet, ni servidor, ni cuenta.
Para qué le sirve un dado al Lince
Un generador de números aleatorios parece un juguete. Pero se usa de tres maneras que importan en los proyectos del Lince.
Un sensor falso para el CanSat
Un CanSat es una mini sonda del tamaño de una lata de refresco. Antes del lanzamiento hay que comprobar que la estación en tierra recibe y dibuja los datos bien.
Si esperas a tener los sensores terminados, pierdes semanas. Con la Pico puedes mandar números inventados con el mismo formato que mandarán los sensores, y probar la página, la gráfica y el CSV desde el primer día. Después solo cambias el dado por la medida, como hicimos en la estación del tiempo con micro:bit.
Elegir sin sesgo en los Detectives climáticos
Climate Detectives es un proyecto de la ESA para que el alumnado investigue el clima de su entorno. Una investigación seria necesita tomar datos sin favorecer lo cómodo.
Si decides tú dónde medir, acabas midiendo siempre a la sombra del patio. Si sorteas los puntos y las horas, los datos representan mejor el sitio. Un dado puede decidir si hoy mides en la puerta, en el patio o junto a la pista, y a qué hora.
Python, como en Astro Pi
Astro Pi es el reto de la ESA para programar en Python ordenadores Raspberry Pi que trabajan en la Estación Espacial Internacional. MicroPython es Python adaptado a placas pequeñas, así que lo aprendido aquí sirve allí.
Con números aleatorios se puede, por ejemplo, estimar el valor de π lanzando puntos al azar sobre un cuadrado. Se llama método de Monte Carlo y puede ser un chisme para más adelante.
Para el aula
El dado da datos baratos y sin riesgo. Con él se pueden practicar ideas que luego servirán con sensores de verdad.
Actividades
- Hipótesis: antes de empezar, cada grupo apunta cuántas veces cree que saldrá el 6 en 60 tiradas. Después se compara con lo que ocurre.
- El experimento: dejad la Pico enviando 5 minutos (60 tiradas) y guardad el CSV. Si la dejáis enchufada una hora, salen 720 tiradas.
- Comparar: si hay varias placas, ¿salen las mismas series? ¿Por qué sí o por qué no?
- La media: ¿se acerca a 3,5? ¿Cuántas tiradas hacen falta para que se quede cerca?
- Dado de verdad: tirad un dado físico 60 veces y apuntad los resultados. ¿Sale más repartido o menos que el de la Pico?
- Representar: pasad el CSV a una hoja de cálculo y haced un gráfico de barras. ¿Coincide con el de la página?
- Sorteo: usad el dado para decidir quién mide y dónde. ¿Por qué es más justo que elegir a mano?
Preguntas para discutir
- ¿Es lo mismo un dato que una medida?
- Si una cara sale 14 veces y otra 6, ¿el dado está trucado? ¿Cómo lo comprobarías?
- ¿Qué errores puede tener un dato inventado? ¿Y uno medido?
Retos
- Haz que funcione. Consigue que lleguen tiradas a la página.
- Modifica algo. Cambia el tiempo entre tiradas a 2 segundos, o el nombre de la placa por el tuyo.
- Cambia el dado. Usa
random.randint(1, 12)y adapta la página para que dibuje un dado de 12 caras con números en vez de puntos. - Guarda los datos. Pulsa Guardar CSV tras 100 tiradas y ábrelo en una hoja de cálculo.
- Representa los datos. Haz un gráfico de barras con el CSV y comprueba si coincide con el de la página.
- Automatiza el sorteo. Haz que la Pico envíe un número del 1 al 4 y úsalo para elegir cuál de cuatro puntos de medida visitar hoy.
- Haz que otra placa participe. Pon dos placas con nombres distintos y compara sus series.
- Conviértelo en investigación. Diseña un experimento para decidir si el dado es justo: cuántas tiradas necesitas y qué resultado te haría sospechar.
Qué hemos aprendido
- La Raspberry Pi Pico W es un microcontrolador pequeño, con Bluetooth y Wi-Fi, que se programa en Python.
- Para ponerla en marcha hay que grabar MicroPython una vez y decirle a Thonny qué puerto usar.
- El Bluetooth de la Pico usa el mismo UART que la micro:bit, así que la misma página sirve para las dos.
- Un número aleatorio de un ordenador es pseudoaleatorio: parece azar pero sale de una fórmula.
- Con pocas tiradas, las barras nunca salen iguales. Eso es el azar, no un fallo.
- Un dato inventado sirve para probar un sistema antes de tener los sensores.
El Lince ya tiene su ordenador de cinco centímetros. El siguiente paso es ponerle un sensor de verdad.
Para seguir investigando
- Cuentapasos con micro:bit y Bluetooth: el mismo Bluetooth, con otra placa.
- El letrero del Lince con Heltec: la placa que hace lo mismo con otro lenguaje.
- Estación del tiempo con micro:bit: datos reales que mandar al móvil.
- Documentación oficial de la Raspberry Pi Pico
- MicroPython para la Pico W
- Astro Pi, CanSat y Climate Detectives, de la ESA.
Este proyecto es un prototipo educativo.



