Volver

Leer un RTC DS1307 virtual con Raspberry Pi Pico I2C

Introducción

¿Alguna vez has querido añadir un reloj en tiempo real (RTC) a tu proyecto pero no tenías el hardware a mano? Con Velxio, puedes simular una lectura completa de un RTC I2C usando una Raspberry Pi Pico y un DS1307 virtual, todo en tu navegador. En este tutorial, recorreremos el circuito, el código y los conceptos clave para que puedas usar la comunicación I2C con confianza en tus propios proyectos.

Recorrido del Circuito

Empecemos viendo el circuito. Abre el ejemplo en Velxio y verás los siguientes componentes:

Diagrama del circuito pico-i2c-rtc-read en el lienzo del simulador Velxio

El circuito es sencillo: una Raspberry Pi Pico (nano-rp2040) está conectada a dos LEDs y un RTC DS1307 virtual (no se muestra como componente separado — el RTC está integrado en la simulación). Los LEDs se usan como indicadores visuales de la actividad I2C.

Ambos LEDs comparten la misma tierra (GND.1). El bus I2C consta de las líneas SDA (datos) y SCL (reloj). El RTC DS1307 está conectado internamente a estas líneas en la dirección 0x68. Los LEDs no son estrictamente necesarios para la comunicación I2C, pero proporcionan una pista visual de que las líneas están cambiando de estado.

Para construir este circuito tú mismo, puedes usar el selector de componentes de Velxio:

Modal del selector de componentes de Velxio explorando piezas por categoría

Busca “Raspberry Pi Pico” y “LED”, luego conéctalos como se describe. La barra de herramientas del lienzo te ayuda a hacer zoom y organizar los componentes:

Barra de herramientas del lienzo de Velxio sobre la ventana de simulación

Recorrido del Código

Ahora vamos a sumergirnos en el código. El sketch utiliza la librería Wire (integrada) para comunicarse con el DS1307 por I2C. Aquí está el código completo:

// Raspberry Pi Pico — I2C DS1307 RTC Read
// Reads time from virtual RTC at address 0x68

#include <Wire.h>

byte bcdToDec(byte val) {
  return ((val >> 4) * 10) + (val & 0x0F);
}

void setup() {
  Serial.begin(115200);
  delay(500);
  Wire.begin();
  Serial.println("=== Pico I2C RTC Read ===");
  Serial.println("Reading DS1307 at 0x68 (system time)");
  Serial.println();
}

void loop() {
  // Set register pointer to 0
  Wire.beginTransmission(0x68);
  Wire.write(0x00);
  Wire.endTransmission();

  // Read 7 bytes: sec, min, hr, dow, date, month, year
  Wire.requestFrom(0x68, 7);
  if (Wire.available() >= 7) {
    byte sec   = bcdToDec(Wire.read() & 0x7F);
    byte min   = bcdToDec(Wire.read());
    byte hr    = bcdToDec(Wire.read() & 0x3F);
    byte dow   = bcdToDec(Wire.read());
    byte date  = bcdToDec(Wire.read());
    byte month = bcdToDec(Wire.read());
    byte year  = bcdToDec(Wire.read());

    const char* days[] = {"", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};

    Serial.print("Time: ");
    if (hr < 10) Serial.print('0'); Serial.print(hr); Serial.print(':');
    if (min < 10) Serial.print('0'); Serial.print(min); Serial.print(':');
    if (sec < 10) Serial.print('0'); Serial.print(sec);
    Serial.print("  Date: ");
    Serial.print(days[dow]); Serial.print(' ');
    if (date < 10) Serial.print('0'); Serial.print(date); Serial.print('/');
    if (month < 10) Serial.print('0'); Serial.print(month); Serial.print('/');
    Serial.print("20"); if (year < 10) Serial.print('0'); Serial.println(year);
  } else {
    Serial.println("RTC not responding!");
  }

  delay(1000);
}

Cómo Funciona

  1. Configuración: Iniciamos la comunicación serie a 115200 baudios e inicializamos el bus I2C con Wire.begin(). El DS1307 está en la dirección 0x68.

  2. Bucle: Cada segundo, hacemos lo siguiente:

    • Enviamos un beginTransmission a la dirección 0x68, escribimos 0x00 (el puntero de registro al registro de segundos) y endTransmission.
    • Solicitamos 7 bytes al RTC usando Wire.requestFrom(0x68, 7).
    • Leemos cada byte y lo convertimos de BCD (Decimal Codificado en Binario) a decimal usando la función auxiliar bcdToDec.
    • Formateamos e imprimimos la hora y la fecha en el Monitor Serie.
  3. Conversión BCD: El DS1307 almacena los valores de tiempo en formato BCD. Por ejemplo, el byte 0x45 representa 45 en BCD (4*10 + 5 = 45). La función bcdToDec extrae el dígito de las decenas (nibble alto) y el dígito de las unidades (nibble bajo) y los combina.

  4. Enmascaramiento: Aplicamos máscaras a ciertos registros:

    • Segundos: & 0x7F limpia el bit CH (parada del reloj).
    • Horas: & 0x3F limpia el bit de modo 12/24 horas (asumiendo modo 24 horas).

Conceptos Clave

Errores Comunes y Consejos de Depuración

Extensiones Sugeridas

¡Pruébalo Tú Mismo!

¿Listo para experimentar? Abre el ejemplo en vivo en Velxio y ejecuta la simulación. Verás la hora impresa en el Monitor Serie cada segundo. Modifica el código para cambiar el intervalo de actualización o añadir nuevas funcionalidades.

Lanzar el Ejemplo de Lectura de RTC I2C con Pico

¡Feliz simulación!


Compartir en:
David Montero

Escrito por

David Montero

Creator of Velxio, the open-source circuit and Arduino simulator.

GitHub velxio.dev

Artículos relacionados


Artículo anterior
Lectura/Escritura de EEPROM I2C con Pico: Simula Memoria No Volátil en tu Navegador
Artículo siguiente
Escáner I2C para Pico: Encuentra Dispositivos en el Bus