arjenhiemstra / IthoEcoFanRFTCombined

1 stars 0 forks source link

Determine the device ID #1

Open Sharangovich opened 5 months ago

Sharangovich commented 5 months ago

Hi! I tried to implement the transmit/receive logic using the wireframe originally from Klusjesman but I can't receive any messages and can't control the Itho Fan. I have a CVE-S PAK, which is not an ECO but since they use the same RFT I guess that control should work without any issues too. I think that it doesn't work because the device ID in the code doesn't match my RFT (with an auto button). Is it correct? If so, how do I get that device ID?

In the simplified setup function it does get to the end (1 out 10 times, often stuck on join command sent).

void setup(void) {
  Serial.begin(115200);
  delay(500);
  Serial.println("setup begin");
  rf.init();
  Serial.println("setup done");
  sendRegister();
  Serial.println("join command sent");
  pinMode(ITHO_IRQ_PIN, INPUT);
  attachInterrupt(ITHO_IRQ_PIN, ITHOcheck, FALLING);
  Serial.println("end setup");
}

Is it reasonable to assume the wiring is correct then? Since the rf.init(); and sendRegister(); don't fail.

setup It runs on UNO R3 board, connected to C1101 as described in README, via level converters. I have also a Pro Mini 3V3 board for this project, but I wanted to validate the concept first.

I'm also able to send commands, like high speed within setup block, and it succeeds, except for the part that the signal goes nowhere (fan does not kick in).

setup begin
setup done
sending join...
sending join done.
join command sent
sending FullSpeed...
sending FullSpeed done.
end setup
Sharangovich commented 5 months ago

@Klusjesman @supersjimmie maybe you could help with this Itho Device ID question?

Klusjesman commented 5 months ago

@Klusjesman @supersjimmie maybe you could help with this Itho Device ID question?

The device id needs to match. When you buy a new remote you have to do some procedure to couple the device id with the unit. I don't know how other people solved this problem. I remember supersjimmie used the device id from his own remote.

You can use the device id from the code and send the join command. You will need to restart the unit and then send the join command within some specific timeframe. I have to say I never tested this! I reverse engineered the commands so I am pretty sure the join command is correct. When your remote/print is joined you would be able to use the code as is.

I would try the join command route first. The other possibility is to reverse engineer the device id of a remote you have at home. You can use the CC1101 for it and write the received bytes to a serial debug port. But this is not the full story. The calculations of the messages are based on the device id. But in my code this is "hardcoded" and based on my own device id. So for your device id to work you will need to do some reverse engineering (intercept many messages and find the pattern in how the calculations are done).

If you get stuck on sending then this might be because of some CC1101 fix which was implemented. There is some endless loop in the code to solve some chip bug. The loop is endless when the wrong speed is used! This might be your issue.

arjenhiemstra commented 5 months ago

Hi! I tried to implement the transmit/receive logic using the wireframe originally from Klusjesman but I can't receive any messages and can't control the Itho Fan. I have a CVE-S PAK, which is not an ECO but since they use the same RFT I guess that control should work without any issues too. I think that it doesn't work because the device ID in the code doesn't match my RFT (with an auto button). Is it correct? If so, how do I get that device ID?

In the simplified setup function it does get to the end (1 out 10 times, often stuck on join command sent).

void setup(void) {
  Serial.begin(115200);
  delay(500);
  Serial.println("setup begin");
  rf.init();
  Serial.println("setup done");
  sendRegister();
  Serial.println("join command sent");
  pinMode(ITHO_IRQ_PIN, INPUT);
  attachInterrupt(ITHO_IRQ_PIN, ITHOcheck, FALLING);
  Serial.println("end setup");
}

Is it reasonable to assume the wiring is correct then? Since the rf.init(); and sendRegister(); don't fail.

setup It runs on UNO R3 board, connected to C1101 as described in README, via level converters. I have also a Pro Mini 3V3 board for this project, but I wanted to validate the concept first.

I'm also able to send commands, like high speed within setup block, and it succeeds, except for the part that the signal goes nowhere (fan does not kick in).

setup begin
setup done
sending join...
sending join done.
join command sent
sending FullSpeed...
sending FullSpeed done.
end setup

The issue is that the version created by @Klusjesman and @supersjimmie are the reverse engineering of the RFT CVE remote with limited possibilities to change the device ID. You have a remote with auto function (probably the RFT Auto or the latest RFT Auto-N.) Those remotes send out a different join message and most of the speed/times also have different RF messages.

In further development of this repo I've created a fork here: https://github.com/arjenhiemstra/IthoEcoFanRFT

This version allows you to send/receive the RFT Auto remote with any remote ID. The fork also has logging code that will tell you exactly what ID your current remote has.

