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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10553|回復(fù): 19
打印 上一主題 下一主題
收起左側(cè)

[寧靜清幽的平衡小車進(jìn)程帖]

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:104166 發(fā)表于 2016-2-4 11:52 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 寧靜清幽 于 2016-2-5 11:24 編輯

組裝曬圖
來幾發(fā)小車照片,曬一曬
小車主控板正面照片




小車主控板反面照片


主控板給我的感覺:板子質(zhì)量杠杠的,焊工也是棒棒噠,沒有什么質(zhì)量問題


小車底盤反面照片



全身照片


感覺小車帥帥噠
基礎(chǔ)實驗
  
1.      Keil工程模板的建立

2.      LED指示燈實驗

這兩個實驗就放一塊了,Keil工程模板的建立在圖中了,不知道這樣算不算完成,好多文件還沒有寫呢,做以后的實驗再補充。

LED指示燈實驗主函數(shù)代碼在下圖就不再貼出來了



all_header.h的代碼如下
  1. #ifndef __all_head_
  2. #define __all_head_

  3. #include "STC15W4Kxx.h"
  4. #include <intrins.h>
  5. #include "Delay.h"

  6. #endif
復(fù)制代碼


Delay.h的代碼和all_header.h的代碼格式一樣,也不貼啦。
還是貼一下吧。
  1. #ifndef __Delay_
  2. #define __Dealy_
  3. #include <intrins.h>
  4. void Delay300ms();                //@20.000MHz
  5. #endif
復(fù)制代碼
在貼一下Delay.c的代碼吧!
  1. #include "Delay.h"
  2. void Delay300ms()                //@20.000MHz
  3. {
  4.         unsigned char i, j, k;
  5.         _nop_();
  6.         _nop_();
  7.         i = 23;
  8.         j = 205;
  9.         k = 120;
  10.         do
  11.         {
  12.                 do
  13.                 {
  14.                         while (--k);
  15.                 } while (--j);
  16.         } while (--i);
  17. }
復(fù)制代碼
最后來張效果圖

打死我,我也不會說這個程序里面控制的兩個LED,但是只有一個亮。這個問題實在是無關(guān)緊要啦

3.      UART串口通訊實驗

還是先上個效果圖


寫好程序編譯,在左側(cè)選好單片機型號,串口號,用的是內(nèi)部時鐘,填好IRC頻率,為了方便通信嘛,就選的11.0592M。
在右側(cè)最下面的藍(lán)色框中,選好串口好,波特率,無校驗位,停止位1位。上面兩個藍(lán)色框就是效果圖了
對了,還得用安卓數(shù)據(jù)線把小車和電腦連起來,裝上CP2102的驅(qū)動。
再上代碼
主函數(shù)main代碼:
  1. #include "all_header.h"

  2. void main()
  3. {        
  4.         Uart1Init();
  5.         EA=1;
  6.                 while(1);
  7. }
  8. void UART1() interrupt 4 using 1
  9. {
  10.         unsigned char date;
  11.         if (RI)
  12.         {        
  13.                 RI=0;
  14.                 date=SBUF;
  15.                 UART1SendByte(date);
  16.         }
  17.         if (TI)
  18.         {
  19.                 TI=0;
  20.         }
  21. }
復(fù)制代碼

all_header.h頭文件代碼:
  1. #ifndef __all_head_
  2. #define __all_head_


  3. #include "STC15W4Kxx.h"
  4. #include <intrins.h>
  5. //#include "Delay.h"
  6. #include "UART1.h"

  7. #endif
復(fù)制代碼
UART1.h代碼:
  1. #ifndef _UART_H_  
  2. #define _UART_H_  

  3. #include "STC15W4Kxx.h"

  4. void Uart1Init(void);
  5. void UART1SendByte(unsigned char TxD1);

  6. #endif  
復(fù)制代碼
UART1.c代碼:
  1. #include "UART1.h"

  2. void Uart1Init(void)                //115200bps@11.0592MHz
  3. {
  4.         SCON = 0x50;                //8位數(shù)據(jù),可變波特率
  5.         AUXR |= 0x01;                //串口1選擇定時器2為波特率發(fā)生器
  6.         AUXR |= 0x04;                //定時器2時鐘為Fosc,即1T
  7.         T2L = 0xE8;                //設(shè)定定時初值
  8.         T2H = 0xFF;                //設(shè)定定時初值
  9.         AUXR |= 0x10;                //啟動定時器2
  10. }


  11. void UART1SendByte(unsigned char TxD1)  
  12. {   
  13.     SBUF=TxD1;  
  14.     while(TI == 0);
  15.     TI=0;   
  16. }
復(fù)制代碼

串口通信實驗就算是完成了

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:94185 發(fā)表于 2016-2-5 18:05 來自手機 | 只看該作者
666
回復(fù)

使用道具 舉報

板凳
ID:104166 發(fā)表于 2016-2-5 22:12 | 只看該作者
4.      PWM驅(qū)動電機實驗
還是先上效果圖打算傳視頻來著,不過不會傳


先是逆時針加速再減速,后是順時針加速再減速。
是時候上代碼了
main.c:
  1. #include "all_header.h"
  2. //20MHZ
  3. void main()
  4. {        int i,temp=0;
  5.         PWMInit();
  6.         P2M0=0x02;      //芯片上電后所有與PWM相關(guān)的IO口均為高阻態(tài)
  7.         P2M1=0x00;        //將PWM2和PWM3IO 設(shè)置為強上拉(推挽)
  8.         P3M0=0x80;        //其余的P2P3口為弱上拉
  9.         P3M1=0x00;
  10.                 while(1)
  11.                 {        for(i=0;i<100;i++)//逆時針加速
  12.                         {
  13.                         temp+=200;
  14.                         PWM2T1=20000-temp;
  15.                         Delay25ms();
  16.                         }
  17.                         for(i=0;i<100;i++)//逆時針減速
  18.                         {
  19.                         temp-=200;
  20.                         PWM2T1=20000-temp;
  21.                         Delay25ms();
  22.                         }//上面的兩個循環(huán)執(zhí)行完后,PWM2T1=20000就不用再重新賦值了
  23.                         for(i=0;i<100;i++)//順時針加速
  24.                         {
  25.                         temp+=200;
  26.                         PWM3T1=20000-temp;
  27.                         Delay25ms();
  28.                         }
  29.                         for(i=0;i<100;i++)//順時針減速
  30.                         {
  31.                         temp-=200;
  32.                         PWM3T1=20000-temp;
  33.                         Delay25ms();
  34.                         }
  35.                 }
  36. }
復(fù)制代碼
pwm.c:
  1. #include "PWM.h"
  2. void PWMInit()
  3. {
  4.         P_SW2|=0x80;                                    //使能訪問XSFR
  5.         PWMCFG = 0x00;          //配置PWM初始化電平為低電平
  6.         PWMCKS = 0x00;          //選擇PWM的時鐘為Fosc/(0+1)=20M
  7.         PWMC = 20001;                //設(shè)置PWM周期 PWM頻率為 PWM時鐘頻率(上行代碼)20M/20001=1k
  8.        
  9.         PWM2T1 = 20000;                //設(shè)置PWM2第一次反轉(zhuǎn)的PWM計數(shù)
  10.         PWM2T2 = 20001;                //設(shè)置PWM2第二次反轉(zhuǎn)的PWM計數(shù)

  11.         PWM3T1 = 20000;                 
  12.         PWM3T2 = 20001;
  13.        
  14.         PWM2CR=0x00;                 //輸出管腳為P3.7 無PWM中斷,無PWM反轉(zhuǎn)中斷
  15.         PWM3CR=0x00;                //輸出管腳為P2.1 無PWM中斷,無PWM反轉(zhuǎn)中斷
  16.         PWMCR |= 0x03;                //使能PWM2 PWM3輸出
  17.         PWMCR |= 0x80;          //使能PWM博興發(fā)生器,PWM計數(shù)器開始計數(shù)
復(fù)制代碼
就貼出這兩個主要的代碼吧!全部代碼打包!
PWM驅(qū)動電機實驗.zip (41 KB, 下載次數(shù): 12)

回復(fù)

使用道具 舉報

地板
ID:104166 發(fā)表于 2016-2-6 00:20 | 只看該作者
bjyxyc 發(fā)表于 2016-2-6 00:03
用什么型號的芯片呢

IPA15w4k61s4
回復(fù)

使用道具 舉報

5#
ID:104166 發(fā)表于 2016-2-21 16:36 | 只看該作者
5.      編碼器數(shù)據(jù)采集實驗

先上一張速度圖像(用的wps表格畫的)



這是在2.5秒內(nèi)加速到最大,延遲300毫秒,再在2.5秒內(nèi)減速的圖像,一共兩個這樣的過程。
如何采集速度:
電機上有霍爾編碼器:電機轉(zhuǎn)一圈回輸出11個左右的脈沖(脈沖個數(shù)有編碼器決定),通過配置單片機的定時器3和定時器4,使其對外部脈沖計數(shù),配置定時器1使其每隔8毫秒讀出脈沖來,再通過串口發(fā)給電腦,這樣就采集到了速度。
配置定時器1的代碼:
  1. void Timer1Init(void)                //8毫秒@20.000MHz
  2. {
  3.         AUXR &= 0xBF;                //定時器時鐘12T模式
  4.         TMOD &= 0x0F;                //設(shè)置定時器模式
  5.         TL1 = 0xEB;                //設(shè)置定時初值
  6.         TH1 = 0xCB;                //設(shè)置定時初值
  7.         TF1 = 0;                //清除TF1標(biāo)志
  8.         TR1 = 1;                //定時器1開始計時
  9.         ET1 = 1;                //允許定時器1中斷

  10. }
復(fù)制代碼
配置定時器3、4的代碼:
  1. void Timer_3_4_Init(void)
  2. {

  3.   T4T3M |= 0xCC;        //允許定時器3、4運行對外部脈沖計數(shù)
  4.   IE2 &= 0x1F;        //進(jìn)制定時器3、4產(chǎn)生中斷
  5. }
復(fù)制代碼

主函數(shù)MAIN和定時器1中斷代碼:
  1. #include "all_header.h"
  2. //20M晶振
  3. int num=0;
  4. void main()
  5. {        int i,temp=0;
  6.         PWMInit();        //PWM初始化
  7.         Uart1Init();        //串口1初始化
  8.         Timer1Init();        //定時器1初始化
  9.         Timer_3_4_Init();//定時器3 4初始化
  10.         P2M0=0x02;      //芯片上電后所有與PWM相關(guān)的IO口均為高阻態(tài)
  11.         P2M1=0x00;        //將PWM2和PWM3所在的IO口設(shè)置為強上拉(推挽)
  12.         P3M0=0x80;        //取余的P2P3口為弱上拉(準(zhǔn)雙向扣)
  13.         P3M1=0x00;
  14.         EA=1;                //允許總中斷
  15.         T3L=0;
  16.         T3H=0;
  17.                 while(1)
  18.                 {        for(i=0;i<100;i++)//正傳加速
  19.                         {
  20.                         temp+=200;
  21.                         PWM2T1=20000-temp;
  22.                         Delay25ms();
  23.                         }
  24.                         Delay300ms();//延遲300毫秒
  25.                         for(i=0;i<100;i++)//正傳減速
  26.                         {
  27.                         temp-=200;
  28.                         PWM2T1=20000-temp;
  29.                         Delay25ms();
  30.                         }
  31.                 }
  32. }

  33. void Timer1_Int() interrupt 3
  34. {
  35.         num=(T3H<<8)+T3L; //獲取脈沖個數(shù)
  36.         T4T3M&=        0x77;        //關(guān)閉定時器3、4
  37.         T3H=T3L=0;        //脈沖個數(shù)清零
  38.         T4T3M |= 0xCC;        //將定時器3、4做計數(shù)用并開啟定時器3、4
  39.         UART1SendByte(num);//發(fā)送num低8位(8毫秒內(nèi)最大在17左右,num的低8位計數(shù)就夠)
  40. }
復(fù)制代碼

實驗所有代碼: 編碼器數(shù)據(jù)采集.zip (45.88 KB, 下載次數(shù): 12)


回復(fù)

使用道具 舉報

6#
ID:104166 發(fā)表于 2016-2-21 23:23 | 只看該作者
6.傳感器數(shù)據(jù)采集實驗
還是先上一張圖

上圖是我找了一個認(rèn)為平衡時,陀螺儀輸出的原始數(shù)據(jù),可以大致認(rèn)為Y軸加速度的零點漂移大約為-390,X軸角速度零點漂移大約為-17。
如何得到的這些數(shù)據(jù):
      MPU6050是一個可以測加速度和角速度的6軸傳感器(里面還有一個溫度傳感器),單片機通過IIC協(xié)議和MPU6050通信,配置MPU6050,定時通信讀出數(shù)據(jù),將這些數(shù)據(jù)通過串口1發(fā)送給電腦。
下面是配置MPU6050的代碼:
  1. void InitMPU6050()
  2. {
  3.         Single_WriteI2C(PWR_MGMT_1, 0x00);        //正常啟用
  4.         Single_WriteI2C(SMPLRT_DIV, 0x07);        //采樣率 = 陀螺儀的輸出率 / (1 + SMPLRT_DIV)
  5.         Single_WriteI2C(CONFIG, 0x04);                //Accelerometer:21hz 8.5ms ; Gyroscope:20hz 8.3ms
  6.         Single_WriteI2C(GYRO_CONFIG, 0x18);        //+-2000°/s
  7.         Single_WriteI2C(ACCEL_CONFIG, 0x00);        //+-2g不自檢
  8. }
復(fù)制代碼
讀取數(shù)據(jù)的代碼:

  1. int GetData(unsigned char REG_Address)
  2. {
  3.         unsigned int H;
  4.         unsigned char L;
  5.         H=Single_ReadI2C(REG_Address);
  6.         L=Single_ReadI2C(REG_Address+1);
  7.         return (H<<8)+L;   //和成數(shù)據(jù)
  8. }
復(fù)制代碼
MPU6050常用寄存器:

  1. //****************************************
  2. //定義MPU6050內(nèi)部寄存器地址
  3. //****************************************

  4. #define        SMPLRT_DIV                0x19        //陀螺儀采樣率0x07(125Hz)
  5. #define        CONFIG                        0x1A        //低通濾波頻率
  6. #define        GYRO_CONFIG                0x1B        //陀螺儀自檢及測量范圍
  7. #define        ACCEL_CONFIG        0x1C        //加速度自檢測量范圍
  8. #define        ACCEL_XOUT_H        0x3B
  9. #define        ACCEL_XOUT_L        0x3C
  10. #define        ACCEL_YOUT_H        0x3D
  11. #define        ACCEL_YOUT_L        0x3E
  12. #define        ACCEL_ZOUT_H        0x3F
  13. #define        ACCEL_ZOUT_L        0x40
  14. #define        TEMP_OUT_H                0x41
  15. #define        TEMP_OUT_L                0x42
  16. #define        GYRO_XOUT_H                0x43
  17. #define        GYRO_XOUT_L                0x44       
  18. #define        GYRO_YOUT_H                0x45
  19. #define        GYRO_YOUT_L                0x46
  20. #define        GYRO_ZOUT_H                0x47
  21. #define        GYRO_ZOUT_L                0x48
  22. #define        PWR_MGMT_1                0x6B        //電源管理 0x00正常啟用
復(fù)制代碼

IIC的代碼就不貼啦,最后打包。

主函數(shù)MAIN代碼
  1. #include "all_header.h"
  2. //20M晶振
  3. int ACCEL,GYRO;
  4. void main()
  5. {       
  6. //設(shè)置所有IO口為弱上拉
  7.         P1M0=0x00;
  8.         P1M1=0x00;
  9.         P2M0=0x00;
  10.         P2M1=0x00;
  11.         P3M0=0x00;
  12.         P3M1=0x00;
  13.         P4M0=0x00;
  14.         P4M1=0x00;
  15.         P5M0=0x00;
  16.         P5M1=0x00;
  17.         Uart1Init();        //串口1初始化
  18.         Timer1Init();        //定時器1初始化8ms中斷

  19.         InitMPU6050();        //初始化MPU6050
  20.         Delay300ms();
  21.                 EA=1;        開總中斷
  22.                 while(1)
  23.                 {       
  24.                 }
  25. }

  26. void Timer1_Int() interrupt 3        //定時器18ms中斷
  27. {
  28.        
  29.         ACCEL=GetData(ACCEL_YOUT_H);        //讀取Y軸加速度
  30.         GYRO=GetData(GYRO_XOUT_H);        //讀取X軸角速度
  31.         UART1SendByte(ACCEL);                //發(fā)送加速度低八位
  32.         UART1SendByte(ACCEL>>8);        //發(fā)送加速度高八位
  33.         UART1SendByte(GYRO);
  34.         UART1SendByte(GYRO>>8);
  35. }
復(fù)制代碼
本實驗代碼 傳感器數(shù)據(jù)采集.zip (53.16 KB, 下載次數(shù): 9)


回復(fù)

使用道具 舉報

7#
ID:77578 發(fā)表于 2016-2-23 20:36 | 只看該作者
你串口助手很好啊,是什么?
回復(fù)

使用道具 舉報

8#
ID:104166 發(fā)表于 2016-2-23 22:31 | 只看該作者
moyuqilin 發(fā)表于 2016-2-23 20:36
你串口助手很好啊,是什么?

為了看數(shù)據(jù)方便,就動手寫了這么個不能再簡陋的助手。
回復(fù)

使用道具 舉報

9#
ID:104166 發(fā)表于 2016-2-24 17:09 | 只看該作者
7.      無線通訊實驗(藍(lán)牙)沒有nRF24l0(不會玩,以后得鼓搗鼓搗),而且小車上有藍(lán)牙,就用藍(lán)牙啦
先上圖


左邊用的是手機藍(lán)牙串口助手,發(fā)送的 hello world,右邊在電腦串口助手接收到的。一共用了單片機上的2個串口,串口2和藍(lán)牙相連接,串口1和電腦連接。在電腦上選好串口號和波特率校驗位,停止位,燒寫上程序就可以通信啦。
數(shù)據(jù)流向:手機藍(lán)牙-->藍(lán)牙模塊-->單片機串口2-->串口1-->電腦串口助手。感覺實際上還是串口通信,藍(lán)牙默認(rèn)的波特率是115200,名稱是HMSoft,喵大應(yīng)該是提前設(shè)置好了,通過命令可以更改藍(lán)牙的一些參數(shù)。
下面是代碼:
串口1 、2初始化代碼:

  1. void Uart1Init(void)                //115200bps@20.000MHz
  2. {
  3.         SCON = 0x50;
  4.         AUXR |= 0x01;
  5.         AUXR |= 0x04;       
  6.         T2L = 0xD5;
  7.         T2H = 0xFF;
  8.         AUXR |= 0x10;
  9.         ES=1;
  10. }
  11. void Uart2Init(void)                //115200bps@20.000MHz
  12. {
  13.         S2CON = 0x50;                //8位數(shù)據(jù),可變波特率
  14.         AUXR |= 0x04;                //定時器2時鐘為Fosc,即1T
  15.         T2L = 0xD5;                //設(shè)定定時初值
  16.         T2H = 0xFF;                //設(shè)定定時初值
  17.         AUXR |= 0x10;                //啟動定時器2
  18.         IE2 |=0x01;                /允許定時器2中斷
  19. }
復(fù)制代碼

串口1發(fā)送數(shù)據(jù)代碼:

  1. void UART1SendByte(unsigned char TxD1)  
  2. {   
  3.     SBUF=TxD1;  
  4.     while(TI == 0);//等待發(fā)送完成
  5.     TI=0;   
  6. }
復(fù)制代碼

Main代碼:

  1. #include "all_header.h"
  2. //20MH
  3. void main()
  4. {               

  5.         //P13 I/O口設(shè)置為弱上拉
  6.         P1M0=0x00;
  7.         P1M1=0x00;
  8.         P3M0=0x00;
  9.         P3M1=0x00;
  10.         Uart1Init();
  11.         Uart2Init();
  12.         EA=1;
  13.                 while(1);
  14. }
  15. void  Interrupt_Uart2(void) interrupt  8 using 1         //125hz
  16. {
  17.         if(S2CON & 0x01)
  18.         {
  19.                 S2CON&=~0x01;
  20.                 UART1SendByte(S2BUF);
  21.         }
  22. }
復(fù)制代碼
無線通訊實驗就算完成啦




閃亮.gif (667.5 KB, 下載次數(shù): 282)

閃亮.gif

長亮.gif (311.88 KB, 下載次數(shù): 254)

長亮.gif
回復(fù)

使用道具 舉報

10#
ID:104166 發(fā)表于 2016-2-26 01:10 | 只看該作者
進(jìn)階實驗:

1.     多傳感器數(shù)據(jù)融合



看了喵大和網(wǎng)上的資料,用互補濾波進(jìn)行數(shù)據(jù)融合就可以滿足,但要調(diào)節(jié)好比例權(quán)重(不知道這樣說有沒有為題),我用的也是互補濾波。
下面就是我所觀察到的實驗結(jié)果:(紅色線為融合后的數(shù)據(jù),黑色線為由加速度算出的角度,縱軸的單位就是度,一個像素代表1度,我沒有軟件中寫坐標(biāo))

圖1:
圖1是加速度比例權(quán)重(此圖為0.1)比較大的圖像,其代碼為CarAngle=0.9*(CarAngle+GyroSpeed*0.008)+0.1*AccelAngle;
小車稍微有點震動,加速度就會變化,但是車體的角度并沒有變化,微小的晃動是噪聲,所以由加速度算出來的角度也會有很多噪聲,加速度權(quán)重過大,就會摻雜更多的噪聲,不能反應(yīng)真實的車體角度。
圖2是車體直立突然到向一個方向,待一會,然后直立,再反相倒的車體角度的圖像。圖中的那些突起的黑線,是轉(zhuǎn)小車時突然停止產(chǎn)生的,車體的角度并沒有那樣的突變(先變大在減。,車體角度而只是增大然后突然不變,在由于加速度比例權(quán)重過大,可以看到融合后的圖像(紅色線)也不能真實反應(yīng)車體的角度。
圖2:
圖2是加速度比例權(quán)重適當(dāng)(此圖為0.005)的數(shù)據(jù)融合圖像。其代碼為CarAngle=0.995*(CarAngle+GyroSpeed*0.008)+0.005*AccelAngle;

可以看到在那些黑線突起地方,紅線也平滑的變化,能夠反應(yīng)真實的車體角度變化。
圖3:
圖3是車體一開始就有一定的傾斜角的情況下供電的圖像(剛開始時黑色線(也就是由加速度算出的角度)能夠反應(yīng)車體的真是角度),進(jìn)行數(shù)據(jù)融合之前沒有給車體角度賦初值(就是先先將由加速度算出的角度賦給車體角度變量)就會出現(xiàn)這樣的情況。在代碼中有賦初值的注釋。
圖4:
圖4是進(jìn)行數(shù)據(jù)融合之前,給車體角度賦初值得圖像,在剛開始的圖像部分,黑色線被紅色先覆蓋了。這樣無論小車在什么角度開機,總能夠確保一開機融合后的角度都是正確的。
下面是MAIN代碼:
  1. #include "all_header.h"
  2. //20MHz
  3. int AccelData;
  4. int GyrolData;
  5. float AccelAngle;
  6. float GyroSpeed;
  7. float CarAngle;
  8. float GyroAngle;
  9. int temp;
  10. void main()
  11. {       
  12.         //設(shè)置所有IO口為準(zhǔn)雙向口
  13.         P0M0=0x00;
  14.         P0M1=0x00;
  15.         P1M0=0x00;
  16.         P1M1=0x00;
  17.         P2M0=0x00;
  18.         P2M1=0x00;
  19.         P3M0=0x00;
  20.         P3M1=0x00;
  21.         P4M0=0x00;
  22.         P4M1=0x00;
  23.         P5M0=0x00;
  24.         P5M1=0x00;
  25.         InitMPU6050();//MPU6050初始化
  26.         Delay300ms();
  27.         Uart1Init();//串口1初始化
  28.         AccelData=GetData(ACCEL_YOUT_H);
  29.         AccelAngle=(float)(AccelData-370)/16384.0f;
  30.         //I在此先將由加速度算出的角度給CarAngle,
  31.         //來確保一開機,融合后的角度就是正確的。
  32.         CarAngle=AccelAngle*57.2957795f;
  33.         Timer1Init();//定時器1初始化
  34.         Delay300ms();
  35.         EA=1;
  36.                 while(1);
  37. }
  38. void  Interrupt_Timer1(void) interrupt  3         //125hz
  39. {
  40.         AccelData=GetData(ACCEL_YOUT_H);        //獲取Y軸加速度
  41.         GyrolData=GetData(GYRO_XOUT_H);                //獲取X軸角速度
  42.         AccelAngle=(float)(AccelData-370)/16384.0f;//出去零點偏移,就是你得到角度(單位是弧度)
  43.         AccelAngle=AccelAngle*57.2957795f;// 180/3.1415926535898弧度轉(zhuǎn)換為度
  44.         temp=(int)AccelAngle;                //強制轉(zhuǎn)換為整形量
  45.         UART1SendByte(temp);                //發(fā)低八位
  46.         UART1SendByte(temp>>8);        //發(fā)高八位
  47.         GyroSpeed=(float)(GyrolData-(-17))/16.4f;
  48.         CarAngle=0.995*(CarAngle+GyroSpeed*0.008)+0.005*AccelAngle;//互補濾波
  49.         temp=(int)CarAngle;
  50.         UART1SendByte(temp);
  51.         UART1SendByte(temp>>8);
  52. }
復(fù)制代碼

實驗代碼: 數(shù)據(jù)融合.zip (51.21 KB, 下載次數(shù): 7)
回復(fù)

使用道具 舉報

11#
ID:94185 發(fā)表于 2016-2-27 17:47 | 只看該作者
寧靜清幽 發(fā)表于 2016-2-26 01:10
進(jìn)階實驗:

1.     多傳感器數(shù)據(jù)融合

非常好。繼續(xù)加油。把小車都學(xué)透~
回復(fù)

使用道具 舉報

12#
ID:79544 發(fā)表于 2016-3-8 10:37 | 只看該作者
真是高手,佩服啊,長見識啦,謝謝分享
回復(fù)

使用道具 舉報

13#
ID:104166 發(fā)表于 2016-3-9 21:35 | 只看該作者
騰飛的龍 發(fā)表于 2016-3-8 10:37
真是高手,佩服啊,長見識啦,謝謝分享

啥高手,參數(shù)調(diào)不好,上面的都是跟著喵大學(xué)的!
回復(fù)

使用道具 舉報

14#
ID:104166 發(fā)表于 2016-3-24 12:55 | 只看該作者
進(jìn)階實驗

2.     PID調(diào)試

關(guān)于小車PID的調(diào)試,也在網(wǎng)上找了好多資料,也看了喵大的角度環(huán)視頻,調(diào)試經(jīng)驗有從網(wǎng)上學(xué)的也有些自己簡單的體會。
原來沒接觸的時候也是一頭霧水(畢竟不是學(xué)自控的孩子),后來在網(wǎng)上搜了一些資料,對這些基本概念也有了大概的了解,下面說一下我對PID的了解吧!1)我對PID的理解:PID分增量式和位置式,增量式的計算結(jié)果是在上一次的控制量基礎(chǔ)上需要增加的量,或減少的量;位置式的每一次計算都是一個新的控制量的大小,而不是增加量,也不知道這說對不對(表達(dá)能力有限)。喵大的貌似是位置式,我的代碼也是參考喵大的。PID控制一定要有反饋,要不然何談控制(有點像廢話)。PID控制就是比例P、積分I、微分控制D,這些運算是對于偏差來說的。    (1)比例運算:對偏差進(jìn)行比例運算,就是偏差乘上一個系數(shù),把這個偏差放大或縮小,對于平衡小車角度環(huán)來說,偏差角度=目標(biāo)角度-當(dāng)前角度,目標(biāo)角度就是平衡時候的角度,就是0嘍,比例控制量=偏差*比例系數(shù),偏差大了,就是小車傾斜程度大了,我們給小車的電機大點電壓,使小車加速運動,來減小偏差,從而使小車趨向平衡,同理,偏差小,給電機的電壓小點,這就是比例控制,比例參數(shù)過小,小車“沒勁”,不能抵消自身重力,太大的話,大幅度搖擺太厲害。
    (2)積分運算:對偏差進(jìn)行積分,就是把偏差進(jìn)行累加,偏差和=偏差和+偏差*積分系數(shù);只要出現(xiàn)偏差,通過累加就會使偏差和變大,我們給電機的電壓就要大,來使小車趨向平衡,直到偏差和為零的時候,積分這一部分對電壓控制沒有貢獻(xiàn)。相對于比例參數(shù)來說,積分系數(shù)是很小的,但積分系數(shù)過小累加和變化不明顯,控制也就不明顯,過大,即出現(xiàn)了一個很小的誤差,通過積分系數(shù)放大了好多,累加和也會變得很大,使系統(tǒng)不穩(wěn)定。
    (3)微分控制:就是偏差對時間求導(dǎo),得到的是偏差的變化率。對于小車的角度環(huán)來說偏差d=C-f(t);C就是我們目標(biāo)角度,是一個恒定值,一般是0,f(t)是當(dāng)前的角度值,偏差d對時間求導(dǎo)=常數(shù)C對時間求導(dǎo)+f(t)對時間求導(dǎo),常數(shù)的導(dǎo)數(shù)是0,所以偏差d對時間求導(dǎo)相當(dāng)于角度對時間求導(dǎo),得到的是角速度,角速度可以直接從陀螺儀上面獲取,就不用我們運算了,不過我們注意角速度的正負(fù)號。角速度的正負(fù)號代表小車像前還是向后倒下了,可以自己規(guī)定。角速度的絕對值代表小車倒下的速度,小車倒下的速度越快,我們就要給小車電機更大的電壓,來抵消小車倒下,微分控制起到加快調(diào)節(jié)的作用。微分控制量=角速度*微分系數(shù),我們把角速度乘以一個系數(shù)(也就是微分系數(shù))就得到微分控制部分的控制量的大小了。微分系數(shù)太小也不能抵消小車的倒下,太大了會使小車小幅度高頻震蕩,容易燒驅(qū)動。
以上只是我的簡單理解,有什么不對或者不全的地方還請大家指出,共同進(jìn)步。
2)調(diào)試
關(guān)于平衡車的控制,用到了兩個環(huán)的控制,分別是角度環(huán)和速度環(huán),角度環(huán)用PD,速度環(huán)用PI,在只有角度環(huán)的時候我也用過PID,以可以達(dá)到平衡,但是由于沒有速度環(huán),小車不一定跑到哪了。
寫一下主要的公式:

    角度環(huán):角度偏差d_Angle=SetAngle-CarAngle;     AngleCtrlOut=d_Angle*P_Angle+w*D_Angle;    w是角速度,在這之前還要對小車的角度進(jìn)行濾波,前面的實驗有過介紹,AngleCtrlOut是角度環(huán)的PWM輸出
    速度環(huán):速度偏差d_Speed=SetSpeed-CarSeed;  Car_I=Car_I+d_Speed*I_Speed;    SpeedCtrlOut=d_Speed*P_Speed+CarI;  SpeedCtrlOut是速度環(huán)的PWM輸出。這些系數(shù)與單片機PWM的最大量有關(guān)系,比如單片機PWM的最大量是10000;在調(diào)角度環(huán)的時候一般是先讓微分系數(shù)D_Angle=0,先只調(diào)比例系數(shù),這樣AngleCtrlOut=d_Angle*P_Angl;當(dāng)偏差角度 d_Angle=10度,比例系數(shù)P_Angle=10,AngleCtrlOut才=100,小車PWM輸出占PWM最大量的1%,理論上小車電機的轉(zhuǎn)速為最快轉(zhuǎn)速的1%(實際上達(dá)不到,也有可能死區(qū)電壓都沒過),這樣小車沒有足夠的加速度來克服重力使車達(dá)到平衡。比例系數(shù)P_Angle還需要調(diào)大。但是當(dāng)單片機PWM的最大量是256的時候,偏差角度 d_Angle=10度,比例系數(shù)P_Angle=10的時候,AngleCtrlOut還是=100,約占PWM最大量的39%,這個系數(shù)可能還靠點譜,所以說這些系數(shù)PWM最大量是有關(guān)系的。
    調(diào)試這些系數(shù)的過程:先調(diào)角度環(huán),再速度環(huán)。關(guān)于反饋類型說的文鄒鄒點:角度環(huán)是負(fù)反饋,速度環(huán)是正反饋。說的通俗點:角度環(huán)中,偏差角度變大時,小車要控制偏差角度減小,就是讓車輪朝著倒下的方向加速轉(zhuǎn)。速度環(huán)中,速度變大,我們得給小車更快的速度,讓小車追上自己,保持平衡。在調(diào)試的時候,可以分別調(diào)一下兩個環(huán),注意參數(shù)的正負(fù),保證每個環(huán),都是使車輪朝向小車傾斜的方向轉(zhuǎn)就行了,在只有速度環(huán)時,手動轉(zhuǎn)一個車輪,另一個車輪會慢慢轉(zhuǎn)起來,最終兩個車輪越轉(zhuǎn)越快。
    調(diào)角度環(huán)時,一般是先讓微分系數(shù)D_Angle=0,先只調(diào)比例系數(shù),調(diào)到能使小車站起來,在平衡位置來回的擺動,再稍微增加比例系數(shù),加入微分系數(shù)D_Angle,微分系數(shù)D_Angle從小到大。調(diào)到小車能夠比較穩(wěn)定的平衡,這時候,你輕推小車,小車會朝著一個方向加速跑過去,直至倒下。這個也是正常的,當(dāng)然小車能接近平衡跑的越遠(yuǎn)說明參數(shù)越好,加入速度環(huán)可以解決這個問題,如果不加速度環(huán),在角度環(huán)里面加入對偏差的積分(累加偏差),也能使小車平衡。只是對小車的速度沒法控制。
    調(diào)速度環(huán)時,一般是先讓積分系數(shù)I_Speed=0,先只調(diào)比例系數(shù),由0開始增加,調(diào)到你推一下小車,小車能有足夠的加速度來使小車保持平衡,這時小車新的平衡位置不再原地了,感覺小車能夠很好的保持平衡之后,這時再加速度積分,加入速度積分后,小車會趨向于原地平衡
    我的理解就是這些,有什么不對或者不全的還請大家指出來,一塊討論共同學(xué)習(xí)哈。我自己感覺對于車速控制的理解還不夠深,對于兩個車輪速度分別控制還有待加強。
    挺感謝喵大的這個平臺的,給我提供了學(xué)習(xí)平衡車基礎(chǔ),有機會讓我這樣的平衡車入門級玩家能從頭到尾深刻了解平衡車的原理。給這個網(wǎng)站平臺點個贊,給喵大的開源精神點個贊,給喵大的熱心腸點個贊。
    本想弄點圖片的,電池,又讓我弄過放了,廢了,平衡充接電池的時候,接反了一下,燈不亮了,平衡沖也出問題了。唉我勒個去,我也是被自己整無語了。在下個實驗中在上圖片吧。

回復(fù)

使用道具 舉報

15#
ID:104166 發(fā)表于 2016-4-16 23:09 | 只看該作者
進(jìn)階實驗
3.     實現(xiàn)平衡小車直立時處于靜止?fàn)顟B(tài)
下面兩個圖片是小車靜止時受到干擾后小車運動的圖片

第一張圖的速度環(huán)是用的PI,第張圖用的是PD,可以看到第一張圖中:用手推車,車會回到原來的位置;第二張圖中:用手推車則不會會到原來的位置。下面是代碼:

  1. Speed_Least=(float)(g_iLeftMotorPluseSigma+g_iRightMotorPluseSigma)/2.0;//獲取速度

  2. g_iRightMotorPluseSigma=g_iLeftMotorPluseSigma=0;//速度清零
  3. g_fCarSpeed=Speed_Least*0.75+g_fCarSpeed*0.25;//速度濾波
  4. fDelta = g_iCarSpeedSet;//此處全局整形目標(biāo)車速 g_iCarSpeedSet為零
  5. fDelta -= g_fCarSpeed;//得到速度偏差
  6. fP = fDelta*g_fcSpeed_P;//速度偏差乘上比例系數(shù)


復(fù)制代碼
上面代碼是兩個車速度環(huán)的公共代碼。

下面是第一個圖片中PI速度環(huán)的代碼:

  1. fI = fDelta*g_fcSpeed_I;速度偏差乘上積分系數(shù)
  2. g_fCarPosition += fI; //偏差累加,在開始初始化的時候g_fCarPosition是為零的
  3. /****************加入積分限幅*****************/
  4. if(g_fCarPosition>20000)g_fCarPosition=20000;
  5. if(g_fCarPosition<-20000)g_fCarPosition=-20000;
  6. /*********************************************/
  7. g_fSpeedCtrlOut = fP+g_fCarPosition;//速度環(huán)控制量輸出
復(fù)制代碼

下面是第二個圖片中PD速度環(huán)的代碼:

  1. fD = (fDelta-g_fcSpeedDerta)*g_fcSpeed_D;//得到速度的變化率
  2. g_fSpeedCtrlOut = fP+fD;<span style="line-height: 1.5;">//速度環(huán)控制量輸出</span>
復(fù)制代碼

所有代碼: 所有代碼.zip (144.52 KB, 下載次數(shù): 36)
附件里的代碼跟喵大的差不多,我是照著喵大的代碼敲的,不過我的這個有些地方比較難看。我剛開始看喵大的代碼的時候,看著也頭大,后來我就先看程序名,看看這個程序的流程;看個大概了,之后再了解程序的細(xì)節(jié),死扣每一句,之后慢慢理解了小車。

由衷感謝喵大的這個平臺,讓我學(xué)到了平衡小車的知識,感謝,感謝,感謝。


靜止1.gif (3.48 MB, 下載次數(shù): 180)

靜止1

靜止1
回復(fù)

使用道具 舉報

16#
ID:102157 發(fā)表于 2016-4-21 10:47 | 只看該作者
厲害,大神,請接下我的膝蓋你做了轉(zhuǎn)向沒?
回復(fù)

使用道具 舉報

17#
ID:114829 發(fā)表于 2016-5-4 12:43 | 只看該作者
樓主能否給我一份具體的資料啊  ?
回復(fù)

使用道具 舉報

18#
ID:145818 發(fā)表于 2016-11-2 22:11 | 只看該作者
不錯!。!值得學(xué)習(xí)!
回復(fù)

使用道具 舉報

19#
ID:200681 發(fā)表于 2017-5-14 17:31 | 只看該作者
值得學(xué)習(xí)學(xué)習(xí),我也在做小車,希望最后能夠成功
回復(fù)

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日本一道本 | 日本黄色片免费在线观看 | 岛国毛片在线观看 | 久久久.com | 99久久精品国产一区二区三区 | 亚洲国产精品久久久久秋霞不卡 | 视频在线一区 | 视频在线h | 欧美日韩国产精品一区 | 蜜桃视频一区二区三区 | 亚洲精品中文字幕av | 日产精品久久久一区二区福利 | 欧美成人精品一区二区男人看 | 久久免费视频2 | 欧美黄视频 | 精品99在线 | 久久久精品视频一区二区三区 | 午夜视频网 | 亚洲成色777777在线观看影院 | 中文字幕在线视频观看 | 久久久www成人免费无遮挡大片 | 欧美电影免费网站 | 色在线看 | 热久久999| 亚洲精品久久久久久一区二区 | 国产亚洲高清视频 | 国产一区二区精品在线观看 | 久久综合av | 欧美美女爱爱 | avtt国产 | 欧美性生活免费 | 欧美精品 在线观看 | 国产一区二区免费 | 91麻豆精品国产91久久久更新资源速度超快 | 在线小视频| 免费视频一区二区 | 做a的各种视频 | 91精品国产一区 | 国产a区 | 久久久久久影院 | 国产亚洲日本精品 |