RF 433 MHz là gì: điều chế ASK/OOK và tự viết giao thức phát, thu bằng ESP32

Giải thích sóng RF 433 MHz và điều chế ASK/OOK, cách mã hóa bit bằng độ rộng xung và khung tin 24 bit. Hướng dẫn tự viết chương trình phát và thu trên hai mạch ESP32, không dùng thư viện ngoài.

Module phát và thu RF 433 MHz là cách rẻ và đơn giản nhất để hai mạch nói chuyện không dây: mỗi module chỉ có ba chân và không cần cấu hình gì. Đổi lại, chúng không làm gì ngoài việc chuyển mức logic thành sóng và ngược lại; địa chỉ, khung tin, chống nhiễu đều phải tự lo. Bài viết giải thích điều chế ASK/OOK, cách mã hóa bit bằng độ rộng xung, rồi tự viết chương trình phát và thu trên hai mạch ESP32 mà không dùng thư viện ngoài, để thấy rõ từng xung trên đường truyền.

1. RF 433 MHz và điều chế ASK/OOK

Điều chế ASK/OOK: chân DATA của mạch phát ở mức cao thì có sóng mang 433,92 MHz, ở mức thấp thì tắt sóng; chân DATA của mạch thu trả lại đúng dạng xung đó
Mạch phát bật sóng mang khi DATA ở mức cao và tắt khi DATA ở mức thấp; mạch thu khôi phục lại dạng xung.
  • Sóng mang là sóng vô tuyến tần số 433,92 MHz. Băng tần quanh 433 MHz dành cho các thiết bị cự ly ngắn, công suất thấp như điều khiển từ xa, chuông cửa không dây, cảm biến thời tiết.
  • ASK (Amplitude Shift Keying) là truyền dữ liệu bằng cách thay đổi biên độ sóng mang. Dạng đơn giản nhất là OOK (On-Off Keying): mức 1 là có sóng, mức 0 là tắt hẳn.
  • Module phát chỉ là một bộ dao động được bật, tắt bởi chân DATA. Module thu dò xem có sóng 433 MHz hay không rồi đưa kết quả ra chân DATA của nó.
  • Module không hiểu dữ liệu: không có địa chỉ, không kiểm tra lỗi, không phát lại. Đường truyền chỉ đi một chiều, từ mạch phát sang mạch thu.
  • Khi không có ai phát, mạch thu tự tăng độ nhạy cho tới khi bắt được nhiễu nền, nên chân DATA của nó nhảy mức liên tục. Chương trình thu phải tách được khung tin thật ra khỏi nhiễu.

2. Mã hóa bit và khung tin

Khung tin RF 433 MHz: xung đồng bộ cao 1T thấp 31T, bit 0 cao 1T thấp 3T, bit 1 cao 3T thấp 1T; một khung gồm xung đồng bộ, 16 bit mã thiết bị và 8 bit lệnh, được phát lặp lại 6 lần mỗi lần nhấn nút
Ba kiểu xung, một khung 24 bit đầy đủ và cách mạch thu xử lý các khung lặp lại.

Không thể nối thẳng UART vào module: mạch thu cần tín hiệu đổi mức đều đặn để giữ được ngưỡng so sánh, một chuỗi dài toàn bit 0 hoặc toàn bit 1 sẽ bị méo. Cách làm phổ biến là mã hóa mỗi bit bằng độ rộng xung, sao cho bit nào cũng có một đoạn mức cao và một đoạn mức thấp.

  • Đơn vị thời gian T = 350 µs. Mọi khoảng thời gian trong giao thức là bội số của T.
  • Bit 0: cao 1T, thấp 3T. Bit 1: cao 3T, thấp 1T. Hai loại bit dài bằng nhau (4T = 1,4 ms), mạch thu chỉ cần so xem đoạn nào dài hơn.
  • Xung đồng bộ: cao 1T rồi thấp 31T. Khoảng thấp dài bất thường này báo cho mạch thu biết một khung mới bắt đầu.
  • Khung tin gồm xung đồng bộ và 24 bit, bit cao gửi trước: 16 bit mã thiết bị và 8 bit lệnh. Mã thiết bị đóng vai trò địa chỉ: mạch thu chỉ làm theo khung mang đúng mã của mình.
  • Lặp lại: mạch phát không biết mạch thu có nhận được hay không, nên mỗi lần nhấn nút nó phát khung 6 lần liên tiếp. Mạch thu chỉ tin một mã khi nhận được hai khung liền nhau giống hệt; nhiễu ngẫu nhiên gần như không thể tạo ra điều đó.

Một khung dài 128T = 44,8 ms, cả lượt phát dài 280 ms. Kiểu mã hóa này cũng được nhiều bộ điều khiển 433 MHz mã cố định sử dụng, nên mạch thu có thể bắt được mã của thiết bị khác ở gần; chương trình sẽ bỏ qua các mã đó.

3. Chuẩn bị

  • Hai mạch ESP32 DevKit V1 30 chân (hoặc bản dùng chip CH340).
  • Một module phát và một module thu 433 MHz loại ASK (thường bán theo cặp).
  • Hai đoạn dây đồng một lõi dài 17,3 cm làm ăng-ten.
  • Điện trở 2,2 kΩ và 3,3 kΩ, cần khi module thu chạy nguồn 5 V.
  • Hai breadboard, dây cắm và hai cáp USB.
  • Arduino IDE 2.x với gói esp32 by Espressif Systems (bài dùng phiên bản 3.3.10). Không cần cài thêm thư viện.

4. Sơ đồ nối

Mạch phát

Sơ đồ nối ESP32 DevKit V1 với module phát RF 433 MHz: DATA nối D4, GND nối GND, VCC nối VIN 5 V, dây ăng-ten dài 17,3 cm hàn vào lỗ ANT của module
Mạch phát: DATA nối D4, nguồn 5 V lấy từ chân VIN, thêm dây ăng-ten 17,3 cm.
  • Chân DATA của module phát là ngõ vào, nhận thẳng mức 3,3 V từ D4.
  • Module phát thường chạy được ở dải điện áp rộng; cấp 5 V từ chân VIN cho sóng mạnh hơn so với cấp 3,3 V.
  • Nút nhấn dùng luôn nút BOOT trên mạch (GPIO0), không phải nối thêm.

Mạch thu

Sơ đồ nối ESP32 DevKit V1 với module thu RF 433 MHz: DATA qua mạch chia áp 2,2 kilôôm và 3,3 kilôôm vào D27, GND nối GND, VCC nối VIN 5 V, dây ăng-ten dài 17,3 cm
Mạch thu: DATA qua mạch chia áp vào D27 khi module chạy nguồn 5 V.
Loại module thuNguồnNối chân DATA
Ghi rõ chạy được 3,3 V (thường là loại siêu ngoại sai)3V3Nối thẳng vào D27
Chỉ chạy 5 V (thường là loại siêu tái sinh, giá rẻ)VIN (5 V)Qua mạch chia áp 2,2 kΩ và 3,3 kΩ
  • Chân của ESP32 chỉ chịu được 3,3 V. Mạch chia áp 2,2 kΩ và 3,3 kΩ đưa mức 5 V xuống 3 V.
  • Ăng-ten: một phần tư bước sóng của 433,92 MHz là 17,3 cm. Hàn đoạn dây vào lỗ ANT của cả hai module và để dây thẳng. Thiếu ăng-ten, hai mạch chỉ liên lạc được trong vài chục centimet.
  • Module thu loại siêu ngoại sai thu xa hơn và ít bị nhiễu hơn loại siêu tái sinh.

5. Chương trình mạch phát

/*
  PYWORLD.VN - RF 433 MHz với ESP32: mạch phát, tự tạo khung 24 bit theo kiểu điều chế độ rộng xung
  Mỗi lần nhấn nút BOOT (GPIO0), mạch phát lần lượt lệnh bật rồi lệnh tắt; mỗi khung được phát lặp lại 6 lần
  Module phát 433 MHz: DATA = D4, VCC = VIN (5 V), GND = GND; hàn thêm dây ăng-ten dài 17,3 cm
*/

#define TX_PIN 4
#define NUT_PIN 0                      // Nút BOOT trên mạch, nhấn là mức thấp

const uint16_t MA_THIET_BI = 0xA5C3;   // 16 bit nhận dạng: mạch thu chỉ nghe mã này
const uint8_t LENH_BAT = 0x01;
const uint8_t LENH_TAT = 0x02;

const unsigned int T_US = 350;         // Đơn vị thời gian của giao thức, micro giây
const int SO_LAN_LAP = 6;

void phatXung(int soTCao, int soTThap) {
  digitalWrite(TX_PIN, HIGH);          // Mức cao: module phát sóng mang
  delayMicroseconds(T_US * soTCao);
  digitalWrite(TX_PIN, LOW);           // Mức thấp: tắt sóng mang
  delayMicroseconds(T_US * soTThap);
}

// Khung: xung đồng bộ (cao 1T, thấp 31T) rồi 24 bit, bit cao trước.
// Bit 0 = cao 1T, thấp 3T. Bit 1 = cao 3T, thấp 1T.
void phatKhung(uint32_t ma24) {
  for (int lan = 0; lan < SO_LAN_LAP; lan++) {
    phatXung(1, 31);
    for (int i = 23; i >= 0; i--) {
      if ((ma24 >> i) & 1) {
        phatXung(3, 1);
      } else {
        phatXung(1, 3);
      }
    }
  }
  phatXung(1, 31);                     // Xung kết thúc để mạch thu chốt bit cuối của khung cuối
}

void setup() {
  Serial.begin(115200);
  pinMode(TX_PIN, OUTPUT);
  digitalWrite(TX_PIN, LOW);
  pinMode(NUT_PIN, INPUT_PULLUP);
  Serial.printf("\nMach phat RF 433 MHz, ma thiet bi 0x%04X. Nhan nut BOOT de phat\n", MA_THIET_BI);
}

void loop() {
  static bool dangBat = false;

  if (digitalRead(NUT_PIN) == LOW) {
    delay(30);                         // Chống dội nút nhấn
    if (digitalRead(NUT_PIN) == LOW) {
      dangBat = !dangBat;
      uint8_t lenh = dangBat ? LENH_BAT : LENH_TAT;
      uint32_t ma24 = ((uint32_t)MA_THIET_BI << 8) | lenh;
      phatKhung(ma24);
      Serial.printf("Da phat ma 0x%06X (%s), lap %d lan\n", (unsigned)ma24, dangBat ? "BAT" : "TAT", SO_LAN_LAP);
      while (digitalRead(NUT_PIN) == LOW) {
        delay(10);                     // Chờ nhả nút
      }
    }
  }
}
  • phatXung() tạo một đoạn mức cao rồi một đoạn mức thấp, độ dài tính theo số lần T.
  • phatKhung() ghép xung đồng bộ với 24 bit, gửi bit cao trước, lặp lại 6 lần. Xung cuối cùng sau vòng lặp tạo ra sườn lên để mạch thu chốt được bit cuối của khung cuối.
  • Mã 24 bit ghép từ mã thiết bị và lệnh: 0xA5C3 với lệnh 0x01 thành 0xA5C301.
  • Hãy đổi MA_THIET_BI thành một số riêng, giống nhau ở cả hai chương trình.

6. Chương trình mạch thu

/*
  PYWORLD.VN - RF 433 MHz với ESP32: mạch thu, giải mã khung 24 bit bằng cách đo độ rộng xung trong hàm ngắt
  Chỉ chấp nhận mã khi nhận được hai khung liên tiếp giống nhau và đúng mã thiết bị; lệnh 0x01 bật, 0x02 tắt LED GPIO2
  Module thu 433 MHz: DATA = D27 (qua mạch chia áp nếu module chạy 5 V), VCC và GND theo loại module
*/

#define RX_PIN 27
#define LED_PIN 2

const uint16_t MA_THIET_BI = 0xA5C3;
const uint8_t LENH_BAT = 0x01;
const uint8_t LENH_TAT = 0x02;

const unsigned int T_US = 350;                   // Phải trùng với mạch phát
const unsigned int DONG_BO_MIN_US = T_US * 24;   // Khoảng thấp của xung đồng bộ là 31T, cho phép sai lệch
const unsigned int DONG_BO_MAX_US = T_US * 40;
const unsigned int BIT_MIN_US = T_US * 4 * 6 / 10;   // Một bit dài 4T, cho phép sai lệch 40 %
const unsigned int BIT_MAX_US = T_US * 4 * 14 / 10;
const unsigned long CUA_SO_LAP_MS = 300;         // Hai khung giống nhau phải tới trong khoảng này

volatile uint32_t maVuaNhan = 0;
volatile bool coMaMoi = false;

