Rắc rối giao tiếp với encoder

Collapse
X
 
  • Giờ
  • Show
Clear All
new posts
  • constfang
    Thành viên mới
    • Sep 2009
    • 6

    #1

    Rắc rối giao tiếp với encoder

    Các pác cho đệ hỏi một vấn đề dễ nhưng vẫn đang hết sức đau đầu, đệ có 1 rotary encoder 2 channel sóng vuông lệch pha 90 độ, đệ cho channel 1 nối vào INT0 với thiết lập "rising edge", còn trong hàm interrupt thì poll channel còn lại:

    interrupt [EXT_INT0] void ext_int0_isr(void)
    {
    // Place your code here
    if(PIND.2==1) count++;
    else count--;
    }

    Điều quái gở là count lúc nào cũng nhận giá trị âm, bất chấp quay ngược quay xuôi. Chỉ đến khi đệ quay trục động cơ thật chậm bằng tay thì nó mới tăng lên nhưng cũng không đều, các pác cho hỏi vì sao vậy, encoder xem trên Oscilloscope thì bình thường, ko có vấn đề gì. Đệ cảm ơn trước.
  • Missile33
    Thành viên mới
    • Jan 2010
    • 26

    #2
    Nếu A là sườn lên thì B thấp là tăng còn B cao là giảm.

    From MTA

    Comment

    • chestnut
      Thành viên tích cực
      • Jun 2008
      • 400

      #3
      Nguyên văn bởi constfang Xem bài viết
      Các pác cho đệ hỏi một vấn đề dễ nhưng vẫn đang hết sức đau đầu, đệ có 1 rotary encoder 2 channel sóng vuông lệch pha 90 độ, đệ cho channel 1 nối vào INT0 với thiết lập "rising edge", còn trong hàm interrupt thì poll channel còn lại:

      interrupt [EXT_INT0] void ext_int0_isr(void)
      {
      // Place your code here
      if(PIND.2==1) count++;
      else count--;
      }

      Điều quái gở là count lúc nào cũng nhận giá trị âm, bất chấp quay ngược quay xuôi. Chỉ đến khi đệ quay trục động cơ thật chậm bằng tay thì nó mới tăng lên nhưng cũng không đều, các pác cho hỏi vì sao vậy, encoder xem trên Oscilloscope thì bình thường, ko có vấn đề gì. Đệ cảm ơn trước.
      Có thể là do đụng độ giữa các ngắt, ưu tiên ngắt ngoài thấp quá so với vài ngắt khác chăng? Đó chỉ là một suy đoán.
      The goal of power electronics is control the flow of energy from an electrical source to an electrical load with high efficiency, high availability, high reliability, light weight and low cost.

      Comment

      • namth.vp
        Thành viên tích cực
        • Oct 2008
        • 182

        #4
        Nó đã đếm khi bạn quay tức là hoạt động tốt. Khi bạn quay chậm mới được, như vậy là đã nhận đựoc tín hiệu đếm lên, còn khi quay nhanh thì do không nhận đựoc tín hiệu đếm lên, nên toàn đếm xuống thôi, bạn phải xử lý các mức ưu tiên ngắt thật hợp lý, tránh xung đột ngắt. Goodluck!
        Học đến bao giờ mới thành tài?

        Comment

        • constfang
          Thành viên mới
          • Sep 2009
          • 6

          #5
          Cảm ơn các pác, khốn nỗi đệ chưa viết gì hết, mới chỉ đang thử cái encoder nên ngoài cái ngắt ngoài kia gần như không còn cái ngắt nào khác, Có vẻ như thằng VXL ko đọc được PIND dương một cách chính xác mặc dù khi đệ thử cắm thẳng PD2 vào +5V thì count vẫn tăng như gió, còn khi để lại vào channel B thì quay thuận chiều 360 độ nó đọc đúng 1000counts nhưng đến khi quay ngược lại nó ko quay ngược về 0 mà lại tăng lên khoảng 1200counts. Đệ đang định chuyển sang cách mấy pác chỉ ở đây, dùng 2 ngắt một lúc: http://www.dientuvietnam.net/forums/...ad.php?t=32078 nhưng dù có làm được bằng cách khác thì chắc đệ sẽ ko bao giờ biết được thằng này bị sai chỗ nào quá...

          Comment

          • chestnut
            Thành viên tích cực
            • Jun 2008
            • 400

            #6
            Nguyên văn bởi constfang Xem bài viết
            Cảm ơn các pác, khốn nỗi đệ chưa viết gì hết, mới chỉ đang thử cái encoder nên ngoài cái ngắt ngoài kia gần như không còn cái ngắt nào khác, Có vẻ như thằng VXL ko đọc được PIND dương một cách chính xác mặc dù khi đệ thử cắm thẳng PD2 vào +5V thì count vẫn tăng như gió, còn khi để lại vào channel B thì quay thuận chiều 360 độ nó đọc đúng 1000counts nhưng đến khi quay ngược lại nó ko quay ngược về 0 mà lại tăng lên khoảng 1200counts. Đệ đang định chuyển sang cách mấy pác chỉ ở đây, dùng 2 ngắt một lúc: http://www.dientuvietnam.net/forums/...ad.php?t=32078 nhưng dù có làm được bằng cách khác thì chắc đệ sẽ ko bao giờ biết được thằng này bị sai chỗ nào quá...
            Vậy vấn đề không phải do ngắt, vậy có lẽ bác cấu hình I/O chưa đúng, tốt nhất bác post cả đoạn code, và cho biết mình đang sài VDK nào?
            The goal of power electronics is control the flow of energy from an electrical source to an electrical load with high efficiency, high availability, high reliability, light weight and low cost.

            Comment

            • constfang
              Thành viên mới
              • Sep 2009
              • 6

              #7
              Đệ xài cái code generation của Codevision thì được, chỉ gắn thêm cái LCD để debug thôi chắc ko ảnh hưởng nhiều.
              /************************************************** ***
              Chip type : ATmega128
              Program type : Application
              AVR Core Clock frequency: 16.000000 MHz
              Memory model : Small
              External RAM size : 0
              Data Stack size : 1024
              ************************************************** ***/

              #include <mega128.h>
              #include <stdio.h>

              // Alphanumeric LCD Module functions
              #asm
              .equ __lcd_port=0x1B ;PORTA
              #endasm
              #include <lcd.h>

              int count=0;
              // External Interrupt 0 service routine
              interrupt [EXT_INT0] void ext_int0_isr(void)
              {
              // Place your code here
              if(PIND.2==0) count++;
              else count--;
              }


              // Declare your global variables here

              void main(void)
              {
              // Declare your local variables here
              char* a="fashfdskjfhsk";
              // Input/Output Ports initialization
              // Port A initialization
              // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
              // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
              PORTA=0x00;
              DDRA=0x00;

              // Port B initialization
              // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
              // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
              PORTB=0x00;
              DDRB=0x00;

              // Port C initialization
              // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
              // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
              PORTC=0x00;
              DDRC=0x00;

              // Port D initialization
              // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
              // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
              PORTD=0x00;
              DDRD=0x00;

              // Port E initialization
              // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
              // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
              PORTE=0x00;
              DDRE=0x00;

              // Port F initialization
              // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
              // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
              PORTF=0x00;
              DDRF=0x00;

              // Port G initialization
              // Func4=In Func3=In Func2=In Func1=In Func0=In
              // State4=T State3=T State2=T State1=T State0=T
              PORTG=0x00;
              DDRG=0x00;

              // Timer/Counter 0 initialization
              // Clock source: System Clock
              // Clock value: Timer 0 Stopped
              // Mode: Normal top=FFh
              // OC0 output: Disconnected
              ASSR=0x00;
              TCCR0=0x00;
              TCNT0=0x00;
              OCR0=0x00;

              // Timer/Counter 1 initialization
              // Clock source: System Clock
              // Clock value: Timer 1 Stopped
              // Mode: Ph. correct PWM top=00FFh
              // OC1A output: Discon.
              // OC1B output: Discon.
              // OC1C output: Discon.
              // Noise Canceler: Off
              // Input Capture on Falling Edge
              // Timer 1 Overflow Interrupt: Off
              // Input Capture Interrupt: Off
              // Compare A Match Interrupt: Off
              // Compare B Match Interrupt: Off
              // Compare C Match Interrupt: Off
              TCCR1A=0x01;
              TCCR1B=0x00;
              TCNT1H=0x00;
              TCNT1L=0x00;
              ICR1H=0x00;
              ICR1L=0x00;
              OCR1AH=0x00;
              OCR1AL=0x00;
              OCR1BH=0x00;
              OCR1BL=0x00;
              OCR1CH=0x00;
              OCR1CL=0x00;

              // Timer/Counter 2 initialization
              // Clock source: System Clock
              // Clock value: Timer 2 Stopped
              // Mode: Normal top=FFh
              // OC2 output: Disconnected
              TCCR2=0x00;
              TCNT2=0x00;
              OCR2=0x00;

              // Timer/Counter 3 initialization
              // Clock source: System Clock
              // Clock value: Timer 3 Stopped
              // Mode: Normal top=FFFFh
              // OC3A output: Discon.
              // OC3B output: Discon.
              // OC3C output: Discon.
              // Noise Canceler: Off
              // Input Capture on Falling Edge
              // Timer 3 Overflow Interrupt: Off
              // Input Capture Interrupt: Off
              // Compare A Match Interrupt: Off
              // Compare B Match Interrupt: Off
              // Compare C Match Interrupt: Off
              TCCR3A=0x00;
              TCCR3B=0x00;
              TCNT3H=0x00;
              TCNT3L=0x00;
              ICR3H=0x00;
              ICR3L=0x00;
              OCR3AH=0x00;
              OCR3AL=0x00;
              OCR3BH=0x00;
              OCR3BL=0x00;
              OCR3CH=0x00;
              OCR3CL=0x00;

              // External Interrupt(s) initialization
              // INT0: On
              // INT0 Mode: Rising Edge
              // INT1: Off
              // INT2: Off
              // INT3: Off
              // INT4: Off
              // INT5: Off
              // INT6: Off
              // INT7: Off
              EICRA=0x03;
              EICRB=0x00;
              EIMSK=0x01;
              EIFR=0x01;


              // Timer(s)/Counter(s) Interrupt(s) initialization
              TIMSK=0x00;
              ETIMSK=0x00;

              // Analog Comparator initialization
              // Analog Comparator: Off
              // Analog Comparator Input Capture by Timer/Counter 1: Off
              ACSR=0x80;
              SFIOR=0x00;

              // LCD module initialization
              lcd_init(16);

              // Global enable interrupts
              #asm("sei")

              while (1)
              {
              // Place your code here
              lcd_gotoxy(3,1);
              sprintf(a,"fsdfd %d",count);
              lcd_puts(a);

              };

              }

              Comment

              • chestnut
                Thành viên tích cực
                • Jun 2008
                • 400

                #8
                Pó tay luôn, không nhìn ra bị sai chổ nào.
                The goal of power electronics is control the flow of energy from an electrical source to an electrical load with high efficiency, high availability, high reliability, light weight and low cost.

                Comment

                • GA_CN
                  Thành viên tích cực
                  • Dec 2008
                  • 332

                  #9
                  Có thể encoder của bạn là loại ngõ ra open collector, bạn cấu hình input lại không có trở kéo lên nên nó cho giá trị - là phải rồi.
                  Đặt PORTD =0xFF;
                  DDRD =0x00;
                  Hoặc dùng trở kéo lên cho chắc, chọn tầm 470-1k5.
                  Brs.

                  Comment

                  • chestnut
                    Thành viên tích cực
                    • Jun 2008
                    • 400

                    #10
                    Nguyên văn bởi GA_CN Xem bài viết
                    Có thể encoder của bạn là loại ngõ ra open collector, bạn cấu hình input lại không có trở kéo lên nên nó cho giá trị - là phải rồi.
                    Đặt PORTD =0xFF;
                    DDRD =0x00;
                    Hoặc dùng trở kéo lên cho chắc, chọn tầm 470-1k5.
                    Brs.
                    Có thể đây là một problem chăng? Cái problem này mình đã từng gặp.
                    The goal of power electronics is control the flow of energy from an electrical source to an electrical load with high efficiency, high availability, high reliability, light weight and low cost.

                    Comment

                    • constfang
                      Thành viên mới
                      • Sep 2009
                      • 6

                      #11
                      Nguyên văn bởi GA_CN Xem bài viết
                      Có thể encoder của bạn là loại ngõ ra open collector, bạn cấu hình input lại không có trở kéo lên nên nó cho giá trị - là phải rồi.
                      Đặt PORTD =0xFF;
                      DDRD =0x00;
                      Hoặc dùng trở kéo lên cho chắc, chọn tầm 470-1k5.
                      Brs.
                      Chính là nó đấy pác, cảm ơn pác nhiều,
                      p/s: thú thực là đệ tìm ra rồi định lên đây khoe thì thấy pác đã chỉ ra từ... 10 ngày trước

                      Comment

                      Về tác giả

                      Collapse

                      constfang Tìm hiểu thêm về constfang

                      Bài viết mới nhất

                      Collapse

                      Đang tải...