I'm trying to understand the bit operations, but after few hours of analysing - still nothing.
Here is the code: https://github.com/merbanan/rtl_433/blob/master/src/rtl_433.c
but the most interesting part is here:
static int prologue_callback(uint8_t bb[BITBUF_ROWS][BITBUF_COLS]) {
int rid;
int16_t temp2;
/* FIXME validate the received message better */
if (((bb[1][0]&0xF0) == 0x90 && (bb[2][0]&0xF0) == 0x90 && (bb[3][0]&0xF0) == 0x90 && (bb[4][0]&0xF0) == 0x90 &&
(bb[5][0]&0xF0) == 0x90 && (bb[6][0]&0xF0) == 0x90) ||
((bb[1][0]&0xF0) == 0x50 && (bb[2][0]&0xF0) == 0x50 && (bb[3][0]&0xF0) == 0x50 && (bb[4][0]&0xF0) == 0x50)) {
/* Prologue sensor */
temp2 = (int16_t)((uint16_t)(bb[1][2] << 8) | (bb[1][3]&0xF0));
temp2 = temp2 >> 4;
fprintf(stderr, "Sensor temperature event:\n");
fprintf(stderr, "protocol = Prologue\n");
fprintf(stderr, "button = %d\n",bb[1][1]&0x04?1:0);
fprintf(stderr, "battery = %s\n",bb[1][1]&0x08?"Ok":"Low");
fprintf(stderr, "temp = %s%d.%d\n",temp2<0?"-":"",abs((int16_t)temp2/10),abs((int16_t)temp2%10));
fprintf(stderr, "humidity = %d\n", ((bb[1][3]&0x0F)<<4)|(bb[1][4]>>4));
fprintf(stderr, "channel = %d\n",(bb[1][1]&0x03)+1);
fprintf(stderr, "id = %d\n",(bb[1][0]&0xF0)>>4);
rid = ((bb[1][0]&0x0F)<<4)|(bb[1][1]&0xF0)>>4;
fprintf(stderr, "rid = %d\n", rid);
fprintf(stderr, "hrid = %02x\n", rid);
fprintf(stderr, "%02x %02x %02x %02x %02x\n",bb[1][0],bb[1][1],bb[1][2],bb[1][3],bb[1][4]);
if (debug_output)
debug_callback(bb);
return 1;
}
return 0;
I don't understand what is bb[BITBUF_ROWS][BITBUF_COLS].
The algorithm gets the 9 nibbles, which are decoded into some variables, eg. temp, humidity etc.
The example taken from http://goughlui.com/2013/12/20/rtl-sdr-433-92mhz-askook-decoding-of-various-devices-with-rtl_433/
The input: 10010110 01000100 00010000 00010010 10111000
The result:
button: 1
battery: Low
temp: 25.7
humidity: 43
channel:1
id: 9
rid :100
hrid: 64
Because I don't know if the input is negative or LSB reversed I prepared the table with all situations:
bin dec neg neg rev rev neg neg
bin dec dec rev rev dec
1001 9 0110 6 1001 9 0110 6
0110 6 1001 9 0110 6 1001 9
0100 4 1011 11 0010 2 1101 13
0100 4 1011 11 0010 2 1101 13
0001 1 1110 14 1000 8 0111 7
0000 0 1111 15 0000 0 1111 15
0001 1 1110 14 1000 8 0111 7
0010 2 1101 13 0100 4 1011 11
1011 11 0100 4 1101 13 0010 2
1000 8 0111 7 0001 1 1110 14
But I definetely don't understand how the temp is 25.7, while there's no 5 at all. the humidity id 43 but there's no 3 value.
What I'm doing wrong?
All values are in there. The input in hex is
96 44 10 12 B8
and writing it as nibbles, we get
A a | B b | C c | D d | E e
9 6 | 4 4 | 1 0 | 1 2 | B 8
With this notation, we can replace bb[1][0]
with Aa
, bb[1][1]
with Bb
and so forth. I will refer to individual nibbles as A
, a
, and so on, without the bit shifting and masking, which may make things a bit clearer. To get A
, B
, etc. take the byte, mask the 4 highest bits ( & 0xF0)
and shift it right 4 bits ( >>4
). To get a
, b
, etc. mask the lowest 4 bits of the original byte: & 0x0F
.
Button is a simple bit flag: bit 2 of b
: 0100
, so it is 1 . (Bits count right to left and start at 0.)
Battery is also a simple bit flag: bit 3 of b
, so it is 0
, which indicates "Low" .
Temperature is ((Cc<<8)|D)>>4
: 10<<8 = 1000 + 10 = 1010 >> 4
, or 101
in hex, 257 in decimal. This appears to be in tenths of degrees, hence the division by 10: 25.7 (all that extra manipulation is to display a negative value correctly).
Humidity is (d<<4) | E
(d<<4) | E
, or 20 | B = 2B
20 | B = 2B
, which is 43 .
Channel is bits 0-1 of b
( 00
) plus 1, which equals 1 .
Id is the value in A
: 9 .
RID , finally, is (a<<4) | B
(a<<4) | B
: 60 | 4 = 64
60 | 4 = 64
, 100 in decimals. hrid is the same value but written in hex.
The temperature bytes are bb[1][2]
and bb[1][3]
= 00010000
and 00010010
.
The code appends these, and then shifts right by 4: 0001 0000 0001
Converting from binary to decimal, this is 257
(hex is 0x101
).
The code divides by ten to get the temperature: 25.7.
The data is packed into the array. For example humidity is extracted from the 4 ls bits of bb[1][3]
and the 4 ms bits of bb[1][4]
.
fprintf(stderr, "humidity = %d\n", ((bb[1][3]&0x0F)<<4)|(bb[1][4]>>4));
So if bb[1][3] = xxxx0010 and bb[1][4] = 1011xxxx, humidity = 00101011 = 43
Temperature is similar but more complicated.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.