Nano Every internal power down

I need to internally power down my Arduino nano every to consume hardly any power so the lipo battery lasts longer. This means I need all the sensors to have power cut to them as well. My project is a datalogger so the switch method is a no-go. It has to be fully integrated via the code to work in my situation. I have some coding experience but had help making the main code from a friend that has no clue how to accomplish this step.



//This code was written to be easy to understand.
//Modify this code as you see fit.
//This code will output data to the Arduino serial monitor.
//Type commands into the Arduino serial monitor to control the D.O. circuit.
//This code was written in the Arduino 1.8.9 IDE
//An Arduino UNO was used to test this code.
//This code was last tested 6/2019



/////////////////////////////////////////////////// RTC  //////////////////////////////////////


#include <Wire.h>
#include "Sodaq_DS3231.h"

char weekDay[][4] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
/////////////////////////////////////////


#include <SoftwareSerial.h>                           //we have to include the SoftwareSerial library, or else we can't use it
#define Drx 1                                          //define what pin rx is going to be
#define Dtx 0                                         //define what pin tx is going to be

SoftwareSerial Dmyserial(Drx, Dtx);                      //define how the soft serial port is going to work

#define Erx 5                                          //define what pin rx is going to be
#define Etx 6                                          //define what pin tx is going to be


SoftwareSerial Emyserial(Erx, Etx);                      //define how the soft serial port is going to work


String Einputstring = "";                              //a string to hold incoming data from the PC
String Esensorstring = "";                             //a string to hold the data from the Atlas Scientific product
boolean Einput_string_complete = false;                //have we received all the data from the PC
boolean Esensor_string_complete = false;               //have we received all the data from the Atlas Scientific product
char *EC;                                           //char pointer used in string parsing
  float f_ec;                                         //used to hold a floating point number that is the EC


String Dinputstring = "";                              //a string to hold incoming data from the PC
String Dsensorstring = "";                             //a string to hold the data from the Atlas Scientific product
String DOVALUE="";
boolean Dinput_string_complete = false;                //have we received all the data from the PC
boolean Dsensor_string_complete = false;               //have we received all the data from the Atlas Scientific product
float DO;                                             //used to hold a floating point number that is the DO


#include <Wire.h>
#include "Adafruit_MCP9808.h"

// Create the MCP9808 temperature sensor object
Adafruit_MCP9808 tempsensor = Adafruit_MCP9808();

float TEMPVALUE=0;

//////////////////////////////////////////////////// SD CARDS THINGS /////////////////////////////////////

#include <SPI.h>
#include <SD.h>

File fd;
const uint8_t BUFFER_SIZE = 20;
char fileEC[] = "EC.csv"; // SD library only supports up to 8.3 names
char fileDO[] = "DO.csv";
char fileTEMP[] = "TEMP.csv";
char buff[BUFFER_SIZE+2] = "";  // Added two to allow a 2 char peek for EOF state
uint8_t index = 0;

const uint8_t chipSelect = 8;
const uint8_t cardDetect = 9;

enum states: uint8_t { NORMAL, E, EO };
uint8_t state = NORMAL;

bool alreadyBegan = false;  // SD.begin() misbehaves if not first call


