lab 2 — Esp32 Devkit C V4 simulation

An interactive Esp32 Devkit C V4 circuit simulation you can run free in your browser on Velxio, by karyllefaye08.

Components

Sketch code

#include <Arduino.h>
#include <DHT.h>
#include <math.h>

// CpE 428 - Laboratory #2
// ESP32 #1: Transmitter
// UART + Timer ISR + GPIO SPI-like TX
// Button interrupt + Red LED
// Arduino-ESP32 3.x

#define DHT_PIN 4
#define DHT_TYPE DHT22

#define UART_RX 16
#define UART_TX 17
#define UART_BAUD 115200

#define SPI_MOSI 23
#define SPI_MISO 19
#define SPI_SCK 18
#define SPI_CS 5

#define BUTTON_PIN 27
#define RED_LED 25

#define SENSOR_INTERVAL 2500UL
#define SPI_INTERVAL_US 30000000ULL
#define SPI_HALF_CLOCK_MS 250UL
#define SPI_CS_SETUP_MS 500UL
#define ALERT_DURATION 3000UL
#define DEBOUNCE_MS 200UL

DHT dht(DHT_PIN, DHT_TYPE);
HardwareSerial uartLink(2);

hw_timer_t *spiTimer = nullptr;

volatile bool spiTimerFlag = false;
volatile bool buttonFlag = false;

float temperature = NAN;
float humidity = NAN;

bool sensorValid = false;

uint32_t lastSensorRead = 0;
uint32_t lastButtonPress = 0;
uint32_t redStart = 0;

bool redActive = false;
bool buttonArmed = true;

uint8_t spiData[4] = {};
uint8_t sequenceNumber = 0;

bool spiActive = false;

uint8_t spiPhase = 0;
uint8_t spiBitIndex = 0;

uint32_t spiStepTime = 0;
uint32_t spiStarted = 0;

uint32_t spiSentCount = 0;
uint32_t uartSentCount = 0;

void ARDUINO_ISR_ATTR onSPITimer() {
  spiTimerFlag = true;
}

void ARDUINO_ISR_ATTR onButtonPress() {
  buttonFlag = true;
}

void updateRedLED() {
  if (redActive &&
      millis() - redStart >= ALERT_DURATION) {

    digitalWrite(RED_LED, LOW);
    redActive = false;

    Serial.println("[RED LED] OFF");
  }
}

void handleButton() {
  if (digitalRead(BUTTON_PIN) == HIGH) {
    buttonArmed = true;
  }

  if (!buttonFlag) return;

  noInterrupts();
  buttonFlag = false;
  interrupts();

  uint32_t now = millis();

  if (!buttonArmed ||
      digitalRead(BUTTON_PIN) != LOW) {
    return;
  }

  if (lastButtonPress != 0 &&
      now - lastButtonPress < DEBOUNCE_MS) {
    return;
  }

  buttonArmed = false;
  lastButtonPress = now;

  digitalWrite(RED_LED, HIGH);

  redActive = true;
  redStart = now;

  uartLink.println("ALERT: Manual Trigger");

  Serial.println();
  Serial.println("[BUTTON ISR] Button event");
  Serial.println("[UART TX] ALERT: Manual Trigger");
  Serial.println("[RED LED] ON");
}

void sendSensorUART() {
  float t = dht.readTemperature();
  float h = dht.readHumidity();

  if (!isfinite(t) || !isfinite(h)) {
    sensorValid = false;

    uartLink.println("ERROR,DHT22");
    Serial.println("[DHT22] ERROR");

    return;
  }

  temperature = t;
  humidity = h;
  sensorValid = true;

  char message[80];

  snprintf(
    message,
    sizeof(message),
    "DATA,%.2f,%.2f,%lu\n",
    temperature,
    humidity,
    (unsigned long)millis()
  );

  uartLink.print(message);
  uartSentCount++;

  Serial.printf(
    "[UART TX] Temp=%.1f C Hum=%.1f %% "
    "Timestamp=%lu ms Packet=%lu\n",
    temperature,
    humidity,
    (unsigned long)millis(),
    (unsigned long)uartSentCount
  );
}

void prepareSPIPacket() {
  sequenceNumber++;

  int tempRoun