
Today we are going to try to capture an IR (infrared) signal using Flipper Zero, analyse it both in Flipper .raw format and on oscilloscope and then consider what is needed to send such a signal from within our microcontroller.
Flipper Zero allows you to conveniently capture, store and transmit IR signals, which is well described in its documentation:
https://docs.flipper.net/infrared/read
Flipper Zero supports a wide range of popular formats, such as RC5, RC6 or NEC, for example, but also supports the raw format - that is, the universal 'raw' (unprocessed) signal format. This allows essentially any device to be controlled, and without knowledge of the signal encoding itself. It also allows the community to create open IR code bases, such as Flipper-IRDB, for example:
https://github.com/Lucaslhm/Flipper-IRDB/
Inside, we have a range of captured signals to choose from.

For example, here signals from Samsung TVs:
https://github.com/Lucaslhm/Flipper-IRDB/blob/main/TVs/Samsung/Samsung_AA-00721A
The protocol here is Samsung 32, this is what the example signal looks like:
Filetype: IR signals file
Version: 1
#
# SAMSUNG TV MODEL UN40FH5005F
# DOWNLOADS URL: https://www.samsung.com/latin/support/model/UN40FH5005FXZP/#downloads
#
name: Power
type: parsed
protocol: Samsung32
address: 07 00 00 00
command: 02 00 00 00
#
This type of file can be uploaded to Flipper via USB and then send the signal described in this way.
And here for the Dyson air freshener:
https://github.com/Lucaslhm/Flipper-IRDB/blob/main/Air_Purifiers/Dyson/Dyson_HotCool_HP02.ir
And here is something we are more interested in on this topic - the raw format:
name: Power
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 2204 708 834 1342 882 1344 837 632 836 1392 836 615 723 738 836 633 861 684 835 658 838 710 835 657 838 656 837 641 723 762 838 1397 727 101537 2257 704 761 1417 884 1342 762 737 731 1467 836 612 828 634 760 707 787 760 835 658 761 786 835 658 761 733 836 637 827 660 763 1473 726
This is the format that Flipper supports, it can both write an unknown signal to RAW and generate a signal from a RAW file. So let's consider how this format works.... <br/span> But perhaps first...
Practical example .
Let us perhaps leave these repositories of codes captured by other users and try to catch some signal ourselves. We just happened to have a "Smart IR Remote" from Tuya, a WiFi-controlled gadget capable of sending and receiving various IR signals. As a test, we decided to send something from it to the Flipper:


After saving the received signal on Flipper, we received such a file:
name: RAW_63
type: raw
frequency: 38000
duty_cycle: 0.330000
data: 3190 1291 951 502 902 1292 903 546 901 640 902 545 903 548 900 545 902 641 901 546 902 546 901 546 902 639 903 1294 901 65009 2376 549 903 1293 1007 1283 901 640 902 1294 901 546 902 546 902 545 902 640 902 546 901 639 903 546 901 639 903 546 902 546 901 1293 902
It is now time to see what the same signal looks like on an oscilloscope. The trigger function was used to capture the data, i.e. triggering the capture with the edge of the signal.
Let's look at the green signal (the yellow one is after processing):

You can see essentially two logical levels here, only that one of them is 'jagged', what does this mean?

This "jagged" signal is a 38kHz carrier wave, the signal here has been modulated. In the first screenshot from the oscilloscope, the demodulated signal is shown in yellow.
We now know what these two parameters mean:
frequency: 38000
duty_cycle: 0.330000
The first is the frequency used (usually around 30-60kHz) and the second is the fill cycle.
What's left is the raw format data. These are not bytes, but times in microseconds:
data: 3190 1291 951 502 902 1292 903 546 901 640 902 545 903 548 900 545 902 641 901 546 902 546 901 546 902 639 903 1294 901 65009 2376 549 903 1293 1007 1283 901 640 902 1294 901 546 902 546 902 545 902 640 902 546 901 639 903 546 901 639 903 546 902 546 901 1293 902
Simply plot their values on the oscillogram and we can already see that everything agrees:

These numbers are the times of the high and low states sequentially, so that the raw format is able to reflect the different signals, regardless of the coding used further down in them.
Generation of IR signals .
Based on the data collected, we already know that a 38kHz hardware PWM will probably be useful, and some way to switch it on and off quickly, preferably using a timer and an interrupt. In addition, some kind of control of how we switch them on and off, some kind of buffer or queue of times that we will count down, will be useful. In this way we will try to make our own mechanism for sending captured signals in RAW format on some MCU. Details in the next section.
Summary .
Here we looked at communication based on infrared light, which is commonly used by many appliaces, because who hasn't used a TV remote control? After capturing the signal, we saw that the IR transmitting diode operates in two states, either an off state (no light) or an active state in which it flashes at a certain frequency. This behaviour of the IR diode is common to many protocols and can be conveniently described using a format such as Raw (frequency, padding, and times of ones and zeros), allowing the signal to be captured and sent back without specific knowledge of its structure.
Have you used IR in your projects, and if so, did you write the send/receive driver from scratch, or did you use an off-the-shelf one (Arduino-IRRemote or IRRemoteESP8266)? .
Cool? Ranking DIY Helpful post? Buy me a coffee.