A lightweight, ESP-IDF 5.5 native C library for the RV-3032-C7 Temperature Compensated Real-Time Clock Module.
- âś… ESP-IDF 5.5 Native: Uses latest ESP-IDF I2C master driver and GPIO APIs
- âś… Time/Date Management: Read and set date/time with high precision
- âś… Alarm Functionality: Flexible alarm system with interrupt support
- âś… Unix Timestamp: Convert between RTC time and Unix timestamps
- âś… Memory Efficient: Minimal RAM footprint and efficient I2C communication
- âś… Thread Safe: Uses ESP-IDF synchronization primitives
- âś… Well Documented: Comprehensive documentation and examples
- âś… Extensible Design: Easy to add more RTC features later
- ESP32 series microcontroller
- RV-3032-C7 RTC module
- Pull-up resistors for I2C (usually built into ESP32 boards)
- Optional: Pull-up resistor for INT pin (10kΩ recommended)
đź“– RV-3032-C7 Application Manual - Official datasheet and technical reference
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2c_master.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "RV3032.h"
static i2c_master_bus_handle_t i2c_bus_handle;
static rv3032_handle_t rtc_handle;
// Initialize I2C bus
static esp_err_t init_i2c(void) {
i2c_master_bus_config_t i2c_config = {
.clk_source = I2C_CLK_SRC_DEFAULT,
.i2c_port = -1,
.scl_io_num = GPIO_NUM_22,
.sda_io_num = GPIO_NUM_21,
.glitch_ignore_cnt = 7,
.flags.enable_internal_pullup = true,
};
return i2c_new_master_bus(&i2c_config, &i2c_bus_handle);
}
void app_main(void) {
// Initialize I2C
ESP_ERROR_CHECK(init_i2c());
// Initialize RTC
ESP_ERROR_CHECK(rv3032_init(&rtc_handle, i2c_bus_handle, GPIO_NUM_NC, NULL));
// Set time: 2024-12-15 12:30:00
rv3032_datetime_t dt = {
.year = 24, .month = 12, .date = 15,
.hours = 12, .minutes = 30, .seconds = 0
};
rv3032_set_datetime(&rtc_handle, &dt);
while (1) {
rv3032_datetime_t current_time;
if (rv3032_get_datetime(&rtc_handle, ¤t_time) == ESP_OK) {
printf("Time: 20%02d-%02d-%02d %02d:%02d:%02d\n",
current_time.year, current_time.month, current_time.date,
current_time.hours, current_time.minutes, current_time.seconds);
}
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
esp_err_t rv3032_init(rv3032_handle_t* handle, i2c_master_bus_handle_t i2c_bus_handle, gpio_num_t int_pin, void (*alarm_callback)(void))
Initialize the RTC module.
handle
: Pointer to RV3032 handle structurei2c_bus_handle
: ESP-IDF I2C master bus handleint_pin
: GPIO pin for interrupt (GPIO_NUM_NC if not used)alarm_callback
: Callback function for alarm interrupt (NULL if not used)- Returns: ESP_OK on success, error code otherwise
Deinitialize the RTC and free resources.
Read current date and time.
Set the RTC date and time.
Get Unix timestamp (seconds since Jan 1, 2000).
Set time using Unix timestamp.
esp_err_t rv3032_set_alarm(rv3032_handle_t* handle, const rv3032_alarm_t* alarm, bool enable_interrupt)
Configure alarm settings.
Read current alarm settings.
Clear alarm flag and disable alarm.
Check if alarm has been triggered.
typedef struct {
uint8_t year; // 0-99 (represents 2000-2099)
uint8_t month; // 1-12
uint8_t date; // 1-31
uint8_t weekday; // 0-6 (user defined)
uint8_t hours; // 0-23
uint8_t minutes; // 0-59
uint8_t seconds; // 0-59
uint8_t hundredths; // 0-99 (read-only)
} rv3032_datetime_t;
typedef struct {
uint8_t date; // 1-31
uint8_t hours; // 0-23
uint8_t minutes; // 0-59
bool date_enable; // Enable date matching
bool hours_enable; // Enable hours matching
bool minutes_enable; // Enable minutes matching
} rv3032_alarm_t;
rv3032_alarm_t alarm = {
.hours = 7, // 7:00 AM
.minutes = 30, // 30 minutes
.date = 1, // Ignored
.hours_enable = true,
.minutes_enable = true,
.date_enable = false // Disable date matching
};
rv3032_set_alarm(&rtc_handle, &alarm, true);
rv3032_alarm_t alarm = {
.date = 15, // 15th of each month
.hours = 9, // 9:00 AM
.minutes = 0,
.date_enable = true,
.hours_enable = true,
.minutes_enable = true
};
rv3032_set_alarm(&rtc_handle, &alarm, true);
static volatile bool alarm_flag = false;
static void alarm_callback(void) {
// Called from ISR context - keep it minimal
alarm_flag = true;
}
void app_main(void) {
// Initialize with interrupt callback
rv3032_init(&rtc_handle, i2c_bus_handle, GPIO_NUM_2, alarm_callback);
// Set up alarm...
while (1) {
if (alarm_flag) {
alarm_flag = false;
printf("Alarm triggered!\n");
// Handle alarm event
bool triggered;
if (rv3032_is_alarm_triggered(&rtc_handle, &triggered) == ESP_OK && triggered) {
// Process alarm
rv3032_clear_alarm(&rtc_handle); // Optional: disable further alarms
}
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
If you're using a C++ file (main.cpp), you need to:
-
Include the library with extern "C":
extern "C" { #include "RV3032.h" }
-
Use proper GPIO types:
// Use GPIO_NUM_X constants instead of plain integers #define RTC_INT_PIN GPIO_NUM_2 // Not just "2"
-
Initialize structs without designated initializers:
// C++ style initialization rv3032_datetime_t dt = {}; dt.year = 24; dt.month = 12; dt.date = 15; // ... set other fields // Instead of C99 designated initializers: // rv3032_datetime_t dt = {.year = 24, .month = 12, .date = 15};
Multiple devices can share the same I2C bus:
// Create I2C bus once
i2c_master_bus_handle_t i2c_bus;
i2c_master_bus_config_t bus_config = {
.clk_source = I2C_CLK_SRC_DEFAULT,
.i2c_port = -1,
.scl_io_num = GPIO_NUM_22,
.sda_io_num = GPIO_NUM_21,
.glitch_ignore_cnt = 7,
.flags.enable_internal_pullup = true,
};
i2c_new_master_bus(&bus_config, &i2c_bus);
// Initialize RTC with shared bus
rv3032_init(&rtc_handle, i2c_bus, GPIO_NUM_2, alarm_callback);
// Initialize other I2C devices with the same bus...
- Uses new
i2c_master
driver (replaces legacyi2c
driver) - Compatible with ESP-IDF 5.5+
- Uses ESP-IDF native error handling (
esp_err_t
) - Thread-safe operations using ESP-IDF primitives
- Default I2C address:
0x51
(7-bit) - Supports up to 400kHz I2C speed
- Uses efficient burst read/write operations
- Built-in timeout handling (1000ms default)
- Minimal RAM footprint (~100 bytes per handle)
- No dynamic memory allocation during normal operation
- Stack-based temporary buffers for I2C operations
This library is designed for easy extension:
- Temperature sensor reading (registers 0x0E, 0x0F)
- Periodic timer interrupts (registers 0x0B, 0x0C)
- External event timestamping (EVI pin)
- Clock output configuration (CLKOUT pin)
- EEPROM access for user data
- Power management features
- Time stamp functions
- Check I2C wiring (SDA, SCL)
- Verify 3.3V power supply
- Ensure pull-up resistors on I2C lines
- Check I2C bus configuration in menuconfig
- Verify I2C pins are not used by other peripherals
- Try lower I2C speed in bus configuration
- Check for I2C conflicts with other devices
- Verify INT pin connection and pull-up
- Check GPIO pin configuration
- Ensure interrupt service is installed
- Verify alarm settings are correct
- Ensure ESP-IDF version is 5.5 or higher
- Check CMakeLists.txt includes required components
- Verify all source files are in SRCS list
- If building the examples: MAKE SURE THE ROOT DIRECTORY IS NAME "RV3032_ESP32" (or change the CMakeList.txt)
This project is licensed under the MIT License - see the LICENSE file for details.
Author: Jonas Schnelli
Based on the RV-3032-C7 Application Manual Rev. 1.3 (May 2023).
Contributions are welcome! Please:
- Follow ESP-IDF coding standards
- Keep the code memory efficient
- Add appropriate error handling
- Test thoroughly with ESP-IDF 5.5+
- Update documentation accordingly