一个基于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);
}