Cảm biến tiệm cận NPN, PNP 24 V nối vào ESP32 qua opto: khoảng cách phát hiện, đếm vật, đo vòng

Nối cảm biến tiệm cận NPN, PNP 24 V vào ESP32 an toàn qua opto PC817, tính điện trở, khoảng cách phát hiện theo thép, inox, nhôm, đồng, chương trình đếm vật và đo vòng quay bằng ngắt.

Cảm biến tiệm cận cảm ứng từ loại M12, M18 (như dòng LJ12A3 hay gặp) phát hiện kim loại không cần chạm, bền, rẻ, hợp để đếm sản phẩm trên băng tải, đo tốc độ quay trục, báo vị trí xi lanh. Nhưng chúng chạy 12–24 V còn ESP32 chỉ chịu 3,3 V. Bài này hướng dẫn nối cảm biến tiệm cận NPN, PNP 24 V vào ESP32 an toàn qua opto PC817, tính điện trở cho opto, khoảng cách phát hiện theo từng loại kim loại, và chương trình đếm vật, đo vòng quay bằng ngắt có lọc nhiễu.

Khái niệm NPN, PNP, NO, NC, cảm biến 2 dây, 3 dây có ở bài cùng cụm về cảm biến NPN và PNP; cấu tạo, nguyên lý dòng xoáy có ở bài cảm biến tiệm cận cảm ứng từ.

1. Nối qua opto PC817

Sơ đồ nối cảm biến tiệm cận NPN và PNP vào ESP32 qua opto PC817: NPN có LED opto nối từ +24 V qua điện trở 4,7 kΩ tới dây đen; PNP có dây đen qua điện trở 4,7 kΩ tới LED opto, cực K xuống 0 V; phía ra opto chân C vào GPIO27, chân E vào GND ESP32
Phía 24 V và phía ESP32 không chung GND.

Không nối thẳng dây đen vào chân ESP32. Nhiều cảm biến NPN có sẵn điện trở kéo lên nguồn 24 V bên trong: lúc không có vật, dây đen mang 24 V và làm hỏng chân ESP32 ngay. PNP thì lúc có vật dây đen là 24 V. Opto PC817 giải quyết cả hai: cảm biến chỉ bật tắt đèn LED trong opto, phía ra là một transistor kéo chân ESP32 xuống GND, hai phía cách ly hoàn toàn.

  • NPN: chân A của opto qua điện trở 4,7 kΩ lên +24 V, chân K vào dây đen.
  • PNP: dây đen qua điện trở 4,7 kΩ vào chân A, chân K xuống 0 V của nguồn 24 V.
  • Phía ESP32: chân C vào GPIO27 (bật kéo lên trong chip), chân E vào GND của ESP32. Có vật thì LED sáng, transistor dẫn, GPIO27 xuống mức thấp.

Cách hoạt động của PC817, đo thời gian đáp ứng có ở bài optocoupler PC817. Cần nhiều ngõ vào thì dùng module cách ly 4, 8 kênh, hoặc xem bài cùng cụm về ngõ vào 24 V cho vi điều khiển.

2. Khoảng cách phát hiện theo vật liệu

Bảng khoảng cách phát hiện cảm biến tiệm cận Sn 4 mm theo vật liệu: thép thường 4 mm lắp cách dưới 3,2 mm, inox 304 khoảng 2,8 mm, đồng thau khoảng 1,8 mm, nhôm khoảng 1,6 mm, đồng khoảng 1,4 mm
Nhôm, đồng phải đưa gần hơn nhiều so với thép.

Khoảng cách ghi trên cảm biến (Sn, ví dụ 4 mm cho loại M12) đo với tấm thép chuẩn. Inox, đồng thau, nhôm, đồng bị phát hiện ở khoảng cách ngắn hơn, có khi chỉ còn một phần ba. Lắp cảm biến cách vật khoảng 80 % khoảng cách phát hiện để không chập chờn khi trục rung, nhiệt độ thay đổi.

3. Lắp đặt và chọn linh kiện

Bảng lắp đặt cảm biến tiệm cận: điện trở LED opto 4,3–4,7 kΩ 0,25 W ở 24 V, một đầu bu lông đo tới khoảng 30000 vòng phút với cảm biến 500 Hz, loại đầu phẳng lắp chìm, loại đầu lồi cần khoảng trống, hai cảm biến cách xa nhau, dây đi riêng
Số tính bằng script; thông số cảm biến lấy theo datasheet.

