Go Down

Topic: 433 MHZ temperature sensor decoding (Read 692 times) previous topic - next topic

Elfishi

Hey,

I have yet another 433 MHz temperature sensor to decode. The model is the remote sensor that belongs to a TCM 214698 station that only displays temperature.
The code I use to read the signals from the receiver goes like this (mostly nicked from somewhere else on this forum):

Code: [Select]
#define PBSIZE 256
#define MINBITPULSE 1500

void setup() {

  Serial.begin(115200);
  Serial.println();
  Serial.println("Start!");

  pinMode(2, INPUT);
  attachInterrupt(0, rx433Handler, CHANGE);
}

volatile unsigned int pulsbuf[PBSIZE]; // ring buffer storing LOW pulse lengths
volatile unsigned int hibuf[PBSIZE]; // ring buffer storing HIGH pulse lengths
volatile byte pbread,pbwrite;  // read and write index into ring buffer

void rx433Handler()
{
  static long rx433LineUp, rx433LineDown;
  long LowVal, HighVal;
  int rx433State = digitalRead(2); // current pin state
  if (rx433State) // pin is now HIGH
  {
    rx433LineUp=micros(); // line went HIGH after being LOW at this time
    LowVal=rx433LineUp - rx433LineDown; // calculate the LOW pulse time
    if (LowVal > MINBITPULSE){
      pulsbuf[pbwrite]=LowVal; // store the LOW pulse length
      pbwrite++;  // advance write pointer in ringbuffer
      if (pbwrite>=PBSIZE) pbwrite=0; // ring buffer is at its end
    }
  }
  else
  {
    rx433LineDown=micros(); // line went LOW after being HIGH
    HighVal=rx433LineDown - rx433LineUp; // calculate the HIGH pulse time
    if (HighVal>31999) HighVal=31999; // we will store this as unsigned int
    hibuf[pbwrite]=HighVal; // store the HIGH pulse length
  }
}


void loop() {
  // put your main code here, to run repeatedly:
  long lowtime, hitime;
  if (pbread!=pbwrite) // check for data in ring buffer
  {
    lowtime=pulsbuf[pbread]; // read data from ring buffer
    hitime=hibuf[pbread];
    Serial.print(pbread);Serial.print("\t");
    Serial.print(lowtime);Serial.print("\t");Serial.println(hitime);
   
    cli(); // Interrupts off while changing the read pointer for the ringbuffer
    pbread++;
    if (pbread>=PBSIZE) pbread=0;
    sei(); // Interrupts on again

  } 
}


The signal I receive beyond noise has 49 pairs of HI and LO pulses each either ca 2000us or ca 4000us and ends with a long LO.
The output shows
pulse #, LO time, HI time (in us)

Code: [Select]


