sensor line tracking ใช้ LDR ไม่รู้จะเก่าไปรึเปล่า

  • 20 Replies
  • 7621 Views
*

Offline nont_peet

  • **
  • 52
  • คนรักหุ่นยนต์
    • View Profile
ผมแจกหมดนะครับ ผมเลิกทำ ABU แล้วครับ   แจกหมดทั้งโค๊ด วงจร     

อันนี้เป็นรูปแบบที่ผมใช้วิ่งตามเส้น  อ่านค่า ADC มาบวกลบกัน  เพื่อให้ ค่างตรงกลางคือ 0  ถ้าเอียงซ้าย จะเป็นค่าลบ เอียงขวาเป็นบวก  เสร็จแล้วนำค่าที่ได้ เข้า PID  จากนั้นนำ output ไปสั่งงานมอเตอร์ครับ


Code: [Select]
void forward1()
{
         const signed int16 dt = 10;
     
      read_ad();
      con_senser();
      previous_error = (ADC[0]) + (ADC[1]) + (ADC[2]) + (ADC[3]) - (ADC[4]) - (ADC[5]) - (ADC[6]) - (ADC[7]);
      integral = 0;

  while(true)
      {
     
      read_ad();
      con_senser();
      if((s2&&s3&&s4&&s5&&s6&&s7)||(s1&&s2&&s3&&s4)||(s5&&s6&&s7&&s8))
         {
         delay_ms(1);
         if((s2&&s3&&s4&&s5&&s6&&s7)||(s1&&s2&&s3&&s4)||(s5&&s6&&s7&&s8))
            {
            output_low(in1_l);
            output_low(in2_l);
            set_pwm2_duty(0);
           
            output_low(in1_r);
            output_low(in2_r);
            set_pwm1_duty(0);
            break;
            }
         }       
//------------------------------------- PID-------------------------------------
error = (ADC[0]) + (ADC[1]) + (ADC[2]) + (ADC[3]) - (ADC[4]) - (ADC[5]) - (ADC[6]) - (ADC[7]);
integral = integral + (error*dt);
derivative = (error - previous_error)/dt;
previous_error = error;
pwm = (error*5) + (integral/10000) + (derivative*3/2);

if(pwm>2040){pwm=2040;}
if(pwm<(-2040)){pwm=(-2040);}

   if(pwm<0)
         {
         if(pwm < (-1023))
            {   
            output_high(in1_l);
            output_low(in2_l);
            set_pwm2_duty((-pwm)-1023);
           
            output_low(in1_r);
            output_high(in2_r);
            set_pwm1_duty(1023);
            }
         else
            {
            output_low(in1_l);
            output_high(in2_l);
            set_pwm2_duty(1023-(-pwm));
           
            output_low(in1_r);
            output_high(in2_r);
            set_pwm1_duty(1023);
            }
         }
      else
         {
         if(pwm > 1023)
            {
            output_low(in1_l);
            output_high(in2_l);
            set_pwm2_duty(1023);
           
            output_high(in1_r);
            output_low(in2_r);
            set_pwm1_duty(pwm-1023);
            }
         else
            {
            output_low(in1_l);
            output_high(in2_l);
            set_pwm2_duty(1023);
           
            output_low(in1_r);
            output_high(in2_r);
            set_pwm1_duty(1023-pwm);
            }
         } 
      delay_ms(dt);   
      }       
}



ป.ล.1 PID ที่ผมใช้อาจจะยังไม่ถูกต้องตามหลักการมากนัก น่าจะยังขาดในส่วนของการจัดการ dt ที่ถูกต้อง      (ผมไม่ได้จบด้านนี้มา)
ป.ล.2 การวิ่ง 2 ล้อแบบนี้  จูนหุ่นยนต์ยากกว่า การทำ 2 ล้อหน้าเป็นล้อบิด ซึ่งจะคุมองศาเหมือนการเลี้ยวรถยนต์   
ป.ล.3 ผมไม่ได้มีเจตนาจะอวดเก่งใดๆทั้งสิ้น ในวงการ ABU จะรู้ครับว่าผมเป็นอย่างไร  เพียงแต่แสดงออกในสิ่งที่ผมทำมา เพื่อให้ น้องๆนักเรียนและเพื่อนครูทั้งหลาย นำไปทดลองใช้กันครับ 
คนรักหุ่นยนต์

*

Offline ozuke

  • *****
  • 118
    • View Profile
    • MCU & Computer Programing Learning by Wittawat Sompong
อิอิ เอาไงดีน๊า อยากโพส แต่โค้ดดูโคตรยาก อิอิ