Script dưới đây tính khoảng cách theo vật liệu, điện trở và công suất cho LED opto, tốc độ quay lớn nhất đo được theo tần số đóng cắt ghi trong datasheet cảm biến:

# PYWORLD.VN - Tính nhanh khi lắp cảm biến tiệm cận cảm ứng từ 24 V với ESP32: khoảng cách phát hiện theo vật liệu, khe lắp an toàn
# PYWORLD.VN - Điện trở cho LED opto PC817 ở phía 24 V, và tốc độ quay lớn nhất đo được theo tần số đóng cắt của cảm biến
# PYWORLD.VN - Chạy: python tinh_tiem_can.py      (sửa SN, TAN_SO_CAM_BIEN theo datasheet cảm biến của bạn)
SN = 4.0                    # mm, khoảng cách danh định (ví dụ cảm biến M12 loại 4 mm, đo với thép)
TAN_SO_CAM_BIEN = 500       # Hz, tần số đóng cắt lớn nhất trong datasheet (giá trị ví dụ)
HE_SO = {"thep thuong": 1.0, "inox 304": 0.7, "dong thau": 0.45, "nhom": 0.4, "dong": 0.35}   # khoảng, theo kích thước và loại cảm biến


def khoang_cach(vat_lieu: str) -> tuple[float, float]:
    """(khoảng cách phát hiện ước tính, khe lắp nên dùng ≈ 80 % để chắc chắn)."""
    s = SN * HE_SO[vat_lieu]
    return s, 0.8 * s


def dien_tro_led(v_nguon: float = 24.0, v_led: float = 1.2, v_sut_cam_bien: float = 1.5, i_led_ma: float = 5.0) -> tuple[float, float]:
    """(điện trở Ω, công suất W) cho LED opto nối nối tiếp với ngõ ra cảm biến."""
    r = (v_nguon - v_led - v_sut_cam_bien) / (i_led_ma / 1000)
    return r, (i_led_ma / 1000) ** 2 * r


def vong_quay_toi_da(so_dau_bu_long: int) -> float:
    return TAN_SO_CAM_BIEN * 60 / so_dau_bu_long


if __name__ == "__main__":
    for vl in HE_SO:
        s, khe = khoang_cach(vl)
        print(f"{vl:12s}: phat hien ~{s:.1f} mm, nen lap khe <= {khe:.1f} mm")
    r, p = dien_tro_led()
    print(f"Dien tro LED opto o 24 V, 5 mA: {r:.0f} Ohm (chon 4,3-4,7 kOhm), cong suat {p:.2f} W")
    for n in (1, 2, 4):
        print(f"{n} dau bu long tren truc: do duoc toi ~{vong_quay_toi_da(n):.0f} vong/phut")

4. Chương trình đếm vật, đo vòng quay

Mỗi lần có vật kim loại đi qua (hoặc đầu bu lông trên trục quay qua), GPIO27 xuống mức thấp và gọi hàm ngắt. Hàm ngắt bỏ qua các xung cách nhau dưới 2 ms (nhiễu, rung tiếp xúc), cộng bộ đếm. Mỗi giây chương trình in tổng số vật, số xung trong giây, vòng/phút, và báo khi trục đang quay bỗng chậm hẳn (băng tải kẹt, đứt đai).

// PYWORLD.VN - Cảm biến tiệm cận cảm ứng từ 24 V (NPN hoặc PNP) nối ESP32 qua opto PC817: đếm vật đi qua và đo tốc độ quay trục bằng ngắt
// PYWORLD.VN - Lọc xung nhiễu ngắn hơn 2 ms ngay trong hàm ngắt; mỗi giây in tổng số vật, vòng/phút; báo khi trục quay chậm bất thường (kẹt)
// PYWORLD.VN - Ngõ ra transistor của opto: chân C -> GPIO27, chân E -> GND ESP32. Có vật: opto dẫn, GPIO27 xuống mức thấp

