Good day.
I have been working on a project for a long time on esp32s3+cc1101 for decoding readings from BMW motorcycle pressure sensors.
I managed to get the required values using rtl_433, but I can't do the same using esp32+cc1101, I only get garbage at the receiver output.
Most likely, I didn't select the reception parameters correctly, but trying out setBitRate, setFrequencyDeviation and setRxBandwidth didn't give any result.
I ask the community for help, because my programming level and knowledge are not high enough for this.
An example of receiving data using rtl_433:
time : 2025-09-01 10:53:09
model : BMW count : 1 num_rows : 1 rows :
len : 45 data : 058639002248 id : 2c31c8
Pressure : 4 Temp_F : 73 F
codes : {45}058639002248
The latest code for Arduino (Platformio):
/*
rtl_433 -X 'name=BMW,m=OOK_MC_ZEROBIT,s=122,l=122,r=300,preamble=7fff,get=id:@3:{24}:%x,get=pressure:@27:{9}:%d,get=temp:@36:{9}:%d' -f 433.92M
-f 433.92M - received frequency
name=BMW
m=OOK_MC_ZEROBIT - On-Off Keying with Manchester Code and a fixed leading zero bit.
s=122 - The expected duration of a "short" pulse or half-bit width in microseconds (µs).
l=122 - The expected duration of a "long" pulse or full-bit width in microseconds (µs
r=300 - The expected duration of a reset gap in microseconds (µs)
preamble=7fff
*/
#include <Arduino.h>
#include <RadioLib.h>
#include <SPI.h>
// https://github.com/jgromes/RadioLib/wiki/Debug-mode
//#define RADIOLIB_DEBUG_BASIC (1) // basic debugging (e.g. reporting GPIO timeouts or module not being found)
// #define RADIOLIB_DEBUG_PROTOCOL (1) // protocol information (e.g. LoRaWAN internal information)
// #define RADIOLIB_DEBUG_SPI (1) // verbose transcription of all SPI communication - produces large debug logs!
// https://github.com/jgromes/RadioLib/blob/master/examples/CC1101/CC1101_Receive_Interrupt/CC1101_Receive_Interrupt.ino
/*
esp32s3 super mini cc0111 connection spi pin
SCK - 4
MISO - 5
MOSI - 6
SS - 7
SCL/CSN -9
*/
#define CC1101_MISO 5
#define CC1101_MOSI 6
#define CC1101_SCKL 4
#define CC1101_CS 9
#define CC1101_GDO0 7
#define CC1101_GDO2 10
SPIClass newSPI(HSPI);
CC1101 radio = new Module(CC1101_CS, CC1101_GDO0, RADIOLIB_NC, CC1101_GDO2, newSPI);
// CC1101 radio = new Module(CC1101_CS, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC, newSPI);
// flag to indicate that a packet was received
volatile bool receivedFlag = false;
// this function is called when a complete packet
// is received by the module
// IMPORTANT: this function MUST be 'void' type
// and MUST NOT have any arguments!
#if defined(ESP8266) || defined(ESP32)
ICACHE_RAM_ATTR
#endif
void setFlag(void) {
// we got a packet, set the flag
receivedFlag = true;
}
void printhex(int h) {
if (h<16) {
Serial.print("0");
}
Serial.print(h,HEX);
}
byte mc_Arr[255]; // array for Manchester bytes
// https://github.com/cterwilliger/tst_tpms/blob/main/examples/CC1101_tpms_recv_example.ino#L216
/*
* decodeManI
* ----------
* Manchester I (IEEE 802.3) bitstream decoder
* Manchester encoded bit stream uses 2 bits to represent 1 bit of data. Manchester I encodes a "1" as a transition
* from low to high and "0" as a transition from high to low. Each byte decodes to 1 nibble.
*/
void decodeManI(byte *array, int size)
{
// array of all possible Manchester I values
byte manIarray[16] = {0xAA, 0xA9, 0xA6, 0xA5, 0x9A, 0x99, 0x96, 0x95, 0x6A, 0x69, 0x66, 0x65, 0x5A, 0x59, 0x56, 0x55};
int k = 0;
// convert each Manchester I byte to it's NRZ equivalent
for ( int i = 0; i < size; i=i+2 ) // look at every 2 bytes in the payload
{
for ( int j = 0; j < 16; j++ )
{
if ( array[i] == manIarray[j] ) // search for ManI pattern
{
array[k] = j << 4; // shift left one nibble, put back into passed array
}
}
for ( int j = 0; j < 16; j++ )
{
if ( array[i+1] == manIarray[j] )
{
array[k] = array[k] | j; // combine previous nibble with this one
}
}
k++;
}
} // end decodeManI
void setup()
{
delay(6000);
Serial.begin(115200);
Serial.setDebugOutput(true);
delay(1000);
Serial.println(F("Starting... "));
delay(1000);
Serial.print(F("[CC1101] Initializing ... "));
//spi.begin();
newSPI.begin(CC1101_SCKL, CC1101_MISO, CC1101_MOSI, CC1101_CS);
// int state = radio.begin(433.92);
int state = radio.begin();
if (state == RADIOLIB_ERR_NONE)
{
Serial.println(F("success!"));
Serial.print(F("[CC1101] Partnumber ")); Serial.println(radio.SPIgetRegValue(0x30), HEX);
Serial.print(F("[CC1101] Version ")); Serial.println(radio.getChipVersion(), HEX);
}
else
{
Serial.print(F("failed: code "));
Serial.println(state);
// while (true);
}
float frequency = 433.92;
// float frequency = 433.919830;
if (radio.setFrequency(frequency) == RADIOLIB_ERR_INVALID_FREQUENCY) {
Serial.println(F("[CC1101] Selected frequency is invalid for this module!"));
while (true);
} else {
Serial.print(F("[CC1101] setFrequency [MHz] ")); Serial.println(frequency);
}
// float bitrate = 19.2; // 19200 baud
float bitrate = 9.6; // 9600 baud
state = radio.setBitRate(bitrate);
if (state == RADIOLIB_ERR_INVALID_BIT_RATE) {
Serial.println(F("[CC1101] Selected bit rate is invalid for this module!"));
while (true);
} else if (state == RADIOLIB_ERR_INVALID_BIT_RATE_BW_RATIO) {
Serial.println(F("[CC1101] Selected bit rate to bandwidth ratio is invalid!"));
Serial.println(F("[CC1101] Increase receiver bandwidth to set this bit rate."));
while (true);
} else {
Serial.print(F("[CC1101] setBitRate [kbps] ")); Serial.println(bitrate);
}
// float bandwidth = 135.0;
// if (radio.setRxBandwidth(bandwidth) == RADIOLIB_ERR_INVALID_RX_BANDWIDTH) {
// Serial.println(F("[CC1101] Selected receiver bandwidth is invalid for this module!"));
// while (true);
// } else {
// Serial.print(F("[CC1101] setBandwidth [kHz] ")); Serial.println(bandwidth);
// }
radio.autoSetRxBandwidth();
byte syncHigh = 0x7F; byte syncLow = 0xFF;
radio.SPIwriteRegister(0x04, syncHigh); Serial.print(F("[CC1101] Reg0x04 SetSyncHigh ")); Serial.println(syncHigh);
radio.SPIwriteRegister(0x05, syncLow); Serial.println(F("[CC1101] Reg0x05 SetSyncLow ")); Serial.println(syncLow);
radio.setEncoding(RADIOLIB_ENCODING_MANCHESTER); // for transmitt encodeind
// set the function that will be called
// when new packet is received
radio.setGdo0Action(setFlag, CHANGE);
// set the function that will be called
// when new packet is received
radio.setPacketReceivedAction(setFlag);
// test cc1101 spi work
radio.SPIwriteRegister(0, 0x29);
delay(500);
if (radio.SPIreadRegister(0) == 0x29)
{
Serial.println(F("CC1101 reset successful"));
}else{
Serial.println(F("CC1101 reset failed. Try rebooting"));
}
radio.setOOK(true); // OOK is on
radio.setFrequency(433.92);
radio.setBitRate(9.6);
radio.setFrequencyDeviation(50);
radio.setRxBandwidth(125);
radio.setCrcFiltering(false);
//radio.setSyncWord(0x7F, 0xFF, 1, true);
//radio.fixedPacketLengthMode(16);
radio.disableAddressFiltering();
radio.disableSyncWordFiltering();
// start listening for packets
Serial.print(F("[CC1101] Starting to listen ... "));
state = radio.startReceive();
if (state == RADIOLIB_ERR_NONE) {
Serial.println(F("success!"));
} else {
Serial.print(F("failed, code "));
Serial.println(state);
while (true) { delay(10); }
}
Serial.println(F("Started!"));
delay(5000);
}
void loop (void)
{
delay(1);
// check if the flag is set
if(receivedFlag) {
bool print_debug=1;
bool find_pre=0;
// you can also read received data as byte array
int len = radio.getPacketLength();
byte byteArr[len+1];
int state = radio.readData(byteArr, len);
if (print_debug==1){
memset(mc_Arr,'\0',sizeof(mc_Arr)); //обнуляем все данные внутри структуры
memcpy(mc_Arr, byteArr, len); // переносим данные в буфер для отправки
// decode manchester I
decodeManI(mc_Arr, 16);
Serial.print(len); Serial.print("; ");
Serial.print(radio.getRSSI());
Serial.print("; ");
Serial.print(radio.getLQI());
Serial.print("; ");
// print data of the packet
for (int i=0; i<len; i++) {
printhex(byteArr[i]);
}
Serial.println();
Serial.print("MC: ");
// print data of the MC packet
for (int i=0; i<len; i++) {
printhex(mc_Arr[i]);
}
Serial.println();
}
// BMW tpms preamble
if (byteArr[0]==0x7F && byteArr[1]==0xFF ){
// https://github.com/merbanan/rtl_433/blob/master/src/devices/tpms_bmw_g3.c
Serial.println("BMW header finded !");
find_pre=1;
}
for (int i=0; i<len; i++) {
if (byteArr[i]==0x7F && byteArr[i+1]==0xFF){
Serial.println("FINDED !!!");
find_pre=1;
}
}
if (find_pre==1){
Serial.print(len); Serial.print("; ");
Serial.print(radio.getRSSI());
Serial.print("; ");
Serial.print(radio.getLQI());
Serial.print("; ");
// print data of the packet
for (int i=0; i<len; i++) {
printhex(byteArr[i]);
}
Serial.println();
}
find_pre=0;
// put module back to listen mode
radio.startReceive();
// reset flag
receivedFlag = false;
}
}
Data output when receiving readings from the sensor:
Starting...
[CC1101] Initializing ... success!
[CC1101] Partnumber 0
[CC1101] Version 14
[CC1101] setFrequency [MHz] 433.92
[CC1101] setBitRate [kbps] 9.60
[CC1101] Reg0x04 SetSyncHigh 127
[CC1101] Reg0x05 SetSyncLow
255
CC1101 reset successful
[CC1101] Starting to listen ... success!
Started!
152; -135.00; 6; 001F9F9E1F99FFFE67F99F9FF87FE7867E78667E01861F86061F8666187F99E19E1866067FFE1F99879E61F807F99E0660181E0601E7E7E61E7F9E1FFF9F818181001F9F9E1F99FFFE67F99F9FF87FE7867E78667E01861F86061F8666187F99E19E1866067FFE1F99879E61F807F99E0660181E0601E7E7E61E7F9E1FFF9F8181001F9F9E1F99FFFE67F99F9FF87FE7867E78667E01861F
MC: 001F9F9E1F99FFFE67F99F9FF87FE7867E78667E01861F86061F8666187F99E19E1866067FFE1F99879E61F807F99E0660181E0601E7E7E61E7F9E1FFF9F818181001F9F9E1F99FFFE67F99F9FF87FE7867E78667E01861F86061F8666187F99E19E1866067FFE1F99879E61F807F99E0660181E0601E7E7E61E7F9E1FFF9F8181001F9F9E1F99FFFE67F99F9FF87FE7867E78667E01861F
102; -73.50; 31; 67F879FE607E01F9980181FE7E6799F8618001F879E7E1FE67E7FE0619FE079819FE799806019FE7878607879E1800AE43DA0FE8493FFF9E7FFFFE18679FF8F88167F879FE607E01F9980181FE7E6799F8618001F879E7E1FE67E7FE0619FE079819FE799806
MC: 67F879FE607E0150980181FE7E6799F8618001F879E7E1FE67E7FE0619FE079819FE799806019FE7878607879E1800AE43DA0FE8493FFF9E7FFFFE18679FF8F88167F879FE607E01F9980181FE7E6799F8618001F879E7E1FE67E7FE0619FE079819FE799806
FINDED !!!
102; -73.50; 31; 67F879FE607E01F9980181FE7E6799F8618001F879E7E1FE67E7FE0619FE079819FE799806019FE7878607879E1800AE43DA0FE8493FFF9E7FFFFE18679FF8F88167F879FE607E01F9980181FE7E6799F8618001F879E7E1FE67E7FE0619FE079819FE799806
Good day.
I have been working on a project for a long time on esp32s3+cc1101 for decoding readings from BMW motorcycle pressure sensors.
I managed to get the required values using rtl_433, but I can't do the same using esp32+cc1101, I only get garbage at the receiver output.
Most likely, I didn't select the reception parameters correctly, but trying out setBitRate, setFrequencyDeviation and setRxBandwidth didn't give any result.
I ask the community for help, because my programming level and knowledge are not high enough for this.
An example of receiving data using rtl_433:
time : 2025-09-01 10:53:09
model : BMW count : 1 num_rows : 1 rows :
len : 45 data : 058639002248 id : 2c31c8
Pressure : 4 Temp_F : 73 F
codes : {45}058639002248
The latest code for Arduino (Platformio):
Data output when receiving readings from the sensor: