久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 17961|回復(fù): 8
收起左側(cè)

Arduino 自平衡小車,制作經(jīng)驗記錄與分享,愿有興趣人士,一起學(xué)習(xí)探討。

[復(fù)制鏈接]
ID:113207 發(fā)表于 2016-4-11 02:47 | 顯示全部樓層 |閱讀模式
論壇潛行1個月,終于做出我的平衡小車了。以下為我的制作經(jīng)驗。希望大家共同學(xué)習(xí)進(jìn)步。

一、以下為物料清單:
NO        名稱                        數(shù)量        功能               
1        電機(jī)JGA25-371                        2Pcs        提供動力               
2        電機(jī)驅(qū)動模塊L298n                        1Pcs        驅(qū)動馬達(dá)               
3        Arduino nano V3.0                        1Pcs        主控制晶片               
4        HC-06藍(lán)牙通訊模塊                        1Pcs        與藍(lán)牙設(shè)備通訊               
5        JY521-MP6050 陀螺儀加速計                        1Pcs        提供平衡依據(jù)               
6        機(jī)構(gòu)件                        若干        拼接               
二、圖片
141106bs6cgf6clesesffu.jpg
三、算法
1.有參考過卡爾曼濾波,加Arduino 內(nèi)置PID庫并使用Processing 圖形工具在線調(diào)試PID參數(shù)方法,小車運動趨勢有,但是無法站立,并且參數(shù)始終沒調(diào)好。
2.參考高通濾波方法,效果出奇的好。調(diào)試了下參數(shù),就站起來了。

四、code分享。
1.請大家重點看MP6050 initial 及公式。如有疑問,愿意解答。
  1. //copyright by kaiser 20140423 V1.0
  2. void loop()
  3. {
  4.   //////////////////////////////////////MP6050//////////////////////////////////////////////////////////////////
  5.      accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  6.     Angle_Calcu();
  7.     Serial.print("Angle");Serial.println(Angle);
  8.     if (abs(Angle)<45) /////////////////up-right judge
  9.     {
  10.       Input=Angle;
  11.       //myPID.SetTunings(Kp, Ki, Kd);
  12.       //myPID.Compute();
  13.       Output=Kp*Angle+Kd*Gyro_y;
  14.       Serial.print("Output");Serial.println(Output);
  15.       SetMotorVoltage(Output,Output);
  16.   }
  17.   else{SetMotorVoltage(0,0);//角度大于45度 停止PWM輸出}
  18.         if(millis()>serialTime)
  19.     {
  20.       SerialReceive();
  21.       SerialSend();
  22.       serialTime+=500;
  23.     }
  24.   }
  25. }
復(fù)制代碼

