Need help with replaying an infrared signal

Hello all!
I'm trying to replay some infrared signals from an air conditioner remote.
The air conditioner is an old Rhoss Artemio.
I know that the signals should be long strings with all the parameters of the air conditioner included.
First I tried to record the signals; this is what I captured, for example for power off and power on:

Power off, 25 °C, fan velocity 2, cool
428 420 434 430 402 432 402 430 406 1238 434 1238 430 1234 432 1238 432 1236 432 428 406 428 406 1236 430 1234 432 430 406 428 406 1238 432 396 434 428 406 430 402 432 402 426 404 430 404 1240 432 404 432 426 404 430 404 1240 432 404 432 424 406 428 406 428 406 1236 430 402 430 430 404 430 404 430 404 1234 432 1238 434 428 402 1242 430 1234 432 428 406 428 406 430 406 424 406 1238 430 406 430 1240 432 426 404 424 406 434 402 430 410 422 404 1246 432 396 430 1250 420 1240 428 428 410 428 404 432 396 432 402 1246 422 406 432 1246 422 1238 424 1252 418 1242 428 1238 430 426 404 432 404 432 404 430 404 9598 428 420 434 430 402 432 402 430 406 1238 434 1238 430 1234 432 1238 432 1236 432 428 406 428 406 1236 430 1234 432 430 406 428 406 1238 432 396 434 428 406 430 402 432 402 426 404 430 404 1240 432 404 432 426 404 430 404 1240 432 404 432 424 406 428 406 428 406 1236 430 402 430 430 404 430 404 430 404 1234 432 1238 434 428 402 1242 430 1234 432 428 406 428 406 430 406 424 406 1238 430 406 430 1240 432 426 404 424 406 434 402 430 410 422 404 1246 432 396 430 1250 420 1240 428 428 410 428 404 432 396 432 402 1246 422 406 432 1246 422 1238 424 1252 418 1242 428 1238 430 426 404 432 404 432 404 430 404

Power on, 25 °C, fan velocity 2, cool
426 418 404 430 404 430 406 426 404 1240 432 1240 432 1232 430 1240 430 1234 432 404 432 432 404 1240 432 1232 430 406 430 430 404 1240 432 398 432 1236 430 406 430 430 404 426 404 430 404 1240 432 404 432 424 406 428 406 1238 430 406 430 426 404 430 404 430 404 1238 432 398 432 430 406 430 406 430 406 1234 430 1240 432 404 432 1238 432 1232 430 406 430 430 404 430 404 426 404 1240 432 402 432 428 406 424 406 420 412 432 398 432 412 422 402 1250 416 406 436 1246 420 1238 430 400 434 434 398 432 402 428 410 1238 426 404 434 428 406 1244 422 1240 426 1242 428 1242 428 396 434 428 406 428 402 430 404 9598 426 418 404 430 404 430 406 426 404 1240 432 1240 432 1232 430 1240 430 1234 432 404 432 432 404 1240 432 1232 430 406 430 430 404 1240 432 398 432 1236 430 406 430 430 404 426 404 430 404 1240 432 404 432 424 406 428 406 1238 430 406 430 426 404 430 404 430 404 1238 432 398 432 430 406 430 406 430 406 1234 430 1240 432 404 432 1238 432 1232 430 406 430 430 404 430 404 426 404 1240 432 402 432 428 406 424 406 420 412 432 398 432 412 422 402 1250 416 406 436 1246 420 1238 430 400 434 434 398 432 402 428 410 1238 426 404 434 428 406 1244 422 1240 426 1242 428 1242 428 396 434 428 406 428 402 430 404

It seems that a single frame contains 2 equal signals, with a pause of 9.6 ms in between.
The issue is that replaying the signal doesn't work, the air conditioner does not power off.
I tried also sending a single signal, same issue.
The signal doesn not look corrupted, they are 72 bit per signal, for example the 2 commands should decode as follows:

Power off, 25 °C, fan velocity 2, cool
000011111001100100000010001000010000110110000101000001011000010111110000
Hex: 0F 99 02 21 0D 85 05 85 F0

