iCare — ESP32 simulation

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

Components

Sketch code

#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <esp_now.h>
#include <WiFi.h>

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

const int PIN_WATER = 13;
const int PIN_TOILET = 26;
const int PIN_NON_EMG = 32;
const int PIN_EMG = 33;
const int PIN_CANCEL = 25;

int countWater = 0;
int countToilet = 0;
int countNonEmg = 0;
int countEmg = 0;

int lastWaterState = HIGH;
int lastToiletState = HIGH;
int lastNonEmgState = HIGH;
int lastEmgState = HIGH;
int lastCancelState = HIGH;

// ---> REPLACE THIS WITH YOUR ESP32 #2 RECEIVER'S MAC ADDRESS <---
uint8_t receiverAddress[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

typedef struct struct_message {
  int buttonId; 
  bool state;
} struct_message;

struct_message myData;
esp_now_peer_info_t peerInfo;

void OnDataSent(const wifi_tx_info_t *info, esp_now_send_status_t status) {
  // Optional status check
}

void setup() {
  Serial.begin(115200);
  Wire.begin(21, 22);
  
  pinMode(PIN_WATER, INPUT_PULLUP);
  pinMode(PIN_TOILET, INPUT_PULLUP);
  pinMode(PIN_NON_EMG, INPUT_PULLUP);
  pinMode(PIN_EMG, INPUT_PULLUP);
  pinMode(PIN_CANCEL, INPUT_PULLUP);

  // Non-blocking OLED initialization
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {
      Serial.println(F("OLED allocation failed"));
    }
  }
  
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
  display.setCursor(0,0);
  display.println("ESP32 #1 Sender Ready");
  display.display();

  WiFi.mode(WIFI_STA);
  if (esp_now_init() != ESP_OK) {
    Serial.println("Error initializing ESP-NOW");
    return;
  }

  esp_now_register_send_cb(OnDataSent);
  
  memcpy(peerInfo.peer_addr, receiverAddress, 6);
  peerInfo.channel = 0;  
  peerInfo.encrypt = false;
  
  if (esp_now_add_peer(&peerInfo) != ESP_OK) {
    Serial.println("Failed to add peer");
    return;
  }
  
  delay(1000);
}

void loop() {
  int waterState = digitalRead(PIN_WATER);
  int toiletState = digitalRead(PIN_TOILET);
  int nonEmgState = digitalRead(PIN_NON_EMG);
  int emgState = digitalRead(PIN_EMG);
  int cancelState = digitalRead(PIN_CANCEL);

  // Water Button (GPIO 13) -> buttonId 0
  if (waterState == LOW && lastWaterState == HIGH) {
    countWater++;
    myData.buttonId = 0;
    myData.state = true;
    esp_now_send(receiverAddress, (uint8_t *)&myData, sizeof(myData));
    Serial.println("Water button pressed");
    delay(50);
  }

  // Toilet Button (GPIO 26) -> buttonId 1
  if (toiletState == LOW && lastToiletState == HIGH) {
    countToilet++;
    myData.buttonId = 1;
    myData.state = true;
    esp_now_send(receiverAddress, (uint8_t *)&myData, sizeof(myData));
    Serial.println("Toilet button pressed");
    delay(50);
  }

  // Non-Emergency Button (GPIO 32) -> buttonId 2
  if (nonEmgState == LOW && lastNonEmgState == HIGH) {
    countNonEmg++;
    myData.buttonId = 2;