I have done a paroject to send data from one device to another using NRF24L01.
Transmitter side there will be sensor. when sensor activates it will send message to receiver.
I have made transmitter to sleep mode when there is no data and wake up if there is any interrupt using WDT. Now i need to check the arduino current consumption in sleep mode and transmitting mode.
I am using Arduino pro mini device.
I tried to check with multi-meter but i couldn't if there is any software or tools to check current please let me know.
A multi meter should mostly work - problem is measuring the average current since most applications have a current draw that varies - Sparkfun makes a recording device that you should be able to put on and leave it for a while to get the total energy used in a given time
I have put arduino pro mini in sleep mode. But why it is still showing 5mA in multimeter.
Can some one please check the code if my code is correct or not.
Code for transmitter.
/////////////////////////////////////////////////////////
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
#include <SPI.h>
#include "RF24.h"
// Changing transmitter num
#define TRANSMITER_NUM 1 // or 1
#define TILT_PIN 3
//#define SERIAL_PRINT
const uint64_t talking_pipes[2] = { 0xF0F0F0F0D2LL, 0xF0F0F0F0C3LL };
const uint64_t listening_pipes[2] = { 0x3A3A3A3AD2LL, 0x3A3A3A3AC3LL };
struct DataPacket {
int voltage;
bool tilt;
};
bool volatile interruptTriggered = false;
RF24 radio(7,8);
void TiltPinInterrupt(void)
{
/* This will bring us back from sleep. */
/* We detach the interrupt to stop it from
* continuously firing while the interrupt pin
* is low.
*/
sleep_disable();
detachInterrupt(digitalPinToInterrupt(TILT_PIN));
interruptTriggered = true;
}
// Set watchdog to trigger every 8 sec.
void watchdogSetup(void)
{
wdt_reset();
/*
WDTCSR configuration:
WDIE = 1: Interrupt Enable
WDE = 1 :Reset Enable
See table for time-out variations:
WDP3 = 0 :For 1000ms Time-out
WDP2 = 1 :For 1000ms Time-out
WDP1 = 1 :For 1000ms Time-out
WDP0 = 0 :For 1000ms Time-out
*/
// Enter Watchdog Configuration mode:
// WDTCSR |= (1<<WDCE) | (1<<WDE);
WDTCSR = bit (WDCE) | bit (WDE);
// Set Watchdog settings:
//WDTCSR = bit (WDCE) | bit (WDE) | bit (WDIE) | bit (WDP3) | bit (WDP0); // set WDIE, and 8 seconds delay
WDTCSR = bit (WDCE) | bit (WDE) | bit (WDIE) | bit (WDP3); // set WDIE, and 4 seconds delay
//WDTCSR = bit (WDCE) | bit (WDE) | bit (WDIE) | bit (WDP2) | bit (WDP1) | bit (WDP0); // set WDIE, and 2 seconds delay
//WDTCSR = bit (WDCE) | bit (WDE) | bit (WDIE) | bit (WDP2) | bit (WDP1); // set WDIE, and 1 seconds delay
}
// Disable hardware to consume battery energy
void disableHardware() {
// radio.sleep(); // Set the radio transceiver in sleep mode
radio.powerDown(); // NOTE: The radio MUST be powered back up again manually
power_spi_disable(); // Disable the Serial Peripheral Interface module.
power_timer0_disable(); // Disable the Timer 0 module..
power_timer1_disable(); // Disable the Timer 1 module.
power_timer2_disable(); // Disable the Timer 2 module
power_twi_disable(); // Disable the Two Wire Interface module.
power_usart0_disable(); // Disable the USART 0 module.
// ADCSRA &= ~(1 << ADEN); // Ensure AD control register is disable before power disable
power_adc_disable(); // Disable the Analog to Digital Converter module
}
// Enable hardware
void enableHardware() {
power_spi_enable(); // Enable the Serial Peripheral Interface module.
power_timer0_enable(); // Enable the Timer 0 module..
power_timer1_enable(); // Enable the Timer 1 module.
power_timer2_enable(); // Enable the Timer 2 module
power_twi_enable(); // Enable the Two Wire Interface module.
#ifdef SERIAL_PRINT
power_usart0_enable(); // Enable the USART 0 module.
#endif
power_adc_enable(); // Enable the Analog to Digital Converter module
radio.powerUp(); // Power up the radio after sleeping
}
void enterSleep(void)
{
sleep_enable();
//disableHardware();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
//set_sleep_mode(SLEEP_MODE_IDLE);
//cli(); // disables all interrupts on the microcontroller so that configuration is never disrupted and left unfinished
noInterrupts();
// clear various "reset" flags
MCUSR = 0;
watchdogSetup();
// sleep_bod_disable();
attachInterrupt(digitalPinToInterrupt(TILT_PIN), TiltPinInterrupt, CHANGE);
//sei(); // reenable interrupts
interrupts();
sleep_cpu();
// wake up here
sleep_disable();
//enableHardware();
}
/***************************************************
* Name: setup
*
* Returns: Nothing.
*
* Parameters: None.
*
* Description: Setup for the Arduino.
*
***************************************************/
void setup()
{
Serial.begin(9600);
// Setup the pin direction.
pinMode(TILT_PIN, INPUT_PULLUP);
radio.begin();
// set power level of the radio
radio.setPALevel(RF24_PA_MAX);
// set RF datarate
radio.setDataRate(RF24_250KBPS);
// set radio channel to use - ensure it matches the target host
radio.setChannel(0x50);
// Ensure autoACK is enabled
//radio.setAutoAck(true);
// Each node has a talking pipe that it will transmit into, and a listening
// pipe that it will read for response.
// Write on our talking pipe
radio.openWritingPipe(talking_pipes[TRANSMITER_NUM]);
// Listen on our listening pipe
radio.openReadingPipe(1,listening_pipes[TRANSMITER_NUM]);
// Start listening
radio.startListening();
// Dump the configuration of the rf unit for debugging
// radio.printDetails();
//delay(2000);
getBandgap();
#ifdef SERIAL_PRINT
Serial.println("Initialisation complete.");
#endif
}
// watchdog interrupt
ISR (WDT_vect)
{
wdt_disable(); // disable watchdog
} // end of WDT_vect
const long InternalReferenceVoltage = 1100; // Adjust this value to your board's specific internal BG voltage
// Code courtesy of "Coding Badly" and "Retrolefty" from the Arduino forum
// results are Vcc * 100
// So for example, 5V would be 500.
int getBandgap ()
{
// REFS0 : Selects AVcc external reference
// MUX3 MUX2 MUX1 : Selects 1.1V (VBG)
ADMUX = bit (REFS0) | bit (MUX3) | bit (MUX2) | bit (MUX1);
ADCSRA |= bit( ADSC ); // start conversion
while (ADCSRA & bit (ADSC))
{ } // wait for conversion to complete (toss this measurement)
ADCSRA |= bit( ADSC ); // start conversion
while (ADCSRA & bit (ADSC))
{ } // wait for conversion to complete
int results = (((InternalReferenceVoltage * 1024) / ADC) + 5) / 10;
return results;
} // end of getBandgap
/***************************************************
* Name: loop
*
* Returns: Nothing.
*
* Parameters: None.
*
* Description: Main application loop.
*
***************************************************/
int cnt=0;
void loop()
{
bool sendValue = false;
DataPacket data;
cnt++;
if (cnt >= 1) {
cnt = 0;
sendValue = true;
}
if (interruptTriggered) {
sendValue = true;
interruptTriggered = false;
}
if (sendValue) {
cnt = 0;
data.voltage = getBandgap();
data.tilt = digitalRead(TILT_PIN);
//TODO: send data and wait for ACK
int resend = 0;
do {
resend++;
radio.stopListening();
// Take the time, and send it. This will block until complete
if (radio.write( &data, sizeof(data) )) {
// Now, continue listening
radio.startListening();
// Wait here until we get a response, or timeout (250ms)
unsigned long started_waiting_at = millis();
bool timeout = false;
while ( ! radio.available() && ! timeout )
if (millis() - started_waiting_at > 250 )
timeout = true;
// Describe the results
if ( timeout )
{
#ifdef SERIAL_PRINT
Serial.println("Failed, response timed out.\n\r");
#endif
}
else
{
// Grab the response, compare, and send to debugging spew
unsigned long dummy;
radio.read( &dummy, sizeof(unsigned long) );
// Spew it
#ifdef SERIAL_PRINT
Serial.println("Got response");
#endif
resend = 0;
}
} else {
#ifdef SERIAL_PRINT
Serial.println("Error sending values");
#endif
}
} while ((resend > 0) && (resend <= 3));
}
#ifdef SERIAL_PRINT
Serial.println(data.voltage, DEC);
Serial.println(data.tilt, DEC);
delay(100);
#endif
enterSleep();
}
bmg1234:
I have put arduino pro mini in sleep mode. But why it is still showing 5mA in multimeter.
Upload a minimal sleep sketch without any functionality.
When the consumption matches your expectations, start adding features until you know what breaks it.