Monday, February 16, 2015

Getting Started with the nRF24L01 Transceiver

In this video we look at how to get up and running with the low cost nRF24L01+ transceiver module from Nordic.



nRF24L01 connected to an Arduino Pro Mini


***********Arduino code for transmit module*********************************
//This sketch is from a tutorial video for getting started with the nRF24L01 tranciever module on the ForceTronics YouTube Channel
//the code was leverage from Ping pair example at http://tmrh20.github.io/RF24/pingpair_ack_8ino-example.html
//This sketch is free to the public to use and modify at your own risk

#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include "printf.h" //This is used to print the details of the nRF24 board. if you don't want to use it just comment out "printf_begin()"

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
byte counter = 1; //used to count the packets sent
bool done = false; //used to know when to stop sending packets
RF24 wirelessSPI(pinCE, pinCSN); // Create your nRF24 object or wireless SPI connection
const uint64_t pAddress = 0xB00B1E5000LL;              // Radio pipe addresses for the 2 nodes to communicate.

void setup()  
{
  Serial.begin(57600);   //start serial to communicate process
  printf_begin();        //This is only used to print details of nRF24 module, needs Printf.h file. It is optional and can be deleted
  wirelessSPI.begin();            //Start the nRF24 module
  wirelessSPI.setAutoAck(1);                    // Ensure autoACK is enabled so rec sends ack packet to let you know it got the transmit packet payload
  wirelessSPI.enableAckPayload();               // Allow optional ack payloads
  wirelessSPI.setRetries(5,15);                 // Sets up retries and timing for packets that were not ack'd, current settings: smallest time between retries, max no. of retries
  wirelessSPI.openWritingPipe(pAddress);        // pipe address that we will communicate over, must be the same for each nRF24 module
  wirelessSPI.stopListening();
  wirelessSPI.printDetails();                   // Dump the configuration of the rf unit for debugging
}


void loop()  
{

 if(!done) { //if we are not done yet
    Serial.print("Now send packet: "); 
    Serial.println(counter); //serial print the packet number that is being sent
    unsigned long time1 = micros();  //start timer to measure round trip
    //send or write the packet to the rec nRF24 module. Arguments are the payload / variable address and size
   if (!wirelessSPI.write( &counter, 1 )){  //if the send fails let the user know over serial monitor
       Serial.println("packet delivery failed");      
   }
   else { //if the send was successful 
      unsigned long time2 = micros(); //get time new time
      time2 = time2 - time1; //calculate round trip time to send and get ack packet from rec module
      Serial.print("Time from message sent to recieve Ack packet: ");
      Serial.print(time2); //print the time to the serial monitor
      Serial.println(" microseconds");
       counter++; //up the packet count
   }
   
   //if the reciever sends payload in ack packet this while loop will get the payload data
   while(wirelessSPI.available() ){ 
       char gotChars[5]; //create array to hold payload
       wirelessSPI.read( gotChars, 5); //read payload from ack packet
       Serial.print(gotChars[0]); //print each char from payload
       Serial.print(gotChars[1]);
       Serial.print(gotChars[2]);
       Serial.println(gotChars[3]);
       done = true; //the ack payload signals we are done
     }
  }

    delay(1000);
}

***********Arduino code for receiver module*********************************
//This sketch is from a tutorial video for getting started with the nRF24L01 tranciever module on the ForceTronics YouTube Channel
//the code was leverage from Ping pair example at http://tmrh20.github.io/RF24/pingpair_ack_8ino-example.html
//This sketch is free to the public to use and modify at your own risk

#include <SPI.h> //Call SPI library so you can communicate with the nRF24L01+
#include <nRF24L01.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include <RF24.h> //nRF2401 libarary found at https://github.com/tmrh20/RF24/
#include "printf.h" //This is used to print the details of the nRF24 board. if you don't want to use it just comment out "printf_begin()"

const int pinCE = 9; //This pin is used to set the nRF24 to standby (0) or active mode (1)
const int pinCSN = 10; //This pin is used to tell the nRF24 whether the SPI communication is a command or message to send out
byte gotByte = 0; //used to store payload from transmit module
bool done = false;
RF24 wirelessSPI(pinCE, pinCSN); // Declare object from nRF24 library (Create your wireless SPI) 
const uint64_t pAddress = 0xB00B1E5000LL;  //Create a pipe addresses for the 2 nodes to communicate over, the "LL" is for LongLong type

