我试图了解位操作,但经过几个小时的分析 - 仍然没有。
以下是代码:https://github.com/merbanan/rtl_433/blob/master/src/rtl_433.c
但最有趣的部分是:
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;
我不明白什么是bb [BITBUF_ROWS] [BITBUF_COLS]。
算法得到9个半字节,它们被解码成一些变量,例如。温度,湿度等。
取自http://goughlui.com/2013/12/20/rtl-sdr-433-92mhz-askook-decoding-of-various-devices-with-rtl_433/
的例子输入:10010110 01000100 00010000 00010010 10111000
结果:
button: 1
battery: Low
temp: 25.7
humidity: 43
channel:1
id: 9
rid :100
hrid: 64
因为我不知道输入是否为负或LSB是否反转我在所有情况下都准备了表格:
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
但我明确地不理解温度是25.7,而根本没有5。湿度id 43但没有3值。
我做错了什么?
答案 0 :(得分:3)
所有价值都在那里。十六进制的输入是
96 44 10 12 B8
并将其写为半字节,我们得到
A a | B b | C c | D d | E e
9 6 | 4 4 | 1 0 | 1 2 | B 8
使用此表示法,我们可以将bb[1][0]
替换为Aa
,bb[1][1]
替换为Bb
,依此类推。我会将单个半字节称为A
,a
等,而不需要进行位移和屏蔽,这可能会使事情更加清晰。要获取A
,B
等取字节,屏蔽4个最高位(& 0xF0)
并将其右移4位(>>4
)。获取{{1 },a
等掩码原始字节的最低4位:b
。
按钮是一个简单的位标志:& 0x0F
的第2位:b
,因此它是 1 。 (位从右到左计数,从0开始。)
电池也是一个简单的位标志:0100
的第3位,所以它是b
,表示“低”。< / p>
温度为0
:((Cc<<8)|D)>>4
,或十六进制为10<<8 = 1000 + 10 = 1010 >> 4
,十进制为257。这似乎是十分之一度,因此除以10: 25.7 (所有额外操作都是正确显示负值)。
湿度为101
,或(d<<4) | E
, 43 。
频道是20 | B = 2B
(b
)的0-1位加1,等于 1 。
Id 是00
中的值: 9 。
RID 最后是小数点A
:(a<<4) | B
, 100 。 hrid 是相同的值,但以十六进制编写。
答案 1 :(得分:2)
温度字节为bb[1][2]
和bb[1][3]
= 00010000
和00010010
。
代码附加这些代码,然后向右移动4:0001 0000 0001
从二进制转换为十进制,这是257
(十六进制是0x101
)。
代码除以10得到温度:25.7。
答案 2 :(得分:1)
数据被打包到数组中。例如,从4升中提取湿度。 bb[1][3]
和4 m.s.的位比特bb[1][4]
。
fprintf(stderr, "humidity = %d\n", ((bb[1][3]&0x0F)<<4)|(bb[1][4]>>4));
所以如果bb [1] [3] = xxxx0010和bb [1] [4] = 1011xxxx,湿度= 00101011 = 43
温度相似但更复杂。