I have an ATtiny85 and an Arduino Uno both using NRF24L01 chips to communicate with one another. The ATtiny85 is powered by a CR2032 coin cell. I am using tmrh20's fork of the RF24 library which can be found here. Here's the problem I'm encountering:
Under the current code posted, the Uno will receive about 80 packets of data (80 packets times 2 seconds per packet is about 160 seconds of time) before the ATtiny will simply stop sending, and the Uno receives no more data. I can tell that it's the ATtiny, because I've got a DMM hooked up to it. Normally, my DMM tells me that the ATtiny is drawing less than 0.005mA of current, but at the instance of the stall the DMM reads approximately 1.4 mA of current draw, which makes sense because under normal conditions with no sleep the ATtiny draws about 1mA, and the radio not in power down mode and not transmitting draws 0.4mA.
I've spent quite some time trying everything from setting the clock speed to a different value (it's at 1MHz) to changing the power amplifier value. The only thing I've tried that makes an impact is getting rid of the powerUp and powerDown function calls. Once these are removed everything works perfectly transmission-wise, except the only issue is that the whole system is drawing 0.4mA constantly, which is too much.
I don't think the coin cell is a problem considering the system works when the powerUp and powerDown calls are removed. Here's my code:
Reciever:
#define CE_PIN 7
#define CSN_PIN 8
#include <SPI.h>
#include "RF24.h"
RF24 radio(CE_PIN, CSN_PIN);
byte address[11] = "SimpleNode";
unsigned long payload = 0;
void setup() {
while (!Serial);
Serial.begin(115200);
radio.begin(); // Start up the radio
radio.setAutoAck(1); // Ensure autoACK is enabled
radio.setRetries(15,15); // Max delay between retries & number of retries
radio.openReadingPipe(1, address); // Write to device address 'SimpleNode'
radio.startListening();
Serial.println("Did Setup");
}
long counter = 0;
void loop(void){
if (radio.available()) {
radio.read( &payload, sizeof(unsigned long) );
if(payload != 0){
Serial.print("Got Payload ");
Serial.print(payload);
Serial.print(" - ");
Serial.println(counter);
counter++;
}
}
}
Transmitter:
//Sleep
#include <avr/sleep.h>
const int sleepSecs = 2;
//Radio
#define CE_PIN 3
#define CSN_PIN 3 //Since we are using 3 pin configuration we will use same pin for both CE and CSN
#include "RF24.h"
RF24 radio(CE_PIN, CSN_PIN);
byte address[11] = "SimpleNode";
unsigned long payload = 0;
void setup() {
//Setup radio
radio.begin(); // Start up the radio
radio.setAutoAck(1); // Ensure autoACK is enabled
radio.setRetries(15,15); // Max delay between retries & number of retries
//RF24_PA_MIN, RF24_PA_LOW, RF24_PA_HIGH and RF24_PA_MAX
radio.setPALevel(RF24_PA_HIGH);
radio.openWritingPipe(address); // Write to device address 'SimpleNode'
//Setup sleep
setup_watchdog(6);
set_sleep_mode(SLEEP_MODE_PWR_DOWN); //Power down everything, wake up from WDT
sleep_enable();
}
volatile int watchdog_counter = 0;
ISR(WDT_vect) {
watchdog_counter++;
}
void loop() {
sleep_mode(); //Go to sleep!
if(watchdog_counter >= sleepSecs)
{
ADCSRA |= (1<<ADEN);
radio.powerUp();
watchdog_counter = 0;
payload = 123456;
radio.write(&payload, sizeof(unsigned long) ); //Send data to 'Receiver' every second
radio.powerDown();
ADCSRA &= ~(1<<ADEN); //Disable ADC, saves ~230uA
}
}
//Sets the watchdog timer to wake us up, but not reset
//0=16ms, 1=32ms, 2=64ms, 3=128ms, 4=250ms, 5=500ms
//6=1sec, 7=2sec, 8=4sec, 9=8sec
//From: http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
void setup_watchdog(int timerPrescaler) {
if (timerPrescaler > 9 ) timerPrescaler = 9; //Limit incoming amount to legal settings
byte bb = timerPrescaler & 7;
if (timerPrescaler > 7) bb |= (1<<5); //Set the special 5th bit if necessary
//This order of commands is important and cannot be combined
MCUSR &= ~(1<<WDRF); //Clear the watch dog reset
WDTCR |= (1<<WDCE) | (1<<WDE); //Set WD_change enable, set WD enable
WDTCR = bb; //Set new watchdog timeout value
WDTCR |= _BV(WDIE); //Set the interrupt enable, this will keep unit from resetting after each int
}