Power on, 25 °C, fan velocity 2, cool
000011111001100101000010001000010000110110000100000001011000010011110000
Hex: 0F 99 42 21 0D 84 05 84 F0

Other captured commands:
power on, 24°C, fan velocity 2, cool
000011111001100001000010001000010000110110000001000001011000000111110000
Hex: 0F 98 42 21 0D 81 05 81 F0

power on, 24°C, fan velocity 1, cool
000011111001100001000001001000010000110110000000000001011000000011110000
Hex: 0F 98 41 21 0D 80 05 80 F0

power on, 25°C, fan velocity 1, cool
000011111001100101000001001000010000110101111111000001010111111111110000
Hex: 0F 99 41 21 0D 7F 05 7F F0

power off, 25°C, fan velocity 1, cool
000011111001100100000001001000010000110101111110000001010111111011110000
Hex: 0F 99 01 21 0D 7E 05 7E F0

First and last bytes (0F - F0) seem an header/footer.
Second byte should be temperature (0x80 + °C)
Third byte should be power/fan setting.
The sixth and eigth bytes look like a decreasing counter (??).
I can't see any checksum in the string.
The signal looks good to me.

At the time of writing my goal is to only replicate the signal (power off for example), however I always failed.

Ir files to replicate the signals have this form (start/end with a mark), for example:

name: Power_ON
type: raw
frequency: 38000
duty_cycle: 0.33
data: 426 418 404 430 404 430 406 426 404 1240 432 1240 432 1232 430 1240 430 1234 432 404 432 432 404 1240 432 1232 430 406 430 430 404 1240 432 398 432 1236 430 406 430 430 404 426 404 430 404 1240 432 404 432 424 406 428 406 1238 430 406 430 426 404 430 404 430 404 1238 432 398 432 430 406 430 406 430 406 1234 430 1240 432 404 432 1238 432 1232 430 406 430 430 404 430 404 426 404 1240 432 402 432 428 406 424 406 420 412 432 398 432 412 422 402 1250 416 406 436 1246 420 1238 430 400 434 434 398 432 402 428 410 1238 426 404 434 428 406 1244 422 1240 426 1242 428 1242 428 396 434 428 406 428 402 430 404 9598 426 418 404 430 404 430 406 426 404 1240 432 1240 432 1232 430 1240 430 1234 432 404 432 432 404 1240 432 1232 430 406 430 430 404 1240 432 398 432 1236 430 406 430 430 404 426 404 430 404 1240 432 404 432 424 406 428 406 1238 430 406 430 426 404 430 404 430 404 1238 432 398 432 430 406 430 406 430 406 1234 430 1240 432 404 432 1238 432 1232 430 406 430 430 404 430 404 426 404 1240 432 402 432 428 406 424 406 420 412 432 398 432 412 422 402 1250 416 406 436 1246 420 1238 430 400 434 434 398 432 402 428 410 1238 426 404 434 428 406 1244 422 1240 426 1242 428 1242 428 396 434 428 406 428 402 430 404

Has anyone ever seen this protocol?
Do you see any error in the raw data or something that can cause the receiver to fail?
I can't see, nor I captured, a physical header (like the 9000 / 4500 nec), so I assume there's no header for this protocol.

Thank you for any idea.

Perhaps you are not doing this correctly. Post the details and someone might be able to help.

A rolling code is another possibility. Make two captures of the same command and compare them to see if anything changes.

I tried to replicate the signal with a lilygo t-embed cc1101 plus with bruce firmware; ir. file contains some tested signals:

Filetype: Bruce IR File
Version: 1
#
# Rhoss_AC
name: Power_OFF
type: raw
frequency: 38000
duty_cycle: 0.33
data: 428 420 434 430 402 432 402 430 406 1238 434 1238 430 1234 432 1238 432 1236 432 428 406 428 406 1236 430 1234 432 430 406 428 406 1238 432 396 434 428 406 430 402 432 402 426 404 430 404 1240 432 404 432 426 404 430 404 1240 432 404 432 424 406 428 406 428 406 1236 430 402 430 430 404 430 404 430 404 1234 432 1238 434 428 402 1242 430 1234 432 428 406 428 406 430 406 424 406 1238 430 406 430 1240 432 426 404 424 406 434 402 430 410 422 404 1246 432 396 430 1250 420 1240 428 428 410 428 404 432 396 432 402 1246 422 406 432 1246 422 1238 424 1252 418 1242 428 1238 430 426 404 432 404 432 404 430 404
#
name: Power_ON_25_V2
type: raw
frequency: 38000
duty_cycle: 0.33
data: 426 418 404 430 404 430 406 426 404 1240 432 1240 432 1232 430 1240 430 1234 432 404 432 432 404 1240 432 1232 430 406 430 430 404 1240 432 398 432 1236 430 406 430 430 404 426 404 430 404 1240 432 404 432 424 406 428 406 1238 430 406 430 426 404 430 404 430 404 1238 432 398 432 430 406 430 406 430 406 1234 430 1240 432 404 432 1238 432 1232 430 406 430 430 404 430 404 426 404 1240 432 402 432 428 406 424 406 420 412 432 398 432 412 422 402 1250 416 406 436 1246 420 1238 430 400 434 434 398 432 402 428 410 1238 426 404 434 428 406 1244 422 1240 426 1242 428 1242 428 396 434 428 406 428 402 430 404
#
name: Power_OFF_2T
type: raw
frequency: 38000
duty_cycle: 0.33
data: 428 420 434 430 402 432 402 430 406 1238 434 1238 430 1234 432 1238 432 1236 432 428 406 428 406 1236 430 1234 432 430 406 428 406 1238 432 396 434 428 406 430 402 432 402 426 404 430 404 1240 432 404 432 426 404 430 404 1240 432 404 432 424 406 428 406 428 406 1236 430 402 430 430 404 430 404 430 404 1234 432 1238 434 428 402 1242 430 1234 432 428 406 428 406 430 406 424 406 1238 430 406 430 1240 432 426 404 424 406 434 402 430 410 422 404 1246 432 396 430 1250 420 1240 428 428 410 428 404 432 396 432 402 1246 422 406 432 1246 422 1238 424 1252 418 1242 428 1238 430 426 404 432 404 432 404 430 404 9598 428 420 434 430 402 432 402 430 406 1238 434 1238 430 1234 432 1238 432 1236 432 428 406 428 406 1236 430 1234 432 430 406 428 406 1238 432 396 434 428 406 430 402 432 402 426 404 430 404 1240 432 404 432 426 404 430 404 1240 432 404 432 424 406 428 406 428 406 1236 430 402 430 430 404 430 404 430 404 1234 432 1238 434 428 402 1242 430 1234 432 428 406 428 406 430 406 424 406 1238 430 406 430 1240 432 426 404 424 406 434 402 430 410 422 404 1246 432 396 430 1250 420 1240 428 428 410 428 404 432 396 432 402 1246 422 406 432 1246 422 1238 424 1252 418 1242 428 1238 430 426 404 432 404 432 404 430 404
#
name: Power_ON_25_V2_2T
type: raw
frequency: 38000
duty_cycle: 0.33
data: 426 418 404 430 404 430 406 426 404 1240 432 1240 432 1232 430 1240 430 1234 432 404 432 432 404 1240 432 1232 430 406 430 430 404 1240 432 398 432 1236 430 406 430 430 404 426 404 430 404 1240 432 404 432 424 406 428 406 1238 430 406 430 426 404 430 404 430 404 1238 432 398 432 430 406 430 406 430 406 1234 430 1240 432 404 432 1238 432 1232 430 406 430 430 404 430 404 426 404 1240 432 402 432 428 406 424 406 420 412 432 398 432 412 422 402 1250 416 406 436 1246 420 1238 430 400 434 434 398 432 402 428 410 1238 426 404 434 428 406 1244 422 1240 426 1242 428 1242 428 396 434 428 406 428 402 430 404 9598 426 418 404 430 404 430 406 426 404 1240 432 1240 432 1232 430 1240 430 1234 432 404 432 432 404 1240 432 1232 430 406 430 430 404 1240 432 398 432 1236 430 406 430 430 404 426 404 430 404 1240 432 404 432 424 406 428 406 1238 430 406 430 426 404 430 404 430 404 1238 432 398 432 430 406 430 406 430 406 1234 430 1240 432 404 432 1238 432 1232 430 406 430 430 404 430 404 426 404 1240 432 402 432 428 406 424 406 420 412 432 398 432 412 422 402 1250 416 406 436 1246 420 1238 430 400 434 434 398 432 402 428 410 1238 426 404 434 428 406 1244 422 1240 426 1242 428 1242 428 396 434 428 406 428 402 430 404
#
name: Power_ON_24_V2
type: raw
frequency: 38000
duty_cycle: 0.33
data: 424 418 404 430 404 430 404 428 406 1238 430 1240 432 1232 430 1242 434 1232 430 430 404 430 404 1240 432 1232 430 430 404 430 404 430 404 426 404 1238 432 428 406 428 402 426 404 430 404 1240 432 428 406 424 406 428 406 1238 430 432 404 426 404 430 404 430 404 1240 432 426 406 430 406 428 406 428 402 1236 432 1240 432 402 432 1236 430 1234 432 402 432 428 406 428 406 424 406 428 406 428 406 1236 430 426 404 430 404 430 404 430 408 426 400 1240 432 428 406 1238 430 1234 432 404 430 430 406 428 408 424 406 430 406 430 406 1238 428 1236 434 1234 430 1244 428 1240 432 398 434 428 408 430 400 430 404
#
name: Power_ON_24_V2_2T
type: raw
frequency: 38000
duty_cycle: 0.33
data: 424 418 404 430 404 430 404 428 406 1238 430 1240 432 1232 430 1242 434 1232 430 430 404 430 404 1240 432 1232 430 430 404 430 404 430 404 426 404 1238 432 428 406 428 402 426 404 430 404 1240 432 428 406 424 406 428 406 1238 430 432 404 426 404 430 404 430 404 1240 432 426 406 430 406 428 406 428 402 1236 432 1240 432 402 432 1236 430 1234 432 402 432 428 406 428 406 424 406 428 406 428 406 1236 430 426 404 430 404 430 404 430 408 426 400 1240 432 428 406 1238 430 1234 432 404 430 430 406 428 408 424 406 430 406 430 406 1238 428 1236 434 1234 430 1244 428 1240 432 398 434 428 408 430 400 430 404 9600 428 414 404 432 404 432 404 430 406 1238 430 1240 432 1232 430 1244 432 1234 430 404 430 430 404 1240 432 1234 430 430 404 430 404 430 404 426 404 1240 432 428 406 428 406 424 406 428 402 1242 430 430 404 426 404 430 406 1238 434 428 402 426 404 430 404 430 410 1236 428 426 406 428 406 430 406 428 406 1234 428 1240 432 428 406 1238 430 1236 430 430 404 430 404 430 408 422 406 430 406 428 406 1238 430 426 404 430 404 430 404 430 404 426 404 1240 432 428 406 1236 430 1236 432 430 404 430 404 430 406 424 406 428 406 430 406 1238 430 1236 432 1240 432 1238 430 1240 432 424 406 428 406 428 406 428 402
#

I also wrote a small apk in android studio to send the raw signals through my xiaomi mobile (I captured the signals on the lilygo before the field test, which were consistent with the raw data).

I have 2 captures of the same command; they are different in one byte ("the decreasing counter"...):

For example:

power on, 25°C, fan velocity 2, cool
000011111001100101000010001000010000110110000100000001011000010011110000
0F 99 42 21 0D 84 05 84 F0

power on, 25°C, fan velocity 2, cool
000011111001100101000010001000010000110110000010000001011000001011110000
0F 99 42 21 0D 82 05 82 F0

Between 84 and 82 there was a shutdown (83), so that "counter" is apparently decreasing by 1 for each pressed key (except for the Temperature+ / Temperature- keys, in this case the counter doesn't move)

I can't really understand that "decreasing counter"..Note that the original ir remote is used to send signals to multiple equal air conditioners, and it works for all (at least it seems).

I'm thinking of forging a signal with that decreasing counter with a low number, like 00...does it make any sense?

How exactly are you sending the commands from the Arduino ?

Before looking at the protocol: how did you verify that your transmitter reproduces the original signal? Many AC units require a surprisingly strong IR signal. A correct timing alone is not sufficient if the optical output power is too low.

I'm first trying to understand what is the signal, with the tools I have; once I know that the signal is ok, I plan to build an arduino micro with an ir led using the IRremote library.

Good point, in real I'm not veryfying it.

When you said

I assumed that you had used an Arduino. How did you replay it ?

I agree with @UKHeliBob. Before diving into the protocol itself, it would help to know exactly how the commands are being transmitted. A decoded frame may look perfectly valid, yet still fail if the transmitted IR signal doesn't faithfully reproduce the original.

I edited the post above; capturing: tried lyligo t-embed with bruce firmware and esp32-bit-pirate; replay: same lilygo with bruce firmware (reads .ir raw file); then I tried the apk on android with the raw signal: I also captured with the same lilygo the signal transmitted from the mobile and the captured frame was consistent

Do you have two pieces of equipment, so that you can send from one, and receive that signal on the other?
That would enable you to verify whether you are sending what you think you are.

Yes, tried the android apk (sender) with the lilygo as receiver; the captured raw data were consistent. (Note that also the apk fails to shutdown the ac :D )

Some AC remotes run at 36 or 40 kHz instead of the usual 38 kHz. A receiver a few cm away will still pick that up fine, but the AC unit itself might not, since it's often less tolerant and further away. If the raw replay tool defaults to 38 kHz on transmit instead of using the frequency it actually measured, that could explain the failure even with perfect raw data.

What's your AC brand and model and is it in that list ?

Some remote systems use a "toggle" bit which changes with each press of a button. This is to help distinguish a new button press from a button being held down and generating repeats. So is this such a toggle? If you press a third time, does it go back to the original value?

The detected timings reflect any imperfections in the original sending remote plus imperfections in the receiving device. And then when that is duplicated by the alternate remote there are more imperfections. Looking at the timings, it's likely that all of the 3xx and 4xx values are nominally the same value, and the same would be true of all the 12xx values. But it doesn't look like what you've posted is different enough from that to cause a problem. The various AIs don't seem to know what the protocol actually is for Rhoss Artemio.

It's a Rhoss Artemio (not the idrowall in the list); not sure if it's the 07, 09 or 12 mini; they are essentially the same apart the power of the unit. The ac is not mine, it's in the clinic where my dad unfortunately is hospitalized. They only have 1 remote for all the ACs, I'd wanted to make a backup of it if something on that remote goes wrong....

Here is the remote:

And here is the ac:

Nope it continues decreasing; First day of tests I registered: 85, 84, 83, 82, 81, 80, second day, 7F, 7E, 7D, 7C, 7C; strange is that for keys T+ and T- that counter doesn't move...I'll try tomorrow to send a signal with 00 counter, let's see if I can shut it down...

Rhoss has historically rebadged units from other OEMs across its range, so the protocol isn't guaranteed to match...

If you wire a TSOP38238 (or similar 38kHz IR receiver) to a GPIO on the ESP32, and run the IRrecvDumpV2 example from IRremoteESP8266, and point the real remote at it while pressing a button you want to reproduce ➜ what protocol does it report?

If the protocol is recognized as an air conditioner type, the resultAcToString(&results) call adds a second block with the decoded state, temperature, mode, fan speed, and so on, so you'd see the actual settings if it matches RHOSS.

Bruce firmware includes the IRremoteESP8266 library and all captures are captured as raw (which defaults if no protocol is found), so no known protocol.

Signal looks clean. I have seen remotes that alternate one or two bits every button press to distinguish consecutive packets. How does your remote behave if you hold the button pressed?

That confirms your earlier guess, RHOSS wasn't a match, so it's fallen back to raw, meaning the Artemio's protocol isn't the same as the Idrowall one built into the underlying library.

If the goal is eventually to port this into your own ESP32 code, maybe it would be worth using directly IRrecvDumpV2, which provides you with the captured signal already compiled into ready to paste C++ source code, including the raw array formatted for a direct sendRaw() call, rather than a file meant to be replayed only from within Bruce itself.