/////////////////////////////////////////////////////////////////
void setup() {  
//
//    pinMode(A1, OUTPUT);     /// FOR 5V ////
//    pinMode(A2, OUTPUT);     ///// FOR 5V ///
//    
//    pinMode(3, OUTPUT);    ///// FOR GRND ///
//    pinMode(4, OUTPUT);    ///// FOR GRND ////
//
    //                             digitalWrite( 3, HIGH); //// MAKING PIN HIGH OR 5V ////
//                                 digitalWrite( A2, HIGH); //// MAKING PIN HIGH OR 5V ////
//                                     
   //                             digitalWrite( 4, LOW); //// MAKING PIN LOW OR 5V ////
//                                digitalWrite( 7, LOW); //// MAKING PIN LOW OR 5V ////

                                                                                                                                     
                                     //set up the hardware
  Serial.begin(9600);                                 //set baud rate for the hardware serial port_0 to 9600
      Wire.begin();
    rtc.begin();
    
  Dmyserial.begin(9600);                               //set baud rate for the software serial port to 9600
  Dinputstring.reserve(10);                            //set aside some bytes for receiving data from the PC
  Dsensorstring.reserve(30);                           //set aside some bytes for receiving data from Atlas Scientific product

    Emyserial.begin(9600);                               //set baud rate for the software serial port to 9600
  Einputstring.reserve(10);                            //set aside some bytes for receiving data from the PC
 Esensorstring.reserve(30);                           //set aside some bytes for receiving data from Atlas Scientific product

  if (!tempsensor.begin(0x18)) {
    Serial.println(F("Couldn't find MCP9808! Check your connections and verify the address is correct."));
    while (1);
  }
    
   Serial.println(F("Found MCP9808!"));

  tempsensor.setResolution(3); // sets the resolution mode of reading, the modes are defined in the table bellow:

    pinMode(cardDetect, INPUT);

  initializeCard();
}

void EserialEvent() {                                  //if the hardware serial port_0 receives a char
 Einputstring = Serial.readStringUntil(13);           //read the string until we see a <CR>
  Einput_string_complete = true;                       //set the flag used to tell if we have received a completed string from the PC
}


void DserialEvent() {                                  //if the hardware serial port_0 receives a char
  Dinputstring = Serial.readStringUntil(13);           //read the string until we see a <CR>
  Dinput_string_complete = true;                       //set the flag used to tell if we have received a completed string from the PC
}

int b=0;
void loop() {   

     tim();
    
  Serial.println(F("                  Let's DO it"));

  sleep(900000)
  
  //here we go...
        Serial.println(F(""));
        Serial.println(F( "    DO SENSOR VALUE"));
        Serial.println(F(""));
        Dmyserial.begin(9600);                               //set baud rate for the software serial port to 9600
        while( DOS()==0);
        delay(100);
        
         if (!digitalRead(cardDetect))
         {
            initializeCard();
           }

         fd = SD.open(fileDO, FILE_WRITE);
          if (fd) {
            Serial.print(F("Writing to DO.txt..."))
    
            ; fd.print( DO)
            ;fd.print(",");
           ;tim();
 
              ; fd.close();
              Serial.println(F("done."));
          } else {
   
           Serial.println(F("error opening DO.txt"));
           }
        
/////////////////////////////////////////////////////////////// EC SENSOR //////////////////////////////////
        Serial.println(F(""));
        Serial.println(F( "    CONDUCTIVIY SENSOR VALUE"));
        Serial.println(F(","));
        Emyserial.begin(9600);                               //set baud rate for the software serial port to 9600
        while ( ECOND()==0);
        delay(100);

         if (!digitalRead(cardDetect))
         {
            initializeCard();
           }

         fd = SD.open(fileEC, FILE_WRITE);
          if (fd) {
            Serial.print(F("Writing to EC.txt..."));
             
             ;fd.print( f_ec);
             ;fd.print(",");
             ;tim();

             
              fd.close();
              Serial.println(F("done."));
          } else {
   
           Serial.println(F("error opening EC.txt"));
           }

         ////////////////////////////////////////////////////////// TEMP ///////////////////////////////////////  
        Serial.println(F(""));
        Serial.println(F( "     TEMPERATURE SENSOR VALUE"));
        Serial.println(F(","));
        MCP();
        

         if (!digitalRead(cardDetect))
         {
            initializeCard();
           }

         fd = SD.open(fileTEMP, FILE_WRITE);
          if (fd) {
            Serial.print(F("Writing to TEMP.txt..."));
                
             ;fd.print( TEMPVALUE);
             ;fd.print(","); 
             ;tim();
             
              fd.close();
              Serial.println(F("done."));
          } else {
   
           Serial.println(F("error opening TEMP.txt"));
           }

}

