Thông báo

Collapse
No announcement yet.

lập trình để robocon bắt và nhớ vạch

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

  • lập trình để robocon bắt và nhớ vạch

    Mình có con robot tự động từ mùa robocon vừa rồi.Năm trc ko thuộc bên lập trình mà làm phần cứng nên khoản viết nách cũng hơi gà.Hè vừa rồi ngồi thiết kế lại phần cứng để có robot tập tành cho mùa tới nhưng vướng ở đoạn lập trình cho robot nhớ và đếm vạch.Mình dùng AVR16L và viết trên codevision.Cụ thể là:
    -Về việc chỉnh định để robot đi thẳng thì ko vấn đề.Đã cày xong
    -Vướng mắc ở chỗ dùng ngắt ngoài INT0 để đếm vạch.Mục đích mình muốn nó đếm vạch đc mà thực hiện công việc tại vị trí ứng với vạch nào đó.Thuật toán của mình là nếu 2 sensor ngoài cùng của cơ cấu sensor mà nhận vạch thì sẽ có ngắt ngoài INT0(phần cứng thì OK, nhận ngắt theo sườn xuống) và khi qua vạch đó thì biến đếm i trong hàm ngắt sẽ tăng lên 1.Giả sử i=1 thì gọi hàm con rẽ trái Nhưng khổ nỗi lúc biến i tăng lên 1 thì nó lại ko rẽ đc trái mà vẫn chạy thẳng.Mình đoán là do nó lại quay về thực hiện tiếp công việc chạy thẳng trc đó.
    Chương trình mình nói gọn như sau:
    //Các khai báo và định nghĩa biến
    ..........
    //Bắt đầu khai báo ngắt ngoài INT0
    ......bỏ bớt 1 số khai báo cho anh em đỡ rối mắt
    if((sensor_1&&sensor_7)==1)
    {
    i=i++;
    }
    //Đoạn CT hàm con chạy thẳng
    void chay_thang()
    {
    while(1)
    {
    ............
    }
    };
    //Đoạn CT hàm con rẽ trái
    void re_trai()
    {
    ...........
    };

    //chương trình chính
    void main(void)
    {
    ............
    while(1)
    {
    if(i==1)
    {
    re_trai();
    }
    else
    {
    chay_thang();
    }
    };
    }
    Anh em nào chơi robocon hoặc ai biết thì xin chỉ giáo cho mình đc ko.Mình đang rất bí bách.Nghĩ mãi mà ko ra đành hỏi anh em vậy.Thanks!
    Last edited by hoangdai; 03-08-2009, 23:51.


    Add: 97 Quán Nam - Lê Chân - Hải Phòng.
    Tel: 031 518648 Phone: 0904 283 505

  • #2
    mình ko rành ngôn ngữ mà bạn đang dùng, nhưng mình nghĩ có khả năng là VXL chỉ thực hiện CT con chạy thẳng mà ko thoát ra dc khỏi CT con này vì bạn thiếu lệnh thoát ra khỏi CT con này để quay lại thực hiện kiểm tra lại từ đầu ở CT chính

    Comment


    • #3
      Đúng là nó phải thực hiện tiếp CT con chạy thẳng sau khi ngắt INT0 đc thực hiện xong.Có cách nào ép chương trình phải quay về chương trình chính ngay ko???Mà ko cho CPU thực hiện công việc dở dang kia.


      Add: 97 Quán Nam - Lê Chân - Hải Phòng.
      Tel: 031 518648 Phone: 0904 283 505

      Comment


      • #4
        Chào bạn! Mình cũng là dân robocon nè, tuy mình ko lập trình nhưng cũng làm việc với nó ít lần, cho mình góp tí ý kiến nha.
        Đầu tiên bạn đừng nên đưa thẳng vào robo mà test, vì có thể sẽ bị nhiễu từ nhiều thứ (cái này dân robo ai cũng biết). Thứ đến nữa là việc ưu tiên công việc trong chương trình của bạn, vì có thể nhiễu gây ra nên có thể ở 1 thời điểm nào đó nó nhận lệnh đi thẳng rùi đang khi thực hiện chương trình đi thẳng thì lại nhận tín hiệu kiu rẽ trái, nên nó không thực hiện được.
        Ban đầu bạn nên test thông qua các con led hiện thị, như thế mình thấy mới kiểm soát đc việc thực thi chương trình.
        Thân!

        Comment


        • #5
          trong chương trình chạy thẳng của bạn là một vong lặp vô hạn, ko thoát được.Ngắt chỉ làm tăng biến đếm chứ ko thể làm thoát ra cái vong lặp ấy.Mình đề xuất 2 ý sau.
          1. Bạn kiểm tra biến i của bạn trong chương trình chạy thẳng đó,nếu biến i có sự thay đổi thì thoát ra vd:
          bạn thay

          while(1){
          .....}

          bằng

          temp=i;
          do{
          .........chương trình chạy thẳng
          }while(temp==i);


          2.Cách này đơn giản hơn.Bạn bỏ luôn while(1) trong hàm chạy thẳng đi.Chip thực hiện lệnh theo kiểu tuần tự nên ở đây bạn có thể hiểu là trong chương trình chính chip sẽ kiểm tra biến i nếu == 1 thì rẽ, nếu !=1 thì đi thẳng.KHi bạn để while(1) trong chươgn trình đi thẳng,nếu nó chạy chương trình này thì nó sẽ chỉ lặp đi lặp lại cai đoạn đi thẳng của bạn.Nếu bỏ while(1) đi thì chương trình chạy thẳng sẽ được chạy hết rồi lại quay ra kiểm tra lại i.Giống như chương trình rẽ trái của bạn đấy.
          Góp thêm một ý nhỏ là khi đọc vạch bằng ngắt thì bạn nên có thêm đoạn thoát vạch nữa,nếu bạn để ngắt theo sườn thì ko sao chứ nếu bạn để ngắt theo mức hay ngắt theo sự thay đổi mức thi yên tâm là khi vào vạch cho đến khi thoát cái vạch ấy i của bạn chắc chắn sẽ >1 => chương trình sẽ bị sai.Đây là chương trình nhỏ nên có thể chưa sinh ra lỗi do cái lỗi đọc vạch, nhưng thiết nghĩ bạn cũng nên tìm hiểu qua để tránh gặp phải sau này.

          Comment


          • #6
            trong chương trình chạy thẳng của bạn là một vong lặp vô hạn, ko thoát được.Ngắt chỉ làm tăng biến đếm chứ ko thể làm thoát ra cái vong lặp ấy.Mình đề xuất 2 ý sau.
            1. Bạn kiểm tra biến i của bạn trong chương trình chạy thẳng đó,nếu biến i có sự thay đổi thì thoát ra vd:
            bạn thay

            while(1){
            .....}

            bằng

            temp=i;
            do{
            .........chương trình chạy thẳng
            }while(temp==i);


            2.Cách này đơn giản hơn.Bạn bỏ luôn while(1) trong hàm chạy thẳng đi.Chip thực hiện lệnh theo kiểu tuần tự nên ở đây bạn có thể hiểu là trong chương trình chính chip sẽ kiểm tra biến i nếu == 1 thì rẽ, nếu !=1 thì đi thẳng.KHi bạn để while(1) trong chươgn trình đi thẳng,nếu nó chạy chương trình này thì nó sẽ chỉ lặp đi lặp lại cai đoạn đi thẳng của bạn.Nếu bỏ while(1) đi thì chương trình chạy thẳng sẽ được chạy hết rồi lại quay ra kiểm tra lại i.Giống như chương trình rẽ trái của bạn đấy.
            Góp thêm một ý nhỏ là khi đọc vạch bằng ngắt thì bạn nên có thêm đoạn thoát vạch nữa,nếu bạn để ngắt theo sườn thì ko sao chứ nếu bạn để ngắt theo mức hay ngắt theo sự thay đổi mức thi yên tâm là khi vào vạch cho đến khi thoát cái vạch ấy i của bạn chắc chắn sẽ >1 => chương trình sẽ bị sai.Đây là chương trình nhỏ nên có thể chưa sinh ra lỗi do cái lỗi đọc vạch, nhưng thiết nghĩ bạn cũng nên tìm hiểu qua để tránh gặp phải sau này.

            Comment


            • #7
              Nguyên văn bởi quick_slow Xem bài viết
              trong chương trình chạy thẳng của bạn là một vong lặp vô hạn, ko thoát được.Ngắt chỉ làm tăng biến đếm chứ ko thể làm thoát ra cái vong lặp ấy.Mình đề xuất 2 ý sau.
              1. Bạn kiểm tra biến i của bạn trong chương trình chạy thẳng đó,nếu biến i có sự thay đổi thì thoát ra vd:
              bạn thay

              while(1){
              .....}

              bằng

              temp=i;
              do{
              .........chương trình chạy thẳng
              }while(temp==i);


              2.Cách này đơn giản hơn.Bạn bỏ luôn while(1) trong hàm chạy thẳng đi.Chip thực hiện lệnh theo kiểu tuần tự nên ở đây bạn có thể hiểu là trong chương trình chính chip sẽ kiểm tra biến i nếu == 1 thì rẽ, nếu !=1 thì đi thẳng.KHi bạn để while(1) trong chương trình đi thẳng,nếu nó chạy chương trình này thì nó sẽ chỉ lặp đi lặp lại cai đoạn đi thẳng của bạn.Nếu bỏ while(1) đi thì chương trình chạy thẳng sẽ được chạy hết rồi lại quay ra kiểm tra lại i.Giống như chương trình rẽ trái của bạn đấy.
              Góp thêm một ý nhỏ là khi đọc vạch bằng ngắt thì bạn nên có thêm đoạn thoát vạch nữa,nếu bạn để ngắt theo sườn thì ko sao chứ nếu bạn để ngắt theo mức hay ngắt theo sự thay đổi mức thi yên tâm là khi vào vạch cho đến khi thoát cái vạch ấy i của bạn chắc chắn sẽ >1 => chương trình sẽ bị sai.Đây là chương trình nhỏ nên có thể chưa sinh ra lỗi do cái lỗi đọc vạch, nhưng thiết nghĩ bạn cũng nên tìm hiểu qua để tránh gặp phải sau này.
              OK-mình đã chọn ngắt theo sườn xuống(bài viết đầu tiên đã nói với mọi người).Một rắc rối nữa là khi i=1 thì rẽ trái, chỉ nhẽ nó cứ rẽ trái mãi à( vì i vẫn bắng 1).?????Trong ngắt mình cho thêm 1 biến j=i, trong hàm re_trai mình sẽ cho j=0, khi trở về CT chính thì nó ko rẽ trái nữa.Nhưng khi rẽ trái thì làm sao để robot biết nó đã vào vạch mới và dừng rẽ trái, nếu cho no rẽ trong 1 khoảng thời gian khi rẽ trái là ko ổn .Phải có đk gì để nó dừng việc quay trái lậi chứ.Kiểu như là:
              Nếu sensor_0 mà chạm vạch mới thì dừng quay trái và về chuơng trình chính thực hiện việc chạy thẳng.Mong các bác chỉ giáo thêm!
              Last edited by hoangdai; 04-08-2009, 14:08.


              Add: 97 Quán Nam - Lê Chân - Hải Phòng.
              Tel: 031 518648 Phone: 0904 283 505

              Comment


              • #8
                Nguyên văn bởi hoangdai Xem bài viết
                OK-mình đã chọn ngắt theo sườn xuống(bài viết đầu tiên đã nói với mọi người).Một rắc rối nữa là khi i=1 thì rẽ trái, chỉ nhẽ nó cứ rẽ trái mãi à( vì i vẫn bắng 1).?????Trong ngắt mình cho thêm 1 biến j=i, trong hàm re_trai mình sẽ cho j=0, khi trở về CT chính thì nó ko rẽ trái nữa.Nhưng khi rẽ trái thì làm sao để robot biết nó đã vào vạch mới và dừng rẽ trái, nếu cho no rẽ trong 1 khoảng thời gian khi rẽ trái là ko ổn .Phải có đk gì để nó dừng việc quay trái lậi chứ.Kiểu như là:
                Nếu sensor_0 mà chạm vạch mới thì dừng quay trái và về chuơng trình chính thực hiện việc chạy thẳng.Mong các bác chỉ giáo thêm!
                khi rẽ trái có nhiều thuật toán tùy vào con robot của bạn.và sân thi đấu .(gs robot chỉ có cảm biến vạch thôi)
                -nếu quay góc 90 độ khi quay đảm bảo không cắt vạch ngang nào thì chỉ cần cảcm biến ngoài cùng hoặc thứ 2,3 gì đó nhận vạch là cho dò đường tiếp khi đó robot tự điều đi theo đúng vạch.
                -nếu bị cắt một vạch ngang nào đó(cái này thì hơi khó)tùy vào từng trường hợp có cách làm hợp lý nhưng có thể kiểm tra cám biến ngoài cùng = 1 2 lần thì cho dò đường tiếp đồng thời tăng biến đếm vạch ngang lên 1
                -nếu quay góc theo một cung tròn nào đó (cài này càng khó) đòi hỏi cơ khí chính xác và hiệu chỉnh nhiều lần và cách làm cũng như hai khả năng trên thôi

                Comment


                • #9
                  Đã lập trình tạm ổn rồi.Quay trái phải ngon lành nhưng phải giảm tốc độ khi quay.Quay nhanh quá thì robot ko kịp nhận vạch.Bác nào có thuật toán nào hay trong vấn đề dò dường cho con tự động ko nhỉ.Chỉ đơn giản chạy thẳng và rẽ theo vạch định trc thôi.Dùng 8 đèn chiếu cho nó dễ.thanks!


                  Add: 97 Quán Nam - Lê Chân - Hải Phòng.
                  Tel: 031 518648 Phone: 0904 283 505

                  Comment


                  • #10
                    Nguyên văn bởi hoangdai Xem bài viết
                    Mình có con robot tự động từ mùa robocon vừa rồi.Năm trc ko thuộc bên lập trình mà làm phần cứng nên khoản viết nách cũng hơi gà.Hè vừa rồi ngồi thiết kế lại phần cứng để có robot tập tành cho mùa tới nhưng vướng ở đoạn lập trình cho robot nhớ và đếm vạch.Mình dùng AVR16L và viết trên codevision.Cụ thể là:
                    -Về việc chỉnh định để robot đi thẳng thì ko vấn đề.Đã cày xong
                    -Vướng mắc ở chỗ dùng ngắt ngoài INT0 để đếm vạch.Mục đích mình muốn nó đếm vạch đc mà thực hiện công việc tại vị trí ứng với vạch nào đó.Thuật toán của mình là nếu 2 sensor ngoài cùng của cơ cấu sensor mà nhận vạch thì sẽ có ngắt ngoài INT0(phần cứng thì OK, nhận ngắt theo sườn xuống) và khi qua vạch đó thì biến đếm i trong hàm ngắt sẽ tăng lên 1.Giả sử i=1 thì gọi hàm con rẽ trái Nhưng khổ nỗi lúc biến i tăng lên 1 thì nó lại ko rẽ đc trái mà vẫn chạy thẳng.Mình đoán là do nó lại quay về thực hiện tiếp công việc chạy thẳng trc đó.
                    Chương trình mình nói gọn như sau:
                    //Các khai báo và định nghĩa biến
                    ..........
                    //Bắt đầu khai báo ngắt ngoài INT0
                    ......bỏ bớt 1 số khai báo cho anh em đỡ rối mắt
                    if((sensor_1&&sensor_7)==1)
                    {
                    i=i++;
                    }
                    //Đoạn CT hàm con chạy thẳng
                    void chay_thang()
                    {
                    while(1)
                    {
                    ............
                    }
                    };
                    //Đoạn CT hàm con rẽ trái
                    void re_trai()
                    {
                    ...........
                    };

                    //chương trình chính
                    void main(void)
                    {
                    ............
                    while(1)
                    {
                    if(i==1)
                    {
                    re_trai();
                    }
                    else
                    {
                    chay_thang();
                    }
                    };
                    }
                    Anh em nào chơi robocon hoặc ai biết thì xin chỉ giáo cho mình đc ko.Mình đang rất bí bách.Nghĩ mãi mà ko ra đành hỏi anh em vậy.Thanks!
                    mình ko hiểu về ngôn ngữ bạn sử dụng. Mình cũng có mạch dò đường robot mình post lên anh em cùng tham khảo nha:
                    Attached Files
                    Last edited by anhtuan0423; 04-08-2009, 21:32.
                    Dân ta phải biết sử ta
                    Cái gì không biết thì tra google.

                    Comment


                    • #11
                      trời ơi bác chơi ASM à?Cái này em bó tay, chỉ quen viết C cho avr thôi.ASM thì quen chơi cho 8051.
                      Last edited by hoangdai; 05-08-2009, 11:56.


                      Add: 97 Quán Nam - Lê Chân - Hải Phòng.
                      Tel: 031 518648 Phone: 0904 283 505

                      Comment


                      • #12
                        Mình có cách viết đếm vạch Khác,Cái này dùng viết cho 89 bạn tham khảo nhé.
                        Trước tiên khai báo cảm biến nhé.
                        Khai báo biến toàn cục cho biến TEMP (unsigned char TEMP)
                        Giả sử đã có chương trình con Bám Vạch (void Bam_Vach())
                        ở đây giả sử có 8 cảm biến nối với P0(89)(AVR thì tùy bạn nối)
                        void tong_so_bit_0() { // sensor nhận ở mức 0//
                        if(SEN1==0) TEMP ++;
                        if(SEN2==0) TEMP ++;
                        if(SEN3==0) TEMP ++;
                        if(SEN4==0) TEMP ++;
                        if(SEN5==0) TEMP ++;
                        if(SEN6==0) TEMP ++;
                        if(SEN7==0) TEMP ++;
                        if(SEN8==0) TEMP ++;
                        return TEMP;
                        }
                        /////////////////////////////////////////
                        void bam_vach_dem_nga_tu(unsigned int nga_tu){
                        while(nga_tu>0){
                        Bam_Vach();
                        if(tong_so_bit_0>=5){
                        while (tong_so_bit_0<=3)
                        nga_tu--;

                        }
                        }
                        }


                        Vào chương trình chính bạn chỉ gọi thế này thôi là được
                        void main(){
                        ............................................
                        ...........................................
                        bam_vach_dem_nga_tu(4); //đếm 4 ngã tư.//
                        xoay_trai(); //ngay ngã tư thứ 4 nó sẽ xoay trái.//
                        }

                        Ở đây mình không dùng ngắt.

                        Comment


                        • #13
                          Thế sau khi rẽ trái rồi thì nó có bám vạch đi thẳng ko vậy?????Bạn viết thế này mình thấy ko ổn cho lắm:
                          -thứ nhất:bạn kiểm tra sensor1, nếu nó = 0 thì tăng biến temp lên 1, nhưng vạch rộng 3cm, như vậy với tốc độ bình thường thì sẽ mất 1 khoảng gian để qua vạch.Như vậy sensor1 cũng sẽ có 1 khoảng thời gian nhất định = 0.Nếu thế thì biến temp cứ tăng mãi à????Em nói vậy có đúng ko hả các bác?
                          -thứ hai:Trong đoạn code này:"
                          /////////////////////////////////////////
                          void bam_vach_dem_nga_tu(unsigned int nga_tu){
                          while(nga_tu>0){
                          Bam_Vach();
                          if(tong_so_bit_0>=5){
                          while (tong_so_bit_0<=3)
                          nga_tu--;

                          }
                          }
                          }
                          "
                          Nó chạy như sau:Nếu giá trị nạp nga_tu >0 thì bám vạch chạy thẳng.Tiếp đó kiểm tra nếu số lần qua vạch mà >= 5 thì vào vòng lặp mãi mãi và lại kiểm tra số lần qua vạch, nếu nó <=3 thì lại giảm giá trị nga_tu đi 1.Em ko hiểu nso làm vậy để làm gì nhỉ????


                          Add: 97 Quán Nam - Lê Chân - Hải Phòng.
                          Tel: 031 518648 Phone: 0904 283 505

                          Comment


                          • #14
                            Nguyên văn bởi hoangdai Xem bài viết
                            Thế sau khi rẽ trái rồi thì nó có bám vạch đi thẳng ko vậy?????Bạn viết thế này mình thấy ko ổn cho lắm:
                            -thứ nhất:bạn kiểm tra sensor1, nếu nó = 0 thì tăng biến temp lên 1, nhưng vạch rộng 3cm, như vậy với tốc độ bình thường thì sẽ mất 1 khoảng gian để qua vạch.Như vậy sensor1 cũng sẽ có 1 khoảng thời gian nhất định = 0.Nếu thế thì biến temp cứ tăng mãi à????Em nói vậy có đúng ko hả các bác?
                            -thứ hai:Trong đoạn code này:"
                            /////////////////////////////////////////
                            void bam_vach_dem_nga_tu(unsigned int nga_tu){
                            while(nga_tu>0){
                            Bam_Vach();
                            if(tong_so_bit_0>=5){
                            while (tong_so_bit_0<=3)
                            nga_tu--;

                            }
                            }
                            }
                            "
                            Nó chạy như sau:Nếu giá trị nạp nga_tu >0 thì bám vạch chạy thẳng.Tiếp đó kiểm tra nếu số lần qua vạch mà >= 5 thì vào vòng lặp mãi mãi và lại kiểm tra số lần qua vạch, nếu nó <=3 thì lại giảm giá trị nga_tu đi 1.Em ko hiểu nso làm vậy để làm gì nhỉ????
                            Ở đây là mình giả sử vậy mà.Còn nếu viết như thế này thì ban đầu nó sẽ chạy thẳng đếm 5 ngã tư rồi xoay trái.Sau đó nó sẽ chạy tiếp 5 ngã tư rồi xoay trái,bà vòng lặp cứ lạp như vậy vô tận.
                            void main(){
                            Bam_Vach_Dem_Nga_Tu(5);
                            xoay_trai();
                            }
                            ///////////////////////////////////////////////////////
                            void bam_vach_dem_nga_tu(unsigned int nga_tu){
                            while(nga_tu>0){
                            Bam_Vach();
                            if(tong_so_bit_0>=5){ ////nghĩa là nếu số Sen nhận >=5 để biết chắc chắn đây là ngã tư.//
                            while (tong_so_bit_0<=3)//Chờ số Sen<=3 biết đã qua ngã tư rồi mới trừ đi ngã tư, làm như vậy để tránh một ngã tư được đếm 2 lần.//
                            nga_tu--;

                            }
                            }
                            }
                            ///////////////end/////////////
                            Bạn nên nhớ là ở đây TEMP chỉ tăng lên tại một thời điểm, sau đó nó sẽ trả về lại 0 nếu như Sensor không nhận vạch.Vì bạn có thấy vì sao mà mình có hàm Return TEMP; ở dưới không.Bạn chưa hiểu rõ lệnh này, Với hàm này thì nếu Sensor không nhận giá trị trả về là 0.

                            Comment


                            • #15
                              void TIMER0_isr(void)
                              {
                              somat=quet_mat();
                              if(somat >= 6) vach = 1;
                              else vach = 0;
                              sau = vach;
                              if(truoc == 0 && sau == 1)
                              sovach++;
                              truoc = sau;
                              //=======================
                              }


                              em có đoạn code đếm vạch này , dùng timer để đếm vạch ngang (ngã 4) chỉ khi nào các sensor thay đổi trạng thái 2 lần thì mới đếm 1 vạch tránh đc tình trạng đếm thừa vạch. Cũng có thể kết hợp phần cứng như encoder để đo đương tắt mở timer quét vạch ngang. khi rẽ xong nên reset lại số vạch vì khi quay rất dễ lạc hay đếm nhầm vạch đó.
                              các bác cho em ý kiến nhá.
                              Mà các bac biết 2010 Robocon diễn ra ở đâu không ạ ???

                              Comment

                              Về tác giả

                              Collapse

                              hoangdai Hoàng Đình Đại-Điện tự động công nghiệp Tìm hiểu thêm về hoangdai

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

                              Collapse

                              Đang tải...
                              X