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.

Vòng dòng 4-20 mA là cách truyền một giá trị đo đi xa lâu đời và phổ biến nhất trong công nghiệp: cảm biến áp suất, mức, nhiệt độ, lưu lượng phần lớn đều có ngõ ra 4-20 mA. Khác với các chuẩn còn lại trong loạt bài này, đây là tín hiệu tương tự: độ lớn của dòng điện chính là giá trị đo. Bài viết giải thích vì sao dùng dòng điện thay cho điện áp, vì sao bắt đầu từ 4 mA, cách đổi dòng điện thành giá trị đo, và cách đọc tín hiệu này bằng ESP32 qua một điện trở shunt, với ADC có sẵn hoặc với module ADS1115.

1. Vòng dòng 4-20 mA hoạt động thế nào?

Sơ đồ vòng dòng 4-20 mA: nguồn 24 V, cảm biến 4-20 mA loại hai dây và điện trở shunt 120 ôm mắc nối tiếp thành một vòng, điện áp trên điện trở shunt đưa tới ADC
Nguồn 24 V, cảm biến và điện trở shunt mắc nối tiếp; cùng một dòng điện chạy qua cả vòng.
  • Cảm biến loại hai dây mắc nối tiếp với nguồn 24 V một chiều. Nó tự điều chỉnh dòng điện chạy qua mình theo giá trị đo: 4 mA ở đầu thang, 20 mA ở cuối thang.
  • Trong một vòng nối tiếp, dòng điện ở mọi điểm bằng nhau. Dây dài, điện trở dây lớn hay mối nối kém đều không làm đổi dòng điện, miễn là nguồn còn đủ điện áp. Tín hiệu điện áp thì bị sụt dọc đường dây.
  • Dòng điện ít bị nhiễu điện từ ảnh hưởng hơn điện áp, nên dây đi được hàng trăm mét trong nhà xưởng.
  • Chính dòng 4 mA tối thiểu là nguồn nuôi cảm biến, nên chỉ cần hai dây cho cả nguồn và tín hiệu.
  • Bên nhận đặt một điện trở shunt trong vòng và đo điện áp trên nó: U = I × R.

2. Từ dòng điện ra giá trị đo

Thang đo 4-20 mA: 4 mA là 0 phần trăm, 12 mA là 50 phần trăm, 20 mA là 100 phần trăm; ví dụ với cảm biến 0 đến 10 bar và điện áp tương ứng trên điện trở 120 ôm là 0,48 V, 1,44 V, 2,40 V; dưới 3,6 mA và trên 21 mA là vùng báo lỗi
Quan hệ giữa dòng điện, phần trăm thang đo, giá trị đo và điện áp trên điện trở shunt.
  • Công thức: giá trị đo = nhỏ nhất + (dòng − 4) / 16 × (lớn nhất − nhỏ nhất), với dòng tính bằng mA.
  • Ví dụ cảm biến áp suất 0 đến 10 bar: 12 mA ứng với 50 %, tức 5 bar.
  • Vì sao bắt đầu từ 4 mA? Nếu đầu thang là 0 mA thì không phân biệt được "giá trị đo bằng 0" với "đứt dây". Với 4 mA là điểm không, dòng 0 mA chắc chắn là sự cố.
  • Ngưỡng báo lỗi: theo quy ước phổ biến, dòng dưới 3,6 mA hoặc trên 21 mA nghĩa là đứt dây, mất nguồn, chập mạch hoặc cảm biến tự báo hỏng.

3. Chọn điện trở shunt cho ESP32

Điện trở shuntĐiện áp ở 4 mAĐiện áp ở 20 mANhận xét
250 Ω1,00 V5,00 VChuẩn công nghiệp cho ngõ vào 1 đến 5 V; quá cao cho ESP32
150 Ω0,60 V3,00 VSát giới hạn của ADC, phần trên thang đo kém chính xác
120 Ω0,48 V2,40 VNằm trong vùng ADC của ESP32 đo tốt; bài dùng giá trị này
100 Ω0,40 V2,00 VDùng được, độ phân giải thấp hơn một chút
  • Dùng điện trở sai số 1 % hoặc tốt hơn: sai số của điện trở shunt đi thẳng vào kết quả đo.
  • Ở 20 mA, điện trở 120 Ω tiêu tán 48 mW; loại 0,25 W là đủ khi làm việc bình thường.
  • Điện trở shunt làm sụt bớt điện áp của vòng (2,4 V ở 20 mA). Nguồn 24 V thừa sức bù phần này cho hầu hết cảm biến.

4. Chuẩn bị

  • Một mạch ESP32 DevKit V1 30 chân (hoặc bản dùng chip CH340).
  • Điện trở 120 Ω loại 1 %, điện trở 10 kΩ, tụ 100 nF.
  • Để thử khi chưa có cảm biến: một biến trở 1 kΩ và một điện trở 47 Ω.
  • Cho chương trình 2: một module ADS1115.
  • Breadboard và dây cắm.
  • 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.

5. Sơ đồ nối

Sơ đồ nguyên lý đọc 4-20 mA bằng ESP32: mạch thử gồm biến trở 1 kilôôm và điện trở 47 ôm từ 3V3 tới điểm X, điện trở shunt 120 ôm từ X xuống GND, điện trở 10 kilôôm và tụ 100 nF bảo vệ và lọc nhiễu trước chân D34
Điện trở shunt 120 Ω, điện trở bảo vệ 10 kΩ và tụ lọc 100 nF trước chân D34; mạch thử dùng biến trở.
  • Mạch thử: biến trở 1 kΩ nối tiếp điện trở 47 Ω từ chân 3V3 tới điểm X. Vặn biến trở, dòng qua điện trở shunt thay đổi từ khoảng 2,8 mA đến 19,8 mA, đủ để thử cả dải đo và ngưỡng báo đứt dây.
  • Với cảm biến thật: bỏ mạch thử. Cực dương nguồn 24 V nối cực dương cảm biến; cực âm cảm biến nối điểm X; cực âm nguồn 24 V nối GND của ESP32.
  • Điện trở 10 kΩ hạn dòng vào chân ADC nếu điểm X lỡ vượt 3,3 V; tụ 100 nF cùng với nó tạo thành bộ lọc nhiễu.
  • Mạch này không cách ly: GND của ESP32 nối chung với cực âm nguồn 24 V.

6. Chương trình 1: đọc bằng ADC của ESP32

/*
  PYWORLD.VN - Vòng dòng 4-20 mA với ESP32: đọc dòng điện qua điện trở shunt 120 ôm bằng ADC, đổi sang giá trị đo
  Điện áp trên điện trở shunt đưa vào D34 qua điện trở 10 kΩ; 4 mA cho 0,48 V và 20 mA cho 2,40 V
  Dòng dưới 3,6 mA được báo là đứt dây hoặc cảm biến lỗi, trên 21 mA là quá dòng
*/

#define CHAN_DO 34

const float DIEN_TRO_SHUNT = 120.0;        // Ôm; nên dùng điện trở sai số 1 %
const float DONG_MIN_MA = 4.0;             // Ứng với giá trị đo nhỏ nhất
const float DONG_MAX_MA = 20.0;            // Ứng với giá trị đo lớn nhất
const float NGUONG_DUT_DAY_MA = 3.6;
const float NGUONG_QUA_DONG_MA = 21.0;

const float GIA_TRI_MIN = 0.0;             // Dải đo của cảm biến, ví dụ cảm biến áp suất 0 đến 10 bar
const float GIA_TRI_MAX = 10.0;
const char *DON_VI = "bar";

const int SO_MAU = 64;

// Lấy trung bình nhiều mẫu để giảm nhiễu; mV chia cho ôm ra mA
float docDongMa() {
  uint32_t tongMv = 0;
  for (int i = 0; i < SO_MAU; i++) {
    tongMv += analogReadMilliVolts(CHAN_DO);
    delayMicroseconds(500);
  }
  float dienApMv = (float)tongMv / SO_MAU;
  return dienApMv / DIEN_TRO_SHUNT;
}

void setup() {
  Serial.begin(115200);
  analogSetPinAttenuation(CHAN_DO, ADC_11db);
  Serial.printf("\nVong dong 4-20 mA, shunt %.0f ohm: %.1f mA = %.1f %s, %.1f mA = %.1f %s\n",
                DIEN_TRO_SHUNT, DONG_MIN_MA, GIA_TRI_MIN, DON_VI, DONG_MAX_MA, GIA_TRI_MAX, DON_VI);
}

void loop() {
  float dongMa = docDongMa();

  if (dongMa < NGUONG_DUT_DAY_MA) {
    Serial.printf("Dong %.2f mA: DUT DAY hoac cam bien mat nguon\n", dongMa);
  } else if (dongMa > NGUONG_QUA_DONG_MA) {
    Serial.printf("Dong %.2f mA: QUA DONG, cam bien bao loi hoac bi chap\n", dongMa);
  } else {
    // Nội suy tuyến tính: 4 mA là 0 %, 20 mA là 100 %
    float tiLe = (dongMa - DONG_MIN_MA) / (DONG_MAX_MA - DONG_MIN_MA);
    tiLe = constrain(tiLe, 0.0f, 1.0f);
    float giaTri = GIA_TRI_MIN + tiLe * (GIA_TRI_MAX - GIA_TRI_MIN);
    Serial.printf("Dong %.2f mA | %.1f %% | %.2f %s\n", dongMa, tiLe * 100.0f, giaTri, DON_VI);
  }
  delay(500);
}

Sửa GIA_TRI_MIN, GIA_TRI_MAX và DON_VI theo dải đo của cảm biến đang dùng. ADC của ESP32 có sai số vài phần trăm và hơi phi tuyến; với phép đo cần chính xác hơn, dùng chương trình 2. Nền tảng về ADC có trong bài đọc ADC trên ESP32.

7. Chương trình 2: đọc bằng ADS1115

Nối chân A0 của ADS1115 vào điểm X (vẫn qua điện trở 10 kΩ), VDD vào 3V3, GND vào GND, SDA vào D21, SCL vào D22. Ở thang ±4,096 V mỗi bước của ADS1115 là 0,125 mV, ứng với khoảng 1 µA trên điện trở 120 Ω.

/*
  PYWORLD.VN - Vòng dòng 4-20 mA với ESP32 và ADS1115: đo chính xác hơn bằng bộ chuyển đổi 16 bit qua I2C
  Điện áp trên điện trở shunt 120 ôm đưa vào chân A0 của ADS1115; mỗi bước của kết quả là 0,125 mV, tức khoảng 1 µA
  ADS1115: VDD = 3V3, SDA = D21, SCL = D22, ADDR để trống (địa chỉ 0x48); đọc thanh ghi trực tiếp bằng thư viện Wire
*/

#include <Wire.h>

#define SDA_PIN 21
#define SCL_PIN 22

const uint8_t DIA_CHI_ADS = 0x48;
const uint8_t THANH_GHI_KET_QUA = 0x00;
const uint8_t THANH_GHI_CAU_HINH = 0x01;
const uint16_t CAU_HINH_DO_A0 = 0xC383;    // Đo một lần kênh A0 so với GND, thang ±4,096 V, 128 mẫu mỗi giây
const float MV_MOI_BUOC = 0.125;

const float DIEN_TRO_SHUNT = 120.0;
const float DONG_MIN_MA = 4.0;
const float DONG_MAX_MA = 20.0;
const float NGUONG_DUT_DAY_MA = 3.6;
const float NGUONG_QUA_DONG_MA = 21.0;

const float GIA_TRI_MIN = 0.0;             // Dải đo của cảm biến
const float GIA_TRI_MAX = 10.0;
const char *DON_VI = "bar";

// Trả về false nếu ADS1115 không trả lời
bool docDienApMv(float *dienApMv) {
  Wire.beginTransmission(DIA_CHI_ADS);
  Wire.write(THANH_GHI_CAU_HINH);
  Wire.write((uint8_t)(CAU_HINH_DO_A0 >> 8));
  Wire.write((uint8_t)(CAU_HINH_DO_A0 & 0xFF));
  if (Wire.endTransmission() != 0) {
    return false;
  }
  delay(10);   // Một lần đo ở 128 mẫu mỗi giây mất khoảng 8 ms

  Wire.beginTransmission(DIA_CHI_ADS);
  Wire.write(THANH_GHI_KET_QUA);
  if (Wire.endTransmission(false) != 0 || Wire.requestFrom(DIA_CHI_ADS, (uint8_t)2) != 2) {
    return false;
  }
  uint8_t byteCao = Wire.read();
  uint8_t byteThap = Wire.read();
  int16_t ketQua = (int16_t)(((uint16_t)byteCao << 8) | byteThap);
  *dienApMv = ketQua * MV_MOI_BUOC;
  return true;
}

void setup() {
  Serial.begin(115200);
  Wire.begin(SDA_PIN, SCL_PIN, 100000);
  Serial.printf("\nVong dong 4-20 mA voi ADS1115, shunt %.0f ohm\n", DIEN_TRO_SHUNT);
}