it should more or less be a drop in replacement to work with your code, most of the functions you probably use are kept backwards compatible. See included example for directions.

a few changes/directions how to use this:

rf.updateRFDeviceID(12,34,56, 0); //to set device ID for send for first remote (ID0, ID1, ID3, remote index)
rf.updateRFDeviceType(RFTAUTO, 0); //sets device type to RFT Auto remote instead of default RFT CVE, for first remote (remote type, remote index)
rf.sendCommand(IthoJoin); //use this instead of sendRegister(), sends a join commando with first remote (remote index=0)
//or
rf.sendRFCommand(3, IthoJoin); (remote index=3, command=join) to send a command with a specifiek configured remote
arjenhiemstra commented 5 months ago

Update; I've updated some things and merged the latest changes in https://github.com/arjenhiemstra/IthoEcoFanRFT/releases/tag/3.0.0

Sharangovich commented 5 months ago

Thanks, @arjenhiemstra and @Klusjesman for the clarification! I have indeed checked all the relevant repos beforehand (including https://github.com/arjenhiemstra/IthoEcoFanRFT) and the refactored version didn't want to compile on my environment initially due to the use of extra standard libraries. This is why I went for the simplest to understand and upload code. I also wanted to keep complexity and memory very low, since my project is a battery-powered RV-sensor/trigger for the Etho. The good news, the concept has been tested and it works (almost all the time now, after I used a transistor to power up the sensor and RF only when they are needed it is even more stable).

Circuit

I don't have much of a circuit-building background to show a nice diagram, but hopefully, it's visible on the image. What I did since 2 days ago, I decided to switch to Pro Mini board to avoid level converters on RF module wires. And that was a solution to the initial RF problem! I was able to bind with my CVE-S PAK, this means the code and circuit work with that model too. Sending other commands worked as well. Then, I added the temperature and humidity sensor to trigger Timer function on the Etho. After that, I experimented with different clock dividers, and I indeed noticed that with some clock settings, CC1101 is not very stable, as @Klusjesman indicated.

If you get stuck on sending then this might be because of some CC1101 fix which was implemented. There is some endless loop in the code to solve some chip bug. The loop is endless when the wrong speed is used! This might be your issue.

But, after changing libraries to account for clock_div in delays it became alright, even with divider 64, which runs Pro Mini at 0.125MHz. After some calculations, I settled on a 2MHz setting as it seems the most power-efficient.

Power

WIP sketch https://gist.github.com/Sharangovich/9509c91b43614f820755c956dcdd66ff

What does it do in the loop:

I have to give a compliment to that HTU2X sensor from Aliexpress, I thought that it would be sluggish and give unreliable readings in that short uptime, but it works like a charm, very responsive and accurate. Way better than the Bluetooth temperature and humidity monitors I was comparing to (GooveeLife H5104, ThermoPro TP357, SwitchBot W3400010).

While this is a working solution, I would still include the receiving part (to monitor the commands and reset the sensor if necessary). And the Auto command, for which I think I need to migrate to @arjenhiemstra's version of the library. Receiving Itho packets doesn't work now at all, even if I remove the device ID check, it's completely silent. I tried to understand the Itho lib, but it's currently above my level of understanding of RF communication. So, I'm not sure I'll be able to reverse-engineer it. What I could do, I could enable packet monitoring, as mentioned here:

You can use the CC1101 for it and write the received bytes to a serial debug port.

But, I don't know how. @Klusjesman can you please, explain how, or maybe give a link?

And get the device ID of my remote if it is visible in the packet and does not require complicated decoding. Otherwise, I would say message monitoring of the other remote is not worth it. In any case, I think, having clarity (or a short manual, or a comment) around device ID would help users of those repositories and libs.

Sharangovich commented 5 months ago

Perhaps important to note, that interrupt

attachInterrupt(ITHO_IRQ_PIN, ITHOcheck, FALLING);

was never triggered on my setups, no matter how hard I push buttons on the remote 😁

Sharangovich commented 5 months ago

This version allows you to send/receive the RFT Auto remote with any remote ID. The fork also has logging code that will tell you exactly what ID your current remote has.

@arjenhiemstra do I understand correctly, that if I run this code on my setup as is it should be able to intercept packets from my current physical remote (with Auto button) without any additional steps, configurations, and reverse engineering?

arjenhiemstra commented 5 months ago

This version allows you to send/receive the RFT Auto remote with any remote ID. The fork also has logging code that will tell you exactly what ID your current remote has.

@arjenhiemstra do I understand correctly, that if I run this code on my setup as is it should be able to intercept packets from my current physical remote (with Auto button) without any additional steps and configurations?

That's correct. But there is a catch (there always is...;-)). My refactored version of the lib is intended to be used with esp8266/esp32 like controllers. It supports multiple remotes and reserves memory for 10 remote instances. Together with the logging string this results in a significant higher memory footprint. In short; this kinda drops support for the arduino r1 type chips (atmega328p etc.). It should compile on those platforms though and with some modifications memory footprint can be brought down.

arjenhiemstra commented 5 months ago

Perhaps important to note, that interrupt

attachInterrupt(ITHO_IRQ_PIN, ITHOcheck, FALLING);

was never triggered on my setups, no matter how hard I push buttons on the remote 😁

The CC1101 chip should trigger a IRQ when a valid package is being received. If that doesn't happen you probably have not connected the right pin or something else in not in order in your config.

arjenhiemstra commented 5 months ago

Thanks, @arjenhiemstra and @Klusjesman for the clarification! I have indeed checked all the relevant repos beforehand (including https://github.com/arjenhiemstra/IthoEcoFanRFT) and the refactored version didn't want to compile on my environment initially due to the use of extra standard libraries. This is why I went for the simplest to understand and upload code. I also wanted to keep complexity and memory very low, since my project is a battery-powered RV-sensor/trigger for the Etho. The good news, the concept has been tested and it works (almost all the time now, after I used a transistor to power up the sensor and RF only when they are needed it is even more stable).

Circuit

I don't have much of a circuit-building background to show a nice diagram, but hopefully, it's visible on the image. What I did since 2 days ago, I decided to switch to Pro Mini board to avoid level converters on RF module wires. And that was a solution to the initial RF problem! I was able to bind with my CVE-S PAK, this means the code and circuit work with that model too. Sending other commands worked as well. Then, I added the temperature and humidity sensor to trigger Timer function on the Etho. After that, I experimented with different clock dividers, and I indeed noticed that with some clock settings, CC1101 is not very stable, as @Klusjesman indicated.

If you get stuck on sending then this might be because of some CC1101 fix which was implemented. There is some endless loop in the code to solve some chip bug. The loop is endless when the wrong speed is used! This might be your issue.

But, after changing libraries to account for clock_div in delays it became alright, even with divider 64, which runs Pro Mini at 0.125MHz. After some calculations, I settled on a 2MHz setting as it seems the most power-efficient. Power

WIP sketch https://gist.github.com/Sharangovich/9509c91b43614f820755c956dcdd66ff

What does it do in the loop:

  • power up sensor
  • read temperature and humidity
  • power down sensor
  • if it's a valid range, sleep 1 time 8 seconds
  • if the humidity is high -> power up RF, send Timer command, power Down RF, sleep 10 minutes (in 8-second intervals). The fan will be running, no need for new measurements in between.

I have to give a compliment to that HTU2X sensor from Aliexpress, I thought that it would be sluggish and give unreliable readings in that short uptime, but it works like a charm, very responsive and accurate. Way better than the Bluetooth temperature and humidity monitors I was comparing to (GooveeLife H5104, ThermoPro TP357, SwitchBot W3400010).

While this is a working solution, I would still include the receiving part (to monitor the commands and reset the sensor if necessary). And the Auto command, for which I think I need to migrate to @arjenhiemstra's version of the library. Receiving Itho packets doesn't work now at all, even if I remove the device ID check, it's completely silent. I tried to understand the Itho lib, but it's currently above my level of understanding of RF communication. So, I'm not sure I'll be able to reverse-engineer it. What I could do, I could enable packet monitoring, as mentioned here:

You can use the CC1101 for it and write the received bytes to a serial debug port.

But, I don't know how. @Klusjesman can you please, explain how, or maybe give a link?

And get the device ID of my remote if it is visible in the packet and does not require complicated decoding. Otherwise, I would say message monitoring of the other remote is not worth it. In any case, I think, having clarity (or a short manual, or a comment) around device ID would help users of those repositories and libs.

Nice work! 1 note, just my 2 cents; I see you use a "thin" wire antenna that probably came with the CC1101 board. I've tested some of there with a VNA and they were far off (seems that they are more suited for 433Mhz). I you experience RF issues, you might consider moving to such an antenna: image

Sharangovich commented 5 months ago

Perhaps important to note, that interrupt

attachInterrupt(ITHO_IRQ_PIN, ITHOcheck, FALLING);

was never triggered on my setups, no matter how hard I push buttons on the remote 😁

The CC1101 chip should trigger a IRQ when a valid package is being received. If that doesn't happen you probably have not connected the right pin or something else in not in order in your config.

Triple-checked that IRQ connection, also with a multimeter, it was 100% in the right place. Maybe a defect in the CC1101 board then.

Sharangovich commented 5 months ago

1 note, just my 2 cents; I see you use a "thin" wire antenna that probably came with the CC1101 board. I've tested some of there with a VNA and they were far off (seems that they are more suited for 433Mhz). I you experience RF issues, you might consider moving to such an antenna:

Thanks for the suggestion! Where do I find those? I have no RF issues on full batteries, but when the voltage drops to <= 2.8 then it only works from few meters away from the fan.

arjenhiemstra commented 5 months ago

I have a few 100 of them laying around, I'll send you one if you like.

Sharangovich commented 5 months ago

I have a few 100 of them laying around, I'll send you one if you like.

I'll drop you an email then. Thanks!

Sharangovich commented 5 months ago

I found the cause of problem of not receiving packets. It was in the code. On my Pro Mini (I guess on most similar boards too) it works when initialized this way:

  pinMode(ITHO_IRQ_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(ITHO_IRQ_PIN), ITHOcheck, FALLING);

I captured the following signals from my RFT

[Low]
H:16 _I P0:4B  P1:-- --,--,-- --,--,-- FF,00,FC 22F1 03:63,02,04
[High]
H:16 _I P0:4C  P1:-- --,--,-- --,--,-- FF,00,FC 22F1 03:63,04,04
[Auto]
H:16 _I P0:45  P1:-- --,--,-- --,--,-- FF,00,FC 22F1 03:63,02,04
[Timer]
H:16 _I P0:4F  P1:-- --,--,-- --,--,-- FF,00,FC 22F3 03:63,00,0A
[Bind]
H:16 _I P0:75  P1:-- --,--,-- --,--,-- FF,00,FC 1FC9 0C:63,22,F8,74,FC,66,01,10,E0,74,FC,66

But when I use the id in the latest revision https://github.com/arjenhiemstra/IthoEcoFanRFT/releases/tag/3.0.0 - it doesn't work, I registered first with the hardcoded ID and it works fine. When I switch to, presumably, RFT ID 255,0,252 or 0xff,0x00,0xfc then nothing happens, none of the commands work. I tried setting different types too (RFTCVE, RFTAUTO, RFTAUTON) - no different. Any ideas what is not right?

arjenhiemstra commented 5 months ago

Not sure what is happing here, FF,00,FC is a bit of a strange address for RFT remotes (never saw them starting with 0xFF before. It also doesn't add up with the bind message: H:16 _I P0:75 P1:-- --,--,-- --,--,-- FF,00,FC 1FC9 0C:63,22,F8,74,FC,66,01,10,E0,74,FC,66 FF,00,FC seems to be the broadcast address here while 74,FC,66 is sent as bind ID address in the message itself twice... cannot explain that, never seen that before. Just tested it with my own RFT-Auto remote with the code I posted and it results in this log message: 18-2-2024 20:56:47: H:16 _I P0:73 P1:-- --,--,-- --,--,-- 74,F8,14 1FC9 0C:63,22,F8,74,F8,14,01,10,E0,74,F8,14

Sharangovich commented 5 months ago

That looks like some sort of checksum at the end, and it is changing. Now bind looks like this:

H:16 _I P0:98  P1:-- --,--,-- --,--,-- FF,00,FC 1FC9 0C:63,22,F8,74,FC,63,9C,63,9C,63,9C,63
arjenhiemstra commented 5 months ago

nah, pretty sure this part is bogus: 9C,63,9C,63,9C,63 a 10E0 (device info opcode or something is expected for a RFT-auto here followed by the sending device ID

Sharangovich commented 5 months ago

When I print out my device ID from the send data sendRFMessage then the FF/255 part is missing.

22:38:16.401 -> 0
22:38:16.401 -> 0
22:38:16.401 -> 252
Sharangovich commented 5 months ago

Could it be a bug in printing out the received package or a bug in sending it (some data transformations)? Given that I provided 255, I'd expect it to be there.

arjenhiemstra commented 5 months ago

not sure but there is 1 thing I can think of to keep in mind. the code just sets a boolean during ISR. This is quick and short but the processing of the actual receive buffer happens in runtime. Itho messages are repeated in quick succesion (3x within 150 ms or something like that).If your using an Atmel, this might be slower than an ESP32 and maybe you are seeing a buffer overwrite because of reentry ISR or something.

You could change to code so that it is ISR safe (ie. implement some sort of mutex) or prevent the ISR from retriggering in any other way.

Sharangovich commented 5 months ago

I don't have an ESP32 yet to test that, but the problem appears to be only with 255 (0xFF) bytes in deviceId. If I pick a different deviceId, such as this example 0x12,0x34,0x56 - then it sends valid commands without any issues, and the fan switches on/off depending on the command, including Auto mode. So, it doesn't look like ISR plays a role here. But again, this is my very first Arduino project, and my common sense may be wrong :)

My remote is from 2019, maybe the deviceId pattern has changed since then and doesn't work with public libs on github, while works fine with original software and hardware.

IMG_2484 Large IMG_2483 Large