kuroの覚え書き

96の個人的覚え書き

ESP32でdeep sleep

ESP32はAVRのATMEGAに比べてえらくエネルギー効率がいいらしく、省エネということになっている。240MHzで動かしていてもそうらしいが、ここは最低速度の10MHzまで落としてやろう。その上でインターバル運転で間をsleepで過ごさせるともっといいらしい。

#include <Wire.h>
#include <RTClib.h>
#include <SPI.h>
#include <SD.h>
#define uS_TO_S_FACTOR 1000000
#define TIME_TO_SLEEP  24 

const int chipSelect = 10;
int sensorPin0 = 4;    // select the input pin for the potentiometer
int sensorValue0 = 0;  // variable to store the value coming from the sensor

RTC_DS1307 RTC;
int serialStat = 0;
RTC_DATA_ATTR int bootCount = 0;

/**************************************************************************/
void setup() {
  Serial.begin(9600);
  delay(10000);
  if(Serial)
  {
    serialStat = 1;
  }
  else
  {
    serialStat = 0;
  }

// SD card  
  if(serialStat == 1)
  {
    Serial.print("Initializing SD card...");
  // see if the card is present and can be initialized:
    if (!SD.begin(chipSelect))
    {
      Serial.println("Card failed, or not present");
    }
    Serial.println("card initialized.");
  }
  else
  {
    SD.begin(chipSelect);
  }

// RTC
  Wire.begin();
  RTC.begin();
  delay(1000);
  if(serialStat == 1)
  {
    if(!RTC.begin())
    {
      Serial.println("RTC failed");
    }
  }
  /* Set RTC with PC initially */
  // RTC.adjust(DateTime(__DATE__, __TIME__));
  // RTC.adjust(DateTime(2022, 10, 29, 0, 13, 30));
  
//Increment boot number and print it every reboot
  ++bootCount;
//sensing
  timeRead();
  delay(10);
  sensorReadSw();
//Set timer to 10 seconds
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
//Go to sleep now
  esp_deep_sleep_start();
}
/**************************************************************************/
void timeRead(void)
{
  DateTime now = RTC.now();
  
  File dataFile = SD.open("/datalog.txt", FILE_WRITE);
  dataFile.print(now.year(),DEC);
  dataFile.print("/");
  dataFile.print(now.month(),DEC);
  dataFile.print("/");
  dataFile.print(now.day(),DEC);
  dataFile.print("_");
  dataFile.print(now.hour(),DEC);
  dataFile.print(":");
  dataFile.print(now.minute(),DEC);
  dataFile.print(":");
  dataFile.print(now.second(),DEC); 
  dataFile.close();
  if(serialStat == 1)
  {
    Serial.print(now.year(),DEC);
    Serial.print("/"); 
    Serial.print(now.month(),DEC);
    Serial.print("/"); 
    Serial.print(now.day(),DEC);
    Serial.print("_"); 
    Serial.print(now.hour(),DEC);
    Serial.print(":"); 
    Serial.print(now.minute(),DEC);
    Serial.print(":"); 
    Serial.println(now.second(),DEC);      
  }
}
/**************************************************************************/
void sensorReadSw(void)
{
  sensorValue0 = analogRead(sensorPin0);

  File dataFile = SD.open("/datalog.txt", FILE_APPEND);
  dataFile.print(", ");
  dataFile.print(sensorValue0);
  dataFile.println("");
  dataFile.close();
  if(serialStat == 1)
  {
    Serial.print("value0: "); Serial.println(sensorValue0);
  }
}
/**************************************************************************/
void loop() {  

}

こんな感じで。
loopは使わずsetupの中身がぐるぐる回る感じ。

ただ、この設定では内臓のRTCを使って時間を測っており、RC発振なのでとにかく精度が悪いとのこと。
内臓RTCではなくI2Cで繋いでいるRTCをトリガーに使った方法の方が良いらしいので、次はそれだな。