void setup()   
{
  Serial.begin(57600);  //start serial to communicate process
  printf_begin();  //This is only used to print details of nRF24 module, needs Printf.h file. It is optional and can be deleted
  wirelessSPI.begin();  //Start the nRF24 module
  wirelessSPI.setAutoAck(1);                    // Ensure autoACK is enabled, this means rec send acknowledge packet to tell xmit that it got the packet with no problems
  wirelessSPI.enableAckPayload();               // Allow optional payload or message on ack packet
  wirelessSPI.setRetries(5,15);                 // Defines packet retry behavior: first arg is delay between retries at 250us x 5 and max no. of retries
  wirelessSPI.openReadingPipe(1,pAddress);      //open pipe o for recieving meassages with pipe address
  wirelessSPI.startListening();                 // Start listening for messages
  wirelessSPI.printDetails();                   //print details of nRF24 module to serial, must have printf for it to print to serial
}

void loop()  
{   
    if(gotByte >= 9 & !done) { //once we get 10 packets send ack packet with payload telling the transmit module we are done
       char cArray[5] = "done"; //create char array to store "done," note that the fifth char is for the null character
       wirelessSPI.writeAckPayload(1, cArray, sizeof(cArray));  //send ack payload. First argument is pipe number, then pointer to variable, then variable size
     }
   //loop until all of the payload data is recieved, for this example loop should only run once
    while(wirelessSPI.available() & !done){ 
     wirelessSPI.read( &gotByte, 1 ); //read one byte of data and store it in gotByte variable
     Serial.print("Recieved packet number: "); //payload counts packet number
     Serial.println(gotByte); //print payload / packet number
    }
    
    if(gotByte > 9) done = true; //we are finished so set "done" to true
   
  delay(200);    
}

***********Arduino code for Printf.h file*********************************
/*
 Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 version 2 as published by the Free Software Foundation.
 */

/**
 * @file printf.h
 *
 * Setup necessary to direct stdout to the Arduino Serial library, which
 * enables 'printf'
 */

#ifndef __PRINTF_H__
#define __PRINTF_H__

#ifdef ARDUINO