const int CHAN_CAM_BIEN = 27, LED_PIN = 2;
const uint32_t KHOANG_MIN_US = 2000;          // xung cách nhau dưới 2 ms coi là nhiễu (tối đa 500 xung/giây)
const int SO_DAU_BU_LONG = 1;                 // số đầu bu lông (vật kim loại) trên một vòng trục
const float VONG_PHUT_TOI_THIEU = 30;         // dưới mức này khi đang chạy thì báo kẹt

volatile uint32_t demTong = 0, demTrongGiay = 0, lucXungCuoi = 0;
portMUX_TYPE khoa = portMUX_INITIALIZER_UNLOCKED;
uint32_t lucIn = 0;
float vongPhutTruoc = 0;

void IRAM_ATTR coVat() {
  uint32_t t = micros();
  if (t - lucXungCuoi < KHOANG_MIN_US) return;
  lucXungCuoi = t;
  portENTER_CRITICAL_ISR(&khoa);
  demTong = demTong + 1;
  demTrongGiay = demTrongGiay + 1;
  portEXIT_CRITICAL_ISR(&khoa);
}

void setup() {
  Serial.begin(115200);
  pinMode(CHAN_CAM_BIEN, INPUT_PULLUP);        // dây dài, nhiều nhiễu: thêm điện trở 4,7 kΩ lên 3,3 V
  pinMode(LED_PIN, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(CHAN_CAM_BIEN), coVat, FALLING);
  Serial.println("San sang dem vat / do vong quay");
}

void loop() {
  digitalWrite(LED_PIN, digitalRead(CHAN_CAM_BIEN) == LOW ? HIGH : LOW);   // đèn sáng khi đang có vật trước cảm biến
  if (millis() - lucIn < 1000) return;
  lucIn = millis();
  portENTER_CRITICAL(&khoa);
  uint32_t tong = demTong, giay = demTrongGiay;
  demTrongGiay = 0;
  portEXIT_CRITICAL(&khoa);
  float vongPhut = giay * 60.0f / SO_DAU_BU_LONG;
  Serial.printf("Tong %lu vat | %lu xung/giay | %.0f vong/phut%s\n", (unsigned long)tong, (unsigned long)giay, vongPhut,
                (vongPhutTruoc >= VONG_PHUT_TOI_THIEU && vongPhut < VONG_PHUT_TOI_THIEU) ? "  <- QUAY CHAM, KIEM TRA KET" : "");
  vongPhutTruoc = vongPhut;
}
Serial Monitor đếm vật và đo vòng quay: 18 xung mỗi giây bằng 1080 vòng phút, trục dừng đột ngột thì báo quay chậm kiểm tra kẹt
Ví dụ minh họa.

Đo vòng quay chậm (vài chục vòng/phút) thì đếm trong 1 giây cho kết quả nhảy bậc; đo khoảng thời gian giữa hai xung bằng micros() sẽ chính xác hơn. Cách dùng ngắt, chống dội trong ngắt có ở bài ngắt GPIO trên ESP32.

5. Lỗi hay gặp

Hiện tượngNguyên nhânCách xử lý
Đèn trên cảm biến sáng mà ESP32 không nhậnNối opto sai chiều NPN/PNP, thiếu GND phía ESP32Đối chiếu sơ đồ; chân E opto nối GND ESP32
Đếm nhiều hơn số vậtNhiễu từ động cơ, vật rung qua lại ở mép vùng phát hiệnTăng khoảng lọc trong ngắt; lắp gần hơn; dây đi riêng
Không phát hiện vật nhôm, đồngKhoảng cách với kim loại màu ngắn hơn nhiềuLắp gần hơn, hoặc dùng cảm biến lớn hơn
Chân ESP32 hỏng sau khi thửNối thẳng dây đen 24 V vào GPIOLuôn qua opto hoặc mạch chuyển mức
Trục quay nhanh đo ra thấp hơn thực tếVượt tần số đóng cắt của cảm biến hoặc khoảng lọc 2 msGiảm số đầu bu lông; chọn cảm biến tần số cao hơn

Mạch dùng trong bài: ESP32 DevKit V1 30 chân.

Bài cùng cụm chủ đề: cảm biến NPN và PNP khác nhau thế nào; ngõ vào 24 V cho vi điều khiển; ESP32 trong môi trường công nghiệp.


Tin tức liên quan

