Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CC1101 Parameters issue, receiving all packets only with invalid bandwidth parameter set #1366

Open
jmatilai opened this issue Dec 30, 2024 · 4 comments

Comments

@jmatilai
Copy link

jmatilai commented Dec 30, 2024

Using CC1101_Receive_Interrupt and CC1101_Transmit_Interrupt, any bandwidth setting does not work, except setting unacceptable value such as "100"

EDIT: after some testing other parameter combinations do receive, but lot of packets are lost. Best result I found is with Radiolib defaults and just setting frequency deviation to 25.4 (radio.begin(434, 4.8, 25.4, 135, 10, 16);), which is able to receive maybe 75% of packets:

[CC1101] Data:          Hello World! #48
[CC1101] RSSI:          -38.00 dBm
[CC1101] LQI:           13
[CC1101] Received packet!
[CC1101] Data:          Hello World! #50
[CC1101] RSSI:          -38.00 dBm
[CC1101] LQI:           13
[CC1101] Received packet!
[CC1101] Data:          Hello World! #51
[CC1101] RSSI:          -38.00 dBm
[CC1101] LQI:           13
[CC1101] Received packet!
[CC1101] Data:          Hello World! #53
[CC1101] RSSI:          -38.00 dBm
[CC1101] LQI:           13
[CC1101] Received packet!

I'm unable to get the module receive anything (EDIT: all packets) with the example templates, except one empty ghost message after booting. However by setting "unacceptable" value such as "100" for bandwidth filter value I can get messages sent/received. With 6.6.0. this works, I get -104 [RADIOLIB_ERR_INVALID_RX_BANDWIDTH] error at start, but after this it works fine. With 7.1.1. I get -104 error also from startReveive, which prevents this "workaround". I have tried few acceptable values for bandwidth filter based on datasheet with no avail.

[CC1101] Data:          Hello World! #512
[CC1101] RSSI:          -30.00 dBm
[CC1101] LQI:           6
[CC1101] Received packet!
[CC1101] Data:          Hello World! #513
[CC1101] RSSI:          -30.00 dBm
[CC1101] LQI:           5

I use platformio in VScode with

  • RadioLib 6.6.0,
  • SPI 1.1.0 and
  • Arduino_Core_STM32 seems to be 2.8.1.

I tried also ELECHOUSE based library https://github.com/LSatan/SmartRC-CC1101-Driver-Lib, which works, but the STM32 crashes after sending for a while. I did not investigate that further since I found your library, but now this made me think is there something wrong with my hardware?

_CC1101_Receive_Interrupt_ and _CC1101_Transmit_Interrupt_ code RX END (only modified pins and radio.begin):
/*
  RadioLib CC1101 Receive with Interrupts Example

  This example listens for FSK transmissions and tries to
  receive them. Once a packet is received, an interrupt is
  triggered.

  To successfully receive data, the following settings have to be the same
  on both transmitter and receiver:
  - carrier frequency
  - bit rate
  - frequency deviation
  - sync word

  For default module settings, see the wiki page
  https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101

  For full API reference, see the GitHub Pages
  https://jgromes.github.io/RadioLib/
*/
#include <SPI.h>
#include <Arduino.h>
// include the library
#include <RadioLib.h>

#define CC1101_GDO0 PB0
#define CC1101_CS PA4
#define CC1101_SCK PA5
#define CC1101_MOSI PA7
#define CC1101_MISO PA6
#define CC1101_GDO2 PA3
#define LED_ONBOARD PC13

// CC1101 has the following connections:
// CS pin:    10
// GDO0 pin:  2
// RST pin:   unused
// GDO2 pin:  3
CC1101 radio = new Module(CC1101_CS, CC1101_GDO0, RADIOLIB_NC, CC1101_GDO2);

// or detect the pinout automatically using RadioBoards
// https://github.com/radiolib-org/RadioBoards
/*
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/

// 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 setup() {
  Serial.begin(9600);
    pinMode(LED_ONBOARD, OUTPUT);

  // initialize CC1101 with default settings
  Serial.print(F("[CC1101] Initializing ... "));
  int state = radio.begin(434.0, 4.8, 25.4, 100, 10, 32);
  if (state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    //while (true) { delay(10); }
  }

  // set the function that will be called
  // when new packet is received
  radio.setPacketReceivedAction(setFlag);

  // 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); }
  }

  // if needed, 'listen' mode can be disabled by calling
  // any of the following methods:
  //
  // radio.standby()
  // radio.sleep()
  // radio.transmit();
  // radio.receive();
  // radio.readData();
}

void loop() {
  // check if the flag is set
  if(receivedFlag) {
    // reset flag
    receivedFlag = false;

    // you can read received data as an Arduino String
    String str;
    int state = radio.readData(str);

    // you can also read received data as byte array
    /*
      byte byteArr[8];
      int numBytes = radio.getPacketLength();
      int state = radio.readData(byteArr, numBytes);
    */

    if (state == RADIOLIB_ERR_NONE) {
      // packet was successfully received
      Serial.println(F("[CC1101] Received packet!"));

      // print data of the packet
      Serial.print(F("[CC1101] Data:\t\t"));
      Serial.println(str);

      // print RSSI (Received Signal Strength Indicator)
      // of the last received packet
      Serial.print(F("[CC1101] RSSI:\t\t"));
      Serial.print(radio.getRSSI());
      Serial.println(F(" dBm"));

      // print LQI (Link Quality Indicator)
      // of the last received packet, lower is better
      Serial.print(F("[CC1101] LQI:\t\t"));
      Serial.println(radio.getLQI());

    } else if (state == RADIOLIB_ERR_CRC_MISMATCH) {
      // packet was received, but is malformed
      Serial.println(F("CRC error!"));

    } else {
      // some other error occurred
      Serial.print(F("failed, code "));
      Serial.println(state);

    }

    // put module back to listen mode
    radio.startReceive();
  }

}

TX END (only modified pins, radio.begin and added onboard led to light up on TX):

/*
  RadioLib CC1101 Transmit with Interrupts Example

  This example transmits packets using CC1101 FSK radio module.
  Once a packet is transmitted, an interrupt is triggered.
  Each packet contains up to 64 bytes of data, in the form of:
  - Arduino String
  - null-terminated char array (C-string)
  - arbitrary binary data (byte array)

  For default module settings, see the wiki page
  https://github.com/jgromes/RadioLib/wiki/Default-configuration#cc1101

  For full API reference, see the GitHub Pages
  https://jgromes.github.io/RadioLib/
*/

#include <SPI.h>
#include <Arduino.h>
// include the library
#include <RadioLib.h>

#define CC1101_GDO0 PB0
#define CC1101_CS PA4
#define CC1101_SCK PA5
#define CC1101_MOSI PA7
#define CC1101_MISO PA6
#define CC1101_GDO2 PA3
#define LED_ONBOARD PC13

// CC1101 has the following connections:
// CS pin:    10
// GDO0 pin:  2
// RST pin:   unused
// GDO2 pin:  3
CC1101 radio = new Module(CC1101_CS, CC1101_GDO0, RADIOLIB_NC, CC1101_GDO2);

// or detect the pinout automatically using RadioBoards
// https://github.com/radiolib-org/RadioBoards
/*
#define RADIO_BOARD_AUTO
#include <RadioBoards.h>
Radio radio = new RadioModule();
*/

// save transmission state between loops
int transmissionState = RADIOLIB_ERR_NONE;

// flag to indicate that a packet was sent
volatile bool transmittedFlag = false;

// this function is called when a complete packet
// is transmitted 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 sent a packet, set the flag
  transmittedFlag = true;
}

void setup() {
  Serial.begin(9600);
  pinMode(LED_ONBOARD, OUTPUT);
  digitalWrite(LED_ONBOARD, LOW);

  // initialize CC1101 with default settings
  Serial.print(F("[CC1101] Initializing ... "));
  int state = radio.begin(434.0, 4.8, 25.4, 100, 10, 32);
  if (state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    //while (true) { delay(10); }
  }

  // set the function that will be called
  // when packet transmission is finished
  radio.setPacketSentAction(setFlag);

  // start transmitting the first packet
  Serial.print(F("[CC1101] Sending first packet ... "));

  // you can transmit C-string or Arduino string up to
  // 64 characters long
  transmissionState = radio.startTransmit("Hello World!");

  // you can also transmit byte array up to 64 bytes long
  /*
    byte byteArr[] = {0x01, 0x23, 0x45, 0x56,
                      0x78, 0xAB, 0xCD, 0xEF};
    state = radio.startTransmit(byteArr, 8);
  */
 digitalWrite(LED_ONBOARD, HIGH);
}

// counter to keep track of transmitted packets
int count = 0;

void loop() {
  // check if the previous transmission finished
  if(transmittedFlag) {
    // reset flag
    transmittedFlag = false;
    

    if (transmissionState == RADIOLIB_ERR_NONE) {
      // packet was successfully sent
      Serial.println(F("transmission finished!"));
      digitalWrite(LED_ONBOARD, HIGH);

      // NOTE: when using interrupt-driven transmit method,
      //       it is not possible to automatically measure
      //       transmission data rate using getDataRate()

    } else {
      Serial.print(F("failed, code "));
      Serial.println(transmissionState);

    }

    // clean up after transmission is finished
    // this will ensure transmitter is disabled,
    // RF switch is powered down etc.
    radio.finishTransmit();

    // wait a second before transmitting again
    delay(1000);

    // send another one
    Serial.print(F("[CC1101] Sending another packet ... "));

    // you can transmit C-string or Arduino string up to
    // 64 characters long
    String str = "Hello World! #" + String(count++);
    transmissionState = radio.startTransmit(str);
    digitalWrite(LED_ONBOARD, LOW);

    // you can also transmit byte array up to 64 bytes long
    /*
      byte byteArr[] = {0x01, 0x23, 0x45, 0x67,
                        0x89, 0xAB, 0xCD, 0xEF};
      int state = radio.startTransmit(byteArr, 8);
    */
  }
}

Hardware setup
Both

  • "Bluepill" STM32F103C8T6
  • Unknown brand generic CC1101 module "V2.0 433MHZ" text, blue with 2x4 pin header and SMA antenna connection
  • connections CC1101 - STM32: GDO0 PB0, CS PA4, SCK PA5, MOSI PA7, MISO PA6, GDO2 PA3
  • some SMA antenna with unknown properties
  • Mini560 3.3V step down as supply

Debug mode output

Debug mode output

Additional info (please complete):

@jmatilai jmatilai changed the title CC1101 Parameters issue, receiving packets only with invalid bandwidth parameter set CC1101 Parameters issue, receiving all packets only with invalid bandwidth parameter set Dec 30, 2024
@jmatilai
Copy link
Author

After reading #1261 I tried 5.7.0 and replaced

  //radio.setPacketReceivedAction(setFlag);
  radio.setGdo0Action(setFlag, RISING);

and

  //radio.setPacketSentAction(setFlag);
  radio.setGdo2Action(setFlag,FALLING);

TX seems to work, but RX node seems to get interrupt continuously

CRC error!
[CC1101] Received packet!
[CC1101] Data:          Hllo World! #2
[CC1101] RSSI:          -41.50 dBm
[CC1101] LQI:           49
CRC error!
[CC1101] Received packet!
[CC1101] Data:          Hllo World! #2A▒D▒˞▒
                                            5▒,p▒5i▒▒\▒7▒-▒▒h▒▒(:n▒▒S/▒▒&▒▒R▒s▒]▒BFHllo World! #2A▒D▒˞▒

[CC1101] RSSI:          -47.50 dBm
[CC1101] LQI:           94
CRC error!
CRC error!
[CC1101] Received packet!
[CC1101] Data:          Helo World! #2
[CC1101] RSSI:          -41.50 dBm
[CC1101] LQI:           49

It receives packets however every now and then.

@jgromes
Copy link
Owner

jgromes commented Dec 30, 2024

This is interesting, I guess it is possible we broke the Rx bandwidth configuration at some point. Though quickly checking with ESP32+CC1101, the configuration seems to be correct, at least for the default 58.0 kHz value.

I tried 5.7.0 and replaced

I would suggest sticking to the latest release, or better yet the master, there were quite a few bufixes to CC1101 since 5.7.0. 6.6.0 is also quite outdated.

@jmatilai
Copy link
Author

jmatilai commented Dec 30, 2024

Did some more testing, now with master instead of 6.6.0. I tried doing a ping pong test (A transmitting at interval, B transmitting response to A), packet loss with different bandwidths

  • 58: 100%
  • 102: 100%
  • 135: 33..90%
  • 162: 0..87%
  • 206: >92%
  • 270: 100%

Settings used (only changed BW from these):
radio.begin(434.0, 4.8, 25.4, 135.0, 10, 16);

I have not calibrated the modules or changed anything. But I expected that is not required with low bit rates. Should I do something like that?

@jgromes
Copy link
Owner

jgromes commented Jan 2, 2025

Seems like there's definitely something weird going on. I'll try to get a test setup with transmitter and receiver up and running.

No calibration should be necessary here. The default bitrate is rather slow, the signal is narrow and the receiver bandwidth should be wide enough.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants