自平衡車主控為STM32f103r 平衡車硬件總體設計,平衡車以STM32為主控芯片,通過處理從各個傳感器返回的數據使小車達到動態平衡以及遙控的實現。 平衡車的軟件結構分為四大部分,各個部分之間相互關聯。軟件總體結構:OLED顯示實時數據、按鍵調試各項參數部分;串口和超聲波部分解析有關指令部分;PID控制器輸出控制部分。在串口和超聲波部分獲取控制指令后,傳輸給PID控制器,最終由PID計算控制器輸出相應PWM值控制電機,以保持平衡車的平衡。主控芯片在接收MPU6050傳感器返回的角度值與角加速度值后,對返回數據進行一階互補濾波處理。一階互補濾波算法將角度數據進行融合,降低MPU6050傳感器的噪聲信號的影響,從而得到準確的平衡車當前姿態。STM32主控芯片通過直立的PD控制器得到較為準確的PWM輸出控制數值,控制電機轉動使得小車實現基本平衡。為了減小小車的左右偏移幅度,將MPU6050返回的Z軸轉動量輸出到轉向PD控制器進行計算,再將轉向PWM增量值與直立PWM增量進行疊加輸出,得到較為準確的PWM控制值,從而使小車保持直立狀態。在Android手機上安裝一個第三方藍牙遙控APP,由APP發出的相應控制指令。系統通過藍牙模塊接收控制指令,再由串口中斷接收藍牙模塊控制數據,之后系統進行控制指令的解析得到控制輸出值,控制小車前后左右的行駛動作。在實際的測試過程中,發現藍牙的有效控制距離為8米左右,并且手機與藍牙模塊的容易被各種因素干擾,使小車在控制距離較遠的位置失去控制。建議大家使用NRF或其它控制信號較遠的模塊進行通訊,從而實現相對較遠的距離控制。
單片機源程序如下:
- /******************** (C) COPYRIGHT 2014 POWSOS Team **************************
- * 文件名 :main.c
- * 描述 :
- * 實驗平臺:STM32F103RBT6
- * 庫版本 :ST3.5.0
- * 作者 : Powsos_Team
- * 版本 :V2.0
- * 日期 :2014.8.23
- * 修訂歷史:V2.0
- ******************************************************************************/
- #include "stm32f10x.h"
- #include "iic.h"
- #include "timer.h"
- #include "usart.h"
- #include "mpu6050.h"
- #include "filter.h"
- #include "calculate.h"
- #include "gpio.h"
- #include "time_test.h"
- #include "hc_sr04.h"
- #include "delay.h"
- #include <stdio.h>
- #include <math.h>
- //#define Debug
- #define GX_OFFSET 0x01
- #define AX_OFFSET 0x01
- #define AY_OFFSET 0x01
- #define AZ_OFFSET 0x01
- #define duoji_offset 120
- extern u8 duoji_flag;
- extern u8 duoji_cnt;
- extern u16 time;
- extern u8 duoji_pwm;
- u8 hcsr04_test_flag = 0;
- u8 receive_data;
- u8 flg_get_senor_data;
- u8 out[35] ={0x5f, 0x60, 0};
- u8 Duoji_direction = 1; /*1,前方,2:左邊 3:右邊,舵機*/
- u8 Move_direcetion = 1; /*1靜止 2,前方, 3,后退 4:左邊 5:右邊 小車運行方向*/
- u16 distance =0 ;
- int pulsewidth;
- float angle, angle_dot, f_angle, f_angle_dot;
- s16 temp;
- s16 gx, gy, gz, ax ,ay, az, temperature;
- #define FILTER_COUNT 16
- s16 gx_buf[FILTER_COUNT], ax_buf[FILTER_COUNT], ay_buf[FILTER_COUNT],az_buf[FILTER_COUNT];
- /******************************************************************************/
- void delay(u32 count)
- {
- for(; count != 0; count--);
- }
- /*************************************************
- 名稱:void acc_filter(void)
- 功能:加速度計數據濾波
- 輸入參數:據濾波后的數據
- 輸出參數:無
- 返回值: 無
- **************************************************/
- void acc_filter(void)
- {
- u8 i;
- s32 ax_sum = 0, ay_sum = 0, az_sum = 0;
- for(i = 1 ; i < FILTER_COUNT; i++)
- {
- ax_buf[i - 1] = ax_buf[i];
- ay_buf[i - 1] = ay_buf[i];
- az_buf[i - 1] = az_buf[i];
- }
- ax_buf[FILTER_COUNT - 1] = ax;
- ay_buf[FILTER_COUNT - 1] = ay;
- az_buf[FILTER_COUNT - 1] = az;
- for(i = 0 ; i < FILTER_COUNT; i++)
- {
- ax_sum += ax_buf[i];
- ay_sum += ay_buf[i];
- az_sum += az_buf[i];
- }
- ax = (s16)(ax_sum / FILTER_COUNT);
- ay = (s16)(ay_sum / FILTER_COUNT);
- az = (s16)(az_sum / FILTER_COUNT);
- }
- /* I/O口模擬輸出PWM控制舵機,50hz */
- void servopulse(int myangle)//定義一個脈沖函數
- {
- // EA = 0;
- // pulsewidth = (((myangle+duoji_offset)*25)+500)/1000;;// 舵機中心值可能會偏,修改20,做調整
- pulsewidth =myangle;
- }
- /*****************************************************************************/
- int main(void)
- {
- SystemInit();
- delay_init(72);
- gpio_init();
- delay(0x80000);
- usart_init();
- iic_init();
- timer_init();
- TIM1_Configuration();
- HCSR04_Init();
- motor_init();
- mpu6050_init();
- STOP_TIME;
- duoji_flag =1;
- duoji_cnt = 0;
- servopulse(3);/*上電將舵機放至中間*/
- while (1)
- {
- if(flg_get_senor_data)
- {
- flg_get_senor_data = 0;
- mpu6050_get_data(&gx, &gy, &gz, &ax, &ay , &az, &temperature);
- acc_filter();
- gx-= GX_OFFSET;
- ax -= AX_OFFSET;
- ay -= AY_OFFSET;
- az -= AZ_OFFSET;
- angle_dot = gx * GYRO_SCALE; //+-2000 0.060975 °/LSB //陀螺儀
- angle = atan(ay / sqrt(ax * ax + az * az ));
-
- angle = angle * 57.295780; //180/pi
- kalman_filter(angle, angle_dot, &f_angle, &f_angle_dot);// 加速度計計算的角度, 陀螺儀角速度 , 融合后的角度, 融合后的角速度
- receive_parameter(receive_data);
- pid(f_angle, f_angle_dot);
- #ifdef Debug
- temp = (s16)(f_angle * 100);
-
- out[2] = (u8)(gx >> 8);
- out[3] = (u8)(gx);
- out[4] = (u8)(gy >> 8);
- out[5] = (u8)(gy);
- out[6] = (u8)(gz >> 8);
- out[7] = (u8)(gz);
- out[8] = (u8)(ax >> 8);
- out[9] = (u8)(ax);
- out[10] = (u8)(ay >> 8);
- out[11] = (u8)(ay);
- out[12] = (u8)(az >> 8);
- out[13] = (u8)(az);
- out[14] = (u8)(temp >> 8);
- out[15] = (u8)(temp);
- USART_SendStringData(USART1,&out[0],16);
- #endif
-
-
- } //end if
-
-
- if(hcsr04_test_flag)
- {
- hcsr04_test_flag=0;
- measure_distance(receive_data);
-
- switch(Duoji_direction)
- {
- case Duoji_Front: USART_printf(USART2,"Front_distance: %d cm\r\n",distance);break;
- case Duoji_Left: USART_printf(USART2,"Left_distance: %d cm\r\n",distance);break;
- case Duoji_Right: USART_printf(USART2,"Right_distance: %d cm\r\n",distance);break;
- }
-
-
- }
- #if 0
- /*若前方距離小于100,并且小車行駛方向是往前的,此時小車需要停止*/
- if((distance<50)&&(Move_direcetion==Move_front))
- {
- receive_data ='s';
- }
-
- #endif
- }
-
- }
- /*****************END OF FILE************************************************************/
復制代碼
下載:
STM32平衡車程序+原理圖(步進電機).7z
(588.1 KB, 下載次數: 173)
2020-8-19 14:34 上傳
點擊文件名下載附件
|