/////////////////////////////////    DO /////////////////////////////
bool DOS()
{
  bool a=0;
  if (Dinput_string_complete == true) {                //if a string from the PC has been received in its entirety
    Dmyserial.print(Dinputstring);                      //send that string to the Atlas Scientific product
    Dmyserial.print('\r');                             //add a <CR> to the end of the string
    Dinputstring = "";                                 //clear the string
    Dinput_string_complete = false;                    //reset the flag used to tell if we have received a completed string from the PC
  }

  if (Dmyserial.available() > 0) {                     //if we see that the Atlas Scientific product has sent a character
    char Dinchar = (char)Dmyserial.read();              //get the char we just received
    Dsensorstring += Dinchar;                           //add the char to the var called sensorstring
    if (Dinchar == '\r') {                             //if the incoming character is a <CR>
      Dsensor_string_complete = true;                  //set the flag
    }
  }


  if (Dsensor_string_complete == true) {               //if a string from the Atlas Scientific product has been received in its entirety
      Serial.print(F("DO = "));
    Serial.println(Dsensorstring);   
    DOVALUE =    Dsensorstring;              
                                                   //uncomment this section to see how to convert the DO reading from a string to a float 
    if (isdigit(Dsensorstring[0])) {                   //if the first character in the string is a digit
      DO = Dsensorstring.toFloat();                    //convert the string to a floating point number so it can be evaluated by the Arduino
  
    }
   
   a=  Dsensor_string_complete;
    Dsensorstring = "";                                //clear the string
    Dsensor_string_complete = false;                   //reset the flag used to tell if we have received a completed string from the Atlas Scientific product
  }
   // Serial.println(a);
  return a;
}

//
int ECOND()
{
  int a=0;
  if (Einput_string_complete == true) {                //if a string from the PC has been received in its entirety
   Emyserial.print(Einputstring);                      //send that string to the Atlas Scientific product
    Emyserial.print('\r');                             //add a <CR> to the end of the string
    Einputstring = "";                                 //clear the string
    Einput_string_complete = false;                    //reset the flag used to tell if we have received a completed string from the PC
  }

  if (Emyserial.available() > 0) {                     //if we see that the Atlas Scientific product has sent a character
    char Einchar = (char)Emyserial.read();              //get the char we just received
    Esensorstring += Einchar;                           //add the char to the var called sensorstring
    if (Einchar == '\r') {                             //if the incoming character is a <CR>
      Esensor_string_complete = true;                  //set the flag
    }
  }


  if (Esensor_string_complete == true) {               //if a string from the Atlas Scientific product has been received in its entirety
    if (isdigit(Esensorstring[0]) == false) {          //if the first character in the string is a digit
      Serial.println(Esensorstring);                   //send that string to the PC's serial monitor
    }
    else                                              //if the first character in the string is NOT a digit
    {
      Eprint_EC_data();                                //then call this function 
    }
    a=Esensor_string_complete;
   Esensorstring = "";                                //clear the string
    Esensor_string_complete = false;                   //reset the flag used to tell if we have received a completed string from the Atlas Scientific product
  }
  return a;
}

void Eprint_EC_data(void) {                            //this function will pars the string  

  char Esensorstring_array[30];                        //we make a char array
  
  char *TDS;                                          //char pointer used in string parsing
  char *SAL;                                          //char pointer used in string parsing
  char *GRAV;                                         //char pointer used in string parsing

  
  Esensorstring.toCharArray(Esensorstring_array, 30);   //convert the string to a char array 
  EC = strtok(Esensorstring_array, ",");               //let's pars the array at each comma
  TDS = strtok(NULL, ",");                            //let's pars the array at each comma
  SAL = strtok(NULL, ",");                            //let's pars the array at each comma
  GRAV = strtok(NULL, ",");                           //let's pars the array at each comma

  Serial.print(F("EC:"));                                //we now print each value we parsed separately
  Serial.println(EC);                                 //this is the EC value

  Serial.print(F("TDS:"));                               //we now print each value we parsed separately
  Serial.println(TDS);                                //this is the TDS value

  Serial.print(F("SAL:"));                               //we now print each value we parsed separately
  Serial.println(SAL);                                //this is the salinity value

  Serial.print(F("GRAV:"));                              //we now print each value we parsed separately
  Serial.println(GRAV);                               //this is the specific gravity
  //Serial.println();                                   //this just makes the output easier to read
  
f_ec= atof(EC);                                     //uncomment this line to convert the char to a float
}



