Sorry. I copied in the wrong code. I’m using the same method across multiple projects. Here is the code that shows my device that is battery powered and uses deep sleep.
#include <Wire.h>
#include <ESP8266WiFi.h>;
#include <BlynkSimpleEsp8266.h>;
#include <OneWire.h>
#include <TimeLib.h>
#include <WidgetRTC.h>
//V0:
//V1: Used for table
//V2: User input to store angle and specific gravity value
//V3: Output of averaged angle from V5
//V4: Specific gravity input from user
//V5: Start Reading: used to set array for averaging angle
//V6: Request for temperature from user
//V7: temperature output
//V8: Battery voltage
//V9: Time from the Blynk RTC
//V10: Date from the Blynk RTC
//V11: Sleep ON/OFF
//Variables for voltage measurement
unsigned int raw = 0;
float volt = 0.0;
//Starting OneWire for communication on pin D6
OneWire ds(D6);
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "**********************";
// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "******************8";
char pass[] = "**********************";
//Both used for Blynk
BlynkTimer timer;
WidgetRTC rtc;
/*MPU-6050 gives you 16 bits data so you have to create some 16int constants
* to store the data for accelerations and gyro*/
int16_t Acc_rawX, Acc_rawY, Acc_rawZ,Gyr_rawX, Gyr_rawY, Gyr_rawZ;
//Variables used for measuring angle
float Acceleration_angle[2];
float Gyro_angle[2];
float Total_angle[2];
float averageAngle;
float elapsedTime;
float time_;
float timePrev;
int i; //used for settling loop
float rad_to_deg = 180/3.141592654;
float celsius, fahrenheit;
const int numReadings = 10; //Number of data points, after settling angle data, to average
float readings[numReadings];
int readIndex = 0;
float total = 0; //sum of all angle data points before averaging
float average = 0; //end result of averaging angle data points
float SG = 1.000; //Specific gravity calculated from angle
int settleIterations = 1000; //Number of iterations to read data to let data point of angle settle to a steady value
int delay_time = 20; //time delay after each angle reading
int deepSleepHours = 1; //how many hours to deep sleep
int pinValue3 = 1; //value used to determine if deep sleep should stop/continue
float userSG;
const int arrayLen = 31;
float SGvalue[arrayLen] = {1.000, 1.001, 1.002, 1.003, 1.004, 1.005, 1.006, 1.007, 1.008, 1.009, 1.010, 1.011, 1.012, 1.013, 1.014, 1.015, 1.016, 1.017, 1.018, 1.019, 1.020, 1.021, 1.022, 1.023, 1.024, 1.025, 1.026, 1.027, 1.028, 1.029, 1.030};
float angleValue[arrayLen];
float tempValue[arrayLen];
int wifi_attempt_count=0;
int max_wifi_connect_attempts=20;
int wait_between_wifi_attempts_millis=500;
void clockDisplay()
{
String currentTime = String(hour()) + ":" + minute() + ":" + second();
String currentDate = String(month()) + "/" + day() + "/" + year();
int rtcSeconds = hour() * 3600 + minute() * 60 + second();
//Serial.print("Current time: ");
//Serial.print(currentDate);
//Serial.print(" ");
//Serial.println(currentTime);
Blynk.virtualWrite(V9, currentTime);
Blynk.virtualWrite(V10, currentDate);
}
void averaging_angle()
{
Serial.println("begin settling process");
readIndex = 0;
total = 0;
average = 0;
//Loop to read angle values, let the values settle before averaging the last set of values
for (int i = 0; i <= settleIterations; i++)
{
timePrev = time_; // the previous time is stored before the actual time read
time_ = millis(); // actual time read
elapsedTime = (time_ - timePrev) / 1000;
/////////////////////////////I M U/////////////////////////////////////
/*The timeStep is the time that elapsed since the previous loop.
* This is the value that we will use in the formulas as "elapsedTime"
* in seconds. We work in ms so we haveto divide the value by 1000
to obtain seconds*/
/*Reed the values that the accelerometre gives.
* We know that the slave adress for this IMU is 0x68 in
* hexadecimal. For that in the RequestFrom and the
* begin functions we have to put this value.*/
Wire.beginTransmission(0x68);
Wire.write(0x3B); //Ask for the 0x3B register- correspond to AcX
Wire.endTransmission(false);
Wire.requestFrom(0x68,6,true);
/*We have asked for the 0x3B register. The IMU will send a brust of register.
* The amount of register to read is specify in the requestFrom function.
* In this case we request 6 registers. Each value of acceleration is made out of
* two 8bits registers, low values and high values. For that we request the 6 of them
* and just make then sum of each pair. For that we shift to the left the high values
* register (<<) and make an or (|) operation to add the low values.*/
Acc_rawX=Wire.read()<<8|Wire.read(); //each value needs two registres
Acc_rawY=Wire.read()<<8|Wire.read();
Acc_rawZ=Wire.read()<<8|Wire.read();
/* Now we can apply the Euler formula. The atan will calculate the arctangent. The
* pow(a,b) will elevate the a value to the b power. And finnaly sqrt function
* will calculate the rooth square.*/
/*---X---*/
Acceleration_angle[0] = atan((Acc_rawY/16384.0)/sqrt(pow((Acc_rawX/16384.0),2) + pow((Acc_rawZ/16384.0),2)))*rad_to_deg;
/*---Y---*/
Acceleration_angle[1] = atan(-1*(Acc_rawX/16384.0)/sqrt(pow((Acc_rawY/16384.0),2) + pow((Acc_rawZ/16384.0),2)))*rad_to_deg;
Wire.beginTransmission(0x68);
Wire.write(0x43); //Gyro data first adress
Wire.endTransmission(false);
Wire.requestFrom(0x68,4,true); //Just 4 registers
Gyr_rawX=Wire.read()<<8|Wire.read(); //Once again we shift and sum
Gyr_rawY=Wire.read()<<8|Wire.read();
/*Now in order to obtain the gyro data in degrees/seconds we have to divide first
the raw value by 131 because that's the value that the datasheet gives us*/
/*---X---*/
Gyro_angle[0] = Gyr_rawX/131.0;
/*---Y---*/
Gyro_angle[1] = Gyr_rawY/131.0;
/*---X axis angle---*/
//Total_angle[0] = 0.98 *(Total_angle[0] + Gyro_angle[0]*elapsedTime) + 0.02*Acceleration_angle[0];
Total_angle[0] = 0.98 *(Total_angle[0] + Gyro_angle[0]*elapsedTime) + 0.02*Acceleration_angle[0]; // responds faster to changes, no shift over time observed...
/*---Y axis angle---*/
//Total_angle[1] = 0.98 *(Total_angle[1] + Gyro_angle[1]*elapsedTime) + 0.02*Acceleration_angle[1];
Total_angle[1] = 0.98 *(Total_angle[1] + Gyro_angle[1]*elapsedTime) + 0.02*Acceleration_angle[1];
/*Now we have our angles in degree and values from -10º0 to 100º aprox*/
//Serial.println(Total_angle[1]);
//Serial.print("X axis angle : "); Serial.print("\t"); Serial.print("\t"); Serial.print("Y axis angle : ");
//Serial.println();
Serial.print(Total_angle[0]);Serial.print("\t"); Serial.print("\t"); Serial.print("\t"); Serial.print(Total_angle[1]);
Serial.println();
/* left for historic and debugging reasons
Serial.print("Acc_rawX: "); Serial.print("\t"); Serial.print("Acc_rawY: ");Serial.print("\t"); Serial.println("Acc_rawZ: ");
Serial.print(Acc_rawX); Serial.print("\t"); Serial.print("\t"); Serial.print(Acc_rawY);Serial.print("\t"); Serial.print("\t"); Serial.println(Acc_rawZ);
Serial.print("Gyr_rawX: "); Serial.print("\t"); Serial.println("Gyr_rawY: ");
Serial.print(Gyr_rawX); Serial.print("\t"); Serial.print("\t"); Serial.println(Gyr_rawY);
Serial.println("------------------------------------------------------------------------------");
*/
//Serial.print("iteration: ");
//Serial.println(i);
//method to only average the last set of values
if ( i > settleIterations - numReadings)
{
// read angle:
readings[readIndex] = Total_angle[0];
// add the reading to the total:
total = total + readings[readIndex];
//Serial.print("total:");
//Serial.println(total);
// advance to the next position in the array:
readIndex = readIndex + 1;
// if we're at the end of the array...
if (readIndex >= numReadings) {
// ...wrap around to the beginning:
readIndex = 0;
}
// calculate the average:
average = total / numReadings;
// send it to the computer as ASCII digits
delay(1); // delay in between reads for stability
}
//keep the delay (loop time) low to minimize the discrete error
delay(delay_time); // around 50 ms loop time
}
Serial.print("Average: ");
average = 90 - average;
Serial.println(average);
SG = 0.000001*average*average*average+(-0.000131373)*average*average+0.006967952*average+0.901451941;
//SG = (SG,3);
Serial.print("SG: ");
Serial.println(SG);
timer.setInterval(3000L, write2blynk); //call the function that writes the values
}
BLYNK_WRITE(V3) //function used to determine, if while in deep sleep, if the user has requested that deep sleep be cancelled after the device wakes up
{
averageAngle = param.asFloat();
}
//BLYNK_WRITE(V4) //function used to determine, if while in deep sleep, if the user has requested that deep sleep be cancelled after the device wakes up
//{
// userSG = param.asFloat();
//}
BLYNK_WRITE(V5) //Blynk button that starts the averaging function
//Also in turn starts the write2blynk function
{
int pinValue = param.asInt();
if (pinValue = 1);
{
Blynk.virtualWrite(V3,0);
Blynk.virtualWrite(V2,0);
Serial.println("Starting averaging of angle");
averaging_angle();
//int timer_length = settleIterations * delay_time + 1000;
Blynk.virtualWrite(V3, average);
Blynk.virtualWrite(V2, SG);
}
}
void getTempData()
{
Serial.println("Gathering Temp");
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
if ( !ds.search(addr))
{
ds.reset_search();
delay(250);
return;
}
if (OneWire::crc8(addr, 7) != addr[7])
{
Serial.println("CRC is not valid!");
return;
}
Serial.println();
// the first ROM byte indicates which chip
switch (addr[0])
{
case 0x10:
type_s = 1;
break;
case 0x28:
type_s = 0;
break;
case 0x22:
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // start conversion, with parasite power on at the end
delay(1000);
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for ( i = 0; i < 9; i++)
{
data[i] = ds.read();
}
// Convert the data to actual temperature
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10)
{
raw = (raw & 0xFFF0) + 12 - data[6];
}
}
else
{
byte cfg = (data[4] & 0x60);
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
}
celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;
fahrenheit = fahrenheit - 2; //Calibration
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.print(" Celsius, ");
Serial.print(fahrenheit);
Serial.println(" Fahrenheit");
Blynk.virtualWrite(V7, fahrenheit);
}
void getVolts()
{
Serial.println("Determining battery voltage");
raw = analogRead(A0);
volt = raw/1023.0;
volt = volt * 5.5;
Blynk.virtualWrite(V8, volt);
if (volt < 2.8)
{
Blynk.email("************************@gmail.com", volt, "Charge Aqua Spindle");
Serial.println("Email sent");
}
if (volt < 2.5)
{
ESP.deepSleep(48*60*60*1000*1000); //Sleep for 48 hour if battery is dangerously low
}
}
BLYNK_WRITE(V6) //Blynk button that will pull temp and voltage data
{
int pinValue2 = param.asInt();
if (pinValue2 = 1)
{
getTempData();
getVolts();
}
}
BLYNK_WRITE(V11) //function used to determine, if while in deep sleep, if the user has requested that deep sleep be cancelled after the device wakes up
{
pinValue3 = param.asInt();
}
void AwakenFromSleep()
{
clockDisplay();
Serial.print("Hour: ");
Serial.println(hour());
if (hour() == 1)
{
getVolts();
getTempData();
averaging_angle();
Blynk.virtualWrite(V3, average);
Blynk.virtualWrite(V2, SG);
String SGstring = "";
SGstring.concat(SG);
String voltstring = "";
voltstring.concat(volt);
String tempstring = "";
tempstring.concat(fahrenheit);
String emailData = String("SG: " + SGstring + ", Temp: " + tempstring + ", Voltage: " + voltstring);
Blynk.email("***********************@gmail.com", emailData, "Aqua Spindle Daily Update");
}
else
{
deepSleepNow();
}
}
void deepSleepNow()
{
Serial.print("Deep sleep pin value: ");
Serial.println(pinValue3);
if (pinValue3 == 0)
{
//if (hour()>=0 && hour()<=1)
//{
Serial.println("Deep sleep mode");
//50*60*1000*1000 = 50 miutes of sleep
//12*60*60*1000*1000 = 12 hours of sleep
//deepSleepHours*60*60*1000*1000 = *deepSleepHours* hours of sleep
ESP.deepSleep(60*1000*1000); //1000x1000 = 1 second
//ESP.deepSleep(deepSleepHours*60*60*1000*1000);
delay(100);
//}
}
else
{
Serial.println("Deep sleep mode is disabled by user");
}
}
BLYNK_CONNECTED()
{
rtc.begin();
Blynk.syncVirtual(V11);
}
void write2blynk()
{
Blynk.virtualWrite(V3, average);
Blynk.virtualWrite(V5,0);
//average = 0
}
bool standalone_mode = true;
void Connect_to_WiFi()
{
Serial.println(F("Connecting to WiFi..."));
if (WiFi.status() != WL_CONNECTED)
{
WiFi.begin(ssid, pass); // connect to the network
}
while (WiFi.status() != WL_CONNECTED && wifi_attempt_count < max_wifi_connect_attempts) // Loop until we've connected, or reached the maximum number of attemps allowed
{
delay(wait_between_wifi_attempts_millis);
wifi_attempt_count++;
Serial.print(F("WiFi connection - attempt # "));
Serial.print(wifi_attempt_count);
Serial.print(F(" of "));
Serial.println(max_wifi_connect_attempts);
}
// we get to this point when either we're connected to Wi-Fi, or we've tried too many times. We need to do differnet things, depending which it is...
if (WiFi.status() == WL_CONNECTED)
{
//WiFi.mode(WIFI_STA);
Serial.println(F("WiFi CONNECTED"));
Serial.println();
}
else
{
// we get here if we tried multiple times, but can't connect to WiFi. We need to go into stand-alone mode and wait a while before re-trying...
standalone_mode = true; // We can't be in connected mode if no wifi
Serial.println();
Serial.println(F("................ In Stand-alone mode ................"));
timer.setInterval(1000*60*60,delayedWIFIconnect);
}
}
void delayedWIFIconnect()
{
if (standalone_mode = true)
{
wifi_attempt_count=0;
Connect_to_WiFi();
}
}
void setup()
{
//delay(5000); // Wait until start. Last chance to upload new sketch!!!
Wire.begin(0,2); //begin the wire comunication
Wire.beginTransmission(0x68); // 0x68 is the i2c address of MPU6050
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
Serial.begin(115200); //
time_ = millis(); //Start counting time in milliseconds
Serial.println("IMU check starting...");
for (int thisReading = 0; thisReading < numReadings; thisReading++)
{
readings[thisReading] = 0;
}
//rtc.begin;
Blynk.begin(auth, ssid, pass);
AwakenFromSleep();
//timer.setInterval(60000L, clockDisplay);
//60*10*1000 = 600000 = 10 minutes of awake time
//timer.setInterval(50000L, getVolts);
timer.setInterval(10000L, deepSleepNow); //time interval between checking if sleep should stop from app, doesn't account for additive sleep time
pinMode (A0, INPUT);
//averaging_angle();
Serial.println("Ready");
//Blynk.virtualWrite(V4, 0.000);
}//end of setup void
void loop()
{
timer.run();
if (WiFi.status() != WL_CONNECTED)
{
Connect_to_WiFi();
}
if (WiFi.status() == WL_CONNECTED)
{
if (!Blynk.connected())
{
Blynk.connect();
}
}
if (Blynk.connected())
{
Blynk.run();
}
}//end of loop void
The output you mentioned is the device going to deep sleep, which I then use a Blynk command to later tell the device on the next wake up if I want it to come out of deep sleep mode until the Blynk command is turned back off. This way, I can save battery most of the time, but if I need to get information repeated to check my saltwater salinity level, I can keep the device out of deep sleep for a period of time.