2008-08-29 26 views
5

Tôi gặp sự cố khi nhận bộ mã hóa vòng quay hoạt động bình thường với bộ điều khiển vi AVR. Bộ mã hóa là một máy cơ khí ALPS encoder và tôi đang sử dụng Atmega168.Sử dụng bộ mã hóa vòng quay với bộ điều khiển AVR Micro

Làm rõ

Tôi đã cố gắng sử dụng một Interrupt ngoài để lắng nghe các chân, nhưng nó có vẻ như nó là quá chậm. Khi Pin A cao, thủ tục ngắt sẽ bắt đầu và sau đó kiểm tra xem Pin B có cao không. Ý tưởng là nếu Pin B cao thì thời điểm Pin A cao, sau đó nó quay ngược chiều kim đồng hồ. Nếu Pin B thấp, thì nó xoay theo chiều kim đồng hồ. Nhưng có vẻ như AVR mất quá nhiều thời gian để kiểm tra Pin B, vì vậy nó luôn được đọc là cao.

Tôi cũng đã cố gắng tạo chương trình chỉ đơn giản là chặn cho đến khi thay đổi Pin B hoặc Pin A. Nhưng nó có thể là có quá nhiều tiếng ồn khi bộ mã hóa được xoay, bởi vì điều này không hoạt động. Nỗ lực cuối cùng của tôi là có bộ đếm thời gian lưu trữ 8 giá trị cuối cùng trong bộ đệm và kiểm tra xem nó có đang từ thấp đến cao hay không. Cái này cũng không làm việc.

Tôi đã thử dò tìm bộ mã hóa và dường như sử dụng từ 2 đến 4ms từ lần thay đổi Pin đầu tiên cho đến khi thay đổi Pin khác.

Trả lời

10

Tôi có một trang web về rotary encoders and how to use them, mà bạn có thể thấy hữu ích.

Rất tiếc, không có thêm thông tin, tôi không thể khắc phục sự cố cụ thể của bạn.

Ghim vi điều khiển nào được kết nối với bộ mã hóa và mã bạn hiện đang sử dụng để giải mã các xung là gì?

Ok, bạn đang xử lý một số vấn đề khác nhau, vấn đề đầu tiên là đây là bộ mã hóa cơ học, vì vậy bạn phải đối phó với tiếng ồn chuyển đổi (bị trả lại, trò chuyện). Các data sheet chỉ ra rằng nó có thể mất đến 3mS cho các bộ phận để ngăn chặn nảy và tạo ra kết quả đầu ra sai.

Bạn cần tạo thói quen gỡ lỗi. Cách đơn giản nhất là liên tục kiểm tra xem A có cao không. Nếu có, hãy bắt đầu hẹn giờ và kiểm tra lại trong 3 ms. Nếu nó vẫn còn cao, thì bạn có thể kiểm tra B - nếu nó không cao thì bạn bỏ qua xung giả và tiếp tục tìm kiếm A cao. Khi bạn kiểm tra B, bạn nhìn vào nó, bắt đầu một bộ đếm thời gian cho 3 ms, và sau đó nhìn vào B một lần nữa. Nếu nó giống nhau cả hai lần, thì bạn có thể sử dụng giá trị đó - nếu nó thay đổi trong vòng 3 ms thì bạn phải làm lại (đọc B, đợi 3 ms, sau đó đọc lại và xem nó có trùng khớp không).

Máy atmega đủ nhanh để bạn không phải lo lắng về những kiểm tra này đang diễn ra chậm, trừ khi bạn cũng đang chạy tốc độ đồng hồ chậm.

Khi bạn xử lý tiếng ồn cơ học, bạn muốn xem xét mã màu xám phù hợp - thuật toán bạn đang theo dõi sẽ không hoạt động trừ khi bạn cũng giảm nếu A cao khi B thấp. Nói chung mọi người lưu trữ giá trị cuối cùng của hai đầu vào, và sau đó so sánh nó với giá trị mới của hai đầu vào và sử dụng một hàm nhỏ để tăng hoặc giảm dựa trên đó. (Xem tiêu đề "đọc độ phân giải cao" trên trang web tôi đã đề cập ở trên cho bảng).Tôi kết hợp hai số đọc vào một số bốn bit và sử dụng một mảng đơn giản để cho tôi biết liệu tôi tăng hoặc giảm bộ đếm, nhưng có các giải pháp thậm chí còn nâng cao hơn và tối ưu hóa kích thước mã, tốc độ hoặc dễ bảo trì mã.

