Nhận biết các lệnh IR sử dụng UART trên AVR


Giới thiệu
Rất nhiều bài báo đã được viết về việc nhận ra các lệnh từ điều khiển từ xa hồng ngoại. Về cơ bản, chúng ta đang nói về giao thức RC5 từ các điều khiển từ xa của Philips [1]. Giao thức này không phải là duy nhất và không phổ biến nhất. Một mô tả tốt về các định dạng khác trong tiếng Nga có thể được tìm thấy trong tài liệu [2]. 
Trong tất cả các bài viết tôi đã tìm thấy, nhận dạng được thực hiện bằng cách đọc trạng thái của cảm biến TSOP tại các thời điểm được xác định nghiêm ngặt (trong trình xử lý ngắt hẹn giờ hoặc trong vòng lặp chương trình chính). Tuy nhiên, trong dự án cuối cùng của tôi, tôi cần liên lạc với một thiết bị bên ngoài với độ trễ thời gian nghiêm ngặt, đó là lý do tại sao tôi phải cấm các gián đoạn trong khoảng thời gian lên tới 2ms. Thực tế này làm cho không thể thăm dò trạng thái của cảm biến TSOP với độ chính xác cần thiết (cứ sau 560 +s + -100 s).  
Vì vậy, ý tưởng đã được sinh ra để sử dụng UART như là một đăng ký thay đổi khó khăn của J. Trong quá trình thực hiện thu được, khi giải mã một giao thức giống như NEC, cần phải từ từ thẩm vấn trạng thái của cảm biến chỉ sau 4ms, trong khi bản thân vi điều khiển có thể ở chế độ không tải hoặc thậm chí ở chế độ tắt nguồn!
Điều khiển từ xa
Giao thức IR
Tôi thấy không có lý do để lặp lại mô tả của các giao thức điều khiển từ xa IR - chúng được mô tả khá tốt trong bài viết [2]. Tôi sẽ chỉ phác thảo những điểm chính:
Gửi IR bằng giao thức NEC làm ví dụ
Việc truyền IR sử dụng giao thức NEC làm ví dụ bao gồm xung Mark (9ms), xung Space (4.5ms) và chuỗi xung dữ liệu.
Trong các giao thức khác nhau, các bit dữ liệu được mã hóa khác nhau, nhưng độ dài xung của một cực luôn bằng hoặc bội số của độ dài xung của cực đối diện (có thể bỏ qua sự khác biệt của vài micro giây, vì lỗi tích lũy trong quá trình gửi không ảnh hưởng đến việc giải mã. giá trị bit). 
Cần lưu ý rằng ở đầu ra của cảm biến TSOP, tín hiệu hiển thị sẽ bị đảo ngược: 
Dao động của tín hiệu điều khiển từ xa
Để giải mã lệnh, cần phải đồng bộ hóa với mặt trước của xung dữ liệu đầu tiên, đợi ở giữa (280) s) và tiếp tục thăm dò trạng thái cảm biến sau mỗi 560 ss:
Các khoảnh khắc thẩm vấn của cảm biến phải được quan sát khá chính xác (không quá + -100 s). 
Nếu các khoảng thời gian không thể được quan sát, thì giải mã phần mềm sẽ không hoạt động. Chúng ta cần tìm kiếm một số giải pháp khác. Giải pháp trong phần trên mũi sẽ là sử dụng một vi điều khiển thứ hai hoặc một chip giải mã chuyên dụng. 
Tuy nhiên, điều đáng ghi nhớ là trên mạng, trên máy tính, AVR có rất nhiều thiết bị mà bạn có thể thử sử dụng cho các mục đích khác :)
Giao thức UART
UART sử dụng giao thức nối tiếp đơn giản [3]:
Giao thức UART nối tiếp
Với một đường kẻ đơn giản, nó được giữ ở vị trí đứng 1. Thời điểm bắt đầu truyền được xác định bởi cạnh rơi của bit bit start start (0). Các bit dữ liệu theo sau, sau đó là một bit chẵn lẻ (có thể không được sử dụng), sau đó một hoặc hai bit stop (1). Nghĩa là, sau khi byte được truyền, dòng trở về trạng thái 1 và chu kỳ truyền bắt đầu lại. Độ dài của tất cả các bit là như nhau và bằng tốc độ 1 / Baud.
Giao thức UART không tương thích với các giao thức IR.
Tuy nhiên, nếu bạn quên giao thức UART và coi bộ thu UART như một thanh ghi thay đổi với bộ đếm thời gian và đồng bộ hóa trên cạnh xuống, thì hóa ra nó phù hợp để nhận ra (gần như) bất kỳ chuỗi nào.
Bạn có thể đọc về cách bộ thu UART hoạt động trong biểu dữ liệu trên AT90USB162 [4]. 
Sau khi xác định cạnh rơi, máy thu tạm dừng dài ½ bit, sau đó nó kiểm tra xem dòng đó có còn ở mức 0 0 không (phát hiện bit bắt đầu hợp lệ). 
Sau đó, một chu kỳ nhận bit dữ liệu bắt đầu, không có bất kỳ kiểm tra nào, tại các khoảng bằng với độ dài của bit. Các bit dữ liệu Nhập vào các thanh ghi dịch chuyển của người nhận và bit dừng đầu tiên - trong cờ FE ở dạng đảo ngược. 
Nếu bạn mô tả toàn bộ quá trình này theo cách đơn giản hóa, thì ở chế độ 7N1, máy thu sẽ chờ một cạnh rơi xuống, sau đó nó sẽ đọc đầu vào 8 lần đều đặn. Nhưng đây chính xác là cách giải mã phần mềm của giao thức IR được mô tả ở trên!
Nhận biết các lệnh IR sử dụng UART
Chúng ta hãy xem điều gì sẽ xảy ra nếu bạn đưa tín hiệu vào mạng tín hiệu từ bộ thu IR đến UART.
Bảng điều khiển của tôi sử dụng một giao thức với các khoảng thời gian như trong giao thức NEC [2], mặc dù bản thân định dạng lệnh là khác nhau. 
Đặt chế độ UART thành 7N1 (7 bit dữ liệu, không có bit chẵn lẻ, 1 bit stop). Đặt tốc độ Baud thành 1.000.000 / 560μs = 1786 baud. 
Dấu Mark 9ms (NG 0 0 tại đầu ra của cảm biến TSOP) sẽ được người nhận chấp nhận là 0000000b với bit dừng sai:
Sau đó, người nhận sẽ đợi cạnh rơi tiếp theo (nó sẽ bỏ qua Mark và toàn bộ Space đến cuối). Khi bắt đầu gửi IR, máy thu sẽ đồng bộ hóa ở giữa bit (560 s / 2 = 280 s) và đọc 7 bit dữ liệu + bit stop:
Sau khi nhận được 7 + 1 bit, UART sẽ đợi cạnh giảm tiếp theo và nếu bit cuối cùng là 1 0 0 thì dòng đầu tiên sẽ quay trở lại với 1 1. Tại thời điểm này, chúng ta có một khoảng trống nhất định trong bộ tiếp nhận, điều này khiến cho việc giải mã chính xác các giao thức IR trong đó các bit được mã hóa theo độ dài xung. Nhưng ngay cả trong trường hợp này, một gói duy nhất sẽ tạo dữ liệu duy nhất trong bộ thu UART. Vì nhiệm vụ không phải là giải mã nội dung của lệnh, nhưng công nhận gói, tình huống này hoàn toàn phù hợp với chúng tôi.
Thực hiện
Một ví dụ được viết trong Codevision AVR 2.05 cho ATMega8A, bộ cộng hưởng thạch anh 8 MHz.
Vòng lặp chương trình chính thăm dò trạng thái UART cứ sau 4ms và ghi dữ liệu nhận được vào bộ đệm tuần hoàn 12 byte. Độ dài của bộ đệm được chọn dựa trên chiều dài của gói IR.
Điều khiển từ xa của tôi có chiều dài bưu kiện là 54ms. 54000/560 = 96 bit hoặc 12 byte đầy đủ. Chúng tôi chọn 11 byte và +1 cho số 0 bắt đầu (không cần thiết phải phân tích toàn bộ gói, nhưng điều rất quan trọng là gói dẫn đến một vòng đệm). Đối với điều khiển từ xa, trong đó độ dài của gói khác nhau tùy thuộc vào nút, thuật toán sẽ phức tạp hơn một chút (nó sẽ không được thảo luận ở đây).
Sau khi nhận được byte tiếp theo, nó được kiểm tra xem byte tiếp theo trong bộ đệm tuần hoàn có bằng không. Zero byte có nghĩa là chúng tôi đã nhận được 11 byte gửi và đã đến lúc trả lời lệnh.
Ví dụ xuất ra thiết bị đầu cuối (9600N1) CRC32 lệnh nhận được, byte lệnh và biểu diễn biểu tượng của gói:
Sau khi nhận được mã, bạn có thể giảm dương tính giả bằng cách bỏ qua phần:
?
1
2
3
4
5
6
( readCMDBuffer( s_cmdBufferIndex ) == 0 ) &&
( readCMDBuffer( s_cmdBufferIndex + 1 ) == 0x95 ) &&
( readCMDBuffer( s_cmdBufferIndex + 2 ) == 0x95 ) &&
( readCMDBuffer( s_cmdBufferIndex + 3 ) == 0xB7 ) &&
( readCMDBuffer( s_cmdBufferIndex + 4 ) == 0xB7 ) &&
( readCMDBuffer( s_cmdBufferIndex + 5 ) == 0xB7 )
   (chèn mã tiêu đề của điều khiển từ xa của bạn ở trên)
Theo báo động sai của Cameron, ở đây có nghĩa là định nghĩa nhiễu là một lệnh với một số loại mã, và không phải là hành động sai của nút chính xác.
Cải tiến
1. Nếu bạn sử dụng UART ở chế độ dữ liệu 9 bit, 1 chẵn lẻ và 1 điểm dừng, thì thời gian bỏ phiếu có thể được tăng thêm.
2. Thuật toán trên không kiểm tra thời gian trôi qua giữa các byte. Bằng cách kiểm tra, báo động sai có thể được giảm.
3. Trong khi chờ lệnh, vi điều khiển có thể ở chế độ không tải và thức dậy khi bị gián đoạn từ UART. 
4. Ở chế độ Tắt nguồn, UART không hoạt động. Nhưng nếu bạn kết nối RX với INT0, thì điều này sẽ giúp đưa vi điều khiển vào chế độ bình thường để nhận lệnh.
Kết luận
Thuật toán đã được thử nghiệm trong một thiết bị thực và cho thấy kết quả tuyệt vời.
Vật liệu
Tệp đính kèm:

Nhận xét

Bài đăng phổ biến từ blog này

SMPS FULLBRIDGE PFC Schematic + PCB Layout PDF

DIY 2kVA SMPS 90V 15A HB PFC with IR2110 Mosfet Driver

3000 Watts Power Amplifier Class D Mosfet IRFP260 / IRFP4227