Xây Hệ Thống Cân Xe Tự Động: Kết Nối Cân Điện Tử Đời Cũ, Camera RTSP Và AI OCR Trong Thực Tế
Vấn đề nhà máy sản xuất: phần cứng ổn, nhưng phần mềm cân đã lỗi thời cả chục năm
Một công ty sản xuất quy mô lớn trong ngành chế biến nguyên liệu, đang vận hành trạm cân với phần cứng không hề tệ: đầu cân điện tử Mettler Toledo IND246 - một thiết bị công nghiệp đáng tin cậy, và hệ thống camera giám sát Hikvision chạy qua phần mềm iVMS-4200.
Vấn đề không nằm ở phần cứng. Nó nằm ở lớp phần mềm kết nối các thiết bị đó lại với nhau.
Phần mềm cân hiện tại được viết trên Visual FoxPro (VFP) 7.0 - một công nghệ ra đời từ đầu những năm 2000, ban đầu phát triển cho Windows XP/98. Về giao diện, nó vận hành gần giống Excel: có auto-fill thông tin theo mã khách hàng/loại hàng, kết nối đọc số cân trực tiếp từ đầu cân, in phiếu theo biểu mẫu. Nhưng nó có 3 giới hạn mang tính cấu trúc, không phải lỗi vặt:
- Camera chỉ giám sát live, không lưu evidence gắn với từng lượt cân. Muốn xem lại một giao dịch cụ thể, không có cách nào tra cứu hình ảnh tương ứng.
- Dữ liệu có thể sửa tay tuỳ ý, không log lại ai sửa, sửa gì, khi nào - tức là về mặt kỹ thuật, không có audit trail.
- Không có cách nào tích hợp thêm lớp xử lý mới (như AI OCR) vào một hệ thống VFP 20 năm tuổi mà không risk vỡ toàn bộ luồng nghiệp vụ đang chạy ổn định.
Nói cách khác: đây không phải bài toán "làm phần mềm cân từ đầu", mà là bài toán khó hơn - thay thế lớp phần mềm trong khi vẫn phải nói chuyện được với phần cứng cũ, quy trình cũ, và biểu mẫu giấy tờ cũ mà công ty đã dùng nhiều năm.
Giải pháp: thiết kế lại lớp phần mềm kết nối cân điện tử, camera và AI OCR
Hướng tiếp cận: xây phần mềm mới hỗ trợ giám sát trực tiếp camera, tích hợp AI OCR để tự động điền thông tin phiếu cân, tự động hoá quy trình, và quan trọng nhất - mọi thao tác chỉnh sửa đều yêu cầu duyệt và được ghi log, đồng thời ghi nhận hình ảnh làm bằng chứng cho mỗi lượt cân.
Đây là phần mà nhiều đội kỹ thuật đánh giá thấp độ khó - tưởng chỉ là "thêm tính năng", nhưng thực chất là 4 bài toán tích hợp phần cứng/thuật toán độc lập, mỗi bài toán đều có iteration thất bại trước khi ra được bản chạy ổn định.
1. Đọc dữ liệu từ đầu cân Mettler Toledo IND246

