LSatan / SmartRC-CC1101-Driver-Lib

This driver library can be used for many libraries that use a simple RF ASK module, with the advantages of the cc1101 module. It offers many direct setting options as in SmartRF Studio and calculates settings such as MHz directly.
Other
440 stars 98 forks source link

2.5.1 update still freezes when switching from Rx to Tx Mode #49

Open gitterman opened 4 years ago

gitterman commented 4 years ago

I ran into the receive/sent freeze and found that it should be fixed in rev. 2.5.1 I have the 2.5.1 installed but it still hangs when I switch from Rx to Tx Mode I had a running receiver and added the following lines: ELECHOUSE_cc1101.SetTx() ; delay( 1000 ) ; Serial.println( "sending 'OK'" ) ; ELECHOUSE_cc1101.SendData( (char*) "OK" ) ; Serial.println( "sent 'OK'" ) ;

I see the output "sending 'OK'" but never the "sent 'OK'"

LSatan commented 4 years ago

Hello, The change from rx to tx works without problems with the library and has been extensively tested. if there are problems it is mostly because the microcontroller cannot read the gdo0 pin. So check the following things:

  1. is gdo0 wired correctly and was not mistakenly mistaken for gdo2.
  2. the " ELECHOUSE_cc1101.setGDO(gdo0,0); " function is included in the setup and the correct pin is set.
  3. I noticed that you put "settx" in front of "send". Under no circumstances should this be done with the internal transmission functions. settx is set automatically with send. therefore ELECHOUSE_cc1101.SendData( "OK" ) ; is completely sufficient. Please give feedback whether you were able to solve the problem or whether the error persists.

addendum: in order to receive again, however, setrx must be set.

Regards

gitterman commented 4 years ago

Thanks for getting back to me. I am using the examples "cc1101_New_Receive_method_advanced" and "cc1101_Transmitt_Hello_World_advanced" which I modified for my tests as attached. The cc1101 modules are the same hardware for send and receive. I exchanged them and both work as sender as well as receiver with the example sketch. Then I added code to the receive loop to send back an OK to acknowledge the reception. With this, the code hangs at the following output:

Rx Mode
Rssi: -18 dBm
Link Quality Indicator (LQI) = 129
DOWN = 0x44,0x4f,0x57,0x4e
sending 'OK'

Regards

cc1101.zip

gitterman commented 4 years ago

BTW> Is there an example sketch which shows how to send an acknowledgement after a successful receive? I know that sophisticated home automation systems implement this to make control more robust. All the examples I found only use uni-directional transmission.

LSatan commented 4 years ago

sorry I didn't get around to testing your sketch yesterday. i will do it this afternoon. but the two-way communication works. look here: https://github.com/LSatan/SmartRC-CC1101-Driver-Lib/issues/43 This point: https://github.com/LSatan/SmartRC-CC1101-Driver-Lib/issues/43#issuecomment-675532122 And here: https://github.com/T-vK/Long-Range-Arduino-Doorbell

LSatan commented 4 years ago

your sketch now works.

sorry i used 433 mhz module. you have to change it to 868mhz!

working

// New receiving method. This method checks the Rx Fifo for any data it contains
// It allows you to do several things in a loop. In addition, the gdo0 and gdo2 pin are not required
// https://github.com/LSatan/SmartRC-CC1101-Driver-Lib by Little_S@tan

#include <ELECHOUSE_CC1101_SRC_DRV.h>

int gdo0 ;
const byte LED_PIN = 3 ;
char  StrBuf[60] ;

void setup()
{   Serial.begin( 9600 ) ;

    pinMode( LED_PIN, OUTPUT ) ;
#ifdef ESP32
gdo0 = 2 ;  // for esp32! GDO0 on GPIO pin 2
#elif ESP8266
gdo0 = 5 ;  // for esp8266! GDO0 on pin 5 = D1
#else
gdo0 = 6 ;  // for Arduino! GDO0 on pin 6
#endif

    ELECHOUSE_cc1101.Init() ;                  // must be set to initialize the cc1101!

    ELECHOUSE_cc1101.setGDO( gdo0,0 ) ;        // set lib internal gdo pins ( gdo0,gdo2 )

    ELECHOUSE_cc1101.setCCMode( 1 ) ;          // config for internal transmission mode
    ELECHOUSE_cc1101.setModulation( 0 ) ;      // modulation mode. 0 = 2-FSK, 1 = GFSK, 2 = ASK/OOK, 3 = 4-FSK, 4 = MSK
    ELECHOUSE_cc1101.setMHZ( 433.3 ) ;         // auto calculated frequency ( default = 433.92 ). CC1101 can: 300-348 MHZ, 387-464MHZ and 779-928MHZ
    ELECHOUSE_cc1101.setDeviation( 47.60 ) ;   // frequency deviation in kHz. Value from 1.58 to 380.85. Default is 47.60 kHz
    ELECHOUSE_cc1101.setChannel( 0 ) ;         // channel number from 0 to 255. Default is 0
    ELECHOUSE_cc1101.setChsp( 199.95 ) ;       // channel spacing is multiplied by channel number CHAN & added to the base freq in kHz. Range: 25.39..405.45. Default 199.95 kHz
    ELECHOUSE_cc1101.setRxBW( 812.50 ) ;       // receive bandwidth in kHz. Range: 58.03..812.50. Default 812.50 kHz
    ELECHOUSE_cc1101.setDRate( 99.97 ) ;       // data rate in kBaud. Range: 0.02..1621.83. Default 99.97 kBaud!
    ELECHOUSE_cc1101.setPA( 10 ) ;             // TxPower. Possible values depending on the frequency band. (-30 -20 -15 -10 -6 0 5 7 10 11 12 ) Default = max!
    ELECHOUSE_cc1101.setSyncMode( 2 ) ;        // Combined sync-word qualifier mode
                                               // 0 = No preamble/sync
                                               // 1 = 16 sync word bits detected
                                               // 2 = 16/16 sync word bits detected
                                               // 3 = 30/32 sync word bits detected
                                               // 4 = No preamble/sync, carrier-sense above threshold
                                               // 5 = 15/16 + carrier-sense above threshold
                                               // 6 = 16/16 + carrier-sense above threshold
                                               // 7 = 30/32 + carrier-sense above threshold
    ELECHOUSE_cc1101.setSyncWord( 211, 145 ) ; // Syncword-H, Syncword-L. Must be the same for the transmitter and receiver. 
    ELECHOUSE_cc1101.setAdrChk( 0 ) ;          // Address check of received packages
                                               // 0=No check, 1=Addr check/no broadcast, 2=Addr check + 0x00 broadcast, 3=Addr check + 0x00 + 0xFF broadcast
    ELECHOUSE_cc1101.setAddr( 0 ) ;            // Address used for packet filtration. Optional broadcast addresses are 0 ( 0x00 ) and 255 ( 0xFF )
    ELECHOUSE_cc1101.setWhiteData( 0 ) ;       // Turn data whitening on/off. 0=Whitening off. 1 = Whitening on
    ELECHOUSE_cc1101.setPktFormat( 0 ) ;       // Format of RX and TX data. 0=Normal mode, use FIFOs for RX and TX
                                               //                           1=Synchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins
                                               //                           2=Random TX test mode; sends random data using PN9 generator. Works as normal mode, setting 0 in RX
                                               //                           3=Asynchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins
    ELECHOUSE_cc1101.setLengthConfig( 1 ) ;    // 0=Fixed packet length mode. 1=Variable packet length mode. 2=Infinite packet length mode. 3=Reserved
    ELECHOUSE_cc1101.setPacketLength( 0 ) ;    // Indicates the packet length in fixed packet length mode or max packet length in variable packet length mode
    ELECHOUSE_cc1101.setCrc( 1 ) ;             // 1=CRC calculation in TX and CRC check in RX enabled. 0=CRC disabled for TX and RX
    ELECHOUSE_cc1101.setCRC_AF( 0 ) ;          // automatic flush RX FIFO if wrong CRC. Requires that only 1 packet is in the RXIFIFO and packet length is limited to FIFO size
    ELECHOUSE_cc1101.setDcFilterOff( 0 ) ;     // Disable digital DC blocking filter before demodulator. Only for data rates < 250 kBaud.
                                               // The recommended IF frequency changes when DC blocking is disabled. 1=Disable (current optimized). 0=Enable (better sensitivity)
    ELECHOUSE_cc1101.setManchester( 0 ) ;      // Enables Manchester encoding/decoding. 0=Disable. 1=Enable
    ELECHOUSE_cc1101.setFEC( 0 ) ;             // Enable Forward Error Correction (FEC) with interleaving for packet payload (Only supported for fixed packet length mode)
    ELECHOUSE_cc1101.setPQT( 0 ) ;             // Preamble quality estimator threshold. The preamble quality estimator increases an internal counter by one each time
                                               //   a bit is received that is different from the previous bit
                                               //   and decreases the counter by 8 each time a bit is received that is the same as the last bit
                                               // A threshold of 4*PQT for this counter is used to gate sync word detection. When PQT=0 a sync word is always accepted
    ELECHOUSE_cc1101.setAppendStatus( 0 ) ;    // When enabled, two status bytes will be appended to the payload of the packet.
                                               // The status bytes contain RSSI and LQI values, as well as CRC OK
    ELECHOUSE_cc1101.SetRx() ;                 // set Receive on
    Serial.println( "Rx Mode" ) ;
}

byte buffer[61] = {0} ;

void loop()
{
    if( ELECHOUSE_cc1101.CheckRxFifo( 100 ) )    // If something is received we give some time to receive the message in full.( time in millis )
    {   blink( 1 ) ;
        if( ELECHOUSE_cc1101.CheckCRC() )          // CRC Check. If "setCrc( false )" crc returns always OK!
        {   sprintf( StrBuf, "Rssi: %d dBm", ELECHOUSE_cc1101.getRssi() ) ;
            Serial.println( StrBuf ) ;

            sprintf( StrBuf, "Link Quality Indicator (LQI) = %d", ELECHOUSE_cc1101.getLqi() ) ;
            Serial.println( StrBuf ) ;

            int len = ELECHOUSE_cc1101.ReceiveData( buffer ) ; // Get received Data and calculate length
            buffer[len] = '\0' ;

            sprintf( StrBuf, "%s = ", (char *)buffer ) ;
            Serial.print( StrBuf ) ;

            sprintf( StrBuf, "%#x", buffer[0] ) ;
            Serial.print( StrBuf ) ;
            for( int i=1 ; i<len; i++ )              // Print received in bytes format
            {   sprintf( StrBuf, ",%#x", buffer[i] ) ;
                Serial.print( StrBuf ) ;
            }
            Serial.println() ;
            //ELECHOUSE_cc1101.SetTx() ;                 
            //delay( 1000 ) ;
            Serial.println( "sending 'OK'" ) ;
            ELECHOUSE_cc1101.SendData( "OK" ) ; 
            Serial.println( "sent 'OK'" ) ;
            ELECHOUSE_cc1101.SetRx() ;                 // set Receive on
            Serial.println( "Rx mode" ) ;
        }
    }
}
void blink( byte Count )
{   while( Count-- > 0 )
    { digitalWrite( LED_PIN, ! digitalRead( LED_PIN ) ) ;
      delay( 100 ) ;
      digitalWrite( LED_PIN, ! digitalRead( LED_PIN ) ) ;
      delay( 200 ) ;
    }
}
// These examples are from the Electronics Cookbook by Simon Monk
// https://github.com/LSatan/SmartRC-CC1101-Driver-Lib, mod by Little_S@tan

#include <ELECHOUSE_CC1101_SRC_DRV.h>

int gdo0 ;
const byte LED_PIN = 3 ;
char  StrBuf[60] ;

byte byte_array[11] = { 72,101,108,108,111,32,87,111,114,108,100 } ;
char *charPtr       =  "UP" ;

void setup() 
{   Serial.begin( 9600 ) ;
    pinMode( LED_PIN, OUTPUT ) ;

#ifdef ESP32
gdo0 = 2 ;  // for esp32! GDO0 on GPIO pin 2
#elif ESP8266
gdo0 = 5 ;  // for esp8266! GDO0 on pin 5 = D1
#else
gdo0 = 6 ;  // for Arduino! GDO0 on pin 6
#endif 

    ELECHOUSE_cc1101.Init() ;                  // must be set to initialize the cc1101!
    ELECHOUSE_cc1101.setGDO( gdo0,0 ) ;        // set lib internal gdo pins (gdo0, gdo2), gdo2 not use for this example
    ELECHOUSE_cc1101.setCCMode( 1 ) ;          // config for internal transmission mode
    ELECHOUSE_cc1101.setModulation( 0 ) ;      // modulation mode. 0 = 2-FSK, 1 = GFSK, 2 = ASK/OOK, 3 = 4-FSK, 4 = MSK
    ELECHOUSE_cc1101.setMHZ( 433.3 ) ;         // auto calculated frequency ( default = 433.92 ). CC1101 can: 300-348 MHZ, 387-464MHZ and 779-928MHZ
    ELECHOUSE_cc1101.setDeviation( 47.60 ) ;   // frequency deviation in kHz. Value from 1.58 to 380.85. Default is 47.60 kHz
    ELECHOUSE_cc1101.setChannel( 0 ) ;         // channel number from 0 to 255. Default is 0
    ELECHOUSE_cc1101.setChsp( 199.95 ) ;       // channel spacing is multiplied by channel number CHAN & added to the base freq in kHz. Range: 25.39..405.45. Default 199.95 kHz
    ELECHOUSE_cc1101.setRxBW( 812.50 ) ;       // receive bandwidth in kHz. Range: 58.03..812.50. Default 812.50 kHz
    ELECHOUSE_cc1101.setDRate( 99.97 ) ;       // data rate in kBaud. Range: 0.02..1621.83. Default 99.97 kBaud!
    ELECHOUSE_cc1101.setPA( 10 ) ;             // TxPower. Possible values depending on the frequency band. (-30 -20 -15 -10 -6 0 5 7 10 11 12 ) Default = max!
    ELECHOUSE_cc1101.setSyncMode( 2 ) ;        // Combined sync-word qualifier mode
                                               // 0 = No preamble/sync
                                               // 1 = 16 sync word bits detected
                                               // 2 = 16/16 sync word bits detected
                                               // 3 = 30/32 sync word bits detected
                                               // 4 = No preamble/sync, carrier-sense above threshold
                                               // 5 = 15/16 + carrier-sense above threshold
                                               // 6 = 16/16 + carrier-sense above threshold
                                               // 7 = 30/32 + carrier-sense above threshold
    ELECHOUSE_cc1101.setSyncWord( 211, 145 ) ; // Syncword-H, Syncword-L. Must be the same for the transmitter and receiver. 
    ELECHOUSE_cc1101.setAdrChk( 0 ) ;          // Address check of received packages
                                               // 0=No check, 1=Addr check/no broadcast, 2=Addr check + 0x00 broadcast, 3=Addr check + 0x00 + 0xFF broadcast
    ELECHOUSE_cc1101.setAddr( 0 ) ;            // Address used for packet filtration. Optional broadcast addresses are 0 ( 0x00 ) and 255 ( 0xFF )
    ELECHOUSE_cc1101.setWhiteData( 0 ) ;       // Turn data whitening on/off. 0=Whitening off. 1 = Whitening on
    ELECHOUSE_cc1101.setPktFormat( 0 ) ;       // Format of RX and TX data. 0=Normal mode, use FIFOs for RX and TX
                                               //                           1=Synchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins
                                               //                           2=Random TX test mode; sends random data using PN9 generator. Works as normal mode, setting 0 in RX
                                               //                           3=Asynchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins
    ELECHOUSE_cc1101.setLengthConfig( 1 ) ;    // 0=Fixed packet length mode. 1=Variable packet length mode. 2=Infinite packet length mode. 3=Reserved
    ELECHOUSE_cc1101.setPacketLength( 0 ) ;    // Indicates the packet length in fixed packet length mode or max packet length in variable packet length mode
    ELECHOUSE_cc1101.setCrc( 1 ) ;             // 1=CRC calculation in TX and CRC check in RX enabled. 0=CRC disabled for TX and RX
    ELECHOUSE_cc1101.setCRC_AF( 0 ) ;          // automatic flush RX FIFO if wrong CRC. Requires that only 1 packet is in the RXIFIFO and packet length is limited to FIFO size
    ELECHOUSE_cc1101.setDcFilterOff( 0 ) ;     // Disable digital DC blocking filter before demodulator. Only for data rates < 250 kBaud.
                                               // The recommended IF frequency changes when DC blocking is disabled. 1=Disable (current optimized). 0=Enable (better sensitivity)
    ELECHOUSE_cc1101.setManchester( 0 ) ;      // Enables Manchester encoding/decoding. 0=Disable. 1=Enable
    ELECHOUSE_cc1101.setFEC( 0 ) ;             // Enable Forward Error Correction (FEC) with interleaving for packet payload (Only supported for fixed packet length mode)
    ELECHOUSE_cc1101.setPQT( 0 ) ;             // Preamble quality estimator threshold. The preamble quality estimator increases an internal counter by one each time
                                               //   a bit is received that is different from the previous bit
                                               //   and decreases the counter by 8 each time a bit is received that is the same as the last bit
                                               // A threshold of 4*PQT for this counter is used to gate sync word detection. When PQT=0 a sync word is always accepted
    ELECHOUSE_cc1101.setAppendStatus( 0 ) ;    // When enabled, two status bytes will be appended to the payload of the packet.

  //  ELECHOUSE_cc1101.SetTx() ;     
    Serial.println( "Tx Mode" ) ;
}
byte buffer[61] = {0} ;
void loop() 
{   //ELECHOUSE_cc1101.SendData( byte_array, 11 ) ;  // Transmit data from byte_array[11] 
    //blink( 1 ) ;
    //delay( 2000 ) ;
    //ELECHOUSE_cc1101.SendData( charPtr ) ;         // Transmit data from *charPtr
    //blink( 2 ) ;
    //delay( 2000 ) ;
    blink( 2 ) ;
    ELECHOUSE_cc1101.SendData( "DOWN" ) ;    // Transmit data from char format directly
    checkACK( 2000 ) ;
    delay( 2000 ) ;
}
void checkACK( uint16_t ackWait )
{   uint32_t waitStart = millis() ;
    bool ackOK         = false ;
    ELECHOUSE_cc1101.SetRx() ;     
    while( millis() - waitStart < ackWait ) 
    {   if( ELECHOUSE_cc1101.CheckRxFifo( 100 ) )    // If something is received we give some time to receive the message in full.( time in millis )
        {   if( ELECHOUSE_cc1101.CheckCRC() )        // CRC Check. If "setCrc( false )" crc returns always OK!
            { sprintf( StrBuf, "Rssi: %d dBm", ELECHOUSE_cc1101.getRssi() ) ;
              Serial.println( StrBuf ) ;

              sprintf( StrBuf, "Link Quality Indicator (LQI) = %d", ELECHOUSE_cc1101.getLqi() ) ;
              Serial.println( StrBuf ) ;

              int len = ELECHOUSE_cc1101.ReceiveData( buffer ) ; // Get received Data and calculate length
              buffer[len] = '\0' ;

              sprintf( StrBuf, "%s = ", (char *)buffer ) ;
              Serial.print( StrBuf ) ;

              sprintf( StrBuf, "%#x", buffer[0] ) ;
              Serial.print( StrBuf ) ;
              for( int i=1 ; i<len; i++ )            // Print received in bytes format
              {   sprintf( StrBuf, ",%#x", buffer[i] ) ;
                  Serial.print( StrBuf ) ;
              }
              Serial.println() ;
              Serial.println( millis() - waitStart ) ;
              ackOK = true ;
              blink( 1 ) ;
              break ;
            }
        }
    }
    if( ! ackOK )
    {   Serial.println( "ERROR: no ACK received" ) ;
    }
  //  ELECHOUSE_cc1101.SetTx() ;     
}
void blink( byte Count )
{   while( Count-- > 0 )
    { digitalWrite( LED_PIN, ! digitalRead( LED_PIN ) ) ;
      delay( 100 ) ;
      digitalWrite( LED_PIN, ! digitalRead( LED_PIN ) ) ;
      delay( 200 ) ;
    }
}
gitterman commented 4 years ago

Thanks for analyzing. Alas, it still does not work. I copied exactly your code and only changed the frequency back to 868.3. The Receiver still hangs after the "sending 'OK'" message. The only difference now is the frequency. The issue #43 which you mentioned, also uses 433 MHz. Thus, I suspect a timing issue which does not work with 868 MHz.

There is another observation I just made. I had left the receiving sketch running for ~20 minutes when I noticed that sometimes it succeeded sending the 'OK'. Within the 20 minutes I got exactly 3 success messages.

Rx Mode Rssi: -30 dBm Link Quality Indicator (LQI) = 130 DOWN = 0x44,0x4f,0x57,0x4e sending 'OK' sent 'OK' Rx mode Rssi: -31 dBm Link Quality Indicator (LQI) = 131 DOWN = 0x44,0x4f,0x57,0x4e sending 'OK' sent 'OK' Rx mode Rssi: -28 dBm Link Quality Indicator (LQI) = 131 DOWN = 0x44,0x4f,0x57,0x4e sending 'OK' sent 'OK' Rx mode Rssi: -26 dBm Link Quality Indicator (LQI) = 131 DOWN = 0x44,0x4f,0x57,0x4e sending 'OK'

LSatan commented 4 years ago

that is quite strange. but i have changed a little more than just the frequency. I would be interested in which microcontroller you are using and which cc1101 module ?! place the cc1101 away from the other.

gitterman commented 4 years ago

Yes I did see your changes and as I said I copied exactly the modified code that you had attached. Of course, I needed to change the frequency to work with my modules. My modules are controlled by Arduino pro Mini with 3.3V/8MHz. I have a bunch of them, and they all behave the same. They are taken from a sygonix device and shown on the attached picture. IMG_20200930_124616_585 As I said I had no problem transmitting and receiving one way. The problem just came up when I tried to switch direction within a sketch.

LSatan commented 4 years ago

Another possible cause of error would be that the crystals work differently. this then affects the frequency. Apart from that, I'll test it later with my 868mhz. I have to solder them together first.

gitterman commented 4 years ago

More about my modules can be found here: https://www.mikrocontroller.net/topic/500817 The sygonix home automation system uses an acknowledgement mode, thus the modules must be able to switch direction.

LSatan commented 4 years ago

the modules are currently no longer available. otherwise I would have ordered two. I know from experience that it gets stuck when sending if there is no response from gdo0. gdo0 pulls up while sending and then goes low again. if he doesn’t even pull it up because it’s not connected, for example. then he gets stuck. I will see if it is possible to transfer without gdo0. as with the new reception method. then it could work.

gitterman commented 4 years ago

In the meantime I have tested the modules with 433MHz. The unidirectional transfer also works with this frequency although of course with a higher attenuation. The transceiver mode does not work with 433MHz either thus it must be an issue with the modules.

LSatan commented 4 years ago

have you tried to use gdo2 instead of gdo0. maybe that's the fault

gitterman commented 4 years ago

Oops, that was hint in the right direction. Shame on me. I did connect to gdo0 correctly on the module but on the receiving slave Arduino I had connected it to pin 5 instead of 6. The master transmitting Arduino was connected correctly. Now once I have plugged it into pin6 it works like a charm. Many thanks for your support.

LSatan commented 4 years ago

never mind. nice that works now.

LSatan commented 4 years ago

a little note. the 868mhz modules can have more than pa level 10. set pa to 12 to have the maximum transmission power. or deactivate set pa with // in front of it. deactivated = default (PA max).

fightforlife commented 3 years ago

I currently have the same problem, that once I switch to TX mode, the CC1101 hangs. Switching between OFF & RX works fine.

GDO0 is connected to GPIO2 and GD2 to GPIO4 on an ESP32. I checked multiple times. I use a mqttCallback to switch between TX / RX / OFF state of the CC1101.

Switching between RX and OFF works just as expected. When in TX mode the builtin LED of the ESP32 is showing receive-activity. But once I switch to TX the CC1101 seems to hang, and does not change mode anymore. The ESP32 does not hang and still works as expected. If I restart the ESP32 I can use RX and OFF again. Maybe there is something I am missing here?

(Compiled on PlatformIO with lsatan/SmartRC-CC1101-Driver-Lib@^2.5.2)

MQTT Payload

{
  "mode" : "RX", //OFF,RX,TX
  "MHZ" : 433.92,
  "RxBW" : 812.50,
  "PA" : 12
}

Code snippet (not complete, just important parts)

#include <PubSubClient.h>
#include <ELECHOUSE_CC1101_SRC_DRV.h>
#include <RCSwitch.h>

#define CC1101_GD0_GPIO 2
#define CC1101_CS_VSPI_CS 15
#define CC1101_SCK_VSPI_CLK 14
#define CC1101_MOSI_VSPI_MOSI 13
#define CC1101_MISO_VSPI_MISO 12
#define CC1101_GD2_GPIO 4

#define CC1101_PA 12
RCSwitch rcSwitch = RCSwitch();

void setup() {
  Serial.begin(SERIAL_SPEED);
  Log.begin(LOG_LEVEL, &Serial);
  Log.setPrefix(printTimestamp);
  Log.setSuffix(printNewline);
  wifiConnection();
  Log.trace("WiFi connected");
  mqttConnection();
  Log.trace("MQTT connected");

  ELECHOUSE_cc1101.setSpiPin(CC1101_SCK_VSPI_CLK, CC1101_MISO_VSPI_MISO, CC1101_MOSI_VSPI_MOSI, CC1101_CS_VSPI_CS); //SCK, MISO,MOSI,SS
  ELECHOUSE_cc1101.setGDO(CC1101_GD0_GPIO, CC1101_GD2_GPIO);
  ELECHOUSE_cc1101.Init();
  ELECHOUSE_cc1101.SpiStrobe(0x36);//Exit RX / TX, turn off frequency synthesizer and exit
  ELECHOUSE_cc1101.SpiStrobe(0x39);//Enter power down mode when CSn goes high.
  Log.trace("CC1101 initialized as OFF"); 
}

void mqttCallback(char* topic, byte *payload, unsigned int length) {
  Log.trace("MQTT RX: %s", topic);

  if(strcmp("gateway/cc1101/config", topic) == 0)
  {
    StaticJsonDocument<MQTT_BUFFER_SIZE> doc;
    const char* json = (char*)payload;
    deserializeJson(doc, json);

    const char* mode = doc["mode"]; //RX, TX, OFF
    Log.verbose("CC1101 mode: %s", mode);
    float RxBW = doc["RxBW"];
    Log.verbose("CC1101 RxBW: %F", RxBW);
    float MHZ = doc["MHZ"];
    Log.verbose("CC1101 MHZ: %F", MHZ);
    int PA = doc["PA"];
    Log.verbose("CC1101 PA: %d", PA);

    if (strcmp("OFF", mode) == 0)
    {
      rcSwitch.disableReceive();
      rcSwitch.disableTransmit();
      ELECHOUSE_cc1101.SpiStrobe(0x36);//Exit RX / TX, turn off frequency synthesizer and exit
      ELECHOUSE_cc1101.SpiStrobe(0x39);//Enter power down mode when CSn goes high.
      Log.trace("CC1101 set to OFF");
    }

    if (strcmp("RX", mode) == 0)
    {
      rcSwitch.disableTransmit();
      ELECHOUSE_cc1101.setRxBW(RxBW);
      rcSwitch.enableReceive(CC1101_GD2_GPIO);
      ELECHOUSE_cc1101.SetRx(MHZ);
      Log.trace("CC1101 set to RX");
    }

    if (strcmp("TX", mode) == 0)
    {
      ELECHOUSE_cc1101.setPA(PA);
      rcSwitch.disableReceive();
      ELECHOUSE_cc1101.SetTx();
      delay(10);
      rcSwitch.enableTransmit(CC1101_GD0_GPIO);
      Log.trace("CC1101 set to TX");
    }
  }
}
LSatan commented 3 years ago

Hi, in itself i can't find any fault. remove times ELECHOUSE_cc1101.setGDO(CC1101_GD0_GPIO, CC1101_GD2_GPIO);. it is not necessary. possibly it should fix the problem. if you go to off and then to tx does it work? or do you have no way to send?

JohnJJG commented 3 years ago

@fightforlife I have the same problem in OpenMQTTGateway. It crashes the ESP32 when it switches to TX. This only happens when I have another SPI device which is on a separate SPI bus. They work separately fine but not when both initialised (SD card & a VS1053b on one SPI bus, the CC1101 on another). I moved the TX so that is is only called when there is an actual MQTTto433 message which means it only crashes when I transmit. Still a problem but not had a chance to debug it yet. might be something about the ESP32 but I will do some more digging as well when I get the chance but I will have a look at the suggestion from LSatan as well.

LSatan commented 3 years ago

a link to the full project would be helpful. I could then adjust it to work. I could also add the project to my list.

fightforlife commented 3 years ago

I got it working by trial and error. Things I needed to change:

If I only do one of those, it is not working correctly.

JohnJJG commented 3 years ago

Back investigating the Tx switch problem on my ESP32 Pico board. I have stripped the code back to bare bones and works it ok. I will build it backup and do some swap out of code until it fails again but hopefully it is in my code. Might be a brownout. If I can repeat it with a small enough section of code I'll share the project files.

bjfhskj commented 2 years ago

I can't get the feedback mesage also(esp32,cc1101 work at 855-925Mhz),Can you help me? The first skech code:

include

unsigned char Send_Buffer[24]; unsigned char bNum; unsigned int tmp=0;

unsigned char Rec_Buffer[300];//最多150汉字 unsigned int recLen=0;/////////接收数据字节数

void setup() {

Serial.begin(9600);

/////////////无线模块cc1101初始化 if (ELECHOUSE_cc1101.getCC1101()){ // Check the CC1101 Spi connection. Serial.println("Connection OK"); }else{ Serial.println("Connection Error"); }

ELECHOUSE_cc1101.Init();                // must be set to initialize the cc1101!
ELECHOUSE_cc1101.setGDO( 2,0 ) ;        // set lib internal gdo pins ( gdo0,gdo2 )
ELECHOUSE_cc1101.setCCMode(1);          // set config for internal transmission mode.
ELECHOUSE_cc1101.setModulation(0);      // set modulation mode. 0 = 2-FSK, 1 = GFSK, 2 = ASK/OOK, 3 = 4-FSK, 4 = MSK.
ELECHOUSE_cc1101.setMHZ(855);        // Here you can set your basic frequency. The lib calculates the frequency automatically (default = 433.92).The cc1101 can: 300-348 MHZ, 387-464MHZ and 779-928MHZ. Read More info from datasheet.
ELECHOUSE_cc1101.setDeviation(47.60);   // Set the Frequency deviation in kHz. Value from 1.58 to 380.85. Default is 47.60 kHz.
ELECHOUSE_cc1101.setChannel(10);         // Set the Channelnumber from 0 to 255. Default is cahnnel 0.
ELECHOUSE_cc1101.setChsp(199.95);       // The channel spacing is multiplied by the channel number CHAN and added to the base frequency in kHz. Value from 25.39 to 405.45. Default is 199.95 kHz.
ELECHOUSE_cc1101.setRxBW(812.50);       // Set the Receive Bandwidth in kHz. Value from 58.03 to 812.50. Default is 812.50 kHz.
ELECHOUSE_cc1101.setDRate(99.97);       // Set the Data Rate in kBaud. Value from 0.02 to 1621.83. Default is 99.97 kBaud!
ELECHOUSE_cc1101.setPA(10);             // Set TxPower. The following settings are possible depending on the frequency band.  (-30  -20  -15  -10  -6    0    5    7    10   11   12) Default is max!
ELECHOUSE_cc1101.setSyncMode(2);        // Combined sync-word qualifier mode. 0 = No preamble/sync. 1 = 16 sync word bits detected. 2 = 16/16 sync word bits detected. 3 = 30/32 sync word bits detected. 4 = No preamble/sync, carrier-sense above threshold. 5 = 15/16 + carrier-sense above threshold. 6 = 16/16 + carrier-sense above threshold. 7 = 30/32 + carrier-sense above threshold.
ELECHOUSE_cc1101.setSyncWord(211, 145); // Set sync word. Must be the same for the transmitter and receiver. (Syncword high, Syncword low)
ELECHOUSE_cc1101.setAdrChk(0);          // Controls address check configuration of received packages. 0 = No address check. 1 = Address check, no broadcast. 2 = Address check and 0 (0x00) broadcast. 3 = Address check and 0 (0x00) and 255 (0xFF) broadcast.
ELECHOUSE_cc1101.setAddr(0);            // Address used for packet filtration. Optional broadcast addresses are 0 (0x00) and 255 (0xFF).
ELECHOUSE_cc1101.setWhiteData(0);       // Turn data whitening on / off. 0 = Whitening off. 1 = Whitening on.
ELECHOUSE_cc1101.setPktFormat(0);       // Format of RX and TX data. 0 = Normal mode, use FIFOs for RX and TX. 1 = Synchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins. 2 = Random TX mode; sends random data using PN9 generator. Used for test. Works as normal mode, setting 0 (00), in RX. 3 = Asynchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins.
ELECHOUSE_cc1101.setLengthConfig(1);    // 0 = Fixed packet length mode. 1 = Variable packet length mode. 2 = Infinite packet length mode. 3 = Reserved
ELECHOUSE_cc1101.setPacketLength(0);    // Indicates the packet length when fixed packet length mode is enabled. If variable packet length mode is used, this value indicates the maximum packet length allowed.
ELECHOUSE_cc1101.setCrc(1);             // 1 = CRC calculation in TX and CRC check in RX enabled. 0 = CRC disabled for TX and RX.
ELECHOUSE_cc1101.setCRC_AF(0);          // Enable automatic flush of RX FIFO when CRC is not OK. This requires that only one packet is in the RXIFIFO and that packet length is limited to the RX FIFO size.
ELECHOUSE_cc1101.setDcFilterOff(0);     // Disable digital DC blocking filter before demodulator. Only for data rates ≤ 250 kBaud The recommended IF frequency changes when the DC blocking is disabled. 1 = Disable (current optimized). 0 = Enable (better sensitivity).
ELECHOUSE_cc1101.setManchester(0);      // Enables Manchester encoding/decoding. 0 = Disable. 1 = Enable.
ELECHOUSE_cc1101.setFEC(0);             // Enable Forward Error Correction (FEC) with interleaving for packet payload (Only supported for fixed packet length mode. 0 = Disable. 1 = Enable.
ELECHOUSE_cc1101.setPRE(0);             // Sets the minimum number of preamble bytes to be transmitted. Values: 0 : 2, 1 : 3, 2 : 4, 3 : 6, 4 : 8, 5 : 12, 6 : 16, 7 : 24
ELECHOUSE_cc1101.setPQT(0);             // Preamble quality estimator threshold. The preamble quality estimator increases an internal counter by one each time a bit is received that is different from the previous bit, and decreases the counter by 8 each time a bit is received that is the same as the last bit. A threshold of 4∙PQT for this counter is used to gate sync word detection. When PQT=0 a sync word is always accepted.
ELECHOUSE_cc1101.setAppendStatus(0);    // When enabled, two status bytes will be appended to the payload of the packet. The status bytes contain RSSI and LQI values, as well as CRC OK.
ELECHOUSE_cc1101.SetRx() ;

}

void loop() { if (ELECHOUSE_cc1101.CheckRxFifo(100)){ if (ELECHOUSE_cc1101.CheckCRC()){ int len = ELECHOUSE_cc1101.ReceiveData(Rec_Buffer); Rec_Buffer[len] = '\0'; if(len>0){ recLen=len; Doshow(); ELECHOUSE_cc1101.SendData("Feed back", 100); ELECHOUSE_cc1101.SetRx() ; Serial.print("ok"); } // for (int i = 0; i<len; i++){ // Serial.print(buffer[i]); // Serial.print(","); // } // Serial.println(); } }

} ///////////////////////////////////////////////////////////////The second skech code:

include

void setup(){

Serial.begin(9600);
if (ELECHOUSE_cc1101.getCC1101()){      // Check the CC1101 Spi connection.
Serial.println("Connection OK");
}else{
Serial.println("Connection Error");
}

ELECHOUSE_cc1101.Init();                // must be set to initialize the cc1101!
ELECHOUSE_cc1101.setGDO( 2,0 ) ;        // set lib internal gdo pins ( gdo0,gdo2 )
ELECHOUSE_cc1101.setCCMode(1);          // set config for internal transmission mode.
ELECHOUSE_cc1101.setModulation(0);      // set modulation mode. 0 = 2-FSK, 1 = GFSK, 2 = ASK/OOK, 3 = 4-FSK, 4 = MSK.
ELECHOUSE_cc1101.setMHZ(855);        // Here you can set your basic frequency. The lib calculates the frequency automatically (default = 433.92).The cc1101 can: 300-348 MHZ, 387-464MHZ and 779-928MHZ. Read More info from datasheet.
ELECHOUSE_cc1101.setDeviation(47.60);   // Set the Frequency deviation in kHz. Value from 1.58 to 380.85. Default is 47.60 kHz.
ELECHOUSE_cc1101.setChannel(10);         // Set the Channelnumber from 0 to 255. Default is cahnnel 0.
ELECHOUSE_cc1101.setChsp(199.95);       // The channel spacing is multiplied by the channel number CHAN and added to the base frequency in kHz. Value from 25.39 to 405.45. Default is 199.95 kHz.
ELECHOUSE_cc1101.setRxBW(812.50);       // Set the Receive Bandwidth in kHz. Value from 58.03 to 812.50. Default is 812.50 kHz.
ELECHOUSE_cc1101.setDRate(99.97);       // Set the Data Rate in kBaud. Value from 0.02 to 1621.83. Default is 99.97 kBaud!
ELECHOUSE_cc1101.setPA(10);             // Set TxPower. The following settings are possible depending on the frequency band.  (-30  -20  -15  -10  -6    0    5    7    10   11   12) Default is max!
ELECHOUSE_cc1101.setSyncMode(2);        // Combined sync-word qualifier mode. 0 = No preamble/sync. 1 = 16 sync word bits detected. 2 = 16/16 sync word bits detected. 3 = 30/32 sync word bits detected. 4 = No preamble/sync, carrier-sense above threshold. 5 = 15/16 + carrier-sense above threshold. 6 = 16/16 + carrier-sense above threshold. 7 = 30/32 + carrier-sense above threshold.
ELECHOUSE_cc1101.setSyncWord(211, 145); // Set sync word. Must be the same for the transmitter and receiver. (Syncword high, Syncword low)
ELECHOUSE_cc1101.setAdrChk(0);          // Controls address check configuration of received packages. 0 = No address check. 1 = Address check, no broadcast. 2 = Address check and 0 (0x00) broadcast. 3 = Address check and 0 (0x00) and 255 (0xFF) broadcast.
ELECHOUSE_cc1101.setAddr(0);            // Address used for packet filtration. Optional broadcast addresses are 0 (0x00) and 255 (0xFF).
ELECHOUSE_cc1101.setWhiteData(0);       // Turn data whitening on / off. 0 = Whitening off. 1 = Whitening on.
ELECHOUSE_cc1101.setPktFormat(0);       // Format of RX and TX data. 0 = Normal mode, use FIFOs for RX and TX. 1 = Synchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins. 2 = Random TX mode; sends random data using PN9 generator. Used for test. Works as normal mode, setting 0 (00), in RX. 3 = Asynchronous serial mode, Data in on GDO0 and data out on either of the GDOx pins.
ELECHOUSE_cc1101.setLengthConfig(1);    // 0 = Fixed packet length mode. 1 = Variable packet length mode. 2 = Infinite packet length mode. 3 = Reserved
ELECHOUSE_cc1101.setPacketLength(0);    // Indicates the packet length when fixed packet length mode is enabled. If variable packet length mode is used, this value indicates the maximum packet length allowed.
ELECHOUSE_cc1101.setCrc(1);             // 1 = CRC calculation in TX and CRC check in RX enabled. 0 = CRC disabled for TX and RX.
ELECHOUSE_cc1101.setCRC_AF(0);          // Enable automatic flush of RX FIFO when CRC is not OK. This requires that only one packet is in the RXIFIFO and that packet length is limited to the RX FIFO size.
ELECHOUSE_cc1101.setDcFilterOff(0);     // Disable digital DC blocking filter before demodulator. Only for data rates ≤ 250 kBaud The recommended IF frequency changes when the DC blocking is disabled. 1 = Disable (current optimized). 0 = Enable (better sensitivity).
ELECHOUSE_cc1101.setManchester(0);      // Enables Manchester encoding/decoding. 0 = Disable. 1 = Enable.
ELECHOUSE_cc1101.setFEC(0);             // Enable Forward Error Correction (FEC) with interleaving for packet payload (Only supported for fixed packet length mode. 0 = Disable. 1 = Enable.
ELECHOUSE_cc1101.setPRE(0);             // Sets the minimum number of preamble bytes to be transmitted. Values: 0 : 2, 1 : 3, 2 : 4, 3 : 6, 4 : 8, 5 : 12, 6 : 16, 7 : 24
ELECHOUSE_cc1101.setPQT(0);             // Preamble quality estimator threshold. The preamble quality estimator increases an internal counter by one each time a bit is received that is different from the previous bit, and decreases the counter by 8 each time a bit is received that is the same as the last bit. A threshold of 4∙PQT for this counter is used to gate sync word detection. When PQT=0 a sync word is always accepted.
ELECHOUSE_cc1101.setAppendStatus(0);    // When enabled, two status bytes will be appended to the payload of the packet. The status bytes contain RSSI and LQI values, as well as CRC OK.
ELECHOUSE_cc1101.SetRx() ;

}

byte buffer[61] = {0};

void loop(){

//Checks whether something has been received. //When something is received we give some time to receive the message in full.(time in millis) if (ELECHOUSE_cc1101.CheckRxFifo(100)){

//CRC Check. If "setCrc(false)" crc returns always OK! if (ELECHOUSE_cc1101.CheckCRC()){

//Rssi Level in dBm // Serial.print("Rssi: "); // Serial.println(ELECHOUSE_cc1101.getRssi()); // // //Link Quality Indicator // Serial.print("LQI: "); // Serial.println(ELECHOUSE_cc1101.getLqi());

//Get received Data and calculate length int len = ELECHOUSE_cc1101.ReceiveData(buffer); buffer[len] = '\0';

//Print received in char format. Serial.println((char *) buffer);

//Print received in bytes format. for (int i = 0; i<len; i++){ Serial.print(buffer[i]); Serial.print(","); } Serial.println(); } } ///////////////串口数据处理 unsigned char Rec_Buffer[300];//最多150汉字 unsigned int recLen=0;/////////接收数据字节数 while (Serial.available() > 0) {

 Rec_Buffer[recLen]=Serial.read();
 recLen++;
 if(recLen>300)recLen=0;////////防止传过来的太多溢出
 delay(2);

} if(recLen>0){ ELECHOUSE_cc1101.SendData(Rec_Buffer, recLen, 300); ///////发送命令 ELECHOUSE_cc1101.SetRx() ; } }

jcohedman commented 1 year ago

I found this solution: ELECHOUSE_cc1101.SendData( "OK",3 ) ; it runs ok