Recent Posts

Pages: [1] 2 3 ... 10
1
ESP32 / ESP8266 / ESP32 can't read FIFO from RFM69 when esp32 wakes up
« Last post by Fran13 on Today at 10:43:27 AM »
Description:
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.

I'm using the RadioHead RFM library and RH_RF69 library to enable communication between Atmega32u4 and ESP32. The situation is the following:

As node:

1- Atmega32u4 wakes up every 60 seconds and reads sensors data.
2- Atmega32u4 sends data over RFM69HCW and goes to sleep again.

As Gateway:

1- Esp32 is in deep sleep mode and the setup for RFM69HCW is done.
2- If data is received by RFM69, then ESP32 will wake up by DIO0 connected to GPIO27 pin from ESP32 and received data will be stored in ESP32.

In a simple RadioHead_RawDemo_RX and RadioHead_RawDemo_TX  examples, without going to sleep, works properly.

When using energy saving mode, the frames are sent but not processed by ESP32 (server). Sometimes when I restart esp32 server i can see the first frame received (using a Logic Analyzer and Logi 2 - Saleae) but ESP32 never wake up again. But normally, if esp32 is not in an eternal sleep, the ESP32 wakes up caused from ext0 wakeup when I receive a message it wakes up but then the  condition if(rf69.available ()) is always false and I am not able to read the message from the buffer.

Feather32u4 code:
Code: [Select]
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();
}
ESP32 code: 
Code: [Select]
#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 seems that while the ESP32 is waking up it is just when the module receives the frame and that is why it is lost. I have tried using low-level programming using the library functions to access the buffer directly using readFifo()... but without success.

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.
2
ATXRaspi / Re: BootOK output/General feedback
« Last post by CaptainSandwich on Today at 09:48:36 AM »
What other controllers do you refer to?

In this case, it's a pair of SKR 1.4's.

While the Pi boots up the bootOK may be open drain or some other state that makes the LED very faint but not enough to be a HIGH as required by the Pi, it's a known artifact but has no effect on the functionality of ATXRaspi or the Pi.

Great, thanks for the info. A pulldown resistor solves the issue of the dim LED (undefined logic level). I had been measuring 2.3v on this input until the Pi output high (3.3v). I use this signal as an input to a SSR to control power to the SKRs.

The bootOK is an input to ATXRaspi, and the BOOTOK green LED is hardwired to it, so it cannot be changed in firmware.

Altering the state of the status LED during the bootup process (dim/flashing) would be possible via firmware though?

ATXRaspi triggers a OS shutdown and then cuts power off completely, which the Pi cannot do on its own. You can see the guide for a soft shutdown that triggers Atxraspi to then do the hard shutdown instead.

Understood. What I was referring to was replacing Raspbian's built-in shutdown script with a new script containing a portion of your code that triggers the ATXRaspi (depending on arguments). This way, any call to shutdown the Pi results in the ATXRaspi doing its business and the Pi completely powering off. This is great because it allows me to perform a complete power off from Fluidd (the interface I'm using for Klipper) without having to modify the source to call a different shutdown script/alias.
3
ATXRaspi / Re: BootOK output/General feedback
« Last post by Felix on May 11, 2021, 10:30:56 AM »
First, I was hoping to use the "BootOK" signal to interface with a relay. This would turn off power to the other controllers when the Pi is off since they're unable to function without it. Unfortunately, the PWM (?) output on this signal while the Pi is starting/shutting down was unexpected and makes this much more complicated. I personally don't feel it's particularly necessary either, at least on this signal. In my case, it would be preferred that the BootOK signal was purely high/low to indicate the 'ready' state of the Pi.
What other controllers do you refer to?
The BOOTOK signal is explained in the guide. It is set by the Pi to HIGH once the OS boots up. It's how the ATXRaspi knows everything is OK and it can request a SHUTDOWN. It is a Green led to let the user know the script has issued that BOOTOK signal and all is good. It is not designed or intended to be used in any other way.
While the Pi boots up the bootOK may be open drain or some other state that makes the LED very faint but not enough to be a HIGH as required by the Pi, it's a known artifact but has no effect on the functionality of ATXRaspi or the Pi.

This kind of leads into the second item as well. The dimmed BootOK LED is nice in that it shows the Pi is on but not yet 'ready', but I feel like this would be better suited to the status LED since it's more likely to be visible. The various flashing states of the status LED on shutdown/reboot are quite effective.

Are these things that could be modified in the firmware?
The bootOK is an input to ATXRaspi, and the BOOTOK green LED is hardwired to it, so it cannot be changed in firmware.