AccelStepper: tăng tốc, giảm tốc mượt cho động cơ bước NEMA 17, A4988, ESP32, về gốc, hàm hay dùng
AccelStepper: tăng tốc, giảm tốc mượt cho động cơ bước NEMA 17, A4988, ESP32, về gốc, hàm hay dùng

Dùng thư viện AccelStepper cho động cơ bước NEMA 17 và A4988 trên ESP32: vì sao cần tăng tốc, cách thư viện tính khoảng cách bước, nối dây, về gốc bằng công tắc, hàm hay dùng, lỗi thường gặp.

Điều khiển relay từ xa bằng ESP-NOW: remote ESP32 một nút nhấn có phản hồi trạng thái
Điều khiển relay từ xa bằng ESP-NOW: remote ESP32 một nút nhấn có phản hồi trạng thái

Hướng dẫn làm bộ điều khiển relay từ xa bằng hai mạch ESP32 và ESP-NOW hai chiều: remote gửi lệnh, mạch relay báo lại trạng thái, lọc theo địa chỉ MAC và bật mã hóa.

Cài Mosquitto trên Windows: cấu hình listener, tài khoản mật khẩu, TLS chứng chỉ tự tạo và ESP32
Cài Mosquitto trên Windows: cấu hình listener, tài khoản mật khẩu, TLS chứng chỉ tự tạo và ESP32

Cài broker MQTT Mosquitto trên Windows: dịch vụ, listener cho mạng nội bộ, mosquitto_passwd, mở tường lửa, TLS với CA tự tạo bằng openssl, thử mosquitto_sub/pub và ESP32 kết nối qua TLS.

Cấu hình TFT_eSPI cho ESP32: User_Setup, chọn driver, khai báo chân và sửa lỗi màn trắng
Cấu hình TFT_eSPI cho ESP32: User_Setup, chọn driver, khai báo chân và sửa lỗi màn trắng

Thư viện TFT_eSPI đọc cấu hình theo thứ tự nào, bốn cách cấu hình (User_Setup, User_Setups, cờ -D, tft_setup.h), chọn driver ILI9341, ST7789, ST7735, khai báo chân ESP32, sketch kiểm tra.

Module 4G A7680C với ESP32: gửi SMS, bật tắt relay bằng tin nhắn, vì sao SIM800L không còn dùng được
Module 4G A7680C với ESP32: gửi SMS, bật tắt relay bằng tin nhắn, vì sao SIM800L không còn dùng được

Sóng 2G ở Việt Nam đã tắt nên SIM800L không còn dùng được; chọn module 4G thay thế, nối A7680C với ESP32, dùng lệnh AT gửi SMS, nhận lệnh từ số chủ máy để bật tắt relay.

Khóa cửa ESP32 mở bằng thẻ RFID hoặc mật khẩu: RC522, bàn phím 4x4, còi, khóa chốt điện từ 12 V
Khóa cửa ESP32 mở bằng thẻ RFID hoặc mật khẩu: RC522, bàn phím 4x4, còi, khóa chốt điện từ 12 V

Làm khóa cửa ESP32 mở bằng thẻ RFID RC522 hoặc mật khẩu bàn phím 4x4: nối dây, nguồn và diode cho khóa chốt 12 V, thêm xóa thẻ, đổi mật khẩu, tạm khóa khi sai 3 lần.

ESP32 điều khiển động cơ DC với driver L298N: đảo chiều, chỉnh tốc độ bằng PWM
ESP32 điều khiển động cơ DC với driver L298N: đảo chiều, chỉnh tốc độ bằng PWM

Hướng dẫn nối ESP32 với driver L298N và động cơ DC giảm tốc: cầu H, đảo chiều, phanh, chỉnh tốc độ bằng PWM, điều khiển bằng lệnh trên Serial Monitor và thí nghiệm STEM.

Cấp nguồn cho ESP32 đúng cách: cổng USB, chân VIN, 3V3, pin 18650 và lỗi brownout khi bật Wi-Fi
Cấp nguồn cho ESP32 đúng cách: cổng USB, chân VIN, 3V3, pin 18650 và lỗi brownout khi bật Wi-Fi

Cấp nguồn cho ESP32 qua cổng USB, chân VIN, 3V3, từ adapter hay pin 18650; vì sao ESP32 tự khởi động lại khi bật Wi-Fi (brownout) và chương trình đo sụt áp nguồn.


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