*

Offline nont_peet

  • **
  • 52
  • คนรักหุ่นยนต์
    • View Profile
จัดเต็มเลยท่าน OZUKE  เดี๋ยวน้องๆเค้าคงเอาไปแกะเอง      8) 8) 8)
คนรักหุ่นยนต์

*

Offline skytec

  • *****
  • 1030
  • "จินตนาการสำคัญกว่าความรู้ " --อัลเบิรต ไอสไตน์
    • View Profile
    • R&D , Technical Consultants , Sensor Developer  , Engineering consultants
@ skytec  สาเหตุที่ใช้ LDR เพราะ สนามที่ใช้ในการแข่งขันนั้นใช้รวมกันและแข่งหลายคู่  บางทีอาจมีเศษโฟม เศษอลูมิเนียม  แสงแฟรชกล้อง  เพราะงั้น LDR จึงยังดีกว่า เพราะความช้าของมันนี่ล่ะครับ   

ไอ้ที่ว่าช้าของ LDR  นี่ มันยังเร็วพอที่จะใช้วิ่งตามเส้น     มอเตอร์ 350rpm 12Vdc   แต่อัด 24Vdc  ล้อเส้นรอบวง 22cm   อัดเต็มๆยังอ่านทันเลย   ลองใช้ดูครับ เผื่อติดใจ


@ Chairat  ใช้งาน LDR ที่สมบูรณ์  ควรจะ  หักค่าให้เป็น 0  และรู้ค่าสูงสุด  จากนั้นนำมาทำเป็น %  และนำไปใช้งาน

อันนี้อาจมีความเข้าใจแตกต่าง การใช้ photo transistor นั้น เราสามารถกำหนดได้หลายอย่างครับ อยู่ที่เทคนิคของ software สังเกตง่ายๆ ก๊อกนำ้ล้างมือที่ผลิตขายเอาแบบมียี่ห้อ ใช้ photo tr อันนี้จะไม่ขึ้นกับสภาวะแวดล้อม ผมเคยทำหลอด led ที่ควบคุมความสว่างด้วย photo tr ขณะที่ปลอดยังติดอยู่ เราสามารถวัด lux ได้โดยเทคนิคทางโปรแกรมครับ สิ่งแวดล้อมสามารถแก้ไขได้หรือไม่ให้มีผลต่อระบบได้ ครับ


โอ้ววว น่าสนใจ   เดี๋ยวผมลองหาข้อมูลดูเผื่อ เอามาพัฒนาให้น้องๆนักศึกษาเอาไปใช้กัน    ขอบคุณมากครับสำหรับคำแนะนำ

หลักการทำแบบนี้ครับ

1. ขาหรือ pin ที่จะต่อกับ sensor ต้องเป็นแบบ อนาลอก
2. ขา led หรือ  infrared ต้องสามารถควบคุมได้ หรือสั่ง on off ได้
3. สั่งปิด infrared ก่อนแล้วอ่านค่า แสงขณะนั้นเช่นอ่านได้ 1.5V
4. หากSensor เจอสีดำแสงก็จะสะท้อนกลับน้อย เช่น สะท้อนกลับมา อ่านได้ 1.2V  ดั่งนั้นความต่างของเส้นจะอยู่ที่ 0.3 V ดั่งนั้น เมื่อ สิ่งแวดล้อมเปลี่ยน ความต่างของสีเส้นก็จะคงยังไม่แตกต่างไปจากเดิม
5. เราก็กำหนดไว้ ในเงื่อนไขว่า หากแสงที่อ่านได้แตกต่างกับ มากกว่า 0.2V แสดงว่ามีการจับแสงสะท้อนจากเส้นได้ อันนี้จะกำหนดค่าน้อยกว่า ปริมาณที่เราวัดวัดได้เพื่อให้เกิดความแม่นยำ
6. หากระดับสดงน้อยไปจนไม่เกิดความแตกต่าง เราก็ใหเปิด LED หรือ Infrared ช่วย
เท่านี้เรก็จะสามารถวัดความแตกต่างของเส้นได้ หากเขียนโปรแกรมได้ดีเราอาจทำให้มันเป็นแบบ Auto adjust ได้ อันนี้แล้วแต่ใครจะใช้ ครับ

"จินตนาการสำคัญกว่าความรู้ ความรู้มีข้อจำกัด จิตนาการไร้ขอบเขต " --อัลเบิร์ต ไอสไตน์

*

Offline nont_peet

  • **
  • 52
  • คนรักหุ่นยนต์
    • View Profile
 :D ขอบคุณครับ 
คนรักหุ่นยนต์