Không có SDK hiện đại nào cho thiết bị này - cần research manual (tài liệu) của cân để tìm hiểu về serial protocol mà cân của hãng Mettler Toledo sử dụng. Qua đó xác định được: cân này dùng giao thức theo chuẩn Standard Continuous Output Format để trả về trọng lượng, với tần suất 4Hz (4 lần/giây), mỗi frame dữ liệu dài 17-18 byte tuỳ có bật checksum hay không:
| Character | 1 | 2 | 3 | 4 | 5–10 | 11–16 | 17 18 |
|---|---|---|---|---|---|---|---|
| Ý nghĩa | STX SB-A | SB-B | SB-C | Indicated Weight (MSD→LSD) | Tare Weight (MSD→LSD) | CR | CHK |
Byte 1 (STX) đánh dấu đầu frame, 3 byte tiếp theo (SB-A/B/C) là status byte mã hoá trạng thái cân (ổn định/không ổn định, âm/dương, đơn vị đo...), 6 byte tiếp là khối lượng đang hiển thị, 6 byte sau là khối lượng bì (tare), byte áp chót là carriage return, byte cuối là checksum (optional). Việc parse đúng frame này là nền tảng cho toàn bộ hệ thống phía sau — sai 1 byte offset là toàn bộ số liệu đọc được sẽ lệch.
2. Kết nối camera qua RTSP - 3 lần đổi kiến trúc
Đây là phần tốn nhiều công sức nhất, và là ví dụ tốt cho việc "giải pháp đầu tiên hiếm khi là giải pháp đúng":
- Phương án 1 - WebSocket: main process decode + restream, UI process connect + decode + render bằng canvas. Thất bại - kết nối không ổn định, tốn nhiều CPU, delay cao. Nguyên nhân gốc: decode video là tác vụ nặng, đẩy cả decode lẫn render qua 2 lớp process khác nhau tạo ra quá nhiều overhead.
- Phương án 2 - WebRTC: main process relay, UI render qua RTCPeerConnection thẳng lên video element, tận dụng GPU. Delay thấp hơn hẳn, nhưng vẫn tốn nhiều CPU - vì main process vẫn phải relay RTP packet lên UI process, khiến chính main process (nơi xử lý toàn bộ business logic khác) bị nghẽn.
- Phương án 3 - go2rtc (hiện tại, đang chạy production): vẫn dựa trên nền WebRTC, nhưng tách hẳn một child process riêng chỉ để relay RTP packet, viết bằng Go để tận dụng hiệu năng cao và footprint nhẹ. UI chỉ việc connect và hiển thị, không đụng vào decode/relay. Kết quả: dưới 80MB RAM để stream đồng thời 4 camera độ phân giải 2K, delay ≤ 500ms.
Bài học kỹ thuật ở đây không phải "go2rtc là lựa chọn đúng" - mà là tách rõ trách nhiệm giữa main process (business logic) và tiến trình xử lý stream nặng, để một cái không kéo chậm cái còn lại. Đây là nguyên tắc áp dụng được cho nhiều hệ thống real-time khác, không riêng gì bài toán cân xe.
3. OCR biển số - vòng lặp cải thiện độ chính xác
Dùng PaddleOCR làm engine chính, nhưng chặng đường đến "chạy đúng" không hề thẳng:
- Lần test 1 - thất bại: PaddleOCR đọc nhầm overlay thông tin của camera (timestamp, tên camera hiển thị đè lên góc màn hình) thay vì đọc biển số xe thật - vì phần overlay này thường to và rõ nét hơn, dễ detect hơn biển số ở góc xa. Giải pháp: bổ sung ROI (Region of Interest) để crop khung hình trước khi đưa vào xử lý - vừa loại bỏ vùng nhiễu, vừa giảm tải CPU vì không cần infer trên full frame 2K nữa.
- Lần test 2 - đạt yêu cầu nhưng vẫn còn dư địa cải thiện: bổ sung thêm một model YOLO chuyên để detect vị trí biển số trước, cắt bounding box kèm 15% padding rồi mới feed vùng ảnh đó cho PaddleOCR đọc ký tự. Cách làm 2 tầng này (detect vị trí → crop → OCR) cho độ chính xác cao hơn và tốc độ xử lý nhanh hơn so với để PaddleOCR tự detect + đọc trên toàn khung hình.
4. Máy in Epson LQ-310 - chi tiết domain-specific dễ bị đánh giá thấp effort
Đây không phải phần cứng "cổ điển" theo nghĩa lỗi thời - mà là một yêu cầu domain -specific: đa số hệ thống khác chỉ cần in trên giấy A4/A5 thường (giấy trắng đơn), nhưng ở đây nghiệp vụ cân xe cần in 2 liên (carbon copy) - một bản đưa cho tài xế/đại lý, một bản giữ lại làm bằng chứng nội bộ. Vì đặc thù này khá hiếm gặp và là lần đầu team tiếp xúc, phải research kỹ mới in đúng: máy in dot-matrix Epson LQ-310, khổ giấy thực tế là A5 nhưng phải in ở định dạng A4 dọc thì layout mới khớp đúng vị trí trên giấy. Test lần 1 thất bại vì lệch layout, phải research thêm và hotfix ngay trong ngày để không làm gián đoạn vận hành thực tế tại nhà máy.
5. Vòng kiểm thử thực tế - không dừng ở "chạy được trên máy dev
- Test hardware lần 1: fix các vấn đề phát sinh khi chạy trên phần cứng thật (khác môi trường dev rất nhiều), cải thiện performance app.
- Test hardware lần 2 + UAT: giải quyết dứt điểm các vấn đề phần cứng còn lại, đồng thời hotfix trực tiếp theo feedback của khách hàng ngay tại hiện trường (UI thay đổi, UX cải thiện, sửa lỗi nhỏ) - đưa thẳng vào production trong ngày, không đợi release cycle dài.
Kết quả sau triển khai: hệ thống chạy ổn định trên phần cứng thật, dữ liệu minh bạch từng lượt cân
Về mặt kỹ thuật, hệ thống hiện đạt được:
- Stream ổn định 4 camera 2K đồng thời, delay ≤ 500ms, footprint dưới 80MB RAM cho phần xử lý stream.
- Pipeline OCR 2 tầng (YOLO detect + PaddleOCR đọc ký tự) cho độ chính xác cao hơn đáng kể so với chạy PaddleOCR đơn lẻ trên full frame.
- Toàn bộ lượt cân đều có ảnh evidence đi kèm, chỉnh sửa dữ liệu bắt buộc qua quy trình duyệt và được log lại - giải quyết đúng vấn đề gốc là thiếu minh bạch dữ liệu ở hệ thống VFP cũ.
- Hệ thống đã qua 2 vòng test hardware + UAT thực tế tại nhà máy và đang chạy production.