void loop() {
  // Trung bình 8 lần đo
  float tongMv = 0;
  for (int i = 0; i < 8; i++) {
    float dienApMv = 0;
    if (!docDienApMv(&dienApMv)) {
      Serial.println("Khong doc duoc ADS1115: kiem tra day SDA, SCL va nguon");
      delay(1000);
      return;
    }
    tongMv += dienApMv;
  }
  float dienApMv = tongMv / 8;
  float dongMa = dienApMv / DIEN_TRO_SHUNT;

  if (dongMa < NGUONG_DUT_DAY_MA) {
    Serial.printf("%.1f mV | dong %.3f mA: DUT DAY hoac cam bien mat nguon\n", dienApMv, dongMa);
  } else if (dongMa > NGUONG_QUA_DONG_MA) {
    Serial.printf("%.1f mV | dong %.3f mA: QUA DONG, cam bien bao loi hoac bi chap\n", dienApMv, dongMa);
  } else {
    float tiLe = constrain((dongMa - DONG_MIN_MA) / (DONG_MAX_MA - DONG_MIN_MA), 0.0f, 1.0f);
    float giaTri = GIA_TRI_MIN + tiLe * (GIA_TRI_MAX - GIA_TRI_MIN);
    Serial.printf("%.1f mV | dong %.3f mA | %.2f %% | %.3f %s\n", dienApMv, dongMa, tiLe * 100.0f, giaTri, DON_VI);
  }
  delay(500);
}

Chương trình đọc thẳng thanh ghi của ADS1115 bằng thư viện Wire. Cách dùng thư viện có sẵn cho module này có trong bài đo điện áp 16 bit bằng ADS1115.

8. Kết quả mong đợi

Hình minh họa Serial Monitor của hai chương trình đọc 4-20 mA trên ESP32: dòng điện, phần trăm thang đo và giá trị tính theo bar, cùng thông báo đứt dây khi dòng dưới 3,6 mA
Kết quả mong đợi trên Serial Monitor (hình minh họa; giá trị dòng điện là ví dụ).
  1. Mở Tools > Serial Monitor ở 115200 baud và vặn biến trở: dòng điện, phần trăm và giá trị đo thay đổi theo.
  2. Vặn biến trở về phía điện trở lớn nhất: dòng xuống dưới 3,6 mA và chương trình báo đứt dây.
  3. Rút dây khỏi điểm X: dòng về gần 0 mA, cũng được báo là đứt dây.
  4. So hai chương trình: kết quả từ ADS1115 ổn định hơn và có nhiều chữ số có nghĩa hơn.

9. Lưu ý an toàn và độ chính xác

  • Điện áp ở điểm X: bình thường không quá 2,4 V. Nhưng nếu cảm biến bị chập, toàn bộ 24 V đặt lên điện trở shunt: điện trở nóng lên rất nhanh và điểm X lên 24 V. Thiết bị dùng thật cần cầu chì hoặc nguồn có giới hạn dòng, và một đi-ốt ổn áp 3,3 V ở chân ADC sau điện trở 10 kΩ.
  • Nối đúng cực tính nguồn 24 V và kiểm tra bằng đồng hồ trước khi nối vào ESP32.
  • Hiệu chuẩn: để đo chính xác, đo giá trị thật của điện trở shunt bằng đồng hồ và sửa hằng DIEN_TRO_SHUNT.
  • Môi trường công nghiệp: đường dây dài có thể mang xung quá áp. Bộ thu thương mại có thêm phần chống sét lan truyền và cách ly; mạch trong bài chỉ dùng để học và thử nghiệm.

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

Hiện tượngNguyên nhân thường gặpCách xử lý
Luôn báo đứt dâyNgược cực cảm biến, thiếu nguồn 24 V, chưa nối chung GNDĐo dòng trong vòng bằng đồng hồ; kiểm tra cực tính và dây GND
Dòng đọc được thấp hơn thực tếGiá trị điện trở shunt lớn hơn khai báo, hoặc sai số ADCĐo lại điện trở shunt; so với đồng hồ; dùng ADS1115
Số đo nhảy lung tungNhiễu trên dây dài, thiếu tụ lọcThêm tụ 100 nF, tăng số mẫu lấy trung bình, dùng dây xoắn có chống nhiễu
Dòng không lên tới 20 mANguồn vòng không đủ điện áp cho cảm biến cộng dây và điện trở shuntDùng nguồn 24 V; giảm điện trở shunt
Không đọc được ADS1115Sai dây SDA, SCL hoặc sai địa chỉKiểm tra dây; chân ADDR để trống hoặc nối GND cho địa chỉ 0x48
Giá trị đo sai tỉ lệKhai báo sai dải đo của cảm biếnSửa GIA_TRI_MIN, GIA_TRI_MAX theo nhãn cảm biến

11. 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.

RF 433 MHz là gì: điều chế ASK/OOK và tự viết giao thức phát, thu bằng ESP32
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.

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