コード例 #1
0
ファイル: ge_coloreffects.c プロジェクト: pm-cz/rtl_433
/*
 * Decodes the following encoding scheme:
 * 10 = 0
 *  1100 = 1
 */
unsigned ge_decode(r_device *decoder, bitbuffer_t *inbuf, unsigned row, unsigned start, bitbuffer_t *outbuf)
{
    uint8_t *bits = inbuf->bb[row];
    unsigned int len = inbuf->bits_per_row[row];
    unsigned int ipos = start;

    while (ipos < len) {
        uint8_t bit1, bit2;

        bit1 = bit(bits, ipos++);
        bit2 = bit(bits, ipos++);

        if (bit1 == 1 && bit2 == 0) {
            bitbuffer_add_bit(outbuf, 0);
        } else if (bit1 == 1 && bit2 == 1) {
            // Get two more bits
            bit1 = bit(bits, ipos++);
            bit2 = bit(bits, ipos++);
            if (bit1 == 0 && bit2 == 0) {
                bitbuffer_add_bit(outbuf, 1);
            } else {
                break;
            }
        } else {
            break;
        }
    }

    return ipos;
}
コード例 #2
0
ファイル: bitbuffer.c プロジェクト: Japi42/rtl_433
int main(int argc, char **argv) {
	fprintf(stderr, "bitbuffer:: test\n");

	bitbuffer_t bits = {0};

	fprintf(stderr, "TEST: bitbuffer:: The empty buffer\n");
	bitbuffer_print(&bits);
	
	fprintf(stderr, "TEST: bitbuffer:: Add 1 bit\n");
	bitbuffer_add_bit(&bits, 1);
	bitbuffer_print(&bits);

	fprintf(stderr, "TEST: bitbuffer:: Add 1 new row\n");
	bitbuffer_add_row(&bits);
	bitbuffer_print(&bits);

	fprintf(stderr, "TEST: bitbuffer:: Fill row\n");
	for (int i=0; i < BITBUF_COLS*8; ++i) {
		bitbuffer_add_bit(&bits, i%2);
	}
	bitbuffer_print(&bits);

	fprintf(stderr, "TEST: bitbuffer:: Add row and fill 1 column too many\n");
	bitbuffer_add_row(&bits);
	for (int i=0; i <= BITBUF_COLS*8; ++i) {
		bitbuffer_add_bit(&bits, i%2);
	}
	bitbuffer_print(&bits);

	fprintf(stderr, "TEST: bitbuffer:: Clear\n");
	bitbuffer_clear(&bits);
	bitbuffer_print(&bits);

	fprintf(stderr, "TEST: bitbuffer:: Add 1 row too many\n");
	for (int i=0; i <= BITBUF_ROWS; ++i) {
		bitbuffer_add_row(&bits);
	}
	bitbuffer_add_bit(&bits, 1);
	bitbuffer_print(&bits);

	return 0;
}
コード例 #3
0
ファイル: lightwave_rf.c プロジェクト: MikeWarriner/rtl_433
static int lightwave_rf_callback(bitbuffer_t *bitbuffer) {
	bitrow_t *bb = bitbuffer->bb;

	// Validate package
	// Transmitted pulses are always 72
	// Pulse 72 (delimiting "1" is not demodulated, as gap becomes End-Of-Message - thus expected length is 71
	if ((bitbuffer->bits_per_row[0] == 71)
		&& (bitbuffer->num_rows == 1))		// There should be only one message (and we use the rest...)
	{
		// Polarity is inverted
		bitbuffer_invert(bitbuffer);

		// Expand all "0" to "10" (bit stuffing)
		// row_in = 0, row_out = 1
		bitbuffer_add_row(bitbuffer);
		for (unsigned n=0; n < bitbuffer->bits_per_row[0]; ++n) {
			if (bitrow_get_bit(bb[0], n)) {
				bitbuffer_add_bit(bitbuffer, 1);
			} else {
				bitbuffer_add_bit(bitbuffer, 1);
				bitbuffer_add_bit(bitbuffer, 0);
			}
		}

		// Check length is correct
		// Due to encoding there will be two "0"s per byte, thus message grows to 91 bits
		if (bitbuffer->bits_per_row[1] != 91)	return 0;

		// Check initial delimiter bit is "1"
		unsigned bit_idx = 0;
		uint8_t delimiter_bit = bitrow_get_bit(bb[1], bit_idx++);
		if (delimiter_bit == 0)	return 0;	// Decode error

		// Strip delimiter bits
		// row_in = 1, row_out = 2
		bitbuffer_add_row(bitbuffer);
		for(unsigned n=0; n<10; ++n) {		// We have 10 bytes
			delimiter_bit = bitrow_get_bit(bb[1], bit_idx++);
			if (delimiter_bit == 0)	return 0;	// Decode error

			for(unsigned m=0; m<8; ++m) {
				bitbuffer_add_bit(bitbuffer, bitrow_get_bit(bb[1], bit_idx++));
			}
		}
		// Final delimiter bit will be missing - so do not check...

		// Decode bytes to nibbles
		// row_in = 2, row_out = 3
		bitbuffer_add_row(bitbuffer);
		for(unsigned n=0; n<10; ++n) {		// We have 10 bytes/nibbles
			int nibble = lightwave_rf_nibble_from_byte(bb[2][n]);
			if (nibble < 0) {
				if (debug_output) {
					fprintf(stderr, "LightwaveRF. Nibble decode error %X, idx: %u\n", bb[2][n], n);
					bitbuffer_print(bitbuffer);
				}
				return 0;	// Decode error
			}
			for (unsigned m=0; m<4; ++m) {	// Add nibble one bit at a time...
				bitbuffer_add_bit(bitbuffer, (nibble & (8 >> m)) >> (3-m));
			}
		}

		// Print out generic decode
		// Decoded nibbles are in row 3
		fprintf(stdout, "LightwaveRF:\n");
		fprintf(stdout, "ID = 0x%X%X%X\n", bb[3][2], bb[3][3], bb[3][4]);
		fprintf(stdout, "Subunit = %u\n", (bb[3][1] & 0xF0) >> 4);
		fprintf(stdout, "Command = %u\n", bb[3][1] & 0x0F);
		fprintf(stdout, "Parameter = %u\n", bb[3][0]);

		if (debug_output) {
			bitbuffer_print(bitbuffer);
			fprintf(stderr, "  Row 0 = Input, Row 1 = Zero bit stuffing, Row 2 = Stripped delimiters, Row 3 = Decoded nibbles\n");
		}


		return 1;
	}
コード例 #4
0
ファイル: rtl_433.c プロジェクト: dducret/rtl_433
static void classify_signal() {
    unsigned int i, k, max = 0, min = 1000000, t;
    unsigned int delta, count_min, count_max, min_new, max_new, p_limit;
    unsigned int a[3], b[2], a_cnt[3], a_new[3], b_new[2];
    unsigned int signal_distance_data[4000] = {0};
    struct protocol_state p = {0};
    unsigned int signal_type;

    if (!signal_pulse_data[0][0])
        return;

    for (i = 0; i < 1000; i++) {
        if (signal_pulse_data[i][0] > 0) {
            //fprintf(stderr, "[%03d] s: %d\t  e:\t %d\t l:%d\n",
            //i, signal_pulse_data[i][0], signal_pulse_data[i][1],
            //signal_pulse_data[i][2]);
            if (signal_pulse_data[i][2] > max)
                max = signal_pulse_data[i][2];
            if (signal_pulse_data[i][2] <= min)
                min = signal_pulse_data[i][2];
        }
    }
    t = (max + min) / 2;
    //fprintf(stderr, "\n\nMax: %d, Min: %d  t:%d\n", max, min, t);

    delta = (max - min)*(max - min);

    //TODO use Lloyd-Max quantizer instead
    k = 1;
    while ((k < 10) && (delta > 0)) {
        min_new = 0;
        count_min = 0;
        max_new = 0;
        count_max = 0;

        for (i = 0; i < 1000; i++) {
            if (signal_pulse_data[i][0] > 0) {
                if (signal_pulse_data[i][2] < t) {
                    min_new = min_new + signal_pulse_data[i][2];
                    count_min++;
                } else {
                    max_new = max_new + signal_pulse_data[i][2];
                    count_max++;
                }
            }
        }
        if (count_min != 0 && count_max != 0) {
            min_new = min_new / count_min;
            max_new = max_new / count_max;
        }

        delta = (min - min_new)*(min - min_new) + (max - max_new)*(max - max_new);
        min = min_new;
        max = max_new;
        t = (min + max) / 2;

        fprintf(stderr, "Iteration %d. t: %d    min: %d (%d)    max: %d (%d)    delta %d\n", k, t, min, count_min, max, count_max, delta);
        k++;
    }

    for (i = 0; i < 1000; i++) {
        if (signal_pulse_data[i][0] > 0) {
            //fprintf(stderr, "%d\n", signal_pulse_data[i][1]);
        }
    }
    /* 50% decision limit */
    if (min != 0 && max / min > 1) {
        fprintf(stderr, "Pulse coding: Short pulse length %d - Long pulse length %d\n", min, max);
        signal_type = 2;
    } else {
        fprintf(stderr, "Distance coding: Pulse length %d\n", (min + max) / 2);
        signal_type = 1;
    }
    p_limit = (max + min) / 2;

    /* Initial guesses */
    a[0] = 1000000;
    a[2] = 0;
    for (i = 1; i < 1000; i++) {
        if (signal_pulse_data[i][0] > 0) {
            //               fprintf(stderr, "[%03d] s: %d\t  e:\t %d\t l:%d\t  d:%d\n",
            //               i, signal_pulse_data[i][0], signal_pulse_data[i][1],
            //               signal_pulse_data[i][2], signal_pulse_data[i][0]-signal_pulse_data[i-1][1]);
            signal_distance_data[i - 1] = signal_pulse_data[i][0] - signal_pulse_data[i - 1][1];
            if (signal_distance_data[i - 1] > a[2])
                a[2] = signal_distance_data[i - 1];
            if (signal_distance_data[i - 1] <= a[0])
                a[0] = signal_distance_data[i - 1];
        }
    }
    min = a[0];
    max = a[2];
    a[1] = (a[0] + a[2]) / 2;
    //    for (i=0 ; i<1 ; i++) {
    //        b[i] = (a[i]+a[i+1])/2;
    //    }
    b[0] = (a[0] + a[1]) / 2;
    b[1] = (a[1] + a[2]) / 2;
    //     fprintf(stderr, "a[0]: %d\t a[1]: %d\t a[2]: %d\t\n",a[0],a[1],a[2]);
    //     fprintf(stderr, "b[0]: %d\t b[1]: %d\n",b[0],b[1]);

    k = 1;
    delta = 10000000;
    while ((k < 10) && (delta > 0)) {
        for (i = 0; i < 3; i++) {
            a_new[i] = 0;
            a_cnt[i] = 0;
        }

        for (i = 0; i < 1000; i++) {
            if (signal_distance_data[i] > 0) {
                if (signal_distance_data[i] < b[0]) {
                    a_new[0] += signal_distance_data[i];
                    a_cnt[0]++;
                } else if (signal_distance_data[i] < b[1] && signal_distance_data[i] >= b[0]) {
                    a_new[1] += signal_distance_data[i];
                    a_cnt[1]++;
                } else if (signal_distance_data[i] >= b[1]) {
                    a_new[2] += signal_distance_data[i];
                    a_cnt[2]++;
                }
            }
        }

        //         fprintf(stderr, "Iteration %d.", k);
        delta = 0;
        for (i = 0; i < 3; i++) {
            if (a_cnt[i])
                a_new[i] /= a_cnt[i];
            delta += (a[i] - a_new[i])*(a[i] - a_new[i]);
            //             fprintf(stderr, "\ta[%d]: %d (%d)", i, a_new[i], a[i]);
            a[i] = a_new[i];
        }
        //         fprintf(stderr, " delta %d\n", delta);

        if (a[0] < min) {
            a[0] = min;
            //             fprintf(stderr, "Fixing a[0] = %d\n", min);
        }
        if (a[2] > max) {
            a[0] = max;
            //             fprintf(stderr, "Fixing a[2] = %d\n", max);
        }
        //         if (a[1] == 0) {
        //             a[1] = (a[2]+a[0])/2;
        //             fprintf(stderr, "Fixing a[1] = %d\n", a[1]);
        //         }

        //         fprintf(stderr, "Iteration %d.", k);
        for (i = 0; i < 2; i++) {
            //             fprintf(stderr, "\tb[%d]: (%d) ", i, b[i]);
            b[i] = (a[i] + a[i + 1]) / 2;
            //             fprintf(stderr, "%d  ", b[i]);
        }
        //         fprintf(stderr, "\n");
        k++;
    }

    if (override_short) {
        p_limit = override_short;
        a[0] = override_short;
    }

    if (override_long) {
        a[1] = override_long;
    }

    fprintf(stderr, "\nShort distance: %d, long distance: %d, packet distance: %d\n", a[0], a[1], a[2]);
    fprintf(stderr, "\np_limit: %d\n", p_limit);

    bitbuffer_clear(&p.bits);
    if (signal_type == 1) {
        for (i = 0; i < 1000; i++) {
            if (signal_distance_data[i] > 0) {
                if (signal_distance_data[i] < (a[0] + a[1]) / 2) {
                    //                     fprintf(stderr, "0 [%d] %d < %d\n",i, signal_distance_data[i], (a[0]+a[1])/2);
                    bitbuffer_add_bit(&p.bits, 0);
                } else if ((signal_distance_data[i] > (a[0] + a[1]) / 2) && (signal_distance_data[i] < (a[1] + a[2]) / 2)) {
                    //                     fprintf(stderr, "0 [%d] %d > %d\n",i, signal_distance_data[i], (a[0]+a[1])/2);
                    bitbuffer_add_bit(&p.bits, 1);
                } else if (signal_distance_data[i] > (a[1] + a[2]) / 2) {
                    //                     fprintf(stderr, "0 [%d] %d > %d\n",i, signal_distance_data[i], (a[1]+a[2])/2);
                    bitbuffer_add_row(&p.bits);
                }

            }

        }
        bitbuffer_print(&p.bits);
    }
    if (signal_type == 2) {
        for (i = 0; i < 1000; i++) {
            if (signal_pulse_data[i][2] > 0) {
                if (signal_pulse_data[i][2] < p_limit) {
                    //                     fprintf(stderr, "0 [%d] %d < %d\n",i, signal_pulse_data[i][2], p_limit);
                    bitbuffer_add_bit(&p.bits, 0);
                } else {
                    //                     fprintf(stderr, "1 [%d] %d > %d\n",i, signal_pulse_data[i][2], p_limit);
                    bitbuffer_add_bit(&p.bits, 1);
                }
                if ((signal_distance_data[i] >= (a[1] + a[2]) / 2)) {
                    //                     fprintf(stderr, "\\n [%d] %d > %d\n",i, signal_distance_data[i], (a[1]+a[2])/2);
                    bitbuffer_add_row(&p.bits);
                }


            }
        }
        bitbuffer_print(&p.bits);
    }

    for (i = 0; i < 1000; i++) {
        signal_pulse_data[i][0] = 0;
        signal_pulse_data[i][1] = 0;
        signal_pulse_data[i][2] = 0;
        signal_distance_data[i] = 0;
    }

};