Thông báo

Collapse
No announcement yet.

Dùng encoder đo tốc độ thê nào nhỉ

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

  • Dùng encoder đo tốc độ thê nào nhỉ

    Em muốn dùng encoder đo tốc độ động cỏ,nhưng k hiểu sao đoạn code em viết k chạy, mặc dù đã tham khảo nhiều tài liệu rùi.Mong mọi người xem dùm.
    Timer0 để đếm xung
    Timer1 để định ra khoảng thời gian 1s
    Nhưng k hiểu sao hiển thị ra toàn la 0000. Em đảm bảo phần hiển thị của em đúng vì em đã đi hỏi và test rồi.Mọi người giúp dùm nha.Code của nó đây:

    Code:
    #include "D:\pro2\vd\lcd1.h"
    #include "def_877a.h"
    #include<lcd_lib_4bit.c>
    #use delay(clock=20000000)
    int8 nghin,tram,chuc,donvi;
    void tinhtoan_hienthi(int16 x);
    int16 count,so_vong,int_count1,x;
    #define INTS_PER_SECOND1 19
    #int_rtcc                           // Ngat Timer 0
    void Timer0_isr()                   // Dem so vong quay dong co
    {
       count++;
    }
    
    #INT_TIMER1                        // Chuong trinh ngat Timer 1
    void Timer11_isr() {                // Ham duoc goi khi TImer1 tran (65535->0)
                                       // Xap xi 19 lan / giay
        if(--int_count1==0)
        {
          int_count1 = INTS_PER_SECOND1;
          so_vong = (count*255 + get_timer0())/100;
          count = 0;
          set_timer0(0);
        }
    }
    void tinhtoan_hienthi(int16 x) // thuc hien tach so va dua ra hien thi luon
    {nghin = x / 1000 + 0x30;
    x = x % 1000;
     tram = x / 100 + 0x30; // tách s? hàng tram
     x = x % 100; // chia l?y ph?n d?
     chuc = x / 10 + 0x30; // tách l?y ph?n ch?c
     donvi = x % 10 + 0x30; // ph?n don v?
     lcd_putcmd(0xC0);
     printf(lcd_putchar,"toc do=");
     lcd_putchar(nghin);
     lcd_putchar(tram);
     lcd_putchar(chuc);
     lcd_putchar(donvi);
    }
    void init()
    {  lcd_putcmd(0x80);
       int_count1 = INTS_PER_SECOND1;//19 lan 1 giay
          setup_timer_0 (RTCC_DIV_1|RTCC_EXT_H_TO_L);  // Timer0 is Counter
       set_timer0(0);
       set_timer1(0);
       setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);    // Timer1 is Timer
       enable_interrupts(INT_RTCC);
       enable_interrupts(INT_TIMER1);
       enable_interrupts(INT_RDA);
       enable_interrupts(GLOBAL);
        count = 0;
       lcd_init();
    delay_ms(200);
    printf(lcd_putchar,"toc do dong co");
    }
    void main()
    {init();
    
    //setup_adc_ports(NO_ANALOGS);
    //setup_adc(ADC_OFF);
    //setup_psp(PSP_DISABLED);
    //setup_spi(FALSE);
    
    
      so_vong = 0;// khoi tao gia tri
    while(1) // doan chuong trinh hien thi len LCD
    {
       tinhtoan_hienthi(so_vong);
       delay_ms(500);
    }
    }

    Đây là phần mô phỏng đi kèm,không rõ encoder em nối đúng k,nhưng mà thử nhiều vẫn k được
    Attached Files

  • #2
    có thể đoạn code trên chạy ra = 0 do 1 lỗi

    giá trị khởi tạo của bạn: so_vong = 0

    sau đấy trong tinhtoan_hienthi(so_vong); thì kqua chạy được của bạn cố định và nó sẽ luôn là 4 số 0

    Comment


    • #3
      Nguyên văn bởi numberzero Xem bài viết
      có thể đoạn code trên chạy ra = 0 do 1 lỗi

      giá trị khởi tạo của bạn: so_vong = 0

      sau đấy trong tinhtoan_hienthi(so_vong); thì kqua chạy được của bạn cố định và nó sẽ luôn là 4 số 0
      so_vong được cập nhật trong ngắt Timer1 mà.

      Chương trình của tác giả có vẻ đúng rồi mà.
      Tác giả coi lại đầu vào MCU từ encoder đã nhấp nháy (xanh đỏ) khi bấm nút PLAY chưa? nếu có rồi mà vẫn không đúng thì em sẽ cài proteus lên để giúp bác.
      Email: - Mobil: tạm thời ngừng liên lạc 1 thời gian
      Giới thiệu website kiếm tiền trực tuyến & tăng thứ hạng website.

      Comment


      • #4
        Trong code bạn không dung đến RS232 thi nên loại bỏ dòng lệnh cho phép ngắt nối tiếp (enable_interrupts(INT_RDA);)
        Thêm nữa, bạn thêm các lệnh khởi tạo vào ra cho cac port của PIC (Port cho LCD là output, chân nhận xung clock (RA4 thì phải) là input và thêm trở kéo 10K lên VCC cho chân này). Sau đó bạn thử chạy lại mo phỏng.
        Code bạn viết về cơ bản đã đúng. Nếu có xung vào chân clock của timer0 thì chắc chắn sẽ hiển thị được. Để chắc chắn, bạn nên lắp mạch thật để test, tạo xung nếu chưa có Encoder thì có thể dùng IC 555 để tạo xung rồi đưa vào Timer0. Tại sao lại cần làm mạch thật mà không dùng mô phỏng?
        Đó là vì Proteus nhiều khi chạy mô phỏng cho các chương trình ngắt của MCU không được tốt nên có thể dẫn đến kết quả sai.
        Chúc thành công.
        Ethernet-RS232, PIC Webserver, RFID Reader
        CallerID, Cảnh báo BTS, ...
        0988006696
        linhnc308@gmail.com
        http://linhnc308.blogspot.com

        Comment


        • #5
          Nguyên văn bởi nghaiha Xem bài viết
          so_vong được cập nhật trong ngắt Timer1 mà.

          Chương trình của tác giả có vẻ đúng rồi mà.
          Tác giả coi lại đầu vào MCU từ encoder đã nhấp nháy (xanh đỏ) khi bấm nút PLAY chưa? nếu có rồi mà vẫn không đúng thì em sẽ cài proteus lên để giúp bác.
          Đầu vào MCU là thế nào hả bạn. Mình cũng không chắc về cách nối chân con motor-encoder của mình lắm, không biết vậy đúng chưa. Nhưng khi chạy thử thì nhiều trường hợp, cả lúc chân vào PIC nháy lẫn lúc nó không nháy xanh đỏ thì con LCD vẫn hiển thị như vậy.
          Bạn giúp mình được phần nối chân cho con encoder ấy thì tốt quá, bạn biết thì post lên giúp mình nhé.Thanks alot!

          Comment


          • #6
            Nguyên văn bởi linhnc308 Xem bài viết
            Trong code bạn không dung đến RS232 thi nên loại bỏ dòng lệnh cho phép ngắt nối tiếp (enable_interrupts(INT_RDA);)
            Thêm nữa, bạn thêm các lệnh khởi tạo vào ra cho cac port của PIC (Port cho LCD là output, chân nhận xung clock (RA4 thì phải) là input và thêm trở kéo 10K lên VCC cho chân này). Sau đó bạn thử chạy lại mo phỏng.
            Code bạn viết về cơ bản đã đúng. Nếu có xung vào chân clock của timer0 thì chắc chắn sẽ hiển thị được. Để chắc chắn, bạn nên lắp mạch thật để test, tạo xung nếu chưa có Encoder thì có thể dùng IC 555 để tạo xung rồi đưa vào Timer0. Tại sao lại cần làm mạch thật mà không dùng mô phỏng?
            Đó là vì Proteus nhiều khi chạy mô phỏng cho các chương trình ngắt của MCU không được tốt nên có thể dẫn đến kết quả sai.
            Chúc thành công.
            Theo hướng dẫn của anh em đã mô phỏng được phần code đếm xung rồi,thêm hàm khởi tạo cho TrisD nữa là được. Cám ơn anh Linhnc308 nhiều nhiều. Nhưng đấy là em thử trên IC555, còn con encoder em vẫn không biểt nối chân thế nào, mong anh em nào biết thì chỉ dùm em với.
            Attached Files

            Comment


            • #7
              @hikaru: A da xem lai trong proteus va phan encoder. Mach cua em chua chay la vi e dau day encoder sai.
              Dau ra motor-encoder có 3 dây, dây chính giữa có thể là day mass chung nên không có xung ra, 2 day 2 bên là tương ứng với đầu ra A,B của encoder. Khi em chạy mo phỏng, cho motor chạy sẽ thấy nó nhấp nháy.
              Ban đầu em lại đi đấu dây giữa vào RA4 nên ko có xung >> không đo được tốc độ
              Em đấu lại, sử dụng 1 trong 2 dây phía ngoài mắc vào RA4 sẽ chạy và đo được tốc độ
              chúc thành công
              Ethernet-RS232, PIC Webserver, RFID Reader
              CallerID, Cảnh báo BTS, ...
              0988006696
              linhnc308@gmail.com
              http://linhnc308.blogspot.com

              Comment


              • #8
                Nguyên văn bởi linhnc308 Xem bài viết
                @hikaru: A da xem lai trong proteus va phan encoder. Mach cua em chua chay la vi e dau day encoder sai.
                Dau ra motor-encoder có 3 dây, dây chính giữa có thể là day mass chung nên không có xung ra, 2 day 2 bên là tương ứng với đầu ra A,B của encoder. Khi em chạy mo phỏng, cho motor chạy sẽ thấy nó nhấp nháy.
                Ban đầu em lại đi đấu dây giữa vào RA4 nên ko có xung >> không đo được tốc độ
                Em đấu lại, sử dụng 1 trong 2 dây phía ngoài mắc vào RA4 sẽ chạy và đo được tốc độ
                chúc thành công
                Cám ơn anh Linhc308 nhiều nhiều, em sẽ nối dây để thử lại con encoder. Nhưng trước hết em dùng tạm con IC555 vậy.
                Tiếp theo phần trước, em muốn mạch của mình có 3 chế độ
                1.Đo và hiển thị tốc độ động cơ
                2.Nhập giá trị thay đổi vào ( ở đây là tăng giảm tốc độ)
                3.PWM
                Em muốn dùng 1 button để chuyển chế độ làm việc cho PIC, chân em chọn là RB4. 2 chân RB5, RB6 em dùng để tăng giảm giá trị. Có thể tóm tắt như sau:
                Khi chay, đầu tiên chưa hiển thị gì cả, nếu ấn nút RB4 thì hiển thị động cơ, ấn lần nữa thì chuyển sang chế độ chờ nhập giá trị tăng giảm, ấn thêm nút nữa thì PWM đồng thời hiển thị luôn.
                Tạm thời chưa xử lý phần PWM, em mới làm phần chuyển mạch thôi, Code của em dưới đây:


                #include "D:\pro2\vd\lcd1.h"
                #include "def_877a.h"
                #include<lcd_lib_4bit.c>
                #use delay(clock=20000000)
                int8 nghin,tram,chuc,donvi,a;
                int16 count,so_vong,int_count1,x;
                void tinhtoan_hienthi(int16 x);
                void kiemtra2(){
                if( portb = 0b11011111 )
                {
                so_vong = so_vong + 10;}
                else {
                if (portd = 0b10111111)
                {so_vong = so_vong - 10;}}}


                void kiemtra1()
                {if(a = 1 ) tinhtoan_hienthi(so_vong); //a=1 thi do va hien thi toc do dong co
                else {
                if(a = 2 ) // nhap gia tri thay doi
                {
                printf(lcd_putchar,"moi nhap gia tri");
                kiemtra2();
                lcd_putcmd(0xc0);
                printf(lcd_putchar,"toc do=");
                lcd_putchar(nghin);
                lcd_putchar(tram);
                lcd_putchar(chuc);
                lcd_putchar(donvi);
                }else {// a khong =2 thi a=3 chay PWM xong lai set a=0
                printf(lcd_putchar,"PWM");
                tinhtoan_hienthi(so_vong);
                a=0;}}
                }


                #define INTS_PER_SECOND1 19
                #int_rtcc // Ngat Timer 0
                void Timer0_isr() // Dem so vong quay dong co
                {
                count++;
                }

                #INT_TIMER1 // Chuong trinh ngat Timer 1
                void Timer11_isr() { // Ham duoc goi khi TImer1 tran (65535->0)
                // Xap xi 19 lan / giay
                if(--int_count1==0)
                {
                int_count1 = INTS_PER_SECOND1;
                so_vong = (count*255 + get_timer0())/100;
                count = 0;
                set_timer0(0);
                }
                }
                #int_RB // ham kiem tra dau vao
                void RB_isr()
                {
                if(portb = 0b11101111) //an nut chuyen trang thai
                {a++;
                lcd_putcmd(0x01);
                kiemtra1();
                }
                else {kiemtra2();}
                portb = 0xff;//reset lai port B
                }
                void tinhtoan_hienthi(int16 x) // thuc hien tach so va dua ra hien thi luon
                {nghin = x / 1000 + 0x30;
                x = x % 1000;
                tram = x / 100 + 0x30; // tách s? hàng tram
                x = x % 100; // chia l?y ph?n d?
                chuc = x / 10 + 0x30; // tách l?y ph?n ch?c
                donvi = x % 10 + 0x30; // ph?n don v?
                printf(lcd_putchar,"hien thi toc do");
                lcd_putcmd(0xC0);
                printf(lcd_putchar,"toc do=");
                lcd_putchar(nghin);
                lcd_putchar(tram);
                lcd_putchar(chuc);
                lcd_putchar(donvi);
                }

                void main()
                {
                setup_timer_0 (RTCC_DIV_1|RTCC_EXT_H_TO_L); // Timer0 is Counter
                set_timer0(0);
                set_timer1(0);
                setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);
                enable_interrupts(INT_RTCC);
                enable_interrupts(INT_TIMER1);
                enable_interrupts(GLOBAL);
                count = 0;
                int_count1 = INTS_PER_SECOND1;
                so_vong = 0;
                a = 0;
                TRISA = 0xFF;
                trisB = 0xFF;
                portb = 0xff;
                RD2 = 1;
                trisD = 0;
                lcd_init();
                delay_ms(200);
                printf(lcd_putchar,"Liencoi");


                while(1) // doan chuong trinh hien thi len LCD
                {enable_interrupts(INT_RB);
                //tinhtoan_hienthi(so_vong);
                delay_ms(500);}
                }



                EM thấy khi chạy mắc 1 số vấn đề sau:
                1.Sau lần đầu tiên ấn BR4(a=1) thì màn hình có clear, nhưng từ những lần sau thì không
                Do đó em cũng không kiểm tra được những phần sau đúng hay chưa
                2.Ấn lần thứ nhất thì tocdo=0000, phải ấn đến lần thử 2 thì mới hiển thị tốc độ
                3.Ngoài ra vì em chưa xử lý được phần lear màn hình sau mỗi lần chuyển chế độ nên không kiểm tra được đúng hay sai.
                Mong anh và anh em giúp đỡ.
                Thanks alot.
                Đây là phần mạch của em.
                Attached Files

                Comment


                • #9
                  cho mình xin gmail của bạn dc ko? mình cũng đang làm đò án về
                  đo tôc độ động cơ .số vòng quay hiển thị trên LCd
                  gmail của mình là quangdadt4@gmail.com

                  Comment


                  • #10
                    bạn nào có hình mô phỏng và chuong trinh của do van toc trung binh dung 2 cam bien khong gui cho minh voi
                    neu co the gui qua dia chi mail nay cho minh voi:tringuyen1501@gmail.com

                    Comment


                    • #11
                      Bạn dùng Dspic hoặc con nào có sẵn QEI ấy, nó có sẵn QEI đếm xung đo encoder rồi. Dễ dàng mà nhanh nữa chứ . Hi

                      Comment


                      • #12
                        hay

                        Nguyên văn bởi hikaru Xem bài viết
                        Em muốn dùng encoder đo tốc độ động cỏ,nhưng k hiểu sao đoạn code em viết k chạy, mặc dù đã tham khảo nhiều tài liệu rùi.Mong mọi người xem dùm.
                        Timer0 để đếm xung
                        Timer1 để định ra khoảng thời gian 1s
                        Nhưng k hiểu sao hiển thị ra toàn la 0000. Em đảm bảo phần hiển thị của em đúng vì em đã đi hỏi và test rồi.Mọi người giúp dùm nha.Code của nó đây:

                        Code:
                        #include "D:\pro2\vd\lcd1.h"
                        #include "def_877a.h"
                        #include<lcd_lib_4bit.c>
                        #use delay(clock=20000000)
                        int8 nghin,tram,chuc,donvi;
                        void tinhtoan_hienthi(int16 x);
                        int16 count,so_vong,int_count1,x;
                        #define INTS_PER_SECOND1 19
                        #int_rtcc                           // Ngat Timer 0
                        void Timer0_isr()                   // Dem so vong quay dong co
                        {
                           count++;
                        }
                        
                        #INT_TIMER1                        // Chuong trinh ngat Timer 1
                        void Timer11_isr() {                // Ham duoc goi khi TImer1 tran (65535->0)
                                                           // Xap xi 19 lan / giay
                            if(--int_count1==0)
                            {
                              int_count1 = INTS_PER_SECOND1;
                              so_vong = (count*255 + get_timer0())/100;
                              count = 0;
                              set_timer0(0);
                            }
                        }
                        void tinhtoan_hienthi(int16 x) // thuc hien tach so va dua ra hien thi luon
                        {nghin = x / 1000 + 0x30;
                        x = x % 1000;
                         tram = x / 100 + 0x30; // tách s? hàng tram
                         x = x % 100; // chia l?y ph?n d?
                         chuc = x / 10 + 0x30; // tách l?y ph?n ch?c
                         donvi = x % 10 + 0x30; // ph?n don v?
                         lcd_putcmd(0xC0);
                         printf(lcd_putchar,"toc do=");
                         lcd_putchar(nghin);
                         lcd_putchar(tram);
                         lcd_putchar(chuc);
                         lcd_putchar(donvi);
                        }
                        void init()
                        {  lcd_putcmd(0x80);
                           int_count1 = INTS_PER_SECOND1;//19 lan 1 giay
                              setup_timer_0 (RTCC_DIV_1|RTCC_EXT_H_TO_L);  // Timer0 is Counter
                           set_timer0(0);
                           set_timer1(0);
                           setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);    // Timer1 is Timer
                           enable_interrupts(INT_RTCC);
                           enable_interrupts(INT_TIMER1);
                           enable_interrupts(INT_RDA);
                           enable_interrupts(GLOBAL);
                            count = 0;
                           lcd_init();
                        delay_ms(200);
                        printf(lcd_putchar,"toc do dong co");
                        }
                        void main()
                        {init();
                        
                        //setup_adc_ports(NO_ANALOGS);
                        //setup_adc(ADC_OFF);
                        //setup_psp(PSP_DISABLED);
                        //setup_spi(FALSE);
                        
                        
                          so_vong = 0;// khoi tao gia tri
                        while(1) // doan chuong trinh hien thi len LCD
                        {
                           tinhtoan_hienthi(so_vong);
                           delay_ms(500);
                        }
                        }

                        Đây là phần mô phỏng đi kèm,không rõ encoder em nối đúng k,nhưng mà thử nhiều vẫn k được
                        bạn ơi cho mình hỏi là cái encoder trong protues có thể thay đổi số xung trên 1 vòng không và có nhất thiết phải nối với cái bộ GND như hình vẽ không tks bạn

                        Comment


                        • #13
                          mình hỏi là cái encoder trong protues có thể thay đổi số xung trên 1 vòng không 100xung/1vong đó,kí hiệu và đi dây như thế napf vậy

                          Comment


                          • #14
                            Encoder có thể mô phỏng trên Proteus sao? bác nào chỉ em với!

                            Let's go!!!

                            Comment


                            • #15
                              go lenh servo

                              Comment

                              Về tác giả

                              Collapse

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

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

                              Collapse

                              Đang tải...
                              X