Please help me decode 433Mhz temperature sensor HYUNDAI WSC 1925

Hi guys,
couple of days I have try to decode my older weather station HYUNDAI WSC 1925:
http://www.levneelektro.cz/p352478-zdravi-hyundai-wsc-1925-g
Code of manufacturer: HYUWSC1925G
EAN: 8592417003405
inner temp: 0°C to +50°C
Humi No

Sensor:
Hyundai WSC
Code of manufacturer: 8594007606140
EAN: 8594007606140
outer temp -50°C to +70°C
Humi No

but I don't have luck. Can someone help me with decoding and writing arduino code?

Very good topics with information and inspiration are:

http://rayshobby.net/reverse-engineer-wireless-temperature-humidity-rain-sensors-part-1/
http://forum.arduino.cc/index.php/topic,110662.msg836278.html#msg836278

RFlink library:

RemoteSwitch (and CrestaProtocol.pdf)
https://bitbucket.org/fuzzillogic/433mhzforarduino/wiki/Home

Some legend:

  • on the Calc document are some tabs, on tabs is binary temperature and picture of recorded "sound"
  • on some tabs are my mistakes :slight_smile:
  • and on tab "Testy" are all values together with some colorization (only my try to make it better readable; probably bad colored... there are more patterns); probably sync and end data is not needed to compute with
  • on some pictures I have sync data as 1000 - this is false, good is 100 (binary code I have repaired, pictures not)
  • all temps are on channel 2; only two of them have channel 1 and 3 (it's on their names)
  • zipped source (with 7zip) with Audacity "code samples" of temperature readings and Paint.net pictures with binary translating that code

there are maybe same sensors with some little differences (smaller range of measuring):

http://www.sencor.cz/cidlo-k-meteostanici/sws-21-ts

Sample:
21,8C 100 10101111010111010111111010110101101 1011011 00
21,9C 100 1010110110101110101111110101101011010 1011011 00

Sources:
https://www.dropbox.com/s/h9gi7ie1kun7oky/Sources.zip?dl=0

Very thanks.

Radius

CrestaProtocol.pdf (523 KB)

Temperatures.zip (780 KB)

Hi RadiusXe,

have a look at these contributions they may help....
Oregon Scientific WS

and

Debuging Weather Stations

Just some general ideas to get you started if you have not seen them before,

Rob

Hi robwlakes,
very thanks, will try.

I doesn't known about that. That will totaly destroy my work :smiley:

All codes are probably bad transcoded to binary form.

Radius

You may have an unusual protocol there, RadiusXe, not like the OS ones at all?

I have attached a gif of my Audacity OS V3.0 signal and as you can see it is quite different. But i guess I was trying to encourage some lateral thoughts about data structures and formats. I pieced most of mine together from the people's work and contributed a bit myself. If you have a look in the program it has quite a few URL's to interesting work that helped me. They may help you too.

Best wishes, Rob

PS The second channel in Audacity can also be used as a debug channel as I connected it to an Arduino output and toggled it at different times to check the logic I was processing the signal with. Quite effective.

I have read them all and now I have to try use your debugger - without luck yet. And problem is, that my amplitudes are all the same length :/...probably not Manchester? As you write... and your debugger will not work?

Indeed I try to get timings of short and long zero (ground) pulse and the timing is probably bad?
18,594 micros for short and 44,671 micros for long

Maybe short zero pulse is zero and long zero pulse one?

My inspiration was
https://rayshobby.net/interface-with-remote-power-sockets-final-version/

and section "Record the Control Signals"

and thanks for your help...

Radius

There is explanation:
http://forum.arduino.cc/index.php/topic,110662.msg836278.html#msg836278

it is not manchester coded, because I have disassembled the sensor, to get raw data without noise... I will read that thread to end and maybe is there solution and maybe what I say before about long and short pulse is true and I will be done. Or will try to get signal over AIR with manchester code.

Radius

Seems that I made it...

as Ï sayd before short zero pulse = 0; long zero pulse = 1

21,7 – reset 2:
21,7 * 10 = 217 integer = 1101 1001b

random ---- -- -----HHHH LLLLCRC?
11011 0000 11 000001101 10011010

Have try 3 positive temepratures and match!!!

Somewhere is channel, battery state and CRC.

More inspecting later.

:slight_smile:

Hi RadiusXe,
I agree with you we are not dealing with a Manchester encoded signal in your case. The signature of a Manchester signal is that hi and lo's only have two lengths, and one is about double the other. So the waveform looks evenly balanced. Your waveform has very short hi's compared to the much (many times) longer lo's. However it is interesting that even though the hi-lo durations are not balanced, and there is much more lo's than hi's, the receiver differentiates them very well, so quite usable.

My debug program is very unlikely to produce meaningful results without considerable tinkering as it assumes that waveform it is tackling is at least strictly Manchester.

If I understand you correctly, you are suggesting that the hi's (which are pretty much constant length) are just the markers between long or short lo's. and a short lo=Zero and long lo=One.

If you can get one thing like the temperature to match then your are well on your way to solving it as it will at least confirm your guess above is correct. It looks good to me so far :slight_smile:

If you quote more binary patterns you can use the Tt or Teletype format as it will alow the bits to line up in columns and makes for easier comparison. Just a suggestion. eg

21,7 - reset 2:
21,7 * 10 = 217 integer = 1101 1001b

                      1
                      2631
                      8426 8421 
-----    ---- -- -----HHHH LLLL CRC?
11011    0000 11 000001101 1001 1010

So 128+64+16+8+1=217, divide by 10 to get 21.7 degrees Centigrade

It seems to be too short a burst to have a checksum in it. Sometimes the checksum effect is made by the Tx repeating the message say four times and IF it gets the same value repeated a number of times then it is considered to have been checked out ok??? Does the same message repeat or only fire off once??

Cheers, Rob

Hi Robwlakes,
yes, you understand. High peak is just delimiter for low short (0) and low long (1) signal. Or someone can say, delimiter is element of data: high peak + low short/long signal.

Transmit is repeated 8 times (the last repeat is little different).

Before I have decoded (and as we known, this decoding is bad; but is visible, that last transmit is different):
22,4 00110111101011101011111101010111111011010100
22,4 – konec 00110111101011101011111101010111111

Tomorrow I have time to play with it.

Radius

Hi RadiusXe,
I reckon if the transmit is repeated 8 times then a checksum in the data is unlikely. The receiver would just work on getting a certain number of repeats exactly the same and assume it was OK. However battery condition is a possibility. and certainly sensor Identification code must be there somewhere too. Do you have more than one sensor, or can you change the ID of the one you have?? Could you post your code you are using to test the data coming in by any chance?

Cheers, Rob

Hi Rob,
I have two sensors, but the second I wish to not disassemble. I wish to receive data on the fly over the air and then study bits...

I can't actively C programming (only passive; reading, maybe some easy corrections of the code etc.) :), thus I don't have any code to automate the process... Hope someone will help and helps me write reading and sending Arduino sketch (my wish is to use interrupt; Arduino will do more, than just send or read temp). Maybe on Netduino (VB) I can write some code. I'm newbie on Arduino and I begin with C :slight_smile: and C is for me very hard.

Here is some news
22,2 - r5 - low bat power on 111110010011 0000 1101 1110 10 01
22,2 – r5 low bat podruhe 111010010011 0000 1101 1110 10 00
22,2 - r5 - low bat on demand 111110010011 0000 1101 1110 10 01
22,2 - r5 - po low bat, bat OK 000010010011 0000 1101 1110 10 10
22,2 - r5 - po low bat, bat OK on demand 000110010011 0000 1101 1110 10 11
-1 - reset 2 101110000110 1111 1111 0110 10 10

first 12bits - ???? (CRC? ID?, both? or? trending?)
next 2 bits - (11) freezing (00) positive temp; maybe just one bit is needed and then one of them will be with the first block
next 10bits - temp; freezing - two complement; (max +70dec = 1010111100b; min -50dec = bin?)
next 2bits - channel (1 = 01b; 2 = 10b; 3 = 11b)
next one bit - low bat; 0b = low; 1b = OK
last one bit - 0b = normal state; 1b = power reset (switching batteries; first measuring) OR transmit on demand (on the back is button) [1b has two functions]; probably is on first 12b trending (very easy implementation, just temp is stable, raise or fall) and this bit destroys trending and thus inner station needs this information (just theory)

All measurings I have made by hands:
-1 - reset 2 101110000110 1111 1111 0110 10 10
-0,1 - reset 2 010010000110 1111 1111 1111 10 10
0,2 - reset 2 100110000110 0000 0000 0010 10 10
0,3 – reset 2 101010000110 0000 0000 0011 10 10
0,4 – reset 2 101110000110 0000 0000 0100 10 10
1,4 – reset 2 010110000110 0000 0000 1110 10 10
21,7 101101100110 0000 1101 1001 10 10
21,7 - reset 1 110100001110 0000 1101 1001 10 10
21,7 - reset 1 repete 110100001110 0000 1101 1001 10 10
21,7 – reset 1 ch1 100100001110 0000 1101 1001 01 10
21,7 - reset 1 ch3 000100001110 0000 1101 1001 11 10
21,7 – reset 2 110110000110 0000 1101 1001 10 10
21,8 110001100110 0000 1101 1010 10 10
21,8 - reset 1 111100001110 0000 1101 1010 10 11
21,9 110101100110 0000 1101 1011 10 10
22,0 111001100110 0000 1101 1100 10 10
22,1 111101100110 0000 1101 1101 10 10
22,2 000001100110 0000 1101 1110 10 10
22,2 - r5 - low bat power on 111110010011 0000 1101 1110 10 01
22,2 – r5 low bat podruhe 111010010011 0000 1101 1110 10 00
22,2 - r5 - low bat on demand 111110010011 0000 1101 1110 10 01
22,2 - r5 - po low bat, bat OK 000010010011 0000 1101 1110 10 10
22,2 - r5 - po low bat, bat OK on demand 000110010011 0000 1101 1110 10 11

22,3 000101100110 0000 1101 1111 10 10
22,4 010001100110 0000 1110 0000 10 11
22,4 - konec 010001100110 0000 1110 0000
28,9 - reset 3 101110110010 0001 0010 0001 10 11
28,9 - reset 3 on demand 101110110010 0001 0010 0001 10 11
23 - reset 3 101010110010 0000 1110 0110 10 10
23,3 - reset 3 on demand 101110110010 0000 1110 0110 10 11

Radius

Just quote you and lay it out a bit more clearly (I don't want to offend you but having things appear in columns makes it easier to compare and observe).

                   <    A     > <B > <C > <D >  E F  Comment
22,2 - r5 -        111110010011 0000 1101 1110 10 01 low bat power on
22,2 - r5          111010010011 0000 1101 1110 10 00 low bat podruhe
22,2 - r5 -        111110010011 0000 1101 1110 10 01 low bat on demand
22,2 - r5 -        000010010011 0000 1101 1110 10 10 po low bat, bat OK
22,2 - r5 -        000110010011 0000 1101 1110 10 11 po low bat, bat OK on demand
-1 - reset 2       101110000110 1111 1111 0110 10 10

first 12bits - ???? (CRC? ID?, both? or? trending?)
next 2 bits - (11) freezing (00) positive temp; maybe just one bit is needed and then one of them will be with the first block
<C,D,E> next 10bits - temp; freezing - two complement; (max +70dec = 1010111100b; min -50dec = bin?)
next 2bits - channel (1 = 01b; 2 = 10b; 3 = 11b)
next one bit - low bat; 0b = low; 1b = OK
last one bit - 0b = normal state; 1b = power reset (switching batteries; first measuring) OR transmit on demand (on the back is button) [1b has two functions]; probably is on first 12b trending (very easy implementation, just temp is stable, raise or fall) and this bit destroys trending and thus inner station needs this information (just theory)

                   <    A     > <B > <C > <D >  E F  Comment
-1 - reset 2       101110000110 1111 1111 0110 10 10
-0,1 - reset 2     010010000110 1111 1111 1111 10 10
0,2 - reset 2      100110000110 0000 0000 0010 10 10
0,3 - reset 2      101010000110 0000 0000 0011 10 10
0,4 - reset 2      101110000110 0000 0000 0100 10 10
1,4 - reset 2      010110000110 0000 0000 1110 10 10
21,7               101101100110 0000 1101 1001 10 10
21,7 - reset 1     110100001110 0000 1101 1001 10 10
21,7 - reset 1     110100001110 0000 1101 1001 10 10 repete 
21,7 - reset 1 ch1 100100001110 0000 1101 1001 01 10
21,7 - reset 1 ch3 000100001110 0000 1101 1001 11 10
21,7 - reset 2     110110000110 0000 1101 1001 10 10
21,8               110001100110 0000 1101 1010 10 10
21,8 - reset 1     111100001110 0000 1101 1010 10 11
21,9               110101100110 0000 1101 1011 10 10
22,0               111001100110 0000 1101 1100 10 10
22,1               111101100110 0000 1101 1101 10 10
22,2               000001100110 0000 1101 1110 10 10
22,2 - r5 -        111110010011 0000 1101 1110 10 01 low bat power on
22,2 - r5          111010010011 0000 1101 1110 10 00 low bat podruhe 
22,2 - r5 -        111110010011 0000 1101 1110 10 01 low bat on demand 
22,2 - r5 -        000010010011 0000 1101 1110 10 10 po low bat, bat OK 
22,2 - r5 -        000110010011 0000 1101 1110 10 11 po low bat, bat OK 
   
22,3               000101100110 0000 1101 1111 10 10
22,4               010001100110 0000 1110 0000 10 11
22,4 - konec       010001100110 0000 1110 0000
28,9 - reset 3     101110110010 0001 0010 0001 10 11
28,9 - reset 3     101110110010 0001 0010 0001 10 11  on demand
23 - reset 3       101010110010 0000 1110 0110 10 10
23,3 - reset 3     101110110010 0000 1110 0110 10 11  on demand

could also have the rolling station ID in it. This is a number that is generated at random when the station/sensor has the batteries replaced or reset to allow it to choose a unique (hopefully) id to be recognised by. Does that number stay constant until after a 'reset' or battery change, then changes but stays constant again?? This allows for the fact there could be other people's sensors nearby.

I would steer away from interrupts if you are just starting out on C and I don't think it is necessary in this case as the timing is pretty simple. A suggested algorithm loosely based on my approach would be-

  1. wait until signal goes high, wait until about halfway of high duration and check again, if so probably a marker signal, otherwise return to looking for highs.
  2. wait until signal goes low and then sample in a loop until the signal goes high, this will tell you whether you have a long pause or a shorter one, if it is too long or too short reject it.
  3. pack a 1 or a 0 into the incoming bit stream in your memory.
  4. if not enough bits then look for next high (step 1)
  5. Analyse the bit pattern captured.

unless you are using the Arduino for some other purpose simultaneously then interrupts are an unecessary complication. Timing loops are easier to think through and also become self synchronising if written properly making them more noise and frequency drift tolerant.

Please correct any errors I may have introduced... sorry, my apoligises, I am just trying to get a clearer picture of what is going on by playing with it.

Cheers, Rob

PS I put the data from your page into an editor with uniform character (mon-spaced) font, lined them all up with spaces and then copied them back into a TTY format segment.

                   <    A     > <B > <C > <D >  E F  Comment
-1 - reset 2       101110000110 1111 1111 0110 10 10
-0,1 - reset 2     010010000110 1111 1111 1111 10 10
0,2 - reset 2      100110000110 0000 0000 0010 10 10
0,3 - reset 2      101010000110 0000 0000 0011 10 10
0,4 - reset 2      101110000110 0000 0000 0100 10 10
1,4 - reset 2      010110000110 0000 0000 1110 10 10

I think A is the random transmitter code.
B,C & D are the temperature (signed 12 bit value in 0.1 degree increments)
E is the channel number.
F is something battery related.

Hi RadiusXe,

I have looked at your data, especially your Audacity screen shot. Now that you have got the significance of the bits in the binary pattern pretty well worked out then, I am going to be so bold as to suggest looking at a way to get the compute to do the hard work of capturing the bit patterns for us.

Before we begin on that journey though, I have attached a graphic that I derived from your Audacity screen shot and used it to try to get the proportions right for the '1' and the '0' signal, and so deduce some information about the timing of those signals. At the moment I am looking at ball park figures, but I need to know it I am basically close, if not perfect and if you could analyse it yourself and add in any refinements or extra info on timing would be good. But we need to know the timing of the waveform in either mS (thousandths) or uS (milionths) of a Second. This need not be extremely precise at this stage (as you will see later on) but we need somewhere to start. Once we have something working we can refine the numbers as we go along.

Looking at the graphic I reckon the high blip that signals the start of a bit, is about 700uS duration? The long low signal that you think is a '1' is about 4.3mS or 4300uS duration? And the short low that you think is a '0' is about 1.8mS or 1800uS duration?

The aim is to sense the durations of the parts of the waveform so that a valid signal can be detected, and that random noise and spurious signals are quickly eliminated. This can be done by waiting for parts of the signal and counting delays in other parts, eg wait for a rising signal such as at 'A' on the graphic, waiting 350uS and sampling again at 'B', if it is a high then it maybe a valid signal! Then looping until 'C' occurs, then we wait another 700us and if it is still a low then we are more confident, as it should be a low whether a '1' or a '0' is coming in. If it is not a low, then we abort, and wait begin waiting for another rising edge (A). If it is a low, then we count how many "100uS waits" it takes until the next rising edge. If is more than 45 and less than 55 then we probably have a '1' if it is shorter eg between 15 and 25 it is probably a '0'.

So this gets repeated until all the possible bits are found. If any non-compliant signal is found then all the data is rejected immediately and and new search cycle began without delay. This type of decoding is CPU intensive, but logically simple and becomes auto synchronising as all decoding is timed off the middle negative going part of the waveform itself.

Anyway let me know what you think and add any improvements. If you have a better off then let me know ASAP :slight_smile:

Rob

You might be able to adapt an old capture program (attached) I wrote to do this job for you. The sync time and 0/1 bit timings need adjusting and also the number of bits to read.

WeatherRF2.ino (6.7 KB)

Hi,
I try to write all data in columns, but the numbers live with their own life :slight_smile:

Just one correction:

AAAAAAAAAA BBCC CCCC CCCC DD EF
-0,1 - reset 2 010010000110 1111 1111 1111 10 10

AAAAAAAAAA BBCC CCCC CCCC DD EF
0,2 - reset 2 100110000110 0000 0000 0010 10 10

A 12bits - ???? (CRC? ID?, both? or? trending?); when I send temp to station from arduino, we will have to clearly known, what is it, if is there CRC, the station will do nothing; if is there only random number or random station ID or both, the inner station will display received temp
Edit: - right, last transmit doesn't have 4 last bits and A section is same... can't be CRC!

B 2 bits - (11) freezing (00) positive temp; maybe just one bit is needed and then one of them will be with the first block

C 10bits - temp; freezing - two complement; (max +70dec = 1010111100b; min -50dec = [11]1000001100b)

D 2bits - channel (1 = 01b; 2 = 10b; 3 = 11b)

E 1bit - low bat; 0b = low; 1b = OK

F 1bit - 0b = normal state; 1b = power reset (switching batteries; first measuring) OR transmit on demand (on the back is button) [1b has two functions]; probably is on first 12b trending (very easy implementation, just temp is stable, raise or fall) and this bit destroys trending and thus inner station needs this information (just theory)

Timings:
I'm going thru this step by step:
https://rayshobby.net/interface-with-remote-power-sockets-final-version/

and my timing is:
0 = 0,001859410430839 18,594 micro seconds (short signal, 82 points / 44100)
1 = 0,0044671201814059 44,671 micro seconds (long signal, 197 points / 44100)
delimiter = 4,308 micro seconds (19 points / 44100)
first leading = delimiter + 2x long signal
n... leading = 2x long signal
ending = 2x long signal (warning, last transmit doesn't have last 4bits)

On all points I don't count first and last point on edges, maybe the true number is about +2 points higher. And our measuring is not same, who has right.

Riva:
Yes, your sketch (on the first listed thread) is on my sign and when will be more time (hope weekend), I will look on him closer.

Thanks Radius

Here is something to try RadiusXe,

I hope it helps you in some way, it is quite different from the one offered by Riva, just for comparison rather than as something in any way superior (not trying to start a WS flame wars :sweat_smile: haha).

I obviously don't have one of these Hyundai machines so I have done all this just see what happens.
I found your calculations for the timing of the waveform not the same as mine so I have used mine in the program. However you should be able to change the delay limits (13,30,50,100) if you want to.

If you can understand my logic then , maybe this will be a way into it for you.

Cheers, Rob

WeatherRF2_0.ino (8.47 KB)

Hi Rob,
untouched ino doesn't work.

Pin 2 attached to 433MHz Rx. Here we go.
S
S
S
S
S
S
S
S
S

Lets look where's problem...

Radius

Edit:
something have...

I change //int half_blip=350; //us
to
int half_blip=215; //us
my delim is 430,84 us

and your right
1859,41 us = 0
4467,12 us = 1

and then I get with little debuging:

< 30
Serial.println('0');

< 50
Serial.println('1');

S
1
0
0
0
0
1
1
1
0
1
1
0
0
0
0
0
1
1
1
0
0
1
0
0
1
0
1
0
S

= 28! That's ours lenght of binary string. This is 3,5 bytes.

I must print the "value" (Serial.print(value);), I can't get data from data_bytes. Seems that nosBits has only value "1".

Uf... but I see the light on the dark tunnel.

Radius

Hi Radius,

I have added a bit more and tried to incorporate your debugging changes as well. Fine tuning the delays is very good as it helps also to compensate for the overheads of the CPU time used up in between the defined delays, the smaller timings like the half-blip will be the greatest effected, so well done on that one :slight_smile:

I have also noticed that you are getting 8 packets in a row. I have added a storage for the 8 packets, so they are stored in sequence in memory as they come in. I think you will find the protocol does not bother with a checksum as it will simply rely on getting identical packets a number of times over to validate the reading and eliminate errors. You could set the bar very high, but getting about 4 in row that were the same would be ok for me. I have added a checking routine as well for your consideration, but it is not linked into the rest of the code. It is near the end of the code so have a look for it as well. It does nothing at the moment.

I am both very relieved and surprised that I supplied you a 'nearly working' program that is giving you results you can begin to work with. Very satisfying for me to write something with no access to the hardware, yay!!

If you could attach your code next time, so I can see what you have done, and you could maybe suggest further developments, that would be very handy for me. Anyway give my code below a try and see what it does, alter it again if need be and then maybe work out how you would like to develop your code, add them in if you can, or just suggest them, and then send me the current code your are working with at the moment. If you don't want to do this publicly then send me a personal message with it in. That will be OK with me.

Cheers, Rob

PS Eventually you will need to remove the '0' and '1' being printed for debug as their printing to screen times are also added into the timing loop and eventually need not be there. Hence I prefer to get the whole packet printed at the end of the packet, though eventually you will not need any debugging at all :slight_smile:

WeatherRF2_0.ino (9.87 KB)

Hi Rob,
I leave the code open for everyone.

The code still doesn't work. I found problem, that the code resets probably too early 2 variables (nosBits;nosBytes):

packet=false; //assume packet is not ready
//nosBits=0;
//nosBytes=0;
synch=0;

//begin main packet capture loop
//Serial.println(); //start a new line for any data
while (! packet){

This ensures, that it counts in this sub "void packBit(byte value)" (not sure, that it counts good), but seems that arduino resets (see screenshot).

Unluckily, I doesn't know, how to help. I'm on my limits with C programming. If your stuck too, please probably add some debug information (that will helps you) and I will send them (result) back to you.

How to decode array and transfer to temperature is for me sci-fi on C.
On VB I will store all 8 packets to one dimensional array (0-7 positions); then compare ?randomly? 2 or 3 packets. Match... Then cut temp, channel, battery bit and on demand bit. VB has very good command "mid" - all datas have static positions :slight_smile: (make it then very easy). Then convert binary temp to decimal (for now doesn't known how... google will probably say). That's all :).

How to make transmitter I doesn't know, but probably with sending 1 and 0 with sleeping? Here I will see, that the first bits are random or have another function (CRC), when the inner station will display or not the temp.

I have added some comments to the code.

Radius

WeatherRF2_0r1.ino (9.9 KB)