Problem with SPI RFM69HCW when esp32 wake up

Francbch
Posts: 1
Joined: Tue May 11, 2021 11:34 am

Problem with SPI RFM69HCW when esp32 wake up

Postby Francbch » Tue May 11, 2021 11:39 am

Hello community. I have been stuck in a problem for a long time and after an intensive search I have not come up with any solution.

The situation is the following:

1- I have a Feather 32u4 with an RFM69HCW radio module. He sends a message every X time and goes to sleep.
2- I have an ESP32 with another RFM69HCW radio module. It receives the interrupt through the DIO0 pin and the message from the Feather is correctly read in the rf69.available ().

The SPI communication between RadioHead RawTx and RawRx example sketches work perfectly.

The problem occurs when I put the esp32 in sleep mode.
In sleep mode and using ext0 as wakeup when I receive a message it wakes up but then the if condition (rf69.available ()) is always false and I am not able to read the message from the buffer.

The code from Feather32u4 is the following:

Code: Select all

char radiopacket[20];

byte u8_watchdog_counter = 0;

RH_RF69 rf69(RFM69_CS, RFM69_INT);

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram rf69_manager(rf69, MY_ADDRESS);

void setup()
{
  Serial1.begin(115200);
  pinMode(RFM69_RST, OUTPUT);
  digitalWrite(RFM69_RST, LOW);
  // manual reset
  digitalWrite(RFM69_RST, HIGH);
  delay(10);
  digitalWrite(RFM69_RST, LOW);
  delay(10);

  if (!rf69_manager.init())
  {
    Serial1.println("RFM69 radio init failed");
    while (1)
      ;
  }
  Serial1.println("RFM69 radio init OK!");
  // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM (for low power module)
  // No encryption
  if (!rf69.setFrequency(RF69_FREQ))
  {
    Serial1.println("setFrequency failed");
  }

  // If you are using a high power RF69 eg RFM69HW, you *must* set a Tx power with the
  // ishighpowermodule flag set like this:
  rf69.setTxPower(20, true); // range from 14-20 for power, 2nd arg must be true for 69HCW

  // The encryption key has to be the same as the one in the server
 
  uint8_t key[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                   0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
  rf69.setEncryptionKey(key);

  pinMode(LED, OUTPUT);

  Serial1.print("RFM69 radio @");
  Serial1.print((int)RF69_FREQ);
  Serial1.println(" MHz");
  Serial1.flush();
}

void loop()
{
  Watchdog.sleep(2000);
  u8_watchdog_counter++;
  if (u8_watchdog_counter >= 30 || u1_pin_changed)
  {
    radiopacket[0] = 0x30 + MY_ADDRESS;
    radiopacket[1] = 0x31;
    rf69.send((uint8_t *)radiopacket, strlen(radiopacket));
    rf69.waitPacketSent();
    u8_watchdog_counter = 0;
	Blink(LED, 40, 3);
  }
  rf69.sleep();
}
The code from ESP32 in sleep mode is the following:

Code: Select all

#include <SPI.h>
#include <RH_RF69.h>
#include <RHReliableDatagram.h>

/************ Radio Setup ***************/

// Change to 434.0 or other frequency, must match RX's freq!
#define RF69_FREQ 434.0

// who am i? (server address)
#define MY_ADDRESS 1

#if defined(ESP32)                     // ESP32 feather w/wing
#define RFM69_RST 26                   // same as LED
#define RFM69_CS 33                    // "B"
#define RFM69_INT 27                   // "A"
#define LED 13
#endif

RTC_DATA_ATTR int bootCount = 0;
// Singleton instance of the radio driver
RH_RF69 rf69(RFM69_CS, RFM69_INT);

// Class to manage message delivery and receipt, using the driver declared above
RHReliableDatagram rf69_manager(rf69, MY_ADDRESS);

RTC_DATA_ATTR int16_t packetnum = 0; // packet counter, we increment per xmission

// Dont put this on the stack:
uint8_t msg_recived[] = "Recived";
// Dont put this on the stack:
RTC_DATA_ATTR uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];

void setup()
{
  pinMode(12, OUTPUT);
  pinMode(LED, OUTPUT);
  digitalWrite(12, LOW);
  Serial.begin(115200);
  delay(1000);
  
  esp_sleep_enable_ext0_wakeup(GPIO_NUM_27, 1); //RFM69 makes an interrupt on GPIO 27 on ESP32
  ++bootCount;
  Serial.println("Boot number: " + String(bootCount));
  print_wakeup_reason();

  radio_RFM69_setup();
  /*CODE*/
  
  if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_EXT0)
  {
    Serial.println("ESP_SLEEP_WAKEUP_EXT0");
  }

  if (rf69.available())
  {
    Serial.println("MSG:");
    // Wait for a message addressed to us from the client
    uint8_t len = sizeof(buf);
    uint8_t from = 13;
    if (rf69.recvfromAck(buf, &len, &from))
    {
      buf[len] = 0; // zero out remaining string

      Serial.print("Got packet from #");
      Serial.print(from);
      Serial.print(" [RSSI :");
      Serial.print(rf69.lastRssi());
      Serial.print("] : ");
      Serial.println((char)buf[1]);

      if (buf[1] == 0x31)
      {
        Blink(12, 40, 3);
      }
    }
  }

  /*END LOOP*/

  ///*GO SLEEP*///////
  Serial.println("Going to sleep now");
  delay(1000);
  Serial.flush();
  esp_deep_sleep_start();
}

void loop()
{
}


void Blink(byte PIN, byte DELAY_MS, byte loops) {
  for (byte i=0; i<loops; i++)  {
    digitalWrite(PIN,HIGH);
    delay(DELAY_MS);
    digitalWrite(PIN,LOW);
    delay(DELAY_MS);
  }
}

void print_wakeup_reason()
{
  esp_sleep_wakeup_cause_t wakeup_reason;

  wakeup_reason = esp_sleep_get_wakeup_cause();

  switch (wakeup_reason)
  {
  case ESP_SLEEP_WAKEUP_EXT0:
    Serial.println("Wakeup caused by external signal using RTC_IO");
    break;
  case ESP_SLEEP_WAKEUP_EXT1:
    Serial.println("Wakeup caused by external signal using RTC_CNTL");
    break;
  case ESP_SLEEP_WAKEUP_TIMER:
    Serial.println("Wakeup caused by timer");
    break;
  case ESP_SLEEP_WAKEUP_TOUCHPAD:
    Serial.println("Wakeup caused by touchpad");
    break;
  case ESP_SLEEP_WAKEUP_ULP:
    Serial.println("Wakeup caused by ULP program");
    break;
  default:
    Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason);
    break;
  }
}

void radio_RFM69_setup()
{
  if (!rf69_manager.init())
  {
    Serial.println("RFM69 radio init failed");
    while (1)
      ;
  }
  // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM (for low power module)
  // No encryption
  if (!rf69.setFrequency(RF69_FREQ))
  {
    Serial.println("setFrequency failed");
  }
   // If you are using a high power RF69 eg RFM69HW, you *must* set a Tx power with the
   // ishighpowermodule flag set like this:
   rf69.setTxPower(20, true); // range from 14-20 for power, 2nd arg must be true for 69HCW

   // The encryption key has to be the same as the one in the server

  uint8_t key[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
                   0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
  rf69.setEncryptionKey(key);
}
The fact is that the wakeup_reason detects me that it has been produced by ESP_SLEEP_WAKEUP_EXT0, but rf69.available () (which in the loop did work) is now always false. It is like that when the ESP32 wakes up, the module's buffer is lost. I have tried using low-level programming, using the library functions to access the buffer directly and I am not able to.

Also trying to read and write RFM69HCW registers without being victorious.

I would appreciate if someone, who understands or something similar has happened, could give me a hand.

Thanks.

Who is online

Users browsing this forum: Bing [Bot] and 48 guests