Thông báo

Collapse
No announcement yet.

Lại là vấn đề encoder :D

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • #16
    Nguyên văn bởi VNarmy Xem bài viết
    Nếu để đo tốc độ sao ko dùng Input Capture để đo độ rộng xung nhỉ?
    anh VNArmy ơi
    cho em hỏi vơi!để xác định tốc độ định mức của động cơ thì mình câp cho động cơ điện áp điịnh mức,sau đó đếm xung từ Encoder trong 1 khoảng thời gian và tính ra vận tốc định mức hả anh?
    cám ơn anh

    Comment


    • #17
      Nếu để đo tốc độ sao ko dùng Input Capture để đo độ rộng xung nhỉ?
      Em đã dùng thử cách này rồi. Nhưng không ổn định vì nếu xung rộng quá thì sẽ bị tràn biến. Em đã dùng biến kiểu unsigned int rồi mà vẫn tràn đấy. Với lại làm bằng cái này phiền hơn bác ạ.
      - Đơn giản nhưng chưa hẳn đã hoạt động, giả sử encoder đưa về 40 xung một phút, liệu 1 s bác đếm được mấy xung? Ví dụ tiếp, giả sử động cơ quay ở 150 vòng / phút, tức 1 giây quay được 2 vòng, liệu 1s của bác đủ thời gian đọc được chính xác số lần encoder không?

      - Việc phụ thuộc vào thời gian ngắt của timer khiến cho chương trình của bác mất tính mềm dẻo, thay vì đọc theo timer, sao bác không sử dụng counter, đếm 10 xung hết bao nhiêu giây để tính ngược lại?
      Nếu 1s mà có 40 xung thì quá ít -> thừa sức đếm. Vì trong hàm ngắt INT thì chỉ cho nó đếm xung thôi còn lại là dùng Timer để tính 1s. Cứ hết 1s thì lại đọc giá trị đếm xung ra là biết một s có bao nhiêu xung. Chỉ sợ 1us có mấy xung thì mới không đếm được thôi (mà điều này lại không thể xảy ra vì đĩa của em chỉ có 10 lỗ ).

      Comment


      • #18
        unsigned int count0, count_timer2, speed;
        // External Interrupt 0 service routine
        interrupt [EXT_INT0] void ext_int0_isr(void)
        {
        // Place your code here

        count0++;

        }

        // Timer 2 overflow interrupt service routine
        interrupt [TIM2_OVF] void timer2_ovf_isr(void)
        {//Timer 2 chạy với tần số 1MHz thiết lập bằng Codewizad nhá
        TCNT2 = 0x9B;
        count_timer2++;
        if(count_timer2==10000)
        {
        speed = count0 / số_lỗ_của_đĩa;
        count = 0;
        count_timer2 = 0;
        }
        }
        Bác BK2012 xem thử xem code này thế nào nhá.
        Last edited by sun_rise; 23-04-2008, 18:15.

        Comment


        • #19
          Nếu 1s mà có 40 xung thì quá ít -> thừa sức đếm
          Bạn đọc nhầm rồi Mình nói là 1 phút 40xung, vị chi 1s chưa đủ 1 xung !
          Mồm chó vó ngựa

          Comment


          • #20
            Nguyên văn bởi sun_rise Xem bài viết
            Bác BK2012 xem thử xem code này thế nào nhá.
            Cám ơn Sunrise,mình cũng đã viết chương trình giống như kiểu của bạn nhưng
            khi chưa cho xung từ encoder về mà chỉ cắm nguồn thì nó cũng đã đếm rồi.nên mình mới phải viết ở chương trình ngắt của Timer để cấm ngắt ngoài 0,ko cho nó đếm nữa
            Mình chỉ hỏi là cấm ngắt ngoài 0 trong ngắt Timer 2 là như thế nào?như mình viết thế đã ok chưa?

            Comment


            • #21
              Bạn đọc nhầm rồi Mình nói là 1 phút 40xung, vị chi 1s chưa đủ 1 xung !
              Uh, đúng rồi nếu 1s mà không có xung nào thì chương trình của mình sẽ báo sai vì vậy mới cần một đĩa lỗ nhiều lỗ hơn để đọc chính xác hơn. Nhưng trong thực tế mình không nghĩ một động cơ chạy 10s mà không hết nổi một vòng. 10s mới quay hết một vòng thì coi như đứng yên rồi còn gì.
              Cám ơn Sunrise,mình cũng đã viết chương trình giống như kiểu của bạn nhưng
              khi chưa cho xung từ encoder về mà chỉ cắm nguồn thì nó cũng đã đếm rồi.nên mình mới phải viết ở chương trình ngắt của Timer để cấm ngắt ngoài 0,ko cho nó đếm nữa
              Mình chỉ hỏi là cấm ngắt ngoài 0 trong ngắt Timer 2 là như thế nào?như mình viết thế đã ok chưa?
              Trời ạ, việc gì mà phải cấm nó đếm. Trước khi bác lặp lại vòng lặp đếm số xung trong khoảng thời gian timer chạy được 1s thì bác reset giá trị nó là xong.

              Comment


              • #22
                Nguyên văn bởi sun_rise Xem bài viết
                Uh, đúng rồi nếu 1s mà không có xung nào thì chương trình của mình sẽ báo sai vì vậy mới cần một đĩa lỗ nhiều lỗ hơn để đọc chính xác hơn. Nhưng trong thực tế mình không nghĩ một động cơ chạy 10s mà không hết nổi một vòng. 10s mới quay hết một vòng thì coi như đứng yên rồi còn gì.

                Trời ạ, việc gì mà phải cấm nó đếm. Trước khi bác lặp lại vòng lặp đếm số xung trong khoảng thời gian timer chạy được 1s thì bác reset giá trị nó là xong.
                ùh
                mình hiểu ý bạn,trước đấy mình cũng đã viết như thế nhưng chỉ trích mẫu trong thời gian 20ms
                Sunrise xem cho mình nhé
                trong 4.txt mình reset dem_xung ở trong trình phục vu ngắt(caí chương trình này mình khi chưa cho xung từ encodervào mà chỉ cắm nguồn thôi,cũng đã đếm loạn lên rồi)
                còn trong 10.txt thì mình để trong vòng while(cái này thì khi có xung từ encođer về nhưng xung chưa ổn định ,chỉ thấy nháy ở lED đơn vị)
                còn cái chương trình mà đếm xung trong t=1s(ở trong 9.txt) thì có hiên tượng giống ở 4.txt
                mình chỉ đếm xung được là ok ,còn vấn đề tính vận tốc thì khó gì nếu đếm được xung phải ko?
                Attached Files

                Comment


                • #23
                  Bạn thử với chương trình mình sửa lại nhé.
                  /************************************************** ***
                  Chip type : ATmega16L
                  Program type : Application
                  Clock frequency : 8.000000 MHz
                  Memory model : Small
                  External SRAM size : 0
                  Data Stack size : 256
                  ************************************************** ***/

                  #include <mega16.h>
                  #include <delay.h>
                  bit start=1;
                  unsigned int dem_xung,dem_xung1,count;

                  // External Interrupt 0 service routine
                  interrupt [EXT_INT0] void ext_int0_isr(void)
                  {
                  if(start) dem_xung++;
                  }

                  // Timer 2 overflow interrupt service routine
                  interrupt [TIM2_OVF] void timer2_ovf_isr(void)
                  {
                  TCNT2=0x9b; //Timer s? đ?m t? giá tr? 0x9b đ?n 0xff => 100 xung timer
                  count++;
                  if(count==10000) //Count=10000 => th?i gian = count x 100 = 10^6(us)
                  {
                  dem_xung1=dem_xung;
                  dem_xung=0;
                  count = 0;
                  start = 0;
                  };
                  }
                  void data(unsigned char x)
                  {
                  switch(x)
                  {
                  case 0: {PORTA=0xF0;break;}
                  case 1: {PORTA=0xF1;break;}
                  case 2: {PORTA=0xF2;break;}
                  case 3: {PORTA=0xF3;break;}
                  case 4: {PORTA=0xF4;break;}
                  case 5: {PORTA=0xF5;break;}
                  case 6: {PORTA=0xF6;break;}
                  case 7: {PORTA=0xF7;break;}
                  case 8: {PORTA=0xF8;break;}
                  case 9: {PORTA=0xF9;break;}
                  }
                  }
                  void hienthi(unsigned int n)
                  {
                  unsigned int a,b,c,d;
                  a=n/1000; // lay so hang nghin
                  b=(n-a*1000)/100; // lay so hang tram
                  c=(n-a*1000-b*100)/10; // lay so hang chuc
                  d=(n-a*1000-b*100-c*10);// lay so hang don vi

                  //Quet led
                  //PORTA=0xFF;
                  data(d); // day data ra Led don vi ,vaf ham data nay cung giu vai tro tat cac A1015
                  PORTA.4=0; //BAT LED DON VI
                  delay_ms(5); // TAO TRE
                  PORTA.4=1;

                  //PORTA=0xFF; //tac cac led
                  data(c);
                  PORTA.5=0 ; // Bat Led hang chuc sang
                  delay_ms(5); // tao tre
                  PORTA.5=1;

                  //PORTA=0xFF ; // tat cac led
                  data(b);
                  PORTA.6=0; // bat Led hang tram
                  delay_ms(5);
                  PORTA.6=1;

                  //PORTA=0xFF; //tat cac led
                  data(a);
                  PORTA.7=0; // bat Led hang nghin
                  delay_ms(5);
                  PORTA.7=1;

                  }
                  // Declare your global variables here

                  void main(void)
                  {dem_xung=0;
                  count=0;
                  // Declare your local variables here

                  // Input/Output Ports initialization
                  // Port A initialization
                  // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
                  // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
                  PORTA=0x00;
                  DDRA=0xFF;

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

                  // External Interrupt(s) initialization
                  // INT0: On
                  // INT0 Mode: Rising Edge
                  // INT1: Off
                  // INT2: Off
                  GICR|=0x40;
                  MCUCR=0x03;
                  MCUCSR=0x00;
                  GIFR=0x40;

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

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

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

                  while (1)
                  {
                  // Place your code here
                  if (!start)
                  {
                  hienthi(dem_xung1);
                  start = 1;
                  }
                  };
                  }

                  Comment


                  • #24
                    Cám ơn Sunrise nhiều!
                    Trước đây mình cũng đã thử cách lấy xung rồi
                    Và thử lại chương trình của bạn.=>ko được
                    Nhưng hôm vừa rồi,gặp được một cao thủ trên diễn đàn,đã chỉ ra lỗi rồi
                    Củng chỉ vì khi lập trình ko nhìn thoáng vấn để ra
                    Bây giờ mình đã tính được tốc độ rồi,mình lấy mẫu trong thời gian 500ms nhưng lại gặp phải vấn đề là tốc độ động cơ không ổn định,cứ sau 500ms thì tốc độ lại thay đổi(ko biết như thê có phải là dải điều chỉnh lớn ko?).Lúc đầu mình đã thử các lấy mẫu với 20ms,30ms thì do thời gian lấy mẫu nhỏ ,nên lây xung như thế bị sai số là(1/số xung thu đuợc) nên ko nhìn thấy,còn khi tăng thời gian lấy mẫu là 200ms thì thu được xung(khi động cơ chạy chế độ xác lập) từ 140 đến 230 (với encoder là 200 xung/vongthi tốc độ tương ứng là 3,5 vòng/s đên 5,5 vòng/s),và khi mình thử lấy mẫu với 500 ms thì từ 6vong/s đến 8 vòng/s
                    Ai biết nguyên nhân tại sao ,chỉ giáo ch mình vớii
                    Cám ơn nhiều

                    Comment


                    • #25
                      Encoder + Pic16f877a

                      + Cho mình hỏi dùng chân ngắt Rb4-Rb7 để đồng thời đếm số xung gửi về từ 2 Encoder độc lập không?
                      Do ngắt Rb4-Rb7 xảy ra ngắt khi có sự thay đổi ở các chân đó + với số lượng xung gửi về lớn.Mình ngại chương trình xảy ra ngắt liên tục quá nhiều nên ảnh đến các công việc khác.Mình dùng thạch anh 20M ! Ai dùng thử rùi cho mình hỏi

                      Comment


                      • #26
                        Các bạn nên dung Counter0 thì sẽ chuẩn hơn => có thể đếm giá trị lên tới 65536 nhử vậy là ok. Sau đó dùng 1 timer để tạo ra xung chuẩn 1s(timer1) => trong ngắt timer1 sẽ đọc giá trị của counter0 và xóa các thanh ghi => khi đocj được mang đi hiển thị là ok.
                        dưới đây là Dũng viêt cho 89. PIC, AVR cũng tưong tự.
                        Phần mềm đã chạy thực tế, có cả file mô phỏng....
                        Attached Files

                        Comment


                        • #27
                          Nguyên văn bởi sun_rise Xem bài viết
                          Hà hà. Em lại làm theo một cách khác đơn giản hơn các bác ạ. Em dùng timer tính toán khoảng 1s, trong thời gian đó, em cho ngắt ngoài đếm và tăng biến đếm lên. Khi timer chạy đủ 1s thì đọc giá trị đếm là biết một giây có bao nhiêu xung. -> đơn giản hơn các bác nhỉ.
                          cách của bạn rất hay, đúng như mình suy nghĩ.

                          Comment


                          • #28
                            Cuối cùng hợp lí hơn cả ta nên dùng counter để đếm xung kết hợp với time đo thời gian các anh hỉ!. Cứ sau khoảng thời gian lưu giá trị counter tính ra tốc độ đồng thời reset lại vậy là ổn định nhất, thay đổi thời gian lấy mẫu vẫn vậy không lỗi j cả, dùng ngắt ngoài đếm xung dẫn đến sai do trễ khi ngắt, ảnh hưởng đến chương trình đang chay khi có ngắt........
                            Năm mới chúc mọi người jui je!!!.
                            Thiết kế chế tạo các loại máy xoáy nắp, chiết rót định lượng dùng trong dược phẩm và thực phẩm.

                            Comment


                            • #29
                              Nguyên văn bởi Le Thi Bich Xem bài viết
                              Cuối cùng hợp lí hơn cả ta nên dùng counter để đếm xung kết hợp với time đo thời gian các anh hỉ!. Cứ sau khoảng thời gian lưu giá trị counter tính ra tốc độ đồng thời reset lại vậy là ổn định nhất, thay đổi thời gian lấy mẫu vẫn vậy không lỗi j cả, dùng ngắt ngoài đếm xung dẫn đến sai do trễ khi ngắt, ảnh hưởng đến chương trình đang chay khi có ngắt........
                              Năm mới chúc mọi người jui je!!!.
                              cũng chưa chuẩn lám .... phải 3->5 lần lấy mẫu , cộng lấy giá trị trung bình , hiển thị giá trị trung bình đó , may ra việc đo tốc độ động cơ mới chính xác (có thể chính xác đến 2 thập phân đó)

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X