Skip to content

Feature request: user callback for raw pulse trains (enables custom decoders without modifying the library) #207

Description

@wiredsim

Summary

Add a user-registerable callback that fires with the raw pulse/gap arrays whenever the library captures a pulse train — independent of whether any built-in decoder matched.

Motivation

Today, downstream code can register setCallback(rtl_433_Callback, ...) to receive JSON-formatted decode results, but only when a built-in decoder matches the packet. For unknown / custom protocols (with -DPUBLISH_UNPARSED), the raw pulse data is written to stdout via printf() (logprintf / alogprintf macros in include/log.h).

This makes it very difficult to implement custom protocol decoders in user code without modifying the library. In a recent project I tried three different interception paths to consume those raw pulses from user code on Arduino-ESP32 v2.x:

Interception path Result
Log.begin(LOG_LEVEL, &myPrint) (ArduinoLog redirect) No effect — logprintf / alogprintf use raw printf(), not ArduinoLog
extern "C" int _write(int fd, const void *data, size_t size) No effect — current Arduino-ESP32 v2.x doesn't route ROM printf through newlib syscalls
ets_install_putc1(my_putc) No effect — different code path on this Arduino-ESP32 build

The only working option ended up being parsing the serial output from a separate Python process on the host PC, which doesn't help for embedded-only deployments.

Proposed API

typedef void (*rtl_433_raw_pulse_cb)(
    const int* pulse_us,
    const int* gap_us,
    unsigned int num_pulses,
    unsigned long duration_us,
    int rssi
);

void rtl_433_ESP::setRawPulsesCallback(rtl_433_raw_pulse_cb cb);

Fired from the same context as the existing JSON callback in signalDecoder.cpp, right around the PUBLISH_UNPARSED block — but unconditional (fires whether or not a decoder matched). Pointers are valid only during the callback; caller must copy if they need to retain.

Use cases

  1. Implementing custom decoders for protocols not in rtl_433's device set (cheap proprietary remotes, off-brand sensors, pyrotechnic cue remotes, etc.)
  2. Logging / exporting pulse data for offline analysis (URH, triq.org/pdv)
  3. Building protocol-discovery tools that run on-device rather than tethered to a host PC

Happy to put together a PR if the maintainer is open to the design. Let me know if you'd prefer a different shape (e.g. a virtual method to override, or a pulse_data_t* rather than separate arrays).

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions