NguyenKhacSon 231432336 — ESP32 simulation

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

Components

Sketch code

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

// --- ĐỊNH NGHĨA CHÂN GIAO TIẾP ---
#define DHTPIN 4
#define DHTTYPE DHT22
#define LED_PIN 2
#define BTN_PIN 15

#define RX2_PIN 16
#define TX2_PIN 17

DHT dht(DHTPIN, DHTTYPE);

// --- BIẾN LƯU DỮ LIỆU CẢM BIẾN ---
float currentTemp = 0.0;
float currentHum = 0.0;

// --- ĐỊNH THỜI CHU KỲ ĐỌC CẢM BIẾN & LED (2000ms) ---
unsigned long lastCycleTime = 0;
const unsigned long CYCLE_PERIOD = 2000;
const unsigned long LED_ON_DURATION = 500;
bool isLedOn = false;

// --- BIẾN CHỐNG DỘI NÚT NHẤN (DEBOUNCE) ---
bool lastBtnState = HIGH;
bool currentBtnState = HIGH;
unsigned long lastDebounceTime = 0;
const unsigned long DEBOUNCE_DELAY = 50;

// --- MÁY TRẠNG THÁI TRUYỀN UART & RETRY ---
enum TxState {
  TX_IDLE,         // Trạng thái rỗi, sẵn sàng gửi khi nhấn nút
  TX_WAIT_ACK,     // Đang chờ gói ACK (0xFD, 0xDE) trong 500ms
  TX_WAIT_RETRY    // Chờ đủ 1000ms giữa các lần gửi lại
};

TxState txState = TX_IDLE;
unsigned long txTimer = 0;
int retryCount = 0;
const int MAX_RETRIES = 3;
const unsigned long ACK_TIMEOUT = 500;     // Thời gian chờ ACK: 500ms
const unsigned long RETRY_INTERVAL = 1000; // Khoảng cách giữa các lần gửi lại: 1s

// Bộ đệm kiểm tra byte ACK nhận về
uint8_t prevRxByte = 0;

// --- HÀM ĐÓNG GÓI VÀ GỬI KHUNG DỮ LIỆU 10 BYTE ---
void sendSensorFrame(float temp, float hum) {
  // Xóa sạch bộ đệm nhận trước khi gửi để tránh đọc nhầm ACK cũ
  while (Serial2.available()) {
    Serial2.read();
  }
  prevRxByte = 0;

  uint8_t frame[10];
  frame[0] = 0xFD;
  frame[1] = 0xAD;
  
  // Sao chép 4 byte của biến float vào mảng byte (Little-Endian trên ESP32)
  memcpy(&frame[2], &temp, sizeof(float));
  memcpy(&frame[6], &hum, sizeof(float));

  Serial2.write(frame, sizeof(frame));
  
  Serial.printf("[Device A] Da gui goi tin: [0xFD 0xAD] | Temp: %.2f C, Hum: %.2f %%\n", temp, hum);
}

// --- HÀM KIỂM TRA GÓI BÁO NHẬN ACK (0xFD, 0xDE) ---
bool checkAckReceived() {
  while (Serial2.available() > 0) {
    uint8_t b = Serial2.read();
    if (prevRxByte == 0xFD && b == 0xDE) {
      prevRxByte = 0;
      return true;
    }
    prevRxByte = b;
  }
  return false;
}

void setup() {
  Serial.begin(115200);
  // Khởi tạo UART2 ở tốc độ 115200 bps
  Serial2.begin(115200, SERIAL_8N1, RX2_PIN, TX2_PIN);

  pinMode(LED_PIN, OUTPUT);
  digitalWrite(LED_PIN, LOW);
  pinMode(BTN_PIN, INPUT_PULLUP);

  dht.begin();
  Serial.println("=== THIET BI A (SENSOR NODE) KHOI DONG ===");
}

void loop() {
  unsigned long now = millis();

  // =================================================================
  // 1. TÁC VỤ ĐỊNH THỜI 2 GIÂY: ĐỌC DHT22 & ĐIỀU KHIỂN LED (500ms SÁNG)
  // =================================================================
  if (now - lastCycleTime >= CYCLE_PERIOD) {
    lastCycleTime = now;

    // Bật sáng LED bắt đầu chu kỳ 2s
    digitalWrite(LED_PIN, HIGH);
    isLedOn = true;

    // Đọc dữ liệu từ cảm biến DHT22
    float t = dht.readTemperature();
    float h = dht.readHumidity();

    if (!isnan(t)

More projects by nks260805