用trae生产了一个基于esp32的设备监控日志

一个基于esp32的设备监控日志代码,搭配DS3231时钟模块,可以将事件发生的时间储存进SD卡中,并通过按钮在0.96寸OLED屏幕上查看

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "RTClib.h"
#include <FS.h>
#include <SD.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
#define SD_CS 5

#define LOW_LEVEL_INPUT 4
#define BUTTON_ENTER 16
#define BUTTON_DOWN 17
#define BUTTON_UP 32

#define TIMEOUT_MS 30000

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
RTC_DS3231 rtc;

bool logViewMode = false;
int currentLogIndex = 0;
int totalLogs = 0;
unsigned long lastButtonPress = 0;
bool lastLowLevelState = HIGH;

void setup() {
  Serial.begin(115200);
  
  Wire.begin();
  
  pinMode(LOW_LEVEL_INPUT, INPUT_PULLUP);
  pinMode(BUTTON_ENTER, INPUT_PULLUP);
  pinMode(BUTTON_DOWN, INPUT_PULLUP);
  pinMode(BUTTON_UP, INPUT_PULLUP);
  
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;);
  }
  
  if(!rtc.begin()) {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    while(1);
  }
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  if(rtc.lostPower()) {
    Serial.println("RTC lost power, setting time to compile time");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
  
  Serial.println("Initializing SD card...");
  if(!SD.begin(SD_CS)) {
    Serial.println("SD card initialization failed!");
    while(1);
  }
  Serial.println("SD card initialized successfully!");
  
  countTotalLogs();
  
  display.clearDisplay();
  display.display();
}

void countTotalLogs() {
  totalLogs = 0;
  File logFile = SD.open("/LP_log.txt");
  if(logFile) {
    while(logFile.available()) {
      String line = logFile.readStringUntil('\n');
      if(line.length() > 0) {
        totalLogs++;
      }
    }
    logFile.close();
  }
}

void writeLog() {
  DateTime now = rtc.now();
  File logFile = SD.open("/LP_log.txt", FILE_APPEND);
  if(logFile) {
    if(now.year() < 10) logFile.print("0");
    logFile.print(now.year(), DEC);
    logFile.print("/");
    if(now.month() < 10) logFile.print("0");
    logFile.print(now.month(), DEC);
    logFile.print("/");
    if(now.day() < 10) logFile.print("0");
    logFile.print(now.day(), DEC);
    logFile.print(" ");
    if(now.hour() < 10) logFile.print("0");
    logFile.print(now.hour(), DEC);
    logFile.print(":");
    if(now.minute() < 10) logFile.print("0");
    logFile.print(now.minute(), DEC);
    logFile.print(":");
    if(now.second() < 10) logFile.print("0");
    logFile.println(now.second(), DEC);
    logFile.close();
    totalLogs++;
    currentLogIndex = totalLogs - 1;
    Serial.println("Log entry added");
  } else {
    Serial.println("Error opening log file!");
  }
}

String readLog(int index) {
  String logEntry = "";
  File logFile = SD.open("/LP_log.txt");
  if(logFile) {
    int lineCount = 0;
    while(logFile.available()) {
      String line = logFile.readStringUntil('\n');
      if(line.length() > 0) {
        if(lineCount == index) {
          logEntry = line;
          break;
        }
        lineCount++;
      }
    }
    logFile.close();
  }
  return logEntry;
}

void displayHomePage() {
  display.clearDisplay();
  
  display.setTextSize(3);
  display.setTextColor(SSD1306_WHITE);
  
  String countStr = String(totalLogs);
  int16_t x, y;
  uint16_t w, h;
  display.getTextBounds(countStr, 0, 0, &x, &y, &w, &h);
  
  int16_t xPos = (128 - w) / 2;
  int16_t yPos = (64 - h) / 2;
  
  display.setCursor(xPos, yPos);
  display.print(totalLogs);
  
  display.display();
}

void parseLogEntry(String logEntry, String &dateStr, String &timeStr) {
  dateStr = "";
  timeStr = "";
  if(logEntry.length() > 0) {
    int spaceIndex = logEntry.indexOf(' ');
    if(spaceIndex > 0) {
      dateStr = logEntry.substring(0, spaceIndex);
      timeStr = logEntry.substring(spaceIndex + 1);
    }
  }
}

void displayLogView() {
  DateTime now = rtc.now();
  
  display.clearDisplay();
  
  display.setTextColor(SSD1306_WHITE);
  
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.print("NOW:");
  if(now.year() < 10) display.print("0");
  display.print(now.year(), DEC);
  display.print("/");
  if(now.month() < 10) display.print("0");
  display.print(now.month(), DEC);
  display.print("/");
  if(now.day() < 10) display.print("0");
  display.println(now.day(), DEC);
  
  display.setTextSize(2);
  display.setCursor(0, 10);
  if(now.hour() < 10) display.print("0");
  display.print(now.hour(), DEC);
  display.print(":");
  if(now.minute() < 10) display.print("0");
  display.print(now.minute(), DEC);
  display.print(":");
  if(now.second() < 10) display.print("0");
  display.println(now.second(), DEC);
  
  display.setTextSize(1);
  display.println();
  
  display.drawLine(0, 29, 127, 29, SSD1306_WHITE);
  
  display.setTextSize(1);
  display.println();
  
  String logDate = "";
  String logTime = "";
  if(totalLogs > 0 && currentLogIndex >= 0 && currentLogIndex < totalLogs) {
    String logEntry = readLog(currentLogIndex);
    parseLogEntry(logEntry, logDate, logTime);
  }
  
  display.setTextSize(1);
  display.setCursor(0, 34);
  display.print("Log:");
  display.print(currentLogIndex + 1);
  display.print(":");
  display.println(logDate);
  
  display.setTextSize(2);
  display.setCursor(0, 44);
  display.println(logTime);
  
  display.display();
}

void checkLowLevelInput() {
  bool currentState = digitalRead(LOW_LEVEL_INPUT);
  if(currentState == LOW && lastLowLevelState == HIGH) {
    writeLog();
    delay(50);
  }
  lastLowLevelState = currentState;
}

void checkButtons() {
  if(digitalRead(BUTTON_ENTER) == LOW) {
    logViewMode = !logViewMode;
    if(logViewMode) {
      currentLogIndex = totalLogs - 1;
    }
    lastButtonPress = millis();
    delay(200);
  }
  
  if(logViewMode) {
    if(digitalRead(BUTTON_DOWN) == LOW) {
      if(currentLogIndex < totalLogs - 1) {
        currentLogIndex++;
      }
      lastButtonPress = millis();
      delay(200);
    }
    
    if(digitalRead(BUTTON_UP) == LOW) {
      if(currentLogIndex > 0) {
        currentLogIndex--;
      }
      lastButtonPress = millis();
      delay(200);
    }
  }
}

void checkTimeout() {
  if(logViewMode && (millis() - lastButtonPress > TIMEOUT_MS)) {
    logViewMode = false;
  }
}

void loop() {
  checkLowLevelInput();
  checkButtons();
  checkTimeout();
  
  if(logViewMode) {
    displayLogView();
  } else {
    displayHomePage();
  }
  
  delay(100);
}