Acurite 06045 add docs, refactor decode out of txr_callback

This commit is contained in:
rct 2017-03-19 11:33:43 -04:00 committed by Benjamin Larsson
parent 2e5f2d0afe
commit 2576d17729

View file

@ -328,6 +328,107 @@ static float acurite_6045_getTemp (uint8_t highbyte, uint8_t lowbyte) {
return temp;
}
/*
* Acurite 06045m Lightning Sensor decoding.
*
* Specs:
* - lightning strike count
* - extimated distance to front of storm, up to 25 miles / 40 km
* - Temperature -40 to 158 F / -40 to 70 C
* - Humidity 1 - 99% RH
*
* Status Information sent per 06047M/01021 display
* - (RF) interference (preventing lightning detection)
* - low battery
*
*
* Message format
* --------------
* Somewhat similar to 592TXR and 5-n-1 weather stations
* Same pulse characteristics. checksum, and parity checking on data bytes.
*
* 0 1 2 3 4 5 6 7 8
* CI? II II HH ST TT LL DD? KK
*
* C = Channel
* I = ID
* H = Humidity
* S = Status/Message type/Temperature MSB.
* T = Temperature
* D = Lightning distanace and status bits?
* L = Lightning strike count.
* K = Checksum
*
* Byte 0 - channel number A/B/C
* - Channel in 2 most significant bits - A: 0xC, B: 0x8, C: 00
* - TBD: lower 6 bits, ID or unused?
*
* Bytes 1 & 2 - ID, all 8 bits, no parity.
*
* Byte 3 - Humidity (7 bits + parity bit)
*
* Byte 4 - Status (2 bits) and Temperature MSB (5 bits)
* - Bitmask PSSTTTTT (P = Parity, S = Status, T = Temperature)
* - 0x40 - Transmitting every 8 seconds (lightning possibly detected)
* normal, off, transmits every 24 seconds
* - 0x20 - TBD: normally off, On is possibly low battery?
* - 0x1F - Temperature MSB (5 bits)
*
* Byte 5 - Temperature LSB (7 bits, 8th is parity)
*
* Byte 6 - Lightning Strike count (7 bits, 8th is parity)
* - Stored in EEPROM or something non-volatile)
* - Wraps at 127
*
* Byte 7 - Lightning Distance (5 bits) and status bits (2 bits) (?)
* - Bits PSSDDDDD (P = Parity, S = Status, D = Distance
* - 5 lower bits is distance in unit? (miles? km?) to edge of storm (theory)
* - Bit 0x20: (RF) interference / strong RFI detected (to be verified)
* - Bit 0x40: TBD, possible activity?
* - distance = 0x1f: possible invalid value indication (value at power up)
* - Note: Distance sometimes goes to 0 right after strike counter increment
* status bits might indicate validifity of distance.
*
* Byte 8 - checksum. 8 bits, no parity.
*
* @todo - Get lightning/distance to front of storm to match display
* @todo - Low battery, figure out encoding
* @todo - figure out remaining status bits and how to report
* @todo - convert to data make once decoding is stable
*/
static int acurite_6045_decode (bitrow_t bb, int browlen) {
int valid = 0;
float tempf;
uint8_t humidity, message_type, l_status;
char channel, *wind_dirstr = "";
char channel_str[2];
uint16_t sensor_id;
uint8_t strike_count, strike_distance;
channel = acurite_getChannel(bb[0]); // same as TXR
sensor_id = (bb[1] << 8) | bb[2]; // TBD 16 bits or 20?
humidity = acurite_getHumidity(bb[3]); // same as TXR
message_type = (bb[4] & 0x60) >> 5; // status bits: 0x2 8 second xmit, 0x1 - TBD batttery?
tempf = acurite_6045_getTemp(bb[4], bb[5]);
strike_count = bb[6] & 0x7f;
strike_distance = bb[7] & 0x1f;
l_status = (bb[7] & 0x60) >> 5;
printf("%s Acurite lightning 0x%04X Ch %c Msg Type 0x%02x: %.1f F %d %% RH Strikes %d Distance %d L_status 0x%02x -",
time_str, sensor_id, channel, message_type, tempf, humidity, strike_count, strike_distance, l_status);
// FIXME Temporarily dump raw message data until the
// decoding improves. Includes parity indicator(*).
for (int i=0; i < browlen; i++) {
char pc;
pc = byteParity(bb[i]) == 0 ? ' ' : '*';
fprintf(stdout, " %02x%c", bb[i], pc);
}
printf("\n");
valid++;
return(valid);
}
/*
@ -408,7 +509,7 @@ static int acurite_txr_callback(bitbuffer_t *bitbuf) {
tempc = acurite_txr_getTemp(bb[4], bb[5]);
sprintf(channel_str, "%c", channel);
battery_low = sensor_status >>7;
data = data_make(
"time", "", DATA_STRING, time_str,
"model", "", DATA_STRING, "Acurite tower sensor",
@ -507,27 +608,8 @@ static int acurite_txr_callback(bitbuffer_t *bitbuf) {
}
if (browlen == ACURITE_6045_BITLEN / 8) {
channel = acurite_getChannel(bb[0]); // same as TXR
sensor_id = (bb[1] << 8) | bb[2]; // TBD 16 bits or 20?
humidity = acurite_getHumidity(bb[3]); // same as TXR
message_type = (bb[4] & 0x60) >> 5; // status bits: 0x2 8 second xmit, 0x1 - TBD batttery?
tempf = acurite_6045_getTemp(bb[4], bb[5]);
strike_count = bb[6] & 0x7f;
strike_distance = bb[7] & 0x1f;
l_status = (bb[7] & 0x60) >> 5;
printf("%s Acurite lightning 0x%04X Ch %c Msg Type 0x%02x: %.1f F %d %% RH Strikes %d Distance %d L_status 0x%02x -",
time_str, sensor_id, channel, message_type, tempf, humidity, strike_count, strike_distance, l_status);
// FIXME Temporarily dump raw message data until the
// decoding improves. Includes parity indicator(*).
for (int i=0; i < browlen; i++) {
char pc;
pc = byteParity(bb[i]) == 0 ? ' ' : '*';
fprintf(stdout, " %02x%c", bb[i], pc);
}
printf("\n");
// @todo check parity and reject if invalid
valid += acurite_6045_decode(bb, browlen);
}
}