void MCP()
{
//   Serial.println("wake up MCP9808.... "); // wake up MCP9808 - power consumption ~200 mikro Ampere
//  tempsensor.wake();   // wake up, ready to read!

  // Read and print out the temperature, also shows the resolution mode used for reading.
//  Serial.print("Resolution in mode: ");
//  Serial.println (tempsensor.getResolution());
  float c = tempsensor.readTempC();
  float f = tempsensor.readTempF();
  Serial.print("Temp: "); 
  Serial.print(c, 4); Serial.print(F("*C\t and ")); 
  Serial.print(f, 4); Serial.println(F("*F."));

  TEMPVALUE =tempsensor.readTempF();
 // delay(2000);
//  Serial.println("Shutdown MCP9808.... ");
//  tempsensor.shutdown_wake(1); // shutdown MSP9808 - power consumption ~0.1 mikro Ampere, stops temperature sampling
  Serial.println("");
  delay(100);
}

//////////////////////////////////////////// CARD  /////////////////////
void initializeCard(void)
{
  Serial.print(F("Initializing SD card..."));

  // Is there even a card?
  if (!digitalRead(cardDetect))
  {
    Serial.println(F("No card detected. Waiting for card."));
    while (!digitalRead(cardDetect));
    delay(250); // 'Debounce insertion'
  }

  // Card seems to exist.  begin() returns failure
  // even if it worked if it's not the first call.
  if (!SD.begin(chipSelect) && !alreadyBegan)  // begin uses half-speed...
  {
    Serial.println(F("Initialization failed!"));
    initializeCard(); // Possible infinite retry loop is as valid as anything
  }
  else
  {
    alreadyBegan = true;
  }
  Serial.println(F("Initialization done."));

  Serial.print(fileEC);
  if (SD.exists(fileEC))
  {
    Serial.println(F(" exists."));
  }
  else
  {
    Serial.println(F(" doesn't exist."));
  }
  
  Serial.print(fileDO);
  if (SD.exists(fileDO))
  {
    Serial.println(F(" exists."));
  }
  else
  {
    Serial.println(F(" doesn't exist. "));
  }

  Serial.print(fileTEMP);
  if (SD.exists(fileTEMP))
  {
    Serial.println(F(" exists."));
  }
  else
  {
    Serial.println(F(" doesn't exist."));
  }
 Serial.println(F(" CARD INITIALIZATION DONE "));
}

void tim()
{
      DateTime now = rtc.now(); //get the current date-time
    uint32_t ts = now.getEpoch();

//    if (old_ts == 0 || old_ts != ts) {
//  old_ts = ts;
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.date(), DEC);
  Serial.print(' ');
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.print(' ');
  
  

  Serial.println();

  fd.print(now.year(), DEC);
 fd.print('/');
 fd.print(now.month(), DEC);
 fd.print('/');
 fd.print(now.date(), DEC);
 fd.print(' ');
 fd.print(now.hour(), DEC);
 fd.print(':');
 fd.print(now.minute(), DEC);
 fd.print(':');
 fd.print(now.second(), DEC);
 fd.print(' ');

 
 
 

 ;fd.println();
}

I make no sense of that. What is this “switch method” you speak of and why is it a no-go?

a7

The Nano Every is not designed to use minimal power. If you put it in sleep-mode, then the usb-serial chip is still running. Putting the sensors into sleep-mode will not make a big difference.

Can you tell what is connected and which libraries you use ? You could check the libraries for a sleep-function.

For example the MKR Zero can be powered with a battery and can go into sleep-mode and use little power.

Some people use an external power switch they flip or button they push to turn power on and off

ds3231 sd module, atlas scientific EC, atlas scientific DO, and MCP9808 temp sensor. Thats all that is connected. Would it be better to just mount a solar panel and just put in a delay?

I’d switch to a more low power friendly Arduino board and stay on that track, but solar power sounds good… you’d still want to minimise the power used, you’ll be right back to wondering and worrying about sleep &c.

Your sensors can be turned on and off with a mosfet switch, NP.

a7