0

Chính xác bạn đang gặp sự cố gì? Tôi giả sử bạn đã có thể móc các chân của bộ mã hóa để PIC của bạn theo các thông số kỹ thuật liên kết trên trang Farnell bạn đã đưa ra, do đó, là vấn đề với việc đọc dữ liệu? Bạn không nhận được bất kỳ dữ liệu nào từ bộ mã hóa? Bạn không biết làm thế nào để giải thích các dữ liệu bạn đang nhận được trở lại?

1

Tốc độ không phải là vấn đề. Chủ yếu là tất cả các công tắc cơ khí cần thói quen gỡ lỗi. Nếu bạn muốn làm điều này với các ngắt sẽ tắt ngắt khi nó kích hoạt, hãy khởi động bộ hẹn giờ sẽ bật lại sau vài ms. Sẽ giữ cho chương trình của bạn không bị bỏ phiếu> :)

0
/* into 0 service rutine */ 
if(CHB) 
{ 
    if(flagB) 
    Count++; 
    FlagB=0; 
} 
else 
{ 
    if(FlagB) 
    count--: 
    FlagB=0: 
} 

/* into 1 service rutine */ 
FlagB=1; 

/* make this give to you a windows time of 1/4 of T of the encoder resolution 
    that is in angle term: 360/ (4*resolution) 
*/ 
5

Thêm bộ lọc lowpass analog giúp cải thiện tín hiệu. Với bộ lọc lowpass, mã trên AVR thực sự đơn giản.

 _________ 
     |   | 
     | Encoder | 
     |_________| 
      | | | 
      | | | 
    100n | O | 100n 
GND O-||-+ GND +-||-O GND 
      |  | 
      \ /
     3K3/ \ 3K3 
      \ /
      |  |  
VCC O-/\/-+  +-\/\-O VCC 
    15K |  | 15K 
      |  | 
      O  O 
      A  B 

Ah, những kỳ quan của nghệ thuật ASCII: p

Đây là chương trình trên AVR. Kết nối A và B để nhập PORTB trên avr:

#include <avr/io.h> 

#define PIN_A (PINB&1) 
#define PIN_B ((PINB>>1)&1) 

int main(void){ 
    uint8_t st0 = 0; 
    uint8_t st1 = 0; 
    uint8_t dir = 0; 
    uint8_t temp = 0; 
    uint8_t counter = 0; 
    DDRD = 0xFF; 
    DDRB = 0; 
    while(1){ 
    if(dir == 0){ 
     if(PIN_A & (!PIN_B)){ 
      dir = 2; 
     }else if(PIN_B & (!PIN_A)){ 
      dir = 4; 
     }else{ 
      dir = 0; 
     } 
    }else if(dir == 2){ 
     if(PIN_A & (!PIN_B)){ 
      dir = 2; 
     }else if((!PIN_A) & (!PIN_B)){ 
      counter--; 
      dir = 0; 
     }else{ 
      dir = 0; 
     } 
    }else if(dir == 4){ 
     if(PIN_B & (!PIN_A)){ 
      dir = 4; 
     }else if((!PIN_A) & (!PIN_B)){ 
      counter++; 
      dir = 0; 
     }else{ 
      dir = 0; 
     } 
    }else if(PIN_B & PIN_A){ 
     dir = 0; 
    } 
     PORTD = ~counter; 
    } 
    return 0; 
} 

Mã này hoạt động trừ khi bạn xoay bộ mã hóa rất nhanh. Sau đó, nó có thể bỏ lỡ một hoặc hai bước, nhưng điều đó không quan trọng, vì người sử dụng bộ mã hóa sẽ không biết họ đã bật bao nhiêu bước.

+1

Nó là ok như là một "hobbyist" giải pháp. Tuy nhiên, phần cứng phụ (điện trở/tụ điện) không được đánh giá thấp. Đó là lý do tại sao phần mềm debouncing là một giải pháp "tốt hơn" (IMHO). –

+2

Điều tuyệt vời về giải pháp phần cứng là nó cung cấp sự bảo vệ bổ sung từ ESD từ người dùng. Không được tối ưu hóa cho điều đó, tất nhiên, nhưng một chút tiền thưởng. –

+1

Tôi nghĩ mạch của bạn không hiển thị bộ lọc LP thụ động từ bộ mã hóa đến µC. Bạn phải trao đổi vị trí của điện trở và tụ điện. –