Acurite 3N1

Has anyone had any luck in decoding Acurite 3N1 / 5N1 devices via Weather Station?

Since rtl_433 can already decode these I’m thinking this would be simple to add.

1 Like

Look in Applications/tools/Weather app. I think it might already be on the Flipper. It works but I don’t think the range is great.

That is where I have been trying. The protocol is not yet implemented.

From rtl_433/acurite.c at master · merbanan/rtl_433 · GitHub

The following needs to be ported?

/**
Acurite 3n1 Weather Station decoder
*/
static int acurite_3n1_decode(r_device *decoder, bitbuffer_t *bitbuffer, uint8_t *bb)
{
// MIC (checkum, parity) validated in calling function
(void)bitbuffer;

char const* channel_str = acurite_getChannel(bb[0]);

// 3n1 sensor ID is 14 bits
uint16_t sensor_id = ((bb[0] & 0x3f) << 8) | bb[1];
uint8_t message_type = bb[2] & 0x3f;

if (*channel_str == 'E') {
    decoder_logf(decoder, 1, __func__,
                 "bad channel Ch %s, msg type 0x%02x",
                 channel_str, message_type);
    return DECODE_FAIL_SANITY;
}

/*
  @todo bug, 3n1 data format includes sequence_num
  which was copied from 5n1, but existing code 3n1 uses
  14 bits for ID. so these bits are used twice.
  Leaving for compatibility, but probaby sequence_num
  doesn't exist and should be deleted. If the 3n1 did use
  a sequence number, the ID would change on each output.
*/
uint8_t sequence_num = (bb[0] & 0x30) >> 4;

int battery_low = (bb[2] & 0x40) == 0;
uint8_t humidity = (bb[3] & 0x7f); // 1-99 %rH
if (humidity > 100) {
    decoder_logf(decoder, 1, __func__, "3n1 0x%04X Ch %s : invalid humidity: %d %%rH",
                 sensor_id, channel_str, humidity);
    return DECODE_FAIL_SANITY;
}

// note the 3n1 seems to have one more high bit than 5n1
// Spec: -40 to 158 F
int temp_raw = (bb[4] & 0x1F) << 7 | (bb[5] & 0x7F);
float tempf        = (temp_raw - 1480) * 0.1f; // regression yields (rawtemp-1480)*0.1

if (tempf < -40.0 || tempf > 158.0) {
    decoder_logf(decoder, 1, __func__, "3n1 0x%04X Ch %s, invalid temperature: %0.1f F",
                 sensor_id, channel_str, tempf);
    return DECODE_FAIL_SANITY;
}


/*
  @todo bug from original decoder
  This can't be a float, must be uint8
  leaving for compatibility
*/
float wind_speed_mph = bb[6] & 0x7f; // seems to be plain MPH

/* clang-format off */
data_t *data;
data = data_make(
        "model",        "",   DATA_STRING,    "Acurite-3n1",
        "message_type", NULL,   DATA_INT,       message_type,
        "id",    NULL,   DATA_FORMAT,    "0x%02X",   DATA_INT,       sensor_id,
        "channel",      NULL,   DATA_STRING,    channel_str,
        "sequence_num",  NULL,   DATA_INT,      sequence_num,
        "battery_ok",       "Battery",      DATA_INT,    !battery_low,
        "wind_avg_mi_h",   "wind_speed",   DATA_FORMAT,    "%.1f mi/h", DATA_DOUBLE,     wind_speed_mph,
        "temperature_F",     "temperature",    DATA_FORMAT,    "%.1f F", DATA_DOUBLE,    tempf,
        "humidity",     NULL,    DATA_FORMAT,    "%u %%",   DATA_INT,   humidity,
        "mic",                  "Integrity",    DATA_STRING, "CHECKSUM",
        NULL);
/* clang-format on */

decoder_output_data(decoder, data);

return 1; // If we got here 1 valid message was output

}

1 Like

It works fine on the stand alone Acurite temperature sensors I have but I don’t have the 3in1. It doesn’t seem to work with Ecowhitt sensors yet either. It would be cool if we could get more of the RTL_433 stuff added.

Just looking at the two repositories. I wonder if the whole thing wasn’t implemented due to resources. The corresponding file in the weather station .fap is much smaller. I might try to write one myself and see what happens. My C is very rusty though.

EDIT: Since I don’t have that sensor to test I won’t be trying to implement the 3 in 1. Maybe if I have luck with a different protocol I’ll try it at a later time.

I can provide you with a RAW .sub
Acurite3N1_82F.sub (2.6 KB)

1 Like

I have a lot to figure out before I get anywhere with this so don’t get your hopes up on me personally adding anything useful any time soon. I haven’t touched C in a very long time and when I did it was Objective C which is a bit different then what the Flipper uses.