A portable, hardware-agnostic C driver for the GROW R503 capacitive fingerprint sensor module, implemented against the official GROW-R503 user manual.
The driver has no platform dependencies. It communicates through two user-supplied UART callbacks, which makes it straightforward to integrate on any microcontroller or Linux system.
- Platform-independent — no HAL or OS dependency; bring your own UART callbacks
- Clean C11 API with consistent
i_/o_-prefixed parameters and a unified return-code type - Static library — easy to add as a CMake subdirectory or copy the two source files directly
- Unit tests (no hardware required) and live tests (sensor on
/dev/ttyUSB0) - Full Doxygen documentation on all public symbols
Currently only a minium set of functions are implemented. They are sufficient for using the sensor in a basic form (adding, removing and scanning fingers; controlling the aura-led).
Option A — CMake subdirectory
add_subdirectory(r503)
target_link_libraries(your_target PRIVATE r503)Option B — copy sources
Copy src/r503.c, src/r503.h, src/r503_pkg.c, src/r503_pkg.h, and src/r503_types.h into your project and add them to your build.
The driver needs two callbacks that match the function-pointer types in r503.h:
#include "r503.h"
/* Write i_buf_size bytes to the UART. Return R503_RC_OK on success. */
static r503_RC_t uart_write(const uint8_t *const i_buf, const uint32_t i_buf_size)
{
/* platform-specific implementation */
return R503_RC_OK;
}
/* Read up to i_buf_size bytes from the UART into o_buf.
Write the number of bytes actually read into *o_bytes_read.
Return R503_RC_ERR_UART_TIMEOUT on timeout, R503_RC_OK on success. */
static r503_RC_t uart_read(uint8_t *const o_buf, const uint32_t i_buf_size,
uint32_t *const o_bytes_read)
{
/* platform-specific implementation */
return R503_RC_OK;
}#include "r503.h"
static const r503_cfg_t cfg = {
.module_address = R503_DEFAULT_ADDRESS,
.module_password = R503_DEFAULT_PASSWORD,
.uart_write_bytes = uart_write,
.uart_read_bytes = uart_read,
.logging_func = NULL, /* optional: pass a wchar_t log callback */
};
int main(void)
{
r503_RC_t rc;
rc = r503_init(&cfg);
rc = r503_verify_password();
/* Enroll a finger into slot 0 */
rc = r503_collect_image_ex(); /* wait for finger */
rc = r503_img_to_char_file(R503_CHAR_BUF_ID_1); /* convert image */
rc = r503_collect_image_ex(); /* lift and re-place*/
rc = r503_img_to_char_file(R503_CHAR_BUF_ID_2);
rc = r503_generate_template(); /* merge buffers */
rc = r503_store_template(0, R503_CHAR_BUF_ID_1); /* save to slot 0 */
/* Identify a finger */
uint16_t found_id, score;
rc = r503_collect_image_ex();
rc = r503_img_to_char_file(R503_CHAR_BUF_ID_1);
rc = r503_search(&found_id, &score,
R503_CHAR_BUF_ID_1,
0, /* search start */
200); /* search count */
if (rc == R503_RC_OK) {
/* matched — found_id and score are valid */
}
return 0;
}Prerequisites: CMake ≥ 3.14, a C11/C++20 compiler. GoogleTest is fetched automatically at configure time.
cmake -B build
cmake --build buildUnit tests (no hardware required):
./build/test/r503_unit_testsLive tests (R503 sensor connected to /dev/ttyUSB0):
# Ensure your user has access to the serial port
sudo usermod -aG dialout $USER # then log out and back in
./build/test/r503_live_testsRun all tests via CTest:
ctest --test-dir build --output-on-failureThe driver was developed and tested with the GROW R503 circular capacitive fingerprint sensor. The communication protocol is UART at 57600 baud (default) with a fixed preamble header, device address, and checksum as described in the GROW-R503 user manual.
Default configuration:
| Parameter | Value |
|---|---|
| Baud rate | 57600 |
| Module address | 0xFFFFFFFF |
| Module password | 0x00000000 |
MIT © 2025 Tom Christ