int serial_putc( char c, FILE * ) 
{
  Serial.write( c );

  return c;


void printf_begin(void)
{
  fdevopen( &serial_putc, 0 );
}

#else
#error This example is only for use on Arduino.
#endif // ARDUINO

#endif // __PRINTF_H__

Monday, February 2, 2015

Getting Started with Digital Potentiomenters

In this video we will look at what Digital Potentiometers are, how to understand their specs, and we will go over an example setup with two digital potentiometers and Arduino.



********************Arduino Code*************************************************
//Example Arduino sketch used to control two digital potential in a video tutorial on the ForceTronics YouTube Channel
//This code is in the public domain and free for anybody to use at their own risk

#include "SPI.h" //SPI communication library

int nVolatile = 0b00100000; //status register value to store resistance value in non-volatile memory
int vWrite = 0b00000000; //status register to write resistance value (volatile)
int countPot1 = 0; //variable for MCP4161 dig pot value
int countPot2 = 0; //variable for MCP4131 dig pot value
int countDown1 = 0; //variable to control counting up and down for dig pot 1
int countDown2 = 0; //variable to control counting up and down for dig pot 2

void setup() {
  pinMode(6, OUTPUT);   //Set PWM pin to output 
  pinMode(2, OUTPUT);   //This pin controls SPI comm with dig pot 1
  pinMode(3, OUTPUT);   //This pin controls SPI comm with dig pot 2
  SPI.begin(); //Starts SPI communication
  analogWrite(6, 100); //Set pin 6 to PWM at 39 percent duty cycle
}

void loop() {
  writeToDigPot1(countPot1); //write resistance setting to dig pot 1
  writeToDigPot2(countPot2); //write resistance setting to dig pot 2

 if(!countDown1 & countPot1 < 255) { //If counting up and below 256 
   countPot1++; //up the resistance setting by 1
 }
 else { //time to count down now
  if(countPot1 > 0) { //if resistor setting is above 0
    countPot1--; //reduce resistor value
    countDown1 = 1; //remain in countdown mode
  } 
  else { //switch back to count up mode
    countPot1++; //up the resistance setting by 1
    countDown1 = 0; //set to count up mode
  }
 }

 if(!countDown2 & countPot2 < 70) { //If counting up and below 70
  countPot2++; //up the resistance setting by 1
 }
 else { //time to count down now
  if(countPot2 > 0) { //if resistor setting is above 0
    countPot2--; //reduce resistor value
    countDown2 = 1; //remain in countdown mode
  } 
  else { //switch back to count up mode
    countPot2++; //up the resistance setting by 1
    countDown2 = 0; //set to count up mode
  }
 }
  
  delay(8);
}

//This function handles the SPI communication to change resistor setting to dig pot 1
//input argument is resistance setting
void writeToDigPot1(int val) {
  digitalWrite(2, LOW);   //enable SPI comm to dig pot one
  digitalWrite(3, HIGH);  //disable SPI comm to dig pot 2
  delay(1); //short delay to ensure dig pins changed state
  SPI.transfer(vWrite); //status register set to write
  SPI.transfer(val); //write resistance value to dig pot
}

//This function handles the SPI communication to change resistor setting to dig pot 2
//input argument is resistance setting
void writeToDigPot2(int val) {
  digitalWrite(3, LOW);   //enable SPI comm to dig pot 2
  digitalWrite(2, HIGH);  //disable SPI comm to dig pot 1
  delay(1); //short delay to ensure dig pins changed state
  SPI.transfer(vWrite); //status register set to write
  SPI.transfer(val); //write resistance value to dig pot
}

//This function handles the SPI communication to set dig pot 1 value in non-volatile memory
//input argument is resistance setting
void writeDigPot1NV(int val) {
  digitalWrite(2, LOW);   //enable SPI comm to dig pot one
  digitalWrite(3, HIGH);  //disable SPI comm to dig pot 2
  delay(1); //short delay to ensure dig pins changed state
  SPI.transfer(nVolatile); //status register set to non-volatile write
  SPI.transfer(val); //write resistance value to dig pot
}

Sunday, January 25, 2015

How to Use a MOSFET as a Switch

In this video we will cover:
  • What is a MOSFET
  • MOSFET switch vs mechanical switch
  • How to use MOSFET as a switch
  • Go over example using a MOSFET as a switch with Arduino



Arduino Code********************************************************************
//This example code was used on the Forcetronics YouTube Channel to demonstrate how to use 
//A MOSFET as a switch. The code is open for anybody to use or modify

const int nMOS = 2; //create variable for n channel MOSFET pin
const int pMOS = 3; //create variable for p channel MOSFET pin

void setup() {
  pinMode(nMOS, OUTPUT);   // set pin to output
  pinMode(pMOS, OUTPUT);   // set pin to output
}

void loop() {
  digitalWrite(nMOS, HIGH);   // set n MOSFET gate to high, this will turn it on or close switch
  digitalWrite(pMOS, HIGH);   // set p MOSFET gate to high, this will turn it off or open switch
  delay(750);
  digitalWrite(nMOS, LOW);    // set n MOSFET gate to low, this will turn it off or open switch
  digitalWrite(pMOS, LOW);    // set p MOSFET gate to low, this will turn it on or close switch
  delay(750);
}

Wednesday, January 21, 2015

Maximizing Arduino’s ADC Resolution and Accuracy Part 3

In part three we look at the three main sources of error in an ADC measurement. We will discuss how to reduce total ADC error and how to quantify the total error of an ADC measurement.


Sunday, January 11, 2015

Maximizing Arduino’s ADC Resolution and Accuracy Part 2

In part 2 we will look at how to increase the accuracy of our ADC measurements using the built-in Noise Reduction Mode



Arduino Code********************************************************************
/*This example sketch shows how to make ADC measurements via registers and how to use the low noise or noise cancellation ADC measurement capability. 
This was shown in an ADC tutorial on the ForceTronics YouTube Channel.
This code is free and open for anybody to use at their own risk. 1/9/15
*/
#include <avr/sleep.h>

int normADC[10]; //Create an arrray to hold the "normal" or non-low noise ADC measurements
int lowNoiseADC[10]; //Create an array to hold the low noise ADC measurements

int const aVCC = 0b01000000; //variable to set ADC to use VCC as reference
int const iREF = 0b11000000; //variable to set ADC to use internal 1.1V as reference
int const aREF = 0b00000000; //variable to set ADC to use VCC as reference
//bits 7 and 6 select the ADC reference source
//The four zeros (bits 3 thru 0) at the end of the above binary register values sets the analog channel to A0
//Bit 5 selects right adjust for the result and bit 4 is not used

//Setup code only run once
void setup() {
  ADMUX = aVCC; //Configure the ADC via the ADMUX register for VCC as reference, result right adjust, and source A0 pin
  ADCSRA |= 1<<ADEN; //Turn the ADC on by setting the ADEN bit to 1 in the ADCSRA register
  ADCSRA |= 1<<ADIE; //Setting the ADIE bit to 1 means when the ADC is done a measurement it generates an interrupt, the interrupt will wake the chip up from low noise sleep
  ADCSRA |= ((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0));    //Prescaler at 128 so we have an 125Khz clock source
  //The ADC clock must be between 50kHz and 200kHz, since the Uno clock is 16MHz we want to divide it by 128 to get 125kHz. This may need to be adjusted for other Arduino boards
  //We do not have to use registers to set the sleep mode since we are using the avr/sleep.h library
  sleep_enable(); //enable the sleep capability
  set_sleep_mode(SLEEP_MODE_ADC); //set the type of sleep mode. We are using the ADC noise reduction sleep mode
  //Note that in this sleep mode the chip automatically starts an ADC measurement once the chip enters sleep mode
  //Note that the reason for making the ADC measurements and storing in arrays was to avoid using the arduino serial functions with sleep mode since serial uses interrupts
  for(int i=0; i<10; i++) { //Loop ten times and make ten ADC measurements in low noise mode
    sei(); //enable interrupts
    sleep_cpu(); //enter low ADC noise sleep mode, this action turns off certain clocks and other modules in the chip so they do not generate noise that affects the accuracy of the ADC measurement
    //The chip remains in sleep mode until the ADC measurement is complete and executes an interrupt which wakes the chip from sleep
    lowNoiseADC[i] = ADC; //get ADC result and store it in low noise measurement array
  }
  
  for(int k=0; k<10; k++) { //loop executes 10 times and makes 10 normal ADC measurements
    ADCSRA |= 1<<ADSC; //this bit starts conversion. It will remain high until conversion is complete
    while(ADCSRA & (1<<ADSC)) { delay(1);} //When ADSC bit goes low conversion is done
    normADC[k] = ADC; //get ADC result and store it in normal ADC measurement array
  }
  
  Serial.begin(9600); //Start serial comm to print out results to serial monitor
  while(!Serial.available()) { delay(1); } //wait to print out results until serial monitor is open and any character is sent
  Serial.println("Noise reduction:"); //labels the readings being printed
  for(int j=0; j<10;j++) { //loop ten times to print out all the low noise measurement in array
    Serial.println(convertToVolt(lowNoiseADC[j]),3); //Convert each low noise measurement to a voltage level and send it over serial with three decimal places precision
  }
  Serial.println(); //print a line feed
  Serial.println("No noise reduction:"); //print heading for normal ADC measurements
  for(int l=0; l<10;l++) { //loop ten times and print each ADC reading
    Serial.println(convertToVolt(normADC[l]),3); //Convert each normal ADC measurement to a voltage level and send it over serial with three decimal places precision
  }
}

void loop() {
 //do nothing in the loop
}

//This function takes the ADC integer value and turns it into a voltage level. The input is the measured ADC value.
float convertToVolt(int aVAL) {
  float refVal = 5.01;  //hard coded in AVCC value, measured the real value for higher accuracy
  return (((float)aVAL/1023)*refVal); //formula to convert ADC value to voltage reading
}

//this is the interrupt service routine for the ADC interrupt. This must be in the code for the interrupt to work correctly
ISR(ADC_vect) {
}

Wednesday, January 7, 2015

Maximizing Arduino’s ADC Resolution and Accuracy Part 1

In part 1, of this 3 to 4 part series, we will look at what ADC measurement resolution is and how to maximize it on the Arduino. We will also look at a simple hint to increase Arduino's ADC measurement accuracy. In later parts we will get much deeper into accuracy and how to increase it.




Arduino Code using analogreference()*************************************************
/*This example sketch shows how to change the reference for Arduino's ADC to default or internal 1.1V.
This sketch was used to show the measurement resolution advantage of scaling Arduino's ADC reference to 
the voltage range or scale being measured. This was shown in an ADC tutorial on the ForceTronics YouTube Channel.
This code is free and open for anybody to use at their own risk. 1/6/15
*/
float const aVCC = 5.049; //Actual measured voltage value at AVCC pin. This is im
float const iREF = 1.084; //Actual measured voltage value of the internal 1.1V reference
//Note that these values can be measured at the AREF pin

void setup() {
  Serial.begin(9600); //setup serial connection
}

void loop() {
  
  delay(1000); //delay 1 second between each ADC measurement
  analogReference(DEFAULT); //set the ADC reference to default which is AVCC (uses power supply voltage or VCC as reference)
  burn8Readings(); //make 8 readings but don't use them to ensure good reading after reference change
  Serial.println("Default (AVCC) Ref:");
  Serial.println(convertToVolt(aVCC,analogRead(A0)),3); //Make ADC measurement at A0, convert it to a voltage value, write value to serial with 3 decimal places 
  Serial.println(" ");
  delay(1000); //delay 1 second between each ADC measurement
  analogReference(INTERNAL); //set the ADC reference to internal 1.1V reference
  burn8Readings(); //make 8 readings but don't use them to ensure good reading after reference change
  Serial.println("Internal 1.1V Ref:");
  Serial.println(convertToVolt(iREF,analogRead(A0)),3); //Make ADC measurement at A0, convert it to a voltage value, write value to serial with 3 decimal places
  Serial.println(" ");
}

//This function makes 8 ADC measurements but does nothing with them
//Since after a reference change the ADC can return bad readings at first. This function is used to get rid of the first 
//8 readings to ensure an accurate one is displayed
void burn8Readings() {
  for(int i=0; i<8; i++) {
    analogRead(A0);
    delay(1);
  }
}

//This function convers the ADC level integer value into a useful voltage value.
//The inputs are the measured ADC value and the ADC reference voltage level
//The formula used was obtained from the data sheet: (ADC value / 1024) x ref voltage
float convertToVolt(float refVal, int aVAL) {
  return (((float)aVAL/1024)*refVal);
}

Arduino Code using Registers*************************************************
/*This example sketch shows how to change the reference for Arduino's ADC to default or internal 1.1V using registers.
This sketch was used to show the measurement resolution advantage of scaling Arduino's ADC reference to 
the voltage range or scale being measured. This was shown in an ADC tutorial on the ForceTronics YouTube Channel.
This code is free and open for anybody to use at their own risk. 1/6/15
*/

int const aVCC = 0b01000000; //variable to set ADC to use VCC as reference
int const iREF = 0b11000000; //variable to set ADC to use internal 1.1V as reference
int const aREF = 0b00000000; //variable to set ADC to use VCC as reference
//The three zeros at the end of the above binary register values sets the analog channel to A0

void setup() {
  Serial.begin(9600);
  ADCSRA |= 1<<ADEN; //Turn on ADC
  ADCSRA |= ((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0));    //Prescaler at 128 so we have an 125Khz clock source
}

void loop() {
  delay(1000);
  Serial.println("Internal Ref:");
  burn8Readings(iREF);
  Serial.println(measADC(iREF),3);
  Serial.println(" ");
  delay(1000);
  Serial.println("AVCC Ref:");
  burn8Readings(aVCC);
  Serial.println(measADC(aVCC),3);
  Serial.println(" ");
}

//This function makes an ADC measurement using registers
float measADC(int ref) {
  ADMUX =  ref; //bits 7&6 select reference, bit 5 R or L adjust (0 R), bit 4 unused, 3:0 is channel select (0000 is ADC0)
  //ADMUX |=  0b00000000; //bits 7&6 select reference, bit 5 R or L adjust (0 R), bit 4 unused, 3:0 is channel select (0000 is ADC0)
  ADCSRA |= 1<<ADSC; //this bit starts conversion. It will remain high until conversion is complete
  
  while(ADCSRA & (1<<ADSC)) { delay(1);} //ADIF bit goes high when conversion is complete and result is in ADCL and ADCH
  return convertToVolt(ref, ADC);
}

//This function takes the ADC integer value and turns it into a voltage level. The inputs are
//the selected reference source and the measured ADC value.
float convertToVolt(int refSet, int aVAL) {
  float refVal;
  if (refSet == iREF) { refVal = 1.08; } //hard coded in reference value for internal
  else { refVal = 5.05; } //hard coded in AVCC value
  
  return (((float)aVAL/1023)*refVal);
}

//This function makes 8 ADC measurements but does nothing with them
//Since after a reference change the ADC can return bad readings at first. 
//This function is used to get rid of the first 
//8 readings to ensure an accurate one is displayed
void burn8Readings(int ref) {
 for(int i = 0; i<8; i++) {
  measADC(ref);
  delay(1);
 } 
}

Thursday, December 11, 2014

Reducing Arduino’s Power Consumption Part 3

Welcome to part 3 of reducing Arduino's power consumption, a must watch series for anybody building a battery powered project with Arduino. In part 3 we will look at how to use the Watch Dog Timer like an alarm clock to wake Arduino up from sleep mode. We we also look at some additional techniques to save power.


*****************************************Arduino Code*************************************************
/*
Example program for using sleep modes and watch dog timer in Arduino. This example code was used in a sleep mode tutorial video on the ForceTronics YouTube Channel.
This code is open for anybody to use at their own risk*/
     
/*WDT BYTE variables for setting timer value
     WDTO_15MS
WDTO_30MS
WDTO_60MS
WDTO_120MS
WDTO_250MS
WDTO_500MS
WDTO_1S
WDTO_2S
WDTO_4S
WDTO_8S */
     
#include <avr/sleep.h>
//We use part of the WDT library, but have to use registers as well since library does not support interrupt mode for WDT
#include <avr/wdt.h> 

int led = 13; //variable for pin that the LED is on
int tog = 1; //variable that toggles between traditional delay() function and WDT sleep delay function

void setup() {
  wdt_disable(); //Datasheet recommends disabling WDT right away in case of low probabibliy event
   pinMode(led, OUTPUT); //set up the LED pin to output
}

void loop() {
  
  if(tog) { //use traditional delay function
    digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(1000);               // wait 
    digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
    delay(1000);       // wait 
    tog = 0; //toggle variable
  }
  else { //after blinking LED setup interrupt and then go to sleep. Note that sleep will only happen once sinc
    digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
    delay(1000);   // turn the LED on (HIGH is the voltage level)//  
    digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
    delayWDT(WDTO_1S);   // Use WDT sleep delay function, argument is byte variable from WDT Library
    //delayWDT(0x06);      //Use WDT sleep delay function, argument is byte value that sets timer to 1 second
    tog = 1; //toggle variable
  }
   
}

//This function serves as a power saving delay function. The argument is a Byte type variable that is used to set the delay time
//The function sets up sleep mode in power down state. The function then sets up the WDT timer in interrupt mode and sets it.
//It then puts the Arduino to sleep for the set time. Upon wake up the WDT and sleep mode are shut off
void delayWDT(byte timer) {
  sleep_enable(); //enable the sleep capability
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); //set the type of sleep mode. Default is Idle
  ADCSRA &= ~(1<<ADEN); //Turn off ADC before going to sleep (set ADEN bit to 0)
  WDTCSR |= 0b00011000;    //Set the WDE bit and then clear it when set the prescaler, WDCE bit must be set if changing WDE bit   
  WDTCSR =  0b01000000 | timer; //Or timer prescaler byte value with interrupt selectrion bit set
 // WDTCSR = 0b01000110; //This sets the WDT to 1 second
  wdt_reset(); //Reset the WDT 
  sleep_cpu(); //enter sleep mode. Next code that will be executed is the ISR when interrupt wakes Arduino from sleep
  sleep_disable(); //disable sleep mode
  ADCSRA |= (1<<ADEN); //Turn the ADC back on
}

//This is the interrupt service routine for the WDT. It is called when the WDT times out. 
//This ISR must be in your Arduino sketch or else the WDT will not work correctly
ISR (WDT_vect) 
{
  wdt_disable();
   MCUSR = 0; //Clear WDT flag since it is disabled, this is optional

}  // end of WDT_vect