Skip to content

Commit

Permalink
Enhance Kedsum with MIC, model changed to "Kedsum-TH"
Browse files Browse the repository at this point in the history
  • Loading branch information
zuckschwerdt committed Feb 16, 2019
1 parent 44a5c13 commit af2fd65
Showing 1 changed file with 71 additions and 58 deletions.
129 changes: 71 additions & 58 deletions src/devices/kedsum.c
Original file line number Diff line number Diff line change
@@ -1,31 +1,53 @@
/* Kedsum temperature and humidity sensor (http://amzn.to/25IXeng)
My models transmit at a bit lower freq. Around ~433.71 Mhz
Copyright (C) 2016 John Lifsey
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
published by the Free Software Foundation.
Largely based on prologue, esperanza_ews, s3318p
Frame appears to be a differently-endianed version of the esperanza
Frame structure:
IIIIIIII????CC++++ttttTTTThhhhHHHH?????? PP
IIIIIIII unique id. changes on powercycle
CC channel, 00 = ch1, 10=ch3
++++ low temp nibble
tttt med temp nibble
TTTT high temp nibble
hhhh humidity low nibble
HHHH humidity high nibble
/** @file
Kedsum temperature and humidity sensor (http://amzn.to/25IXeng).
My models transmit at a bit lower freq. of around 433.71 Mhz.
Also NC-7415 from Pearl.
Copyright (C) 2016 John Lifsey
Enhanced (C) 2019 Christian W. Zuckschwerdt <zany@triq.net>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
*/
/**
Largely based on prologue, esperanza_ews, s3318p.
Frame appears to be a differently-endianed version of the esperanza.
Frame structure:
00 IIIIIIII BBCC++++ ttttTTTT hhhhHHHH FFFFXXXX
- IIIIIIII: unique id. changes on powercycle
- BB: Battery state 10 = Ok, 01 = weak, 00 = bad
- CC: channel, 00 = ch1, 10=ch3
- ++++: low temp nibble
- tttt: med temp nibble
- TTTT: high temp nibble
- hhhh: humidity low nibble
- HHHH: humidity high nibble
- FFFF: flags
- XXXX: LFSR-4 (simple, not digest), static key 0x3
*/

#include "decoder.h"

static uint8_t lfsr4(uint8_t const message[], unsigned nBits, uint8_t key)
{
int sum = 0;
for (unsigned i = 0; i < nBits; i++) {
if (i % 8 == 0)
sum |= *message++;
sum <<= 1;
if (sum & 0x1000)
sum ^= key << 8;
}
return (sum & 0xf00) >> 8;
}

static int kedsum_callback(r_device *decoder, bitbuffer_t *bitbuffer) {
bitrow_t *bb = bitbuffer->bb;
uint8_t b[5];
data_t *data;

// the signal should start with 15 sync pulses (empty rows)
Expand All @@ -41,44 +63,32 @@ static int kedsum_callback(r_device *decoder, bitbuffer_t *bitbuffer) {
// the signal should have 6 repeats with a sync pulse between
// require at least 4 received repeats
int r = bitbuffer_find_repeated_row(bitbuffer, 4, 42);
if (r<0 || bitbuffer->bits_per_row[r] != 42)
if (r < 0 || bitbuffer->bits_per_row[r] != 42)
return 0;

uint8_t *b = bb[r];

uint8_t humidity;
uint8_t channel;
uint16_t temperature_with_offset;
float temperature_f;

channel = (uint8_t)(((b[1] & 0x0C) >> 2) + 1);
humidity = (uint8_t)((b[3] & 0x03) << 6) | ((b[4] & 0xC0) >> 2) | ((b[3] & 0x3C) >> 2);

uint8_t tnH, tnM, tnL;
tnL = ((b[1] & 0x03) << 2) | ((b[2] & 0xC0) >> 6); // Low temp nibble
tnM = ((b[2] & 0x3C) >> 2); // Med temp nibble
tnH = ((b[2] & 0x03) << 2) | ((b[3] & 0xC0) >> 6); // high temp nibble

temperature_with_offset = (tnH<<8) | (tnM<<4) | tnL;
temperature_f = (temperature_with_offset - 900) / 10.0;

if (decoder->verbose) {
fprintf(stdout, "Bitstream HEX = ");
bitrow_print(b, 48);
fprintf(stdout, "Humidity HEX = %02x\n", b[3]);
fprintf(stdout, "Humidity DEC = %u\n", humidity);
fprintf(stdout, "Channel HEX = %02x\n", b[1]);
fprintf(stdout, "Channel = %u\n", channel);
fprintf(stdout, "temp_with_offset HEX = %02x\n", temperature_with_offset);
fprintf(stdout, "temp_with_offset = %d\n", temperature_with_offset);
fprintf(stdout, "TemperatureF = %.1f\n", temperature_f);
}
// remove the two leading 0-bits and align the data
bitbuffer_extract_bytes(bitbuffer, r, 2, b, 40);
int chk = lfsr4(b, 36, 0x3);
if (chk != (b[4] & 0xf))
return 0;

int id = b[0];
int battery = b[1] >> 6;
int channel = ((b[1] & 0x30) >> 4) + 1;
int humidity = ((b[3] & 0xf0) >> 4) | ((b[3] & 0x0f) << 4);
int temp_raw = ((b[1] & 0x0f) << 0) | ((b[2] & 0xf0) << 0) | ((b[2] & 0x0f) << 8);
float temp_f = (temp_raw - 900) * 0.1;

char *battery_str = battery == 2 ? "OK" : battery == 1 ? "WEAK" : "LOW";

data = data_make(
"model", "", DATA_STRING, "Kedsum Temperature & Humidity Sensor",
"channel", "Channel", DATA_INT, channel,
"temperature_F", "Temperature", DATA_FORMAT, "%.02f F", DATA_DOUBLE, temperature_f,
"humidity", "Humidity", DATA_FORMAT, "%u %%", DATA_INT, humidity,
"model", "", DATA_STRING, "Kedsum-TH",
"id", "ID", DATA_INT, id,
"channel", "Channel", DATA_INT, channel,
"battery", "Battery", DATA_STRING, battery_str,
"temperature_F", "Temperature", DATA_FORMAT, "%.02f F", DATA_DOUBLE, temp_f,
"humidity", "Humidity", DATA_FORMAT, "%u %%", DATA_INT, humidity,
"mic", "Integrity", DATA_STRING, "CRC",
NULL);

decoder_output_data(decoder, data);
Expand All @@ -87,14 +97,17 @@ static int kedsum_callback(r_device *decoder, bitbuffer_t *bitbuffer) {

static char *output_fields[] = {
"model",
"id",
"channel",
"battery",
"temperature_F",
"humidity",
"mic",
NULL
};

r_device kedsum = {
.name = "Kedsum Temperature & Humidity Sensor",
.name = "Kedsum Temperature & Humidity Sensor, Pearl NC-7415",
.modulation = OOK_PULSE_PPM,
.short_width = 2000,
.long_width = 4000,
Expand Down

0 comments on commit af2fd65

Please sign in to comment.