MAS LAB Project — ESP32 simulation

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

Components

Sketch code

#include <WiFi.h>
#include <PubSubClient.h>

// =====================================
// 1. VELXIO WI-FI AND MQTT SETTINGS
// =====================================
const char* WIFI_SSID = "Velxio-GUEST";
const char* MQTT_SERVER = "broker.hivemq.com";
const int MQTT_PORT = 1883;

const char* PATIENT_TOPIC = "touchtalk_demo_7f31/patient";
const char* CAREGIVER_TOPIC = "touchtalk_demo_7f31/caregiver";

// =====================================
// 2. FIVE PATIENT BUTTONS
// =====================================
const int CALL_NURSE_BUTTON = 13;  // Blue
const int PAIN_BUTTON       = 14;  // Red
const int WATER_BUTTON      = 27;  // Yellow
const int WASHROOM_BUTTON   = 32;  // Green
const int DRIP_BUTTON       = 33;  // White

// Vibration motor/module signal
const int MOTOR_PIN = 23;

WiFiClient wifiClient;
PubSubClient mqtt(wifiClient);

// Previous button states
bool lastCallNurse = HIGH;
bool lastPain      = HIGH;
bool lastWater     = HIGH;
bool lastWashroom  = HIGH;
bool lastDrip      = HIGH;

// =====================================
// 3. VIBRATION CONTROL
// =====================================
bool motorActive = false;
bool vibrationIsOn = false;
int pulsesRemaining = 0;

unsigned long vibrationPhaseStarted = 0;
unsigned long vibrationDuration = 0;

const unsigned long SHORT_PULSE = 200;
const unsigned long SHORT_GAP = 200;

void startVibration(int pulseCount, unsigned long pulseDuration) {
  pulsesRemaining = pulseCount;
  vibrationDuration = pulseDuration;
  motorActive = true;
  vibrationIsOn = true;
  vibrationPhaseStarted = millis();

  digitalWrite(MOTOR_PIN, HIGH);
}

void updateVibration() {
  if (!motorActive) return;

  unsigned long elapsed = millis() - vibrationPhaseStarted;

  if (vibrationIsOn && elapsed >= vibrationDuration) {
    digitalWrite(MOTOR_PIN, LOW);
    vibrationIsOn = false;
    vibrationPhaseStarted = millis();
    pulsesRemaining--;

    if (pulsesRemaining <= 0) {
      motorActive = false;
    }
  }
  else if (!vibrationIsOn &&
           pulsesRemaining > 0 &&
           elapsed >= SHORT_GAP) {
    digitalWrite(MOTOR_PIN, HIGH);
    vibrationIsOn = true;
    vibrationPhaseStarted = millis();
  }
}

// =====================================
// 4. RECEIVE CAREGIVER REPLIES
// =====================================
void onMessage(char* topic, byte* payload, unsigned int length) {
  String message = "";

  for (unsigned int i = 0; i < length; i++) {
    message += (char)payload[i];
  }

  Serial.print("Caregiver reply received: ");
  Serial.println(message);

  if (message == "REQUEST_RECEIVED") {
    startVibration(1, SHORT_PULSE);
  }
  else if (message == "PLEASE_WAIT") {
    startVibration(2, SHORT_PULSE);
  }
  else if (message == "COMING_TO_HELP") {
    startVibration(1, 1000);
  }
  else {
    Serial.println("Unknown caregiver reply");
  }
}

// =====================================
// 5. CONNECT TO MQTT
// =====================================
void connectMQTT() {
  while (WiFi.status() == WL_CONNECTED && !mqt