433 Weather sensor from Oregon Scientific problems decoding

Sometimes it helps with reverse decoding of unknown sensors, to find out all the types of sensors that the receiving console supports, including ones that you dont have, as the data fields being transmitted will be common to all the sensors.
You can usually look up the accuracy specs for the temps and the RH and find out if its 1 Deg C or 0.1 D C
and similar with the RH.
Are these sensors actually made by OS or are they 3rd party sensors which have been re badged as OS ones?
The latter would explain the non standard protocol.

I'll bet you are right that the EW99 is a 3rd party sensor.
It doesn't seem to be available in the U.S., which is rather strange for a U.S. company!

well protocols - Checksum/CRC calculation - Stack Overflow
This guy shared his findings (while looking for CRC calc help) and...
It seems I am one bit off. When I skip one bit things look a bit more sensible. Still confirming.

To determine the most likely range of bits used for temperature & humidity place the sensor in the fridge/freezer (depending on it's specs) for about 30 minutes then bring it out and start logging the data. The temperature, humidity & checksum bits should be changing quite rapidly while fixed values like sensor ID, channel number will remain constant.
Once you have an idea what bits to look at you might have a better chance of decoding them.

I don't think that the sensor described in the stackoverflow post is of the same type.

I've rearranged the data table from post#14 into 8-bit columns as follows and see that primarily, fields D, H and I change. B and F take on just two values and the same row in each changes. Presumably column I (or perhaps H and I) is a checksum.

If D and H are temperature and humidity, they change a lot. This is inconsistent with your claim that the temperature and humidity are relatively constant.

I second Riva's suggestion of the freezer.

A       B        C        D        E        F        G        H        I
1110001 11011000 10011100 10111000 00001110 00100111 01100011 01000111 10110111
1110001 11011000 10011100 10101111 00001110 00100111 01100011 01010000 01010011
1110001 01011000 10011100 01111100 00001110 10100111 01100011 10000011 00111111
1110001 01011000 10011100 01111011 00001110 10100111 01100011 10000100 01000010
1110001 01011000 10011100 01111010 00001110 10100111 01100011 10000101 01010011
1110001 01011000 10011100 01111001 00001110 10100111 01100011 10000110 01100010
1110001 01011000 10011100 01111000 00001110 10100111 01100011 10000111 01110011
1110001 01011000 10011100 01110111 00001110 10100111 01100011 10001000 10001110
1110001 01011000 10011100 01110110 00001110 10100111 01100011 10001001 10011111
1110001 01011000 10011100 01101111 00001110 10100111 01100011 10010000 00011111
1110001 01011000 10011100 01101110 00001110 10100111 01100011 10010001 00100000
1110001 01011000 10011100 01101100 00001110 10100111 01100011 10010011 01000000
1110001 01011000 10011100 01101010 00001110 10100111 01100011 10010101 01100100
1110001 01011000 10011100 01101001 00001110 10100111 01100011 10010110 01110011
1110001 01011000 10011100 01101000 00001110 10100111 01100011 10010111 10000100
1110001 01011000 10011100 01100111 00001110 10100111 01100011 10011000 10011111
1110001 01011000 10011100 01101011 00001110 10100111 01100011 10010100 01010011

It's been outside for past 8 hours. Temperature reported by another sensor is 1.2C.
Readings for the past 5 min.

11100010101111100111111111111100000111010100000110000000000000101011001
11100010101111100111111111111100000111010100000110000000000000101011001
11100010101111100111111111111100000111010100000110000000000000101011001
11100010101111100111111111111100000111010100000110000000000000101011001
11100010101111100111111111111100000111010100000110000000000000101011001

I've opened one of these out. Photo attached in case you recognise something (not much to see).

UPDATE:
Well the temperature just rose by about 0.1 degree outside and something interesting (perhaps happened).

This is the transition afait

11100010101111100111111111111100000111010100000110000000000000101011001
11100010101111100111111111111000000111010100000110000000000001101111001

What are they doing?

By just adding some spaces I get the following:

11   1000 1010 1111 1001 1111 1111 1111   0000 
     0111 0101 0000 0110 0000 0000 0000   101011001

11   1000 1010 1111 1001 1111 1111 1110   0000 
     0111 0101 0000 0110 0000 0000 0001   101111001

Looks like somewhere mid way they reverse the bits and transmit again?

UPDATE 2:
Some old captures broken down in exactly the same way

11 1000111101001010011011100110 1000 
   0111000010110101100100011001 001111011

11 1000111101001010011011100110 1000 
   0111000010110101100100011001 001111011

11 1000111101001010011011100110 1000 
   0111000010110101100100011001 001111011

11 1000111101001010011011100111 1000 
   0111000010110101100100011000 001011011

Your results suggest that the following 12 bits are the temperature, a signed 12 bit integer in tenths of a degree C. The second line is the complement of the data (a common error-checking approach).

In this interpretation, the top temperature is negative (-1 or -0.1 degree) and then changes to -0.2. Or, the bottom code is the temperature 0.0, which then changes to 0.1.

1111 1111 1111
0000 0000 0000

1111 1111 1110
0000 0000 0001

If this is correct, the 16 bits preceding the temperature could be the humidity, and perhaps some other measure.

I retract post #21 (although the observation is valid), because I think I found the temperature, encoded as BCD digits.

I converted the last 6 columns of the data in post #14 and earlier ones (with data for 21.2, around 0.0 and -6.5) to hex. You mentioned in post #14 that the temperature was near 39 C. The last 3 hex digits before the presumed 8-bit checksum appear to be BCD digits for temperatures in the range of 38.3 and 39.8

If you add in the data for 21.2, about 0.0 and -6.5 degrees, it becomes rather convincing, but considering that -6.5 is represented as 059, there must be a negative sign somewhere else.

The complement of the data comes earlier in the message. I don't know what that means.

Below, the presumed temperature digits are separated by spaces for clarity.

about 38 C
1110001 11011000 10011100 10111000 00001110 00100111 01100011 01000111 10110111 B80E276 347 B7
1110001 11011000 10011100 10101111 00001110 00100111 01100011 01010000 01010011 AF0E276 350 53
1110001 01011000 10011100 01111100 00001110 10100111 01100011 10000011 00111111 7C0EA76 383 3F
1110001 01011000 10011100 01111011 00001110 10100111 01100011 10000100 01000010 7B0EA76 384 42
1110001 01011000 10011100 01111010 00001110 10100111 01100011 10000101 01010011 7A0EA76 385 53
1110001 01011000 10011100 01111001 00001110 10100111 01100011 10000110 01100010 790EA76 386 62
1110001 01011000 10011100 01111000 00001110 10100111 01100011 10000111 01110011 780EA76 387 73
1110001 01011000 10011100 01110111 00001110 10100111 01100011 10001000 10001110 770EA76 388 8E
1110001 01011000 10011100 01110110 00001110 10100111 01100011 10001001 10011111 760EA76 389 9F
1110001 01011000 10011100 01101111 00001110 10100111 01100011 10010000 00011111 6F0EA76 390 1F
1110001 01011000 10011100 01101110 00001110 10100111 01100011 10010001 00100000 6E0EA76 391 20
1110001 01011000 10011100 01101100 00001110 10100111 01100011 10010011 01000000 6C0EA76 393 40
1110001 01011000 10011100 01101010 00001110 10100111 01100011 10010101 01100100 6A0EA76 395 64
1110001 01011000 10011100 01101001 00001110 10100111 01100011 10010110 01110011 690EA76 396 73
1110001 01011000 10011100 01101000 00001110 10100111 01100011 10010111 10000100 680EA76 397 84
1110001 01011000 10011100 01100111 00001110 10100111 01100011 10011000 10011111 670EA76 398 9F
1110001 01011000 10011100 01101011 00001110 10100111 01100011 10010100 01010011 6B0EA76 394 53

about 21.2 C
1110001 01011101 01111101 11101100 00001110 10100010 10000010 00010011 10000110 EC0EA28 213 86
1110001 01011101 01111101 11101010 00001110 10100010 10000010 00010101 10101010 EA0EA28 215 AA

about -6.5 C
1110001 01010101 11111111 10100110 00001110 10101010 00000000 01011001 00001010 A60EAA0 059 0A

about 1.2
1110001 01011111 00111111 11111110 00001110 10100000 11000000 00000001 01011001 7E0EA0C 001 59

about 0.0
1110001 01011111 00111111 11111110 00001110 10100000 11000000 00000001 01011001 FE0EA0C 001 59
1110001 01011111 00111111 11111100 00001110 10100000 11000000 00000011 01111001 FC0EA0C 003 79

There is always the possibility the reading program I knocked up is interpreting the bits the wrong way round (I was guessing) so 6000us is a zero and 4000us is a 1

//    ______        ______     ___     ___
//   |      |      |      |   |   |   |
//___|      |______|      |___|   |___|
//
//   |    Sync     |     1    |   0   |
//   |    8000us   |  6000us  | 4000us

If you invert all the bits in the message, the presumed temperature field just comes earlier in the message. Converting the central 48 bits (which appear to carry the data and the data complement) to hex, you get

10011100 01101011 00001110 10100111 01100011 10010100 =
9C6B0EA76394, which complemented, is
6394F1589C6B

Either way, the proposed temperature digits would be 394.

Assuming 1=4000 us and 0 = 6000 us is more likely to be correct, as people often send the data and then the data complement as a check.

Hi folks,

You may like to process the packet trough the following routine as it breaks the packet up into binary and hexadecimal.

//Useful to invoke to debug the byte Array
void hexBinDump() {
  //Serial.println("T A3 10100011 07 00000111 02 00000010 AA 10101010 F0 11110000 06 00000110 FF 11111111 07 00000111 33 00110011 60 01100000");
  Serial.print("D ");
  for ( int i = 0; i < maxBytes; i++) {
    byte mask = B10000000;
    if (manchester[i] < 16) {
      Serial.print("0");
    }
    Serial.print(manchester[i], HEX);
    Serial.print(" ");
    for (int k = 0; k < 8; k++) {
      if (manchester[i] & mask) {
        Serial.print("1");
      }
      else {
        Serial.print("0");
      }
      mask = mask >> 1;
    }
    Serial.print(" ");
  }
  Serial.println();
}

This may help you to spot either binary patterns or BCD patterns in your data. How relevant this is will depend on how the byte patterns line up, so you may have to shift your primary data capturing process along or back a few bits to get anything meaningful from it. However putting a standard alcohol analogue themometer beside the device and getting a ball park figure to look for may well help.
Also don't be too surprised if for one factor eg Temperature they use binary representation of temperature byte1*10+byte2=temp/10 and for Humidity the use BCD B00110111 ie 37%. Don't assume too much and keep an open mind.

Cheers, R

BCD as in each i.e. 4 bits represent a single digit left to right rather than larger i.e. 12 bits being just base converted to decimal... right? In that case . I wrote a "walking" decoder over a CSV of bit dumps but have not found a reliable representation probably because BCD thing... ehh. Will have a look now.

Hi PawPro,

BCD are 4 bit numbers, so 2 independent BCD's can be in one 8 bit number:

eg 8bits -> 10010011, is 93 in BCD, ie 8+0+0+1, 0+0+2+1

but as pure binary 128+0+0+16+0+0+2+1= 147 as in common base 10.

As hexadecimal decodes BCD if it exists, just doing Hexadecimal is also handy, as any illegal BCD such as 1100, ie C in the data stream will be obvious too.

Rob

I think that all Oregon Scientific protocols use BCD data encoding, but this particular sensor may be from a third party. Nevertheless, BCD is very commonly used.

Yes I agree, all the OS V3.0 is BCD. However a couple of little tricks to the data packet that made it a bit more difficult to decode was the "synch" bit was inside the first byte (and nybble) boundaries, but less obvious was the nybbles had the order of bits reversed eg

one nybble -
MSB LSB
A B C D

was transmitted to the receiver as DCBA. So the receiving software had to reverse the bits back to ABCD
(where A=8, B=4, C=2 and D=1) then start processing to find the value. eg

  temperature = (double)((nyb(11) * 100) + (nyb(10) * 10) + nyb(9)) / 10;

However the sequence of nibbles of BCD were in ascending order after that and easy to work with.

A quick hand check of where the byte boundaries are, and the possibility of nybble reversal may be worth while.

Cheers, Rob

Hi PawPro,

If this subject is still interesting to you.

I have an ew99 sensor and a base station of ew91 which shows temperature. I obtain data from the sensor on the SDR receiver and I use rtl_433 for decoding of a signal (GitHub - merbanan/rtl_433: Program to decode radio transmissions from devices on the ISM bands (and other frequencies)).

Analyzing pulses...
Total count: 75, width: 91787 (367.1 ms)
Pulse width distribution:
[ 0] count: 74, width: 474 [466;482] (1896 us)
[ 1] count: 1, width: 968 [968;968] (3872 us)
Gap width distribution:
[ 0] count: 36, width: 501 [497;508] (2004 us)
[ 1] count: 38, width: 990 [984;998] (3960 us)

Sensors have the similar protocol
In nexus.c

  • the packets are ppm modulated (distance coding) with a pulse of ~500 us
  • followed by a short gap of ~1000 us for a 0 bit or a long ~2000 us gap for a
  • 1 bit, the sync gap is ~4000 us.
    In prologue.c
  • the packets are ppm modulated (distance coding) with a pulse of ~500 us
  • followed by a short gap of ~2000 us for a 0 bit or a long ~4000 us gap for a
  • 1 bit, the sync gap is ~9000 us.
    Probably?

short gap for a 0 bit
long gap for a 1 bit

You decoded a signal on the contrary - a short gap 1, a long gap - 0.

If to make on the contrary (see attach file), then we will receive:

10001110_10010100_11001010_00101000_1111000.....
8___e____9___4____c___a____2___8____f

10001110_00010100_11000010_00100111_1111000.....
8___e____1___4____c___2____2___7____f

10001110_00010100_11000010_00100111_1111000.....
8___e____1___4____c___2____2___7____f

10001110_10010011_01111010_00100100_1111000.....
8___e____9___3____7___a____2___4____f

For my device I have:

EW99 bitbuffer event 2016-02-29 23:19:51 - 23,8 C
10001110 10010000 11000010 00111000 11110001 01101111 00111101 11000111 11110101
8___e____9___0____c___2____3___8
EW99 bitbuffer event 2016-03-01 02:11:49 - 0,0 C
10001110 10010000 11000000 00000000 11110001 01101111 00111111 11111111 11000110
8___e____9___0____c___0____0___0
EW99 bitbuffer event 2016-03-01 02:52:49 - -0,6 C
10001110 10011000 11000000 00000110 11110001 01100111 00111111 11111001 11100010
8___e____9___8____c___0____0___6


EW99 bitbuffer event 2016-02-29 16:46:03 - 19,4 C canal 1
10001110 00010011 10010001 10010100 11110001 11101100 01101110 01101011 01100010
8___e____1___3____9___1____9___4
EW99 bitbuffer event 2016-02-29 16:44:22 - 19,3 C canal 2
10001110 00100010 10010001 10010011 11110001 11011101 01101110 01101100 01110111
8___e____2___2____9___1____9___3
EW99 bitbuffer event 2016-02-29 16:38:48 - 19,4 C canal 3
10001110 00110110 01110001 10010100 11110001 11001001 10001110 01101011 00111011
8___e____3___6____7___1____9___4

EW99 bitbuffer event 2016-02-29 15:45:01 - reverse the bits
10001110 10010000 00000001 10010011 11110001 01101111 11111110 01101100 10110111
_1110001 01101111 11111110 01101100__==================================

So, that as a result:

8___e____3___6____7___1____9___4
10001110 00110110 01110001 10010100 11110001 11001001 10001110 01101011 00111011
___________^^   canal___^^_^^^^^^^^ temp                                           CRS?
_____________^  sign

It is all so far.

Cheers, Alex

That appears to agree with my previous analysis, with the bits inverted. The temp is BCD encoded, and sent along with its complement later in the message.

If you invert all the bits in the message, the presumed temperature field just comes earlier in the message. Converting the central 48 bits (which appear to carry the data and the data complement) to hex, you get

10011100 01101011 00001110 10100111 01100011 10010100 =
9C6B0EA76394, which complemented, is
6394F1589C6B (temp = 39.4 C)

Hi, jremington!

I agree with "bits inverted" excepting the first bit first four bytes.

EW99 bitbuffer event 2016-02-29 15:45:01 - reverse the bits (excepting the first bit of first byte)
10001110 10010000 00000001 10010011 11110001 01101111 11111110 01101100 10110111
_1110001 01101111 11111110 01101100__==================================

I agree with "the temp is BCD encoded" - but "packed BCD" (Binary-coded decimal - Wikipedia.

I have been surprised - "(temp = 39.4 C)" in your message. It in Africa :slight_smile: ? Or in the room :o?

Ok.

The sensor transfers temperature from-40 to +60 (according to the description).
I have put the sensor on the battery and have heated to 45,5 C

EW99 bitbuffer event 2016-03-05 03:27:52 - 45,5 C
10001110 10010000 11000100 01010101 11110001 01101111 00111011 10101010 11101000 
8___e___ 9___0___ c___4___ 5___5___ f1 6f 3b aa e8

So, three bits on tens of temperature at the end of the third byte, the fourth byte of unit + 1/10.

As a result what we have:

EW99 bitbuffer event 2016-03-05 03:27:52 - 45,5 C
10001110 10010000 11000100 01010101 11110001 01101111 00111011 10101010 11101000 
kkkkkkkk ??ccs??? ?????ttt tttttttt _rrrrrrr rrrrrrrr rrrrrrrr rrrrrrrr CRS__CRS

k - device code
c - canal
s - sign
t - temperature
r - reverse (excepting the first bit)
? - ???????

How to define what is meant by the remained unknown bits? There are ideas?

Yours faithfully, Alex

I have been surprised - "(temp = 39.4 C)" in your message. It in Africa :slight_smile: ? Or in the room :o?

Read post #14.

How to define what is meant by the remained unknown bits?

"CRS" could be a CRC checksum, but there are other possibilities, like a simple sum. Other bits could be battery status, temperature increasing or decreasing, etc.

You have to look at a lot of entries to make sure, and if "CRS" is a CRC checksum, many bits will change, even if only one bit in the message changes.

If it is a CRC you need to determine the polynomial and input/output constants. I have used the program reveng to reverse engineer CRC calculations. http://reveng.sourceforge.net/