1 — ESP32 simulation

An interactive ESP32 circuit simulation you can run free in your browser on Velxio, by ailisiwoshinidezhuren.

Components

Sketch code

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RTClib.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
RTC_DS3231 rtc;
#define PIR_PIN 5
#define LED_PIN 2
bool prevMotion = false;
unsigned long detections = 0;
#define BTN_PIN 19
bool isOut = false;
int userEvtHour = 0;
int userEvtMinute = 0;
bool showUserEvent = false;
unsigned long userEvtTimer = 0;
const unsigned long USER_EVT_DURATION = 3000;
const int pinTV = 34;
const int pinCook = 33;
const int TV_VOLT_THRESHOLD = 1065;
const int COOK_VOLT_THRESHOLD = 2200;
const int averageValue = 10;
#define MAX_EVENT_COUNT 4
struct Event {
  DateTime time;
  String msg;
};
Event eventList[MAX_EVENT_COUNT];
int eventIndex = 0;
void addEvent(String message){
  eventList[eventIndex].time = rtc.now();
  eventList[eventIndex].msg = message;
  eventIndex = (eventIndex + 1) % MAX_EVENT_COUNT;
}
float readSigVoltage(int pin)
{
  long sum = 0;
  for (int i = 0; i < averageValue; i++) {
    sum += analogRead(pin);
    delay(2);
  }
  float voltage = (sum / (float)averageValue) * 3300.0 / 4095.0;
  return voltage;
}
bool lastTvState = false;
bool lastCookState = false;
void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22);
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("SSD1306 not found!");
    while (true) delay(10);
  }
  if (!rtc.begin()) {
    Serial.println("DS3231 RTC NOT FOUND!");
  }
  pinMode(PIR_PIN, INPUT);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BTN_PIN, INPUT_PULLUP);
  addEvent("System Start");
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0, 0);
  display.println("System warming up...");
  display.display();
  delay(2000);
  Serial.println("Ready!");
}
void loop() {
  DateTime now = rtc.now();
  float voltTV = readSigVoltage(pinTV);
  bool tvOn = (voltTV >= TV_VOLT_THRESHOLD);
  bool cookSensorEnable = true;
  bool cookOn = false;
  float voltCook = 0;
  if(cookSensorEnable)
  {
    voltCook = readSigVoltage(pinCook);
    cookOn = (voltCook >= COOK_VOLT_THRESHOLD);
  }
  if(tvOn != lastTvState){
    if(tvOn) addEvent("TV ON");
    else addEvent("TV OFF");
    lastTvState = tvOn;
  }
  if(cookOn != lastCookState){
    if(cookOn) addEvent("Cooking ON");
    else addEvent("Cooking OFF");
    lastCookState = cookOn;
  }
  if(digitalRead(BTN_PIN) == LOW)
  {
    delay(50);
    if(digitalRead(BTN_PIN) == LOW)
    {
      isOut = !isOut;
      DateTime t = rtc.now();
      userEvtHour = t.hour();
      userEvtMinute = t.minute();
      showUserEvent = true;
      userEvtTimer = millis();
      if(isOut){
        Serial.println("=== AWAY 出门 ===");
        addEvent("User Leave");
      }else{
        Serial.println("=== HOME 在家 ===");
        addEvent("User Back");
      }
      while(digitalRead(BTN_PIN)==LOW);
    }
  }
  if(showUserEvent && (millis() - userEvtTimer > USER_EVT_DURATION))
  {
    showUserEvent