Start!
0 13420 560
1 13036 172
2 1836 20
3 14712 464
4 13324 396
5 1976 16
6 2408 84
7 3576 372
8 2256 16
9 3828 2036
10 3864 2020
11 3884 1984
12 1992 1980
13 2008 3856
14 2008 3864
15 3920 3848
16 3908 1952
17 3920 1948
18 3908 1952
19 2012 1952
20 3924 3844
21 3920 1948
22 3920 1940
23 2012 1952
24 3924 3844
25 3916 1944
26 3928 1944
27 3924 1936
28 2048 1928
29 2100 3792
30 3984 3772
31 3984 1880
32 2080 1888
33 2080 3780
34 2064 3792
35 2072 3796
36 3972 3788
37 3968 1900
38 3960 1896
39 2056 1912
40 2052 3804
41 2040 3820
42 2048 3820
43 3952 3808
44 2044 1924
45 2048 3812
46 2044 3828
47 3948 3812
48 2028 1928
49 2044 3828
50 2044 3816
51 2040 3828
52 3944 3820
53 3928 1928
54 2036 1932
55 2028 3832
56 3940 3832
57 2032 1924
58 22280 316
59 2116 52
60 3816 2376
61 3844 2020
62 3880 2004
63 1972 1988
64 2004 3872
65 2012 3852
66 3904 3860
67 3920 1952
68 3908 1952
69 3920 1952
70 2000 1952
71 3924 3856
72 3920 1936
73 3904 1952
74 2012 1956
75 3912 3856
76 3924 1948
77 3916 1944
78 3940 1936
79 2052 1912
80 2096 3804
81 3988 3764
82 3976 1884
83 2080 1888
84 2064 3792
85 2072 3796
86 2068 3788
87 3956 3804
88 3964 1904
89 3948 1908
90 2056 1912
91 2036 3820
92 2052 3820
93 2052 3808
94 3940 3820
95 2048 1920
96 2036 3824
97 2048 3824
98 3948 3812
99 2044 1924
100 2044 3816
101 2028 3828
102 2040 3832
103 3928 3832
104 3940 1932
105 2036 1920
106 2036 3832
107 3940 3824
108 2020 1932
109 22212 320
110 4884 24
111 3840 2048
112 3860 2008
113 3884 1992
114 1980 1980
115 2012 3868
116 2000 3860
117 3920 3856
118 3920 1940
119 3912 1948
120 3924 1948
121 2016 1948
122 3920 3844
123 3908 1952
124 3916 1952
125 2012 1940
126 3908 3860
127 3928 1948
128 3920 1940
129 3944 1932
130 2044 1920
131 2100 3800
132 3992 3760
133 3972 1884
134 2080 1888
135 2076 3792
136 2072 3784
137 2060 3800
138 3968 3800
139 3964 1892
140 3944 1912
141 2056 1916
142 2040 3816
143 2052 3820
144 2048 3808
145 3940 3824
146 2048 1920
147 2036 3820
148 2044 3828
149 3936 3824
150 2040 1928
151 2044 3816
152 2040 3832
153 2044 3816
154 3932 3828
155 3944 1928
156 2036 1916
157 2036 3836
158 3940 3824
159 2024 1932
160 21464 316
161 3816 2096
162 3860 2012
163 3880 1996
164 1980 1980
165 2008 3872
166 2012 3848
167 3924 3856
168 3924 1936
169 3908 1948
170 3920 1952
171 2000 1952
172 3924 3856
173 3908 1948
174 3920 1952
175 2012 1940
176 3912 3856
177 3924 1948
178 3916 1944
179 3940 1936
180 2040 1924
181 2100 3800
182 3992 3764
183 3972 1880
184 2084 1888
185 2064 3792
186 2072 3796
187 2072 3788
188 3956 3800
189 3968 1904
190 3948 1908
191 2052 1912
192 2040 3820
193 2052 3820
194 2052 3804
195 3940 3824
196 2048 1920
197 2032 3824
198 2044 3828
199 3948 3812
200 2040 1928
201 2040 3820
202 2032 3828
203 2040 3828
204 3944 3820
205 3932 1928
206 2036 1928
207 2024 3836
208 3940 3836
209 2036 1920
210 15944 316
211 1896 40


From my initial research into this subject, this pattern doesn't match with BP-M style encoding b/c in BP-M short HI and LO pulses come in pairs. In my pattern there's plenty of short HI pulses framed by two long LOs or short LO pulses framed by two long HIs.

So, what code is this and how can I decode it?

Thx

jremington

You need lots of examples of messages before you can start decoding.

Overview of the process at https://rayshobby.net/reverse-engineer-wireless-temperature-humidity-rain-sensors-part-1/

Elfishi

I have seen ray's page, thx. His sensor transmits in OOK for which you find plenty of examples for decoding software. My sensor signal is different. I first need to find out how to turn it into ones and zeros.

jremington

#3
Mar 10, 2018, 08:38 pm Last Edit: Mar 10, 2018, 08:38 pm by jremington
Is what you describe NOT OOK? If so, what are these "pulses"? Please elaborate.

If you could post a trace by Audacity, that would help.

Elfishi

I posted the trace of the pulses in my first post.
You find there a table that has the number of the pulse in the first column, the duration of the low phase in microseconds in the second column and the duration of the high phase in the third column.

The signature from the sensor apparently starts with pulse 9: 4ms low, followed by 2ms high.
Periods of low and high signal with durations of 2 or 4ms continue until pulse 57.
Pulse 58 seems to be a long stop bit of 22ms.

The next transmission starts at pulse 60 until the stop bit in pulse 109. Next burst from 111 to 160. Last burst in this recording from 161 to 210.

This is not regular OOK, b/c there the high periods would have similar lengths. In my signal highs are  either 2ms or 4ms long, as are lows. I can't interpret the signal as B-PM, either.

How can I turn the highs and lows into 1s and 0s?

jremington

#5
Mar 10, 2018, 10:00 pm Last Edit: Mar 10, 2018, 10:19 pm by jremington
Quote
I posted the trace of the pulses in my first post.
Not successfully. It would make great sense to post a picture like this:


Code: [Select]
int rx433State = digitalRead(2); // current pin state
  if (rx433State) // pin is now HIGH
  {
    rx433LineUp=micros(); // line went HIGH after being LOW at this time

When using digitalRead() to distinguish between high and low states of an input, you are assuming OOK (On Off Keying). 

The problem you appear to face is the typical one of converting the timing between highs and lows into 1s and 0s. In doing that, it is much easier to look at a picture like the above than a table of numbers.

Elfishi

Code: [Select]
__=__=__=_=_==_==__==__=__=__=_=__==__=__=_=__==__=_=__==__=__=_=_==_==_==_==_==__==__=__=_=_==_==_==__==_=_==_==__==_=_==__==_=_==_==__==__=__=_=

_  2ms low
__ 4ms low
=  2ms high
== 4ms high

jremington

That is a good start, but not like any encoding I've seen before.

Following the outline of the Ray's Hobby blog article, I would collect several messages for different known temperatures, for example -1, 0, 1, 2, 4, ... degrees C  and look to see what changes in the message. That will give strong hints on how to interpret 1s and 0s.

Elfishi

ok, here goes

In the attached file you find the development of temperature reading (times 10), the battery status and the level codes received.

The pattern I can observe is
Code: [Select]
__=__=__=_=_==_==_aaaaaaaa=__=_=_==__==__=_bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb=_==_==__==__=__=_cccccccc==__==__=_=_==_ddddddddddddddddddddddddddddddd=

battery OK
a: _==__=__
c: =_==_==_

battery Low
a: ==_==__=
c: _=__=_=_


a and c seem to depend on the battery status, although one reading is not consistent with this. I tend to consider this a reading error on my behalf, though.

b (30 symbols) and d (31 symbols) go like this
Code: [Select]

temp bbbbbbbbbbbbbbbbbbbbbbbbbbbbbb ddddddddddddddddddddddddddddddd
-80 _=__=_=__==__=__=__=__=__=__=_ ==_==__==_=_==_==_==_==_==_==_=
-80 _=__=_=__==__=__=__=__=__=__=_ ==_==__==_=_==_==_==_==_==_==_=
-80 _=__=_=__==__=__=__=__=__=__=_ ==_==__==_=_==_==_==_==_==_==_=
-80 _=__=_=__==__=__=__=__=__=__=_ ==_==__==_=_==_==_==_==_==_==_=
-60 _=__=__=_=_==__==__=__=__=__=_ ==_==_==__==__=_=_==_==_==_==_=
-40 _=__=__=_=__==__=__=__=__=__=_ ==_==_==__==_=_==_==_==_==_==_=
-20 _=__=__=__=_=__==__=__=__=__=_ ==_==_==_==__==_=_==_==_==_==_=
0 _=__=__=__=__=__=__=__=__=_=_= ==_==_==_==_==_==_==_==_==__==_
0 _=__=__=__=__=_=__==_=__==_=_= ==_==_==_==_==__==_=__==_=__==_
29 _=__=__=__=_=__==_=__==__=_=_= ==_==_==_==__==_=__==_=_==__==_
39 _=__=__=__=_=_==_==__==__=_=_= ==_==_==_==__==__=__=_=_==__==_
50 _=__=__=_=__==_=__==__=__=__=_ ==_==_==__==_=__==_=_==_==_==_=
63 _=__=__=_=_==__==__=__=_=_==_= ==_==_==__==__=_=_==_==__==__=_
63 _=__=__=_=_==__==__=__=_=_==_= ==_==_==__==__=_=_==_==__==__=_
65 _=__=__=_=_==__==__=_=__==_=_= ==_==_==__==__=_=_==__==_=__==_
67 _=__=__=_=_==__==__=_=_==_==_= ==_==_==__==__=_=_==__==__=__=_
72 _=__=__=_=_==_==__==__=_=__==_ ==_==_==__==__=__=_=_==__==_=_=
74 _=__=__=_=_==_==__==_=__==__=_ ==_==_==__==__=__=_=__==_=_==_=
79 _=__=__=_=_==_==_==__==__=_=_= ==_==_==__==__=__=__=_=_==__==_
88 _=__=_=__==__=__=_=__==__=__=_ ==_==__==_=_==_==__==_=_==_==_=
91 _=__=_=__==__=_=__==__=__=_=_= ==_==__==_=_==__==_=_==_==__==_
94 _=__=_=__==__=_=__==_=__==__=_ ==_==__==_=_==__==_=__==_=_==_=
117 _=_=__==__=__=_=__==_=_==_==_= ==__==_=_==_==__==_=__==__=__=_
122 _=_=__==__=_=__==__=__=_=__==_ ==__==_=_==__==_=_==_==__==_=_=
123 _=_=__==__=_=__==__=__=_=_==_= ==__==_=_==__==_=_==_==__==__=_
131 _=_=__==__=_=_==__==__=__=_=_= ==__==_=_==__==__=_=_==_==__==_
134 _=_=__==__=_=_==__==_=__==__=_ ==__==_=_==__==__=_=__==_=_==_=
137 _=_=__==__=_=_==__==_=_==_==_= ==__==_=_==__==__=_=__==__=__=_
139 _=_=__==__=_=_==_==__==__=_=_= ==__==_=_==__==__=__=_=_==__==_
141 _=_=__==_=__==__=__=__=__=_=_= ==__==_=__==_=_==_==_==_==__==_
144 _=_=__==_=__==__=__=_=__==__=_ ==__==_=__==_=_==_==__==_=_==_=
146 _=_=__==_=__==__=__=_=_==__==_ ==__==_=__==_=_==_==__==__=_=_=
150 _=_=__==_=__==_=__==__=__=__=_ ==__==_=__==_=__==_=_==_==_==_=
152 _=_=__==_=__==_=__==__=_=__==_ ==__==_=__==_=__==_=_==__==_=_=
156 _=_=__==_=__==_=__==_=_==__==_ ==__==_=__==_=__==_=__==__=_=_=
158 _=_=__==_=__==_=_==__==__=__=_ ==__==_=__==_=__==__=_=_==_==_=
159 _=_=__==_=__==_=_==__==__=_=_= ==__==_=__==_=__==__=_=_==__==_
160 _=_=__==_=_==__==__=__=__=__=_ ==__==_=__==__=_=_==_==_==_==_=
166 _=_=__==_=_==__==__=_=_==__==_ ==__==_=__==__=_=_==__==__=_=_=
172 _=_=__==_=_==_==__==__=_=__==_ ==__==_=__==__=__=_=_==__==_=_=
178 _=_=__==_=_==_==_==__==__=__=_ ==__==_=__==__=__=__=_=_==_==_=
185 _=_=_==__==__=__=__=_=__==_=_= ==__==__=_=_==_==_==__==_=__==_
191 _=_=_==__==__=_=__==__=__=_=_= ==__==__=_=_==__==_=_==_==__==_
197 _=_=_==__==__=_=__==_=_==_==_= ==__==__=_=_==__==_=__==__=__=_
198 _=_=_==__==__=_=_==__==__=_=_= ==__==__=_=_==__==__=_=_==__==_
199 _=_=_==__==__=_=_==__==__=_=_= ==__==__=_=_==__==__=_=_==__==_
200 =__==__=__=__=__=__=__=__=__=_ _==_=_==_==_==_==_==_==_==_==_=
200 =__==__=__=__=__=__=__=__=__=_ _==_=_==_==_==_==_==_==_==_==_=
200 =__==__=__=__=__=__=__=__=__=_ _==_=_==_==_==_==_==_==_==_==_=
201 =__==__=__=__=__=__=__=__=_=_= _==_=_==_==_==_==_==_==_==__==_
202 =__==__=__=__=__=__=__=_=__==_ _==_=_==_==_==_==_==_==__==_=_=
203 =__==__=__=__=__=__=__=_=_==_= _==_=_==_==_==_==_==_==__==__=_
207 =__==__=__=__=__=__=_=_==_==_= _==_=_==_==_==_==_==__==__=__=_
210 =__==__=__=__=_=__==__=__=__=_ _==_=_==_==_==__==_=_==_==_==_=
223 =__==__=__=_=__==__=__=_=_==_= _==_=_==_==__==_=_==_==__==__=_
223 =__==__=__=_=__==__=__=_=_==_= _==_=_==_==__==_=_==_==__==__=_
231 =__==__=__=_=_==__==__=__=_=_= _==_=_==_==__==__=_=_==_==__==_
232 =__==__=__=_=_==__==__=_=__==_ _==_=_==_==__==__=_=_==__==_=_=
234 =__==__=__=_=_==__==_=__==__=_ _==_=_==_==__==__=_=__==_=_==_=
236 =__==__=__=_=_==__==_=_==__==_ _==_=_==_==__==__=_=__==__=_=_=
240 =__==__=_=__==__=__=__=__=__=_ _==_=_==__==_=_==_==_==_==_==_=
243 =__==__=_=__==__=__=__=_=_==_= _==_=_==__==_=_==_==_==__==__=_
249 =__==__=_=__==__=_=__==__=_=_= _==_=_==__==_=_==__==_=_==__==_
254 =__==__=_=__==_=__==_=__==__=_ _==_=_==__==_=__==_=__==_=_==_=
260 =__==__=_=_==__==__=__=__=__=_ _==_=_==__==__=_=_==_==_==_==_=
265 =__==__=_=_==__==__=_=__==_=_= _==_=_==__==__=_=_==__==_=__==_
266 =__==__=_=_==__==__=_=_==__==_ _==_=_==__==__=_=_==__==__=_=_=
282 =__==_=__==__=__=__=__=_=__==_ _==_=__==_=_==_==_==_==__==_=_=
292 =__==_=__==__=_=__==__=_=__==_ _==_=__==_=_==__==_=_==__==_=_=
299 =__==_=__==__=_=_==__==__=_=_= _==_=__==_=_==__==__=_=_==__==_
305 =_==__==__=__=__=__=_=__==_=_= _==__=_=_==_==_==_==__==_=__==_
307 =_==__==__=__=__=__=_=_==_==_= _==__=_=_==_==_==_==__==__=__=_


You may note that at the two temperature readings of 0C (shown as 0) I read two different patterns. From the full data attached you can see that the difference in the two readings is the patterns in a and c. This is where I am unsure whether my battery status reading is correct.

Negative temperatures are displayed by the weather station without decimals.


Elfishi

My assumption in the post earlier was wrong. I took more readings around zero degrees where the battery starts to get weak. The codes in a and c do not change upon battery status, but on sign of the temperature.
so
Code: [Select]

a: ==_==__=
c: _=__=_=_

when the temperature is negative and

a: _==__=__
c: =_==_==_

when the temperature is positive

jremington

#10
Mar 11, 2018, 04:29 pm Last Edit: Mar 11, 2018, 04:35 pm by jremington
Looks like a Manchester code, possibly a differential Manchester encoding to me. There is either a transition in the middle of a bit interval, or not.

Elfishi

AFAIU both manchester codings require level transitions to happen at the borders of bit intervals. Effectively, this means that I can have only _= and =_ code elements.
I can't find a way, however, to cut my code such that I don't get lots of == and __ also in the middle of the signal. Apparently these type of signals are only used to terminate the signal in manchester code.

 

jremington

#12
Mar 11, 2018, 05:54 pm Last Edit: Mar 12, 2018, 11:41 pm by jremington
Quote
Effectively, this means that I can have only _= and =_ code elements.
Not true with differential  Manchester encoding, which is exactly why I suggested it. There seems to be quite a bit of confusion on the web about Manchester vs. differential Manchester, though.

This post explains the difference between the two a bit more clearly, and shows how you get double length intervals: http://www.pcbheaven.com/wikipages/manchester_coding/


Elfishi

Help me.

The explanation you linked says "In the middle of each clock pulse, a transition occurs, regardless of the bit that was sent or is about to be sent".

This means, however, that a pattern like
==__=__
cannot occur: first two bits == say no transition, then comes the required transition, next two bits __ say no transition, again comes a required transition, third pair =_ means there is a transition, so far so good.
But the next bit would require a transition to = as it would be in the middle of the clock pulse. Only there is no transition in violation of the code.

If the data bit boundaries were shifted by one code bit we'd ignore the first bit =, look at the next two =_ and find a transition, but after that the level has to change as per the code definition. But it doesn't so my example doesn't match the description of differential Manchester code.

My readings are full with such sequences.

 

jremington

#14
Mar 11, 2018, 10:00 pm Last Edit: Mar 12, 2018, 01:13 am by jremington
Yep, as I said, there is a lot of confusion and poor explanation on the web.

For "middle of the clock pulse" in that link read "rising edge".

So one way to transmit differential Manchester is as follows:

(1) make a transition in the output line at the rising edge of the clock pulse.
(2) at the falling edge of the clock pulse, sample the data input line.
(3) if the data bit is a "1" make a transition on the output line.
(4) if the data bit is a "0" DO NOT make a transition on the output line.

For the other way to transmit differential Manchester, swap "0" and "1" in (3) and (4).  All output bits are just inverted.

Reverse this process to decode.

Example from one of your data posts. I started with the first T=200 line, after converting _ to 0 and = to 1, and ignored the first 001001001
Code: [Select]

200 0 00100100101011011001100100100101011001100101001100100100100100100100100101011011001100100101011011011001100101011001101011011011011011011011011011


The picture below shows two ways to decode the "signal", depending on whether a transmitter  output transition on the falling clock edge happens if the transmitter data input line is a 0 or a 1.

CK = reconstructed clock signal.

[in line display of incorrect diagram removed]

Of course, the more interesting part of the message would be where the bits are changing as the temp rises from 200 to 201, etc.

There is a surprising dearth of code examples on the web for this process, so if you get that far,  your efforts would be welcomed. On the other hand, this is the only temperature sensor I've encountered that uses this method of encoding.

Go Up