Finally, I have no idea if this is frowned upon, however I followed a post here (https://askubuntu.com/questions/1010120/intercept-shutdown-call-and-run-script-to-allow-or-prevent-shutdown) to replace the original shutdown script with the soft power off script. It works fantastically so selecting shutdown from the webui runs the soft power off.
ATXRaspi triggers a OS shutdown and then cuts power off completely, which the Pi cannot do on its own. You can see the guide for a soft shutdown that triggers Atxraspi to then do the hard shutdown instead.

Anyway, thanks for your efforts Felix. Such a simple function but really makes the user experience a lot better.
You're welcome!
4
Moteino / Re: Moteino RFM95 - switch freq to 868
« Last post by Felix on May 10, 2021, 10:56:03 AM »
it will work, albeit not as well as a perfectly tuned antenna.
5
ATXRaspi / BootOK output/General feedback
« Last post by CaptainSandwich on May 10, 2021, 09:40:00 AM »
Hi Felix,

I've just today finished installing my ATXRaspi R3 into a 3D printer running Klipper on a Pi. It's nice being able to safely shutdown the Pi from the machine without having to login to the webui first. In this application, I have a couple of questions/points of feedback.

First, I was hoping to use the "BootOK" signal to interface with a relay. This would turn off power to the other controllers when the Pi is off since they're unable to function without it. Unfortunately, the PWM (?) output on this signal while the Pi is starting/shutting down was unexpected and makes this much more complicated. I personally don't feel it's particularly necessary either, at least on this signal. In my case, it would be preferred that the BootOK signal was purely high/low to indicate the 'ready' state of the Pi.

This kind of leads into the second item as well. The dimmed BootOK LED is nice in that it shows the Pi is on but not yet 'ready', but I feel like this would be better suited to the status LED since it's more likely to be visible. The various flashing states of the status LED on shutdown/reboot are quite effective.

Are these things that could be modified in the firmware?

Finally, I have no idea if this is frowned upon, however I followed a post here (https://askubuntu.com/questions/1010120/intercept-shutdown-call-and-run-script-to-allow-or-prevent-shutdown) to replace the original shutdown script with the soft power off script. It works fantastically so selecting shutdown from the webui runs the soft power off.

Anyway, thanks for your efforts Felix. Such a simple function but really makes the user experience a lot better.
6
Moteino / Re: Moteino RFM95 - switch freq to 868
« Last post by d00m178 on May 09, 2021, 01:59:42 AM »
thank you

I suppose also I need change antenna for 868?
with old antenna (for 915) - it will not work well?
7
Pi Gateway / Re: Pi Hat PCB feedback?
« Last post by Felix on May 08, 2021, 10:32:53 AM »
Thanks for the update.
One thought I have is whether this type of approach with radio driven by a software driver can even work reliably.
Latency is of utmost importance especially when ACKs are involved, and a low power node cannot sit in RX mode a "long" time to wait until a OS decides to give attention to a received package at the gateway, and then wait until it has the next turn to the GPIO to send a reply.
I have not even tried actually, hence my blurb. I have always used a Moteino which handles all the RF part, or lately the RFGateway board. Then the Pi has no knowledge of the RF part, and can nicely meet the separation of concerns pattern.
8
Pi Gateway / Re: Pi Hat PCB feedback?
« Last post by amadeuspzs on May 08, 2021, 08:37:35 AM »
I did indeed make it and found two errors:

1. I messed up the footprint of the GPIO header; KiCad's default is left to right but on the Pi it's top to bottom
2. I guessed a trace width, instead of calculating an impedance matched trace.

I've since fixed 1 and 2 (with a coplanar waveguide with ground calculated using KiCad's tool) and am just waiting for the PCBs to (very very slowly) arrive from JLCPCB.

When it's up and running I'll share here.

The motivation for this is that I don't need the full functionality of the Pi Gateway/PiHat etc - I just need access to read/write packets from the RFM chip using the python wrapper https://pypi.org/project/rpi-rfm69/ so I can send on the data via MQTT to Home Assistant.

A
9
Pi Gateway / Permission Levels for Gateway App
« Last post by Jason on May 07, 2021, 07:35:48 PM »
Has anyone played around with making accounts with different permission levels for the gateway app?

Example:
Admin Account - Everything
Middle Account - Read and Interact - like could turn motes on and off
Viewer Account - Read only - just look at data
10
Pi Gateway / Re: Pi Hat PCB feedback?
« Last post by Jason on May 07, 2021, 07:31:18 PM »
That looks really cool!

Did you end up making it and trying it out?

What is your reasoning for doing it this way without having a micro controller between the radio and the pi?
Pages: [1] 2 3 ... 10