Hi Chris,
Yes I’ve tried with 5V from USB and I now use the 4V from Vhi + capacitor, not from external AA.
You module is not working well even at 4V if I don’t add the cap.
Everything is now “working as expected” but the slow speed on wake up.
I’ve tried again with the Chinese model, and it is also slower, but not as much, it’s lot less noticeable for unknown reasons.
I’ve tried my code on a Pro Micro 16Mhz, same behavior, so it’s not the ItsyBitsy.
Even if I cut down the power totally and initialize again on wake up it is slow.
What’s strange, is that if I click on the button right after the wake up the first Tx is OK, it means that it’s only after a very short period (~2-3s) that the Tx become slow.
After all the tests I’ve performed I don’t think it’s due to the RF module, something that is happening inside the device during sleep is impacting the RF transmissions, but what ?
Here is my full code :
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <ctype.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <Bounce2.h>
#include <LowPower.h>
#define BUTTON_PIN 0
#define LED_PIN 1
#define CE_PIN A4
#define CSN_PIN A5
#define LOW_POWER_MODE_PIN 8
#define BLINK_INTERVAL 1000
#define SLEEP_DELAY 480000
//LED states
#define LED_OFF 0
#define LED_ON 1
#define LED_BLINK 2
//LED blink speed
#define LED_SLOW 1000
//LED Brightness
#define LED_MAX_BRIGHTNESS 255
#define LED_MED_BRIGHTNESS 150
#define LED_MIN_BRIGHTNESS 50
//**************************************************************************************
float version = 2.06;
//**************************************************************************************
//RF24
const uint8_t masterAddress[6] = "SRV00";
uint8_t thisButtonAddress[6];
const uint8_t DIPSwitchPins[] = { 7, 9, 10, 11 };
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
volatile int ledState = LOW;
volatile bool do_blinkLed = false;
volatile bool wakeUP = false;
//volatile bool turnedON = true;
long previousMillis = 0;
long lastActionMillis = 0;
Bounce debouncer = Bounce();
int RcvCnt = 0;
int buttonNumber = 0;
//Struct for LED
struct LED {
byte state;
int blinkSpeed;
int blinkCount;
int brightness;
unsigned long lastStateChange;
};
//Struct for data to send
typedef struct {
uint8_t rnd;
uint8_t type;
uint8_t msg;
}
A_t;
//Struct for data received
typedef struct {
uint8_t rnd;
uint8_t type;
uint8_t msg;
}
B_t;
A_t Data_Sent;
B_t Data_Received;
struct LED led = { LED_BLINK, LED_FAST, 3, 0, 0 };
//****************************************
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT); //Led pin
pinMode(13, OUTPUT);// onboard LED
digitalWrite(13, LOW);
pinMode(LOW_POWER_MODE_PIN, INPUT_PULLUP); //Low power mode pin
getButtonNr();
delay(500);
radio.begin();
delay(500);// Give RF module some time to run.
setupRF24();
debouncer.attach(BUTTON_PIN, INPUT_PULLUP);
debouncer.interval(5); // interval in ms
// No power save if Button is pressed or if Jumper is present
if (digitalRead(BUTTON_PIN) ? 1 : 0 || digitalRead(LOW_POWER_MODE_PIN) ? 0 : 1) {
digitalWrite(13, HIGH);//turn ON on board led to indicate that we are well connected to USB
}
else {
//save power
ADCSRA = 0;
power_adc_disable();
power_twi_disable();
power_usart0_disable();
power_usart1_disable();
power_timer2_disable();
power_timer3_disable();
// disable the USB
USBCON |= _BV(FRZCLK); //freeze USB clock
PLLCSR &= ~_BV(PLLE); // turn off USB PLL
USBCON &= ~_BV(USBE); // disable USB
power_usb_disable();
}
}
//****************************************
void loop() {
if (wakeUP) {
radio.powerUp();
delay(500);
pinMode(BUTTON_PIN, INPUT_PULLUP);
led.state = LED_BLINK;
led.blinkCount = 3;
wakeUP = false;
lastActionMillis = millis();
}
do {
LED();
debouncer.update(); // Update the Bounce instance
// Wait for button being pressed
if (debouncer.read() == HIGH) {
if (millis() - lastActionMillis > 200) {
if (led.state == LED_OFF || !LED_BLINK) {
sendToMaster(buttonNumber);
}
}
lastActionMillis = millis();
}
//Go to sleep if no actions for some times
if (millis() - lastActionMillis > SLEEP_DELAY) {
sleepNow(); //Time to go to sleep to save some power, wake up when button pressed
}
} while (!radio.available());
radio.read(&Data_Received, sizeof(Data_Received));
int order = Data_Received.msg;
switch (Data_Received.msg) {
case 0://test
break;
case 10://Make the led blinking
led.state = LED_BLINK;
led.blinkCount = 65000;
led.brightness = 0;
break;
case 11://Turn light on
led.state = LED_ON;
break;
case 12://Turn light off
led.state = LED_OFF;
break;
case 55://Force to go to sleep
sleepNow();
break;
case 66://Reset button
led.state = LED_OFF;
led.blinkCount = 0;
break;
break;
case 99://Answer Hello I'm alive
break;
}
lastActionMillis = millis();
}
//****************************************
void setupRF24() {
radio.setDataRate(RF24_250KBPS);
radio.setPALevel(RF24_PA_MAX);
radio.setChannel(125);
radio.openReadingPipe(1, thisButtonAddress);
radio.enableAckPayload();
radio.setRetries(5, 15); // delay, count
radio.startListening();
radio.openWritingPipe(masterAddress);
}
//****************************************
void sendToMaster(int cmd) {
if (Data_Sent.rnd == 0) {
srandom(random() ^ ((uint32_t)analogRead(4) << 22) ^ micros());
Data_Sent.rnd = random(0, 5000);
}
else {
Data_Sent.rnd++;
}
Data_Sent.msg = cmd;
radio.stopListening();
delay(10);
radio.write(&Data_Sent, sizeof(Data_Sent));
radio.startListening();
}
//****************************************
void blinkLED() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > BLINK_INTERVAL) {
// save the last time you blinked the LED
previousMillis = currentMillis;
// set the LED with the ledState of the variable:
digitalWrite(LED_PIN, ledState);
ledState = !ledState;
}
}
//****************************************
void blinkLED(int d) {
digitalWrite(LED_PIN, HIGH);
delay(d);
digitalWrite(LED_PIN, LOW);
}
//****************************************
void blinkLED(int d, int t) {
for (int i = 0; i < t; i++) {
blinkLED(d);
delay(d);
}
}
//****************************************
//Read the button number from the DIP switch
void getButtonNr() {
for (int i = 0; i < sizeof(DIPSwitchPins); ++i) {
// Setup pin
pinMode(DIPSwitchPins[i], INPUT_PULLUP);
uint8_t curState = digitalRead(DIPSwitchPins[i]) ? 0 : 1;
buttonNumber += (curState << i);
}
snprintf(thisButtonAddress, 6, "BTN%02d", buttonNumber);
}
//****************************************
void LED() {
unsigned long date = millis();
int valeurPWM;
switch (led.state) {
case LED_OFF:
analogWrite(LED_PIN, 0);
break;
case LED_ON:
analogWrite(LED_PIN, LED_MAX_BRIGHTNESS);
break;
case LED_BLINK:
if (date - led.lastStateChange >= led.blinkSpeed) {
led.lastStateChange = date;
switch (led.brightness) {
case 0:
led.brightness = 250;
break;
case 250:
led.brightness = 0;
led.blinkCount--;
break;
}
analogWrite(LED_PIN, led.brightness);
if (led.blinkCount == 0)
led.state = LED_OFF;
}
break;
}
}
//****************************************
void wakeUpNow() {
power_timer0_enable();
power_timer1_enable();
power_spi_enable();
wakeUP = true;
}
//****************************************
void sleepNow() {
radio.powerDown();
blinkLED(300, 2);
led.state = LED_OFF;
attachInterrupt(2, wakeUpNow, CHANGE);
power_timer0_disable();
power_timer1_disable();
power_spi_disable();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode();
sleep_disable();
detachInterrupt(2);
}