diff --git a/README.md b/README.md
index 95888078..cdcace55 100644
--- a/README.md
+++ b/README.md
@@ -77,7 +77,7 @@ See [CONTRIBUTING.md](./docs/CONTRIBUTING.md).
   [-F kv | json | csv | mqtt | influx | syslog | trigger | null | help] Produce decoded output in given format.
        Append output to file with :<filename> (e.g. -F csv:log.csv), defaults to stdout.
        Specify host/port for syslog with e.g. -F syslog:127.0.0.1:1514
-  [-M time[:<options>] | protocol | level | noise[:secs] | stats | bits | help] Add various meta data to each output.
+  [-M time[:<options>] | protocol | level | noise[:<secs>] | stats | bits | help] Add various meta data to each output.
   [-K FILE | PATH | <tag> | <key>=<tag>] Add an expanded token or fixed tag to every output line.
   [-C native | si | customary] Convert units in decoded output.
   [-n <value>] Specify number of samples to take (each sample is an I/Q pair)
@@ -302,6 +302,7 @@ See [CONTRIBUTING.md](./docs/CONTRIBUTING.md).
     [217]  EMOS E6016 rain gauge
     [218]  Microchip HCS200/HCS300 KeeLoq Hopping Encoder based remotes (FSK)
     [219]  Fine Offset Electronics WH45 air quality sensor
+    [220]  Maverick XR-30 BBQ Sensor
 
 * Disabled by default, use -R n or a conf file to enable
 
@@ -421,7 +422,7 @@ E.g. -X "n=doorbell,m=OOK_PWM,s=400,l=800,r=7000,g=1000,match={24}0xa9878c,repea
 	Use "replay[:N]" to replay file inputs at (N-times) realtime.
 	Use "protocol" / "noprotocol" to output the decoder protocol number meta data.
 	Use "level" to add Modulation, Frequency, RSSI, SNR, and Noise meta data.
-	Use "noise[:secs]" to report estimated noise level at intervals (default: 10 seconds).
+	Use "noise[:<secs>]" to report estimated noise level at intervals (default: 10 seconds).
 	Use "stats[:[<level>][:<interval>]]" to report statistics (default: 600 seconds).
 	  level 0: no report, 1: report successful devices, 2: report active devices, 3: report all
 	Use "bits" to add bit representation to code outputs (for debug).
diff --git a/conf/rtl_433.example.conf b/conf/rtl_433.example.conf
index aa7e2926..98b624a9 100644
--- a/conf/rtl_433.example.conf
+++ b/conf/rtl_433.example.conf
@@ -441,6 +441,7 @@ stop_after_successful_events false
   protocol 217 # EMOS E6016 rain gauge
   protocol 218 # Microchip HCS200/HCS300 KeeLoq Hopping Encoder based remotes (FSK)
   protocol 219 # Fine Offset Electronics WH45 air quality sensor
+  protocol 220 # Maverick XR-30 BBQ Sensor
 
 ## Flex devices (command line option "-X")
 
diff --git a/include/rtl_433_devices.h b/include/rtl_433_devices.h
index 94d95a4e..99f6ba9c 100644
--- a/include/rtl_433_devices.h
+++ b/include/rtl_433_devices.h
@@ -227,6 +227,7 @@
     DECL(emos_e6016_rain) \
     DECL(hcs200_fsk) \
     DECL(fineoffset_wh45) \
+    DECL(maverick_xr30) \
 
     /* Add new decoders here. */
 
diff --git a/man/man1/rtl_433.1 b/man/man1/rtl_433.1
index 708c94c8..a0c0552d 100644
--- a/man/man1/rtl_433.1
+++ b/man/man1/rtl_433.1
@@ -129,7 +129,7 @@ Produce decoded output in given format.
        Append output to file with :<filename> (e.g. \-F csv:log.csv), defaults to stdout.
        Specify host/port for syslog with e.g. \-F syslog:127.0.0.1:1514
 .TP
-[ \fB\-M\fI time[:<options>] | protocol | level | noise[:secs] | stats | bits | help\fP ]
+[ \fB\-M\fI time[:<options>] | protocol | level | noise[:<secs>] | stats | bits | help\fP ]
 Add various meta data to each output.
 .TP
 [ \fB\-K\fI FILE | PATH | <tag> | <key>=<tag>\fP ]
@@ -412,7 +412,7 @@ Use "protocol" / "noprotocol" to output the decoder protocol number meta data.
 Use "level" to add Modulation, Frequency, RSSI, SNR, and Noise meta data.
 .RE
 .RS
-Use "noise[:secs]" to report estimated noise level at intervals (default: 10 seconds).
+Use "noise[:<secs>]" to report estimated noise level at intervals (default: 10 seconds).
 .RE
 .RS
 Use "stats[:[<level>][:<interval>]]" to report statistics (default: 600 seconds).
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 831a58cc..fda252b3 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -152,6 +152,7 @@ add_library(r_433 STATIC
     devices/marlec_solar.c
     devices/maverick_et73.c
     devices/maverick_et73x.c
+    devices/maverick_xr30.c
     devices/mebus.c
     devices/megacode.c
     devices/missil_ml0757.c
diff --git a/src/devices/maverick_xr30.c b/src/devices/maverick_xr30.c
new file mode 100644
index 00000000..929ff0d6
--- /dev/null
+++ b/src/devices/maverick_xr30.c
@@ -0,0 +1,114 @@
+/** @file
+    Maverick XR-30 BBQ Sensor.
+
+    Copyright (C) 2022 jbfunk
+    Heavily derived from Maverick ET-73x BBQ Sensor (maverick_et73x.c), Copyright (C) 2016 gismo2004
+
+    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.
+*/
+
+/**
+Maverick XR-30 BBQ Sensor.
+
+The thermometer transmits 4 identical messages every 12 seconds at 433.92 MHz,
+
+Each message consists of 26 nibbles (104 bits total) but the first (non-data) bit (1) is getting dropped sometimes in reception, so for analysis the payload is shifted 7 bits left to align the bytes (or 8 bits if 0xaa is observed rather than 0x55 as the first byte received)
+
+Payload:
+
+- P = 32 bit preamble (0xaaaaaaaa; 7 or 8 bits shifted left for analysis)
+- S = 32 bit sync-word (0xd391d391)
+- F =  4 bit device state (0=default; 5=init)
+- T = 10 bit temp1 (degree C, offset by 532)
+- t = 10 bit temp2 (degree C, offset by 532)
+- D = 16 bit digest (over FTt, includes non-transmitted device id renewed on a device reset) gen 0x8810 init 0x0d42
+
+    byte (after shift):       0   1   2   3   4   5     6     7     8     9     10    11
+    nibble (after shift):     0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+    msg:                  P P P P P P P P S S S S S  S  S  S  F  T  T  Tt t  t  D  D  D  D
+    PRE:32h SYNC: 32h FLAG:4h T:10d t:10d | DIGEST:16h
+
+*/
+
+#include "decoder.h"
+
+static int maverick_xr30_callback(r_device *decoder, bitbuffer_t *bitbuffer)
+{
+    data_t *data;
+
+    if (bitbuffer->num_rows != 1)
+        return DECODE_ABORT_EARLY;
+
+    //check correct data length
+    if (bitbuffer->bits_per_row[0] != 104) // 104 bits
+        return DECODE_ABORT_LENGTH;
+
+    uint8_t b[12];
+    //check for correct preamble/sync (0xaaaaaad391d391)
+    if (bitbuffer->bb[0][0] == 0x55) {
+        bitbuffer_extract_bytes(bitbuffer, 0, 7, b, 12 * 8); // shift in case first bit was not received properly
+    } else if (bitbuffer->bb[0][0] == 0xaa) {
+        bitbuffer_extract_bytes(bitbuffer, 0, 8, b, 12 * 8); // shift in case first bit was received properly
+    } else {
+        return DECODE_ABORT_EARLY; // preamble/sync missing
+    }
+    if (b[0] != 0xaa || b[1] != 0xaa || b[2] != 0xaa || b[3] != 0xd3 || b[4] != 0x91 || b[5] != 0xd3 || b[6] != 0x91)
+        return DECODE_ABORT_EARLY; // preamble/sync missing
+
+    int sync   = b[3] << 24 | b[4] << 16 | b[5] << 8 | b[6];
+    int flags  = (b[7] & 0xf0) >> 4;
+    int temp1  = (b[7] & 0x0f) << 6 | (b[8] & 0xfc) >> 2;
+    int temp2  = (b[8] & 0x03) << 8 | b[9];
+    int digest = b[10] << 8 | b[11];
+
+    float temp1_c = temp1 - 532.0f;
+    float temp2_c = temp2 - 532.0f;
+
+    char *status = "unknown";
+    if (flags == 0)
+        status = "default";
+    else if (flags == 5)
+        status = "init";
+
+    //digest is used to represent a session. This means, we get a new id if a reset or battery exchange is done.
+    int id = lfsr_digest16(&b[7], 3, 0x8810, 0x0d42) ^ digest;
+
+    decoder_logf(decoder, 1, __func__, "sync %08x, flags %0x, t1 %d, t2 %d, digest %04x, chk_data %02x%02x%02x, digest xor'ed: %04x",
+                sync, flags, temp1, temp2, digest, b[7], b[8], b[9], id);
+
+    /* clang-format off */
+    data = data_make(
+            "model",            "",                     DATA_STRING, "Maverick-XR30",
+            "id",               "Session_ID",           DATA_INT,    id,
+            "status",           "Status",               DATA_STRING, status,
+            "temperature_1_C",  "TemperatureSensor1",   DATA_FORMAT, "%.02f C", DATA_DOUBLE, temp1_c,
+            "temperature_2_C",  "TemperatureSensor2",   DATA_FORMAT, "%.02f C", DATA_DOUBLE, temp2_c,
+            NULL);
+    /* clang-format on */
+
+    decoder_output_data(decoder, data);
+    return 1;
+}
+
+static char *output_fields[] = {
+        "model",
+        "id",
+        "status",
+        "temperature_1_C",
+        "temperature_2_C",
+        "mic",
+        NULL,
+};
+
+r_device maverick_xr30 = {
+        .name        = "Maverick XR-30 BBQ Sensor",
+        .modulation  = FSK_PULSE_PCM,
+        .short_width = 360,
+        .long_width  = 360,
+        .reset_limit = 4096,
+        .decode_fn   = &maverick_xr30_callback,
+        .fields      = output_fields,
+};