NAME
Protocol::IR::Format::Pronto - Raw Pronto Hex encoder and decoder
VERSION
version 1.2
SYNOPSIS
use Protocol::IR::Converter;
my $converter = Protocol::IR::Converter->new();
my $code = $converter->import_code('NEC', '0x10EF00FF');
# Encode an Protocol::IR::Code object as Pronto Hex
my $pronto = $converter->export_code($code, 'Pronto');
# Decode Pronto Hex back into an Protocol::IR::Code
my $decoded = $converter->import_format('Pronto', $pronto);
DESCRIPTION
Protocol::IR::Format::Pronto encodes Protocol::IR::Code objects into Pronto Hex strings and decodes Pronto Hex back into Protocol::IR::Code objects. Only the raw form (header 0000) is supported.
- Example Pronto Hex (a 32-bit NEC transmission)
-
0000 006D 0022 0000 0157 00AC 0015 0015 0015 0015 0015 0015 0015 0015 \ 0015 0040 0015 0015 0015 0015 0015 0015 0015 0040 0015 0040 0015 0040 \ 0015 0040 0015 0015 0015 0040 0015 0040 0015 0040 0015 0015 0015 0015 \ 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0015 0040 \ 0015 0040 0015 0040 0015 0040 0015 0040 0015 0040 0015 0040 0015 0040 \ 0015 0689The fields are the raw-format marker (
0000), the carrier frequency word (006D), the burst-pair counts for the one-time and repeat sequences (0022 0000), then that many mark/space pulse-count pairs, the final value being the trailing stop bit. See the IR Scrutinizer glossary for the full field layout (http://www.harctoolbox.org/Glossary.html).
The carrier frequency word is stored in the frequency field and converted to a period in microseconds: the pulse count stored for each mark/space is the duration in carrier cycles, so the actual duration depends on the transmitter's carrier frequency. Protocol encoders emit frequency words for their nominal carrier (typically 38 kHz) and pulse counts quantized to that carrier, so the decoded microsecond timings round-trip cleanly.
Because decoding works from the microsecond timing signature (see "DECODING VERSUS GENERATING TIMINGS" in Protocol::IR::Converter), a Pronto string is only recognized if it matches a registered protocol. Whether or not it does, the decoded Protocol::IR::Code keeps the exact capture -- the quantized timings and the hex stashed verbatim in pronto -- so export (and any Pronto-passthrough container such as wig or the JSON dump importer) round-trips the string byte-identically. A well-formed string with real timing data that no protocol recognizes is not an error: it decodes to an opaque UNKNOWN code (bypass_protocol set) so container conversions that move Pronto hex can still complete. Truncated or empty payloads are still rejected.
prontois set on every Pronto decode, soexportre-emits the original string rather than re-quantizing through the protocol encoder.timingsis set on every Pronto decode, so the same microsecond waveform feeds the other timing formats (Tasmota, mode2, LIRC) losslessly.
METHODS
export
my $pronto = $class->export($ir_code, $registry);
Converts a single Protocol::IR::Code object into a Pronto Hex string. When the code was itself decoded from Pronto Hex, its stashed pronto string is re-emitted verbatim. Otherwise the registered protocol handler for the code's protocol encodes it from its decoded fields (to_pronto).
decode
my $code = $class->decode($pronto_str, $registry);
Parses a Pronto Hex string into microsecond mark/space pairs and tries each registered protocol's decode_timing in registration order. Returns the first matching Protocol::IR::Code, or dies if the string cannot be decoded.
decode is named decode rather than import to avoid clashing with Perl's module import hook.
SUPPORT
Source code: https://github.com/bwarden/perl-protocol-ir
Bug reports and feature requests: https://github.com/bwarden/perl-protocol-ir/issues
AUTHOR
Brett T. Warden <bwarden@cpan.org>
COPYRIGHT AND LICENSE
Copyright (c) 2026 Brett T. Warden
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation.