OneWire (bus 1-Wire)
OneWire (1-Wire) es un bus en el que varios dispositivos comparten un solo cable de datos (más masa; opcionalmente una línea de alimentación, o “alimentación parásita” tomada del propio cable de datos). El dispositivo más típico es el sensor de temperatura DS18B20, y puedes encadenar varios en el mismo pin.
Cada dispositivo trae un identificador único (una dirección de 64 bits grabada de fábrica). El flujo es: configurar el pin → buscar los dispositivos para obtener sus identificadores → leer/escribir dirigiéndote a uno por su identificador.
El flujo de trabajo
Sección titulada «El flujo de trabajo»- Configura el pin como bus 1-Wire:
sendOneWireConfig(pin, parasita). - Busca dispositivos:
sendOneWireSearch(pin, callback). - Lee o escribe usando el identificador de un dispositivo.
- Usa
sendOneWireDelaycuando un dispositivo necesite tiempo para un cálculo (p. ej. una conversión de temperatura).
Las lecturas usan callbacks estilo (error, datos): el primer argumento es un error
(o null si todo fue bien) y el segundo, los datos. Comprueba siempre el error
antes de usar los datos.
Configurar: sendOneWireConfig(pin, alimentacionParasita)
Sección titulada «Configurar: sendOneWireConfig(pin, alimentacionParasita)»pin: el pin de datos del bus.alimentacionParasita(booleano):truesi los dispositivos se alimentan del propio cable de datos (modo parásito);falsesi tienen su propia alimentación.
board.sendOneWireConfig(2, false);Buscar dispositivos
Sección titulada «Buscar dispositivos»sendOneWireSearch(pin, callback) recorre el bus y entrega la lista de identificadores
encontrados:
board.sendOneWireSearch(2, (error, dispositivos) => { if (error) return; varG.numDispositivos = dispositivos.length; // cada elemento de "dispositivos" es el identificador de un dispositivo});sendOneWireAlarmsSearch(pin, callback) es igual, pero solo devuelve los dispositivos
en estado de alarma (los que soportan esa función, como sensores con umbral
configurado).
Leer, escribir y reiniciar
Sección titulada «Leer, escribir y reiniciar»| Método | Qué hace |
|---|---|
sendOneWireReset(pin) | envía un pulso de reset a todos los dispositivos del bus |
sendOneWireWrite(pin, dispositivo, datos) | escribe datos (un byte o un arreglo de bytes) al dispositivo |
sendOneWireRead(pin, dispositivo, nBytes, callback) | lee nBytes del dispositivo; callback(error, datos) |
sendOneWireWriteAndRead(pin, dispositivo, datos, nBytes, callback) | escribe y luego lee en una sola operación; callback(error, datos) |
sendOneWireDelay(pin, ms) | pide a la placa esperar ms milisegundos (para dar tiempo a un cálculo del dispositivo) |
dispositivo es uno de los identificadores que devolvió la búsqueda. La selección del
dispositivo en el bus la hace la placa internamente; tú solo pasas el identificador.
Ejemplo completo: temperatura con un DS18B20
Sección titulada «Ejemplo completo: temperatura con un DS18B20»const PIN = 2;board.sendOneWireConfig(PIN, false);
board.sendOneWireSearch(PIN, (error, dispositivos) => { if (error || dispositivos.length === 0) { varG.error = "Sin dispositivos 1-Wire"; return; } const sensor = dispositivos[0]; // primer dispositivo encontrado
// 1) Pedir una conversión de temperatura (comando 0x44 del DS18B20) board.sendOneWireReset(PIN); board.sendOneWireWrite(PIN, sensor, 0x44);
// 2) Esperar a que el sensor calcule (~750 ms a 12 bits) board.sendOneWireDelay(PIN, 1000);
// 3) Leer el "scratchpad" (comando 0xBE) y sus 9 bytes board.sendOneWireReset(PIN); board.sendOneWireWriteAndRead(PIN, sensor, 0xBE, 9, (err, data) => { if (err) return; // Los 2 primeros bytes son la temperatura: byte bajo y byte alto const crudo = (data[1] << 8) | data[0]; varG.temperatura = crudo / 16; // °C (resolución de 12 bits) });});(Sobre (data[1] << 8) | data[0], mira cómo se combinan dos bytes en
I2C. Los comandos 0x44/0xBE y el formato de la
temperatura son propios del DS18B20; otros dispositivos 1-Wire usan los suyos, según su
datasheet.)
Muestrear periódicamente
Sección titulada «Muestrear periódicamente»Como una conversión tarda, repite el ciclo dentro de un setInterval con margen:
const PIN = 2;board.sendOneWireConfig(PIN, false);
board.sendOneWireSearch(PIN, (error, dispositivos) => { if (error || dispositivos.length === 0) return; const sensor = dispositivos[0];
setInterval(() => { board.sendOneWireReset(PIN); board.sendOneWireWrite(PIN, sensor, 0x44); board.sendOneWireDelay(PIN, 1000); board.sendOneWireReset(PIN); board.sendOneWireWriteAndRead(PIN, sensor, 0xBE, 9, (err, data) => { if (err) return; const crudo = (data[1] << 8) | data[0]; pushData("temperaturas", crudo / 16); }); }, 2000);});Errores típicos
Sección titulada «Errores típicos»- Usar un dispositivo sin buscarlo antes: necesitas el identificador que devuelve
sendOneWireSearch. - No esperar la conversión: sin
sendOneWireDelaytras pedir una medición, lees datos incompletos o viejos. - Ignorar el
errordel callback: comprueba siempre el primer argumento antes de usar los datos.