Nickduino / Somfy_Remote

An Arduino Sketch able to simulate a Somfy remote control
Other
221 stars 95 forks source link

Can't Get it to Work #19

Closed robbymeier closed 5 years ago

robbymeier commented 6 years ago

I use an FS1000A from which I removed the original resonater (433.92) with a new one (433.42). I know it still works because the FS1000A was still able to control another device. I then changed REMOTE to 0x2727 and newRollingCode to 1. After compiling I pressed the programming button on the original remote until the shade briefly moved. Then in the serial monitor I pressed the button p + [Enter]. Then I tried sending commands to move up and down but nothing happened. Here is one output from the serial monitor:

Descend Frame : A7 40 00 15 00 27 27 With checksum : A7 4D 00 15 00 27 27 Obfuscated : A7 EA EA FF FF D8 FF Rolling Code : 21

Note that there were some warning. The first couple are probably ok but the one for delayMicroseconds might be of concern.

SomfyRTSControl.ino: In function 'void BuildFrame(byte, byte)': SomfyRTSControl.ino:96:24: warning: right shift count >= width of type frame[4] = REMOTE >> 16; // Remote address ^ SomfyRTSControl.ino:98:12: warning: large integer implicitly truncated to unsigned type [-Woverflow] frame[6] = REMOTE; // Remote address ^ SomfyRTSControl.ino: In function 'void SendCommand(byte, byte)': SomfyRTSControl.ino:154:28: warning: large integer implicitly truncated to unsigned type [-Woverflow] delayMicroseconds(89565); ^

Nickduino commented 6 years ago

Hum, have you tried using a six digit address? Like 0x121300

robbymeier commented 6 years ago

I tried with 6 digits but it still doesn't work. Below is the signal that the Arduino sends. Does that look ok?

signal

Edit: Ok, I did look more into this and also checked what my remote is sending. The pauses are a bit different so I changed that but this still didn't make a difference. Everything looks identical between the remote and the Arduino (except for the payload) so I can only think of two things:

1) The payload is not correctly created. I did not modify that part. I assume you are using this yourself and it's unlikely Somfy changed their RTS protocol so I would think this should work. 2) The programming doesn't work. I assume you also used this sketch to program the Arduino.

robbymeier commented 6 years ago

After a lot more 'debugging' it seems my Somfy remote is sending different commands. See the screenshot below. It shows the beginning of the first frame, the wake up pulse with some silence and then the HW and SW sync. The part highlighted in blue is the 3rd nibble, i.e. supposedly the key code. I get 0x2 for the program button, 0x8 for the up button, 0xe for the down button and 0xb for the my/stop button. This is consistent across two different remotes.

Note that this is for SunSetter awnings which use the Somfy Telis remotes. I start to suspect that the motors and remote controls that somfy provides to SunSetter use a slightly different protocol. On the other hand, Somfy is in many different products and if they use different codes for each brand they are in then I would expect a lot more people having problems with this sketch. For what product are you using this sketch?

Any ideas to get this to work are appreciated!

keycode

Nickduino commented 6 years ago

I'm surprised by your button values. Are these after de-obfuscation? See what the community agrees on:

0x1 | My | Stop or move to favourite position 0x2 | Up | Move up 0x3 | My + Up | Set upper motor limit in initial programming mode 0x4 | Down | Move down 0x5 | My + Down | Set lower motor limit in initial programming mode 0x6 | Up + Down | Change motor limit and initial programming mode 0x8 | Prog | Used for (de-)registering remotes, see below 0x9 | Sun + Flag | Enable sun and wind detector (SUN and FLAG symbol on the Telis Soliris RC) 0xA | Flag | Disable sun detector (FLAG symbol on the Telis Soliris RC)

https://pushstack.wordpress.com/somfy-rts-protocol/

I use my algorithm in a Raspberry Pi controlling blinds made by Simu (this may answer your "different brands => different protocols" idea) but people have been replacing their Telis remotes with that.

My sketch compiles without warnings, I'm inclined to think that some of your mods broke something. How did you define frame and REMOTE? Is REMOTE three bytes? (I don't think the first two warnings are ok)

robbymeier commented 6 years ago

I finally got this to work. My biggest issue was a really dumb mistake. I modified one of my FS1000A to send signals at 433.4 by replacing the resonator. I initially I had some issues with it and swapped it out with some unmodified FS1000A. I finally ended up with a 433.9 in my setup thinking I switched back the modified 433.4 one. I know some devices still work when the frequency is a bit off but then the range is terrible. In this case it didn't work even when I held the transmitter within 2' of the motor (I held it this close not because I knew I had the wrong transmitter but to check if range was the problem). I finally used the 'spectrum analyzer' at which point I realized I had the wrong FS1000A. After switching it with the correct one it worked.

Having said that, there might have been some others issues. The code does give warning errors for a Arduino Nano. The reason is that the Nano is 16-bit and some of the constants are 24 bit. Hence it complains. Maybe the compiler does end up doing it correctly (because the fixed 24-bit value is shifted by a fixed amount so the compiler can calculate the real value). In any case, I changed it so that I have individual bytes for the device code.

define REMOTE_B1 0x98 //<-- Change it!

define REMOTE_B2 0x73 //<-- Change it!

define REMOTE_B3 0x43 //<-- Change it!

The other potential issue is the following code:

if (EEPROM.get(EEPROM_ADDRESS, rollingCode) < newRollingCode) { EEPROM.put(EEPROM_ADDRESS, newRollingCode); }

In my case it seems I had all 0xFF in the EEPROM. So the test "<newRollingCode" should always fail, i.e. the new address isn't being set. Even if that is the case, it probably doesn't matter because then my device ID is just 0xFFFFFF. It only would become a problem if I have a second device which would then end up with the same ID. I didn't really investigate this further but just wanted to mention it as a potential issue.

Anyways, thanks a lot(!) for your replies and providing this code.

Nickduino commented 6 years ago

Yes, the blinds are incredibly picky frequency-wise Not so timing-wise

Your Nano uses an ATMega 328P, right? Same as me and I don't have any compiling warning.

I don't understand how your sketch can keep working after a reboot if the rolling code isn't properly stored in the EEPROM

robbymeier commented 6 years ago

Yes, my nano has an ATMega 328. It's not the P version but that really shouldn't make a difference in regards to the warning I am getting. The warning btw is related to the device address which is a 24-bit address. So then in BuildFrame you take this 24-bit constant and bit shift it to assign it to a 16-bit variable. Hence, the compiler gives a warning because you try to assign a 24-bit constant to a 16-bit constant. Of course, we know that after the shift the upper 8 bits are 0 but the compiler still takes issue with that. I am somewhat surprised your compiler doesn't give any orange warning.

Note that even if the compiler doesn't handle it properly, i.e. if it first converts the 24-bit constant to the 16-bit target size and then shifts, it would still work. The ID of the remote will just have the upper 8-bits cut off. Hopefully, the compiler is smart enough to first shift and then assign the shifted value to the 16-bit variable.

As for the EEPROM, yes, it wouldn't work if the rolling code wasn't written into the EEPROM because each time you read the value back. What I am saying is that it might POTENTIALLY fail. Assume that you have never run the code yet and currently the value in the EEPROM is 0xFFFF. So now you run it for the first time and in setup it retrieves the value with EEPROM.get(EEPROM_ADDRESS, rollingCode). So this will return 0xFFFF. No matter what newRollingCode is 0xFFFF<newRollingCode will never be true and hence you don't write newRollingCode into the EEPROM. Then in BuildFrame you read the rolling code and it will be 0xFFFF and not newRollingCode. Hmm, playing this through, I guess it's ok. All that will happen is that you start out with the rolling code 0xFFFF rather than the rolling code defined in newRollingCode. So all good in regards to the EEPROM.

Thanks for providing this library!!