Điểm khác biệt: cái khó nằm ở tích hợp phần cứng thật, không phải ở thuật toán AI
Cái khó của dự án này không nằm ở việc "biết dùng OCR" hay "biết dùng RTSP" - cả hai đều là công nghệ khá phổ biến. Cái khó nằm ở:
- Tích hợp với phần cứng đã tồn tại nhiều năm, không phải build trên nền tảng sạch. Đọc protocol serial của một đầu cân không có SDK hiện đại, hay canh layout in cho đúng khổ giấy của một máy in dot-matrix đời cũ - đây là loại việc không có trong tutorial, chỉ có trong tài liệu kỹ thuật gốc và thử-sai thực tế.
- Tối ưu hiệu năng cho môi trường giới hạn tài nguyên, không phải chạy trên cloud server mạnh. go2rtc là một streaming server viết bằng Go, hỗ trợ nhiều protocol trong đó có WebRTC - team dùng go2rtc để chạy phần WebRTC relay trong một process riêng, tách khỏi main process.
- Coi minh bạch dữ liệu là yêu cầu kỹ thuật, không phải tính năng phụ. Ảnh evidence, log chỉnh sửa, quy trình duyệt - đây là những thứ phải thiết kế ngay từ đầu ở tầng data model và workflow, không thể "thêm sau" như một plugin.
Đây cũng là lý do các dự án dạng "phần mềm gặp phần cứng thật, tại hiện trường thật" thường tốn effort ở tầng tích hợp và độ tin cậy vận hành nhiều hơn là ở tầng thuật toán AI - điều mà nhìn từ ngoài (chỉ thấy demo cuối cùng) rất dễ bị đánh giá thấp.
All rights reserved