2.我把程序在更新下,最終版上傳。
  1. //copyright by kaiser 20140521 V1.0
  2. /////////////////////////////////////////////////////////////////////////////////////////////////////
  3. #include "Wire.h"            //serial
  4. #include "I2Cdev.h"          //IIC
  5. #include "MPU6050.h"         //acc&gyro Sensor
  6. //Define Variables we'll be connecting to
  7. char val='s';int Speed_need=0;int Turn_need=0;
  8. float speeds,speeds_filter, positions;
  9. float diff_speeds,diff_speeds_all;
  10. ////////////////////PID parameter///////////////////////////////////////
  11. double Output=0;
  12. float Kp=10,Kd=0.06,Ksp = 2.8,Ksi = 0.11;        //

  13. ////////////////////////////////////////////////
  14. MPU6050 accelgyro;
  15. int16_t ax, ay, az;
  16. int16_t gx, gy, gz;
  17. /********************角度參數(shù)**************/
  18. float Gyro_y;            //Y軸陀螺儀數(shù)據(jù)暫存
  19. float Angle_ax;          //由加速度計算的傾斜角度
  20. float Angle;             //小車最終傾斜角度
  21. //int Setpoint=0;
  22. ////////////////////////////////////////Pin assignment///////////////////////////////////////
  23. int PinA_right= 2; //interrupt 0
  24. int PinA_left= 3; //interrupt 1
  25. int E_left =6;//ENA
  26. int M_right =7;
  27. int M_right2=8;
  28. int E_right =5; //ENB
  29. int M_left =9;  
  30. int M_left2 =10;
  31. //////////////////////////////////////////////////////////////////////////////
  32. int PWM_right=0; int PWM_left=0;
  33. int PWM_left_least=87; int PWM_right_least=88;//left:77,right:78
  34. ///////////////////////////////interrupt for Speed/////////////////////////////////
  35. int count_right =0;
  36. int count_left  =0;
  37. int old_time=0;
  38. int flag;
  39. void Code_right(){  if(Output>=0){count_right += 1;}else{count_right -= 1;} }//if only +,can't stand up 編碼器碼盤計數(shù)加一
  40. void Code_left(){  if(Output>=0){count_left += 1;} else{count_left -= 1;}}// 編碼器碼盤計數(shù)加一   
  41. /////////////////////////Right&Left&Stop///////////////////////////////////////////////
  42. void SetMotorVoltage(int nLeftVol, int nRightVol) {
  43.     if(nLeftVol >=0)
  44.   {  digitalWrite(M_left,LOW);
  45.      digitalWrite(M_left2,HIGH);
  46.    } else {      
  47.      digitalWrite(M_left,HIGH);
  48.      digitalWrite(M_left2,LOW);
  49.      nLeftVol=-nLeftVol;
  50.    }
  51.     if(nRightVol >= 0) {
  52.      digitalWrite(M_right,LOW);
  53.      digitalWrite(M_right2,HIGH);
  54.     } else {
  55.      digitalWrite(M_right,HIGH);
  56.      digitalWrite(M_right2,LOW);
  57.     nRightVol=-nRightVol;
  58.   }
  59.     if(nLeftVol>255) { nLeftVol = 255 ; }   //防止PWM值超過255
  60.     if(nRightVol>255) { nRightVol = 255 ; }//防止PWM值超過255
  61.     analogWrite(E_left,nLeftVol);
  62.     analogWrite(E_right,nRightVol);
  63. }

  64. /////////////////////////////////////////////////////////////////////////////////////////////
  65. void Angle_Calcu(void)         {
  66.         Angle_ax = (ax+1942)/238.2 ;   //去除零點偏移1942,//16384*3.14/1.2*180//弧度轉(zhuǎn)換為度,
  67.               Gyro_y = -(gy-119.58)/16.4;         //去除零點偏移119,2000deg/s 16.4 LSB/(deg/s)250---131 ,負(fù)號為方向處理
  68.         //Serial.print("Angle_ax,Angle_gy");Serial.print(Angle_ax);Serial.println(Angle_gy);
  69.         Angle=0.97*(Angle+Gyro_y*0.0005)+0.03*Angle_ax;
  70.         //Kalman_Filter(Angle_ax,Gyro_y);       //卡爾曼濾波計算傾角                                                                                                         
  71. }   

  72. void setup()
  73. {
  74.     Wire.begin();
  75.     Serial.begin(9600);  
  76.    ///////////////////////////////////////////////////////////////////
  77.     accelgyro.reset();//reset
  78.     delay(1);
  79.     accelgyro.setClockSource(MPU6050_CLOCK_PLL_YGYRO);//PLL with Y Gyro reference*/
  80.     accelgyro.setFullScaleGyroRange(MPU6050_GYRO_FS_2000);//0x1B Value 0x18 2000°/s
  81.     accelgyro.setFullScaleAccelRange(MPU6050_ACCEL_FS_4);//0x1C Value 0x18 16g
  82.     accelgyro.setDLPFMode(MPU6050_DLPF_BW_5);//0x06 means acc 5Hz delay19.0ms Gyro 5Hz delay 18.6ms
  83.     accelgyro.setTempSensorEnabled(true);//disable temsensor
  84.     accelgyro.setSleepEnabled(false);
  85.     Serial.println("Testing device connections...");
  86.     Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
  87.    ////////////////////////pin mode////////////////////////////////////////
  88.    pinMode(E_right, OUTPUT); pinMode(M_right, OUTPUT);pinMode(M_right2, OUTPUT);  //right
  89.    pinMode(E_left, OUTPUT);  pinMode(M_left, OUTPUT);pinMode(M_left2, OUTPUT);  //left
  90.    pinMode(PinA_right,INPUT);pinMode(PinA_left,INPUT);// in 0 in 1
  91.    Serial.println("Pin mode ...");
  92.    /////////////////////////////interrupt/////////////////////////////////////////////
  93.    attachInterrupt(0, Code_right, FALLING);attachInterrupt(1, Code_left, FALLING);
  94.    
  95. }

  96. void loop()
  97. {
  98.    if (Serial.available() > 0){val = Serial.read();Serial.println(val);}
  99.      switch(val){
  100.      case 'a':Speed_need=30;Turn_need=0;positions=80;break;//Go
  101.      case 'b':Speed_need=10;Turn_need=-10;positions=10;break;//right
  102.      case 'c':Speed_need=10;Turn_need=10;positions=10;break;//left
  103.      case 'd':Speed_need=0;Turn_need=0;positions=0;break;
  104.      default:Speed_need=0;Turn_need=0;positions=0;break;}//stop
  105.    
  106.      //Speed_need=30;Turn_need=0;positions=80;  
  107.      //SetMotorVoltage(255,255);
  108.     //Kp=15,Kd=0.09,Ksp = 2.8,Ksi = 0.11;
  109.          //Serial.print("count_left");Serial.println(count_left);
  110.     accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  111.     Angle_Calcu();
  112.     //Serial.print("Angle");Serial.println(Angle);
  113.     PWM_Calcu();
  114.   
  115.    //if(millis()-old_time>=500){ Serial.print("count_right");Serial.print(count_right);Serial.print("count_left");Serial.println(count_left);old_time=millis();count_right=0;count_left=0;}     
  116. }
  117. void PWM_Calcu(void)
  118. {
  119.   if (abs(Angle)>40)
  120.     {SetMotorVoltage(0,0);}//角度大于45度 停止PWM輸出
  121.     else
  122.     { //Speed_need=30;Turn_need=0;positions=80;
  123.       //////////////////////
  124.       speeds=(count_left + count_right)*0.5;
  125.       diff_speeds = count_left - count_right;
  126.       diff_speeds_all += diff_speeds;
  127.       speeds_filter *=0.85;  //一階互補(bǔ)濾波
  128.       speeds_filter +=speeds*0.15;
  129.       positions += speeds_filter;
  130.       positions += Speed_need;
  131.       positions = constrain(positions, -2300, 2300);//抗積分飽和
  132.       ////////////////////
  133.       Output=Kp*Angle+Kd*Gyro_y+ Ksp*speeds_filter + Ksi*positions ;
  134.       //Serial.print("Output");Serial.println(Output);
  135.       if(Turn_need==0){PWM_right=Output-diff_speeds_all;
  136.       PWM_left=Output+diff_speeds_all;}
  137.       
  138.       PWM_right=Output+Turn_need;
  139.       PWM_left=Output-Turn_need;
  140.       
  141.       if(PWM_right>=0){PWM_right+=PWM_right_least;}else{PWM_right-=PWM_right_least;}
  142.       if(PWM_left>=0){PWM_left+=PWM_left_least;}else{PWM_left-=PWM_left_least;}

  143.       SetMotorVoltage(PWM_left,PWM_right);}
  144.        count_left = 0;
  145.   count_right = 0;
  146. }
復(fù)制代碼

//////////////////////////////////////////////////////////
五、吃水不忘挖井人,以下為我的參考文章,前輩們還是要非常尊敬的。
1.Processing 圖形工具在線調(diào)試PID參數(shù)教程。http://blog.sina.com.cn/s/blog_69bcf45201019bp8.html
2.PVCBOT【9號】忐忑者·自平衡雙輪小車。http://blog.163.com/pvc_robot/bl ... 643220113334818803/
3.基于Arduino+MPU6050+Tp-link 703n平衡小車。http://www.zg4o1577.cn/bbs/dpj-47875-1.html
4.虛擬NXT的NXTway-GS自行平衡兩輪機(jī)器人教程 http://bbs.cmnxt.com/thread-7697-1-1.html
5.第二個Arduino小車 兩輪自平衡(Arduino PID方式)http://www.zg4o1577.cn/bbs/dpj-48038-1.html
6.碉堡的雙輪平衡小車(蕭大哥)http://www.zg4o1577.cn/bbs/dpj-48039-1.html
7.總算實現(xiàn)了 PID 調(diào)速(重點推薦)http://www.zg4o1577.cn/bbs/dpj-48040-1.html

--------------------------------------------------

PID_v1.h庫: PID_v1.rar (6.3 KB, 下載次數(shù): 44)
附件為MP6050標(biāo)準(zhǔn)庫,example中有兩種方式:
1.普通方式
2.DMP方式,此方式需要占用中斷資源 MPU6050.rar (79.67 KB, 下載次數(shù): 25)

評分

參與人數(shù) 2黑幣 +10 收起 理由
偶游QHD + 5 樓主的分享正是我所需要的
sax_yang + 5 感謝樓主分享,資料很全,對我這樣的新人幫.

查看全部評分

回復(fù)

使用道具 舉報

ID:187533 發(fā)表于 2017-4-10 20:58 | 顯示全部樓層
請問樓主,我從別的地方下載的庫文件里好像缺文件,你的這個MPU6050.rar包含所需庫文件嗎?
回復(fù)

使用道具 舉報

ID:187533 發(fā)表于 2017-4-11 05:36 | 顯示全部樓層
加入樓主的MPU6050后,代碼編譯秒過,接線圖我也按代碼自己畫了一個,不知道能不能行,先去采購配件,感謝樓主的分享。
回復(fù)

使用道具 舉報

ID:187533 發(fā)表于 2017-4-11 06:16 | 顯示全部樓層
請問樓主能分享一下線路圖嗎?
回復(fù)

使用道具 舉報

ID:267777 發(fā)表于 2017-12-27 15:38 | 顯示全部樓層
請問樓主能分享一下線路圖嗎?
回復(fù)

使用道具 舉報

ID:267813 發(fā)表于 2017-12-27 16:53 | 顯示全部樓層
正需要這個  謝謝樓主分享
回復(fù)

使用道具 舉報

ID:268845 發(fā)表于 2017-12-29 14:18 | 顯示全部樓層
材料采購大家有哪個網(wǎng)店推薦一下嗎?新手想學(xué)著試試,望指教
回復(fù)

使用道具 舉報

ID:282823 發(fā)表于 2018-2-7 15:34 | 顯示全部樓層
收藏參考
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 久久久久久久久精 | 国产一区二区三区四区在线观看 | 国产精品一区一区 | 一区二区三区免费 | 欧美激情欧美激情在线五月 | 日日噜噜夜夜爽爽狠狠 | 国产一区中文字幕 | 美女天天操| av日日操 | 国产在线视频一区 | www.亚洲免费 | 成人影 | 日韩一区二区在线视频 | 日韩一级黄色片 | 久久精品小视频 | 91精品国产91久久久久游泳池 | 一区二区三区免费 | 伊人超碰在线 | 福利视频网站 | 成人在线视频看看 | 国产在线精品一区二区三区 | 日韩欧美国产综合 | 久久国产精品色av免费观看 | 中文字幕乱码视频32 | 性视频一区| 国产99久久精品一区二区永久免费 | 欧美一级片免费看 | 国产精品福利网站 | a网站在线观看 | 成人二区三区 | 黄色国产| 色综合九九| 国产日韩精品视频 | 久久人 | 亚洲一区二区久久久 | 国产福利91精品一区二区三区 | 国产精品爱久久久久久久 | 国产精品视频999 | 国产精品毛片一区二区三区 | 久久久久亚洲精品 | 精品久久久久久 |