BT 1 — ESP32 simulation

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

Components

Sketch code

#include <DHT.h>

#define DHT_PIN  4
#define BTN_PIN  5
#define LED_PIN  2
#define UART_RX  16
#define UART_TX  17

DHT dht(DHT_PIN, DHT22);

const uint32_t SENSE_PERIOD   = 2000;
const uint32_t LED_ON_TIME    = 500;
const uint32_t ACK_TIMEOUT    = 500;
const uint32_t RETRY_INTERVAL = 1000;
const uint8_t  MAX_RETRY      = 3;
const uint32_t DEBOUNCE_MS    = 50;

const uint8_t HDR1 = 0xFD, HDR2 = 0xAD;
const uint8_t ACK1 = 0xFD, ACK2 = 0xDE;

float temp = 0, hum = 0;
uint32_t tSense = 0;
bool ledOn = false;

enum TxState { IDLE, WAIT_ACK, WAIT_RETRY };
TxState st = IDLE;
uint32_t tSend = 0;
uint8_t retryCnt = 0;

bool lastBtn = HIGH;
uint32_t lastDebounce = 0;
uint8_t ackIdx = 0;

void sendFrame() {
  int16_t t = (int16_t)lroundf(temp * 10);
  int16_t h = (int16_t)lroundf(hum * 10);
  uint8_t f[7];
  f[0] = HDR1; f[1] = HDR2;
  f[2] = (uint8_t)(t >> 8); f[3] = (uint8_t)(t & 0xFF);
  f[4] = (uint8_t)(h >> 8); f[5] = (uint8_t)(h & 0xFF);
  f[6] = f[2] ^ f[3] ^ f[4] ^ f[5];
  Serial2.write(f, 7);
  Serial.printf("[A] Gui frame (lan %d): T=%.1f H=%.1f\n", retryCnt, temp, hum);
}

bool checkAck() {
  while (Serial2.available()) {
    uint8_t b = Serial2.read();
    if (ackIdx == 0) {
      if (b == ACK1) ackIdx = 1;
    } else {
      if (b == ACK2) { ackIdx = 0; return true; }
      ackIdx = (b == ACK1) ? 1 : 0;
    }
  }
  return false;
}

void setup() {
  Serial.begin(115200);
  Serial2.begin(115200, SERIAL_8N1, UART_RX, UART_TX);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BTN_PIN, INPUT_PULLUP);
  digitalWrite(LED_PIN, LOW);
  dht.begin();
  Serial.println("[A] San sang");
}

void loop() {
  uint32_t now = millis();

  if (now - tSense >= SENSE_PERIOD) {
    tSense = now;
    float t = dht.readTemperature();
    float h = dht.readHumidity();
    if (!isnan(t) && !isnan(h)) { temp = t; hum = h; }
    Serial.printf("[A] Doc DHT22: T=%.1f H=%.1f\n", temp, hum);
    digitalWrite(LED_PIN, HIGH);
    ledOn = true;
  }

  if (ledOn && now - tSense >= LED_ON_TIME) {
    digitalWrite(LED_PIN, LOW);
    ledOn = false;
  }

  bool btn = digitalRead(BTN_PIN);
  if (lastBtn == HIGH && btn == LOW && now - lastDebounce > DEBOUNCE_MS) {
    lastDebounce = now;
    if (st == IDLE) {
      while (Serial2.available()) Serial2.read();
      ackIdx = 0;
      retryCnt = 0;
      sendFrame();
      tSend = now;
      st = WAIT_ACK;
    } else {
      Serial.println("[A] Dang gui, bo qua lan nhan nut nay");
    }
  }
  lastBtn = btn;

  if (st != IDLE && checkAck()) {
    Serial.println("[A] Nhan ACK -> ket thuc gui");
    st = IDLE;
  }
  if (st == WAIT_ACK && now - tSend >= ACK_TIMEOUT) {
    if (retryCnt >= MAX_RETRY) {
      Serial.println("[A] Het 3 lan gui lai, that bai!");
      st = IDLE;
    } else {
      st = WAIT_RETRY;
    }
  }
  if (st == WAIT_RETRY && now - tSend >= RETRY_INTERVAL) {
    retryCnt++;
    sendFrame();
    tSend = now;
    st = WAIT_ACK;
  }
}