// Chạy mỗi khi chân DATA đổi mức: đo thời gian mức cao và mức thấp của từng xung
void IRAM_ATTR khiDoiMuc() {
  static unsigned long lucTruoc = 0;
  static uint32_t thoiGianCao = 0;
  static int soBit = -1;                         // -1: đang chờ xung đồng bộ
  static uint32_t ma = 0;

  unsigned long bayGio = micros();
  uint32_t doDai = bayGio - lucTruoc;
  lucTruoc = bayGio;

  if (digitalRead(RX_PIN) == LOW) {              // Vừa hết một đoạn mức cao
    thoiGianCao = doDai;
    return;
  }

  // Vừa hết một đoạn mức thấp: đã có đủ một cặp cao, thấp
  uint32_t thoiGianThap = doDai;
  if (thoiGianThap > DONG_BO_MIN_US && thoiGianThap < DONG_BO_MAX_US && thoiGianCao < 2 * T_US) {
    soBit = 0;                                   // Xung đồng bộ: bắt đầu một khung mới
    ma = 0;
    return;
  }
  if (soBit < 0) {
    return;
  }
  uint32_t tong = thoiGianCao + thoiGianThap;
  if (tong < BIT_MIN_US || tong > BIT_MAX_US) {
    soBit = -1;                                  // Không phải bit hợp lệ: bỏ khung, chờ đồng bộ lại
    return;
  }
  ma = (ma << 1) | (thoiGianCao > thoiGianThap ? 1 : 0);
  soBit++;
  if (soBit == 24) {
    maVuaNhan = ma;
    coMaMoi = true;
    soBit = -1;
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(LED_PIN, OUTPUT);
  pinMode(RX_PIN, INPUT);
  attachInterrupt(digitalPinToInterrupt(RX_PIN), khiDoiMuc, CHANGE);
  Serial.printf("\nMach thu RF 433 MHz, chi nghe ma thiet bi 0x%04X\n", MA_THIET_BI);
}

void loop() {
  static uint32_t maTruoc = 0;
  static unsigned long lucMaTruoc = 0;
  static unsigned long lucXuLyCuoi = 0;

  if (!coMaMoi) {
    return;
  }
  noInterrupts();
  uint32_t ma = maVuaNhan;
  coMaMoi = false;
  interrupts();

  // Nhiễu có thể tạo ra một khung ngẫu nhiên; hai khung liên tiếp giống hệt nhau thì gần như chắc chắn là thật
  bool lapLai = (ma == maTruoc) && (millis() - lucMaTruoc < CUA_SO_LAP_MS);
  maTruoc = ma;
  lucMaTruoc = millis();
  if (!lapLai || millis() - lucXuLyCuoi < 500) {
    return;                                      // Chưa đủ tin cậy, hoặc vừa xử lý chính lần nhấn này
  }
  lucXuLyCuoi = millis();

  uint16_t maThietBi = ma >> 8;
  uint8_t lenh = ma & 0xFF;
  Serial.printf("Nhan ma 0x%06X: thiet bi 0x%04X, lenh 0x%02X", (unsigned)ma, maThietBi, lenh);
  if (maThietBi != MA_THIET_BI) {
    Serial.println(" -> khong phai ma cua minh, bo qua");
  } else if (lenh == LENH_BAT) {
    digitalWrite(LED_PIN, HIGH);
    Serial.println(" -> BAT LED");
  } else if (lenh == LENH_TAT) {
    digitalWrite(LED_PIN, LOW);
    Serial.println(" -> TAT LED");
  } else {
    Serial.println(" -> lenh khong ro");
  }
}

Hàm ngắt khiDoiMuc() chạy mỗi khi chân DATA đổi mức và đo thời gian từ lần đổi mức trước:

  1. Ở sườn xuống, khoảng thời gian vừa đo là độ dài đoạn mức cao; hàm ghi lại rồi thoát.
  2. Ở sườn lên, khoảng thời gian vừa đo là độ dài đoạn mức thấp; lúc này đã có đủ một cặp cao, thấp.
  3. Cặp có đoạn thấp dài 24T đến 40T và đoạn cao ngắn là xung đồng bộ: bắt đầu đếm bit từ 0.
  4. Các cặp tiếp theo phải có tổng thời gian gần 4T (cho phép lệch 40 %). Đoạn cao dài hơn đoạn thấp là bit 1, ngược lại là bit 0.
  5. Gặp một cặp sai độ dài thì bỏ cả khung và chờ xung đồng bộ kế tiếp. Nhiễu nền bị loại gần hết ở bước này.
  6. Đủ 24 bit thì chuyển mã cho loop() qua hai biến volatile.

Trong loop(), mã chỉ được chấp nhận khi trùng với mã của khung ngay trước đó trong vòng 300 ms. Sau khi thực hiện lệnh, chương trình bỏ qua các khung lặp còn lại trong 500 ms để một lần nhấn nút chỉ được xử lý một lần. Cách dùng ngắt trên ESP32 có trong bài ngắt GPIO và chống dội nút nhấn.

7. Kết quả mong đợi

Hình minh họa Serial Monitor của mạch phát và mạch thu RF 433 MHz: mạch phát in mã đã phát cho lệnh bật và lệnh tắt, mạch thu in mã nhận được, mã thiết bị, lệnh và việc bật tắt LED
Kết quả mong đợi trên Serial Monitor của hai mạch (hình minh họa).
  1. Nạp chương trình phát cho mạch thứ nhất, chương trình thu cho mạch thứ hai. Mở Tools > Serial Monitor ở 115200 baud cho mạch thu.
  2. Nhấn nút BOOT trên mạch phát: đèn LED trên mạch thu sáng. Nhấn lần nữa: đèn tắt.
  3. Đưa hai mạch ra xa dần để biết tầm liên lạc; thử lại sau khi tháo ăng-ten để thấy khác biệt.
  4. Đổi MA_THIET_BI ở mạch phát rồi nạp lại: mạch thu in mã nhận được và báo không phải mã của mình.

8. Giới hạn và lưu ý khi dùng

  • Không có xác nhận: đường truyền một chiều, mạch phát không biết lệnh đã tới nơi chưa. Việc quan trọng cần đường truyền hai chiều có trả lời, như ESP-NOW hoặc LoRa.
  • Không bảo mật: mã cố định truyền đi không mã hóa; ai có một mạch thu 433 MHz ở gần cũng đọc được và phát lại được. Không dùng cách này cho khóa cửa, cổng hay báo động. Thiết bị cần bảo mật dùng mã thay đổi sau mỗi lần nhấn (mã nhảy) hoặc giao thức có mã hóa.
  • Băng tần dùng chung: nhiều thiết bị cùng phát ở 433 MHz. Khi hai thiết bị phát cùng lúc, cả hai khung đều hỏng; khung lặp lại và mã thiết bị giúp giảm ảnh hưởng nhưng không loại bỏ được.
  • Chỉ dùng cho thiết bị của chính mình và giữ nguyên công suất của module bán sẵn, không gắn thêm mạch khuếch đại công suất.
  • Tốc độ thấp: khoảng 700 bit mỗi giây, hợp với lệnh bật tắt và số đo nhỏ. Dữ liệu dài hơn nên thêm mã kiểm tra lỗi CRC vào khung.

9. Xử lý lỗi thường gặp

Hiện tượngNguyên nhân thường gặpCách xử lý
Mạch thu không in gì dù hai mạch đặt gần nhauSai chân DATA, module chưa có nguồn, hai chương trình khác giá trị TKiểm tra dây theo bảng nối; để T_US giống nhau ở hai chương trình
Vẫn không nhận được khi module thu chạy 5 V qua mạch chia ápMột số module thu có mức cao ở chân DATA thấp hơn nguồn khá nhiều; sau chia áp không còn đủ để ESP32 nhận là mức caoĐo mức cao của chân DATA bằng máy hiện sóng; nếu không vượt 3,6 V thì bỏ mạch chia áp, nối thẳng DATA vào D27
Chỉ nhận được ở khoảng cách rất gầnThiếu ăng-ten, ăng-ten sai chiều dài hoặc cuộn lại; mạch phát cấp nguồn thấpHàn dây 17,3 cm cho cả hai module, để thẳng; cấp 5 V cho module phát
Lúc nhận lúc khôngNhiễu từ thiết bị 433 MHz khác, nguồn của module thu bị nhiễuTăng SO_LAN_LAP; gắn tụ 100 nF và 10 µF sát chân nguồn module thu; đặt module xa mạch nguồn xung
Mạch thu in mã lạBắt được thiết bị 433 MHz khác ở gầnBình thường; chương trình đã bỏ qua mã không khớp MA_THIET_BI
Phải nhấn hai lần đèn mới đổiMột lượt phát bị lỡ; mạch phát gửi lệnh bật, tắt xen kẽ nên lần nhấn sau mang lệnh còn lạiXem Serial Monitor của mạch phát để biết lệnh vừa gửi; tăng SO_LAN_LAP
Thêm Wi-Fi hoặc việc nặng khác vào chương trình thì nhận kémHàm ngắt bị trễ, thời gian đo sai lệch nhiều hơnTăng T ở cả hai chương trình, ví dụ lên 500 µs

10. Xem thêm


Tin tức liên quan

Bluetooth Low Energy (BLE) là gì: quảng bá, GATT, dịch vụ, đặc tính và ESP32
Bluetooth Low Energy (BLE) là gì: quảng bá, GATT, dịch vụ, đặc tính và ESP32

Giải thích Bluetooth Low Energy: quảng bá và kết nối, cấu trúc GATT gồm dịch vụ, đặc tính, mô tả, UUID. Hướng dẫn cho ESP32 làm thiết bị BLE có đặc tính đọc, ghi, thông báo và thử bằng điện thoại.

Điều khiển hồng ngoại hoạt động thế nào: sóng mang 38 kHz, giao thức NEC và ESP32
Điều khiển hồng ngoại hoạt động thế nào: sóng mang 38 kHz, giao thức NEC và ESP32

Giải thích điều khiển hồng ngoại: sóng mang 38 kHz, mắt thu và giao thức NEC với khung 32 bit, mã lặp. Hướng dẫn tự giải mã phím điều khiển và tự phát lệnh bằng ESP32, không dùng thư viện ngoài.

Vòng dòng 4-20 mA là gì và cách đọc cảm biến 4-20 mA bằng ESP32
Vòng dòng 4-20 mA là gì và cách đọc cảm biến 4-20 mA bằng ESP32

Giải thích vòng dòng 4-20 mA: vì sao dùng dòng điện, vì sao bắt đầu từ 4 mA, cách đổi ra giá trị đo và ngưỡng báo lỗi. Hướng dẫn đọc bằng ESP32 qua điện trở shunt 120 Ω, với ADC có sẵn và với ADS1115.

CAN bus (phần 2): bộ lọc nhận, tốc độ bit và xử lý lỗi bus-off trên ESP32
CAN bus (phần 2): bộ lọc nhận, tốc độ bit và xử lý lỗi bus-off trên ESP32

Phần 2 về CAN bus với ESP32: đặt bộ lọc nhận theo mã lọc và mặt nạ, chọn tốc độ bit theo chiều dài dây, hiểu ba trạng thái lỗi của nút và viết chương trình theo dõi bộ đếm lỗi, tự hồi phục sau bus-off.

CAN bus (phần 1): tín hiệu, khung tin, phân xử ưu tiên và gửi nhận bằng ESP32
CAN bus (phần 1): tín hiệu, khung tin, phân xử ưu tiên và gửi nhận bằng ESP32

Giải thích CAN bus: hai dây CAN_H, CAN_L, mức trội và mức lặn, khung tin có ID 11 bit, phân xử ưu tiên, CRC và ACK. Kèm hai chương trình ESP32 dùng bộ điều khiển TWAI: tự kiểm tra và hai nút gửi nhận.

Modbus TCP/IP (phần 2): ESP32 làm máy khách và cổng chuyển đổi Modbus TCP sang RTU
Modbus TCP/IP (phần 2): ESP32 làm máy khách và cổng chuyển đổi Modbus TCP sang RTU

Hướng dẫn dùng ESP32 làm máy khách Modbus TCP đọc thanh ghi của một thiết bị trong mạng, và làm cổng chuyển đổi Modbus TCP sang Modbus RTU qua RS-485: cách đổi khung, mã thiết bị, thời gian chờ, mã lỗi 0x0B.

Modbus TCP/IP (phần 1): phần đầu MBAP và ESP32 làm máy chủ qua Wi-Fi
Modbus TCP/IP (phần 1): phần đầu MBAP và ESP32 làm máy chủ qua Wi-Fi

Giải thích Modbus TCP/IP: phần đầu MBAP, cổng 502, điểm khác với Modbus RTU. Kèm chương trình ESP32 làm máy chủ Modbus TCP qua Wi-Fi với 10 thanh ghi giữ và 8 cuộn, tự phân tích khung, không dùng thư viện.

TCP và UDP là gì: địa chỉ IP, cổng, kết nối và cách dùng trên ESP32
TCP và UDP là gì: địa chỉ IP, cổng, kết nối và cách dùng trên ESP32

Giải thích TCP và UDP cho người làm vi điều khiển: địa chỉ IP, cổng, kết nối, xác nhận, vì sao TCP là dòng byte. Kèm hai chương trình ESP32: máy chủ TCP nhận lệnh và phát, nhận gói UDP trong mạng Wi-Fi.


Bình luận
Đã thêm vào giỏ hàng