基於Qt的wifi智能小車的制作(一)
好久不寫博客了,真的是有點慚愧了。翻開上一次的博客,到現在已經2個多月了,只能說是自己太懶惰了!忙是另一回事!趁今天晚上有點時間回顧下這一段時間的收獲以及做的一些東西,算是一份筆記,一遍以后能回想起。
首先說說開始做的一款wifi小車吧,一方面是因為個人的愛好,一方面算是其他原因。首先上幾張小車照片。
由於光線原因,可能不太清楚。一下是我的上位機,基於Qt的,總體感覺還是挺漂亮的,不過最主要的還是有美工的幫助了,在這里多謝這位美工了。(小車控制主界面)
再來一張配置控制協議。其中有視頻流地址、控制地址以及端口號,控制動作命令等等……
其實做這個小車根本沒有多少難度的,之所以要做也是自己的愛好罷了,今天在這里記錄下一些珍貴的東西,希望自己以后看到后能想起其中的過程,最讓人享受的還是做某一件東西的過程。希望高手最下留情。
1.下位機
下位機簡單來說就是利用stm32控制驅動小車做動作,不外乎前進、后退、左轉、右轉、停止,在加上雲台的上升,下降,左轉和右轉,實現的基本原理很簡單,使用的驅動的L298N,控制起來也最簡單;而雲台方向的控制就是利用PWM進行控制。
首先說說舵機的控制吧,這個用到了PWM,下車速度也是利用這個控制的。
舵機的相關原理
1)什么是舵機
在機器人機電控制系統中,舵機控制效果是性能的重要影響因素。舵機可以在微機電系統和航模中作為基本的輸出執行結構,其簡單的控制和輸出使得單片 機系統非常容易與之接口。舵機是一種位置(角度)伺服的驅動器,適用於那些需要不斷變化並可以保持的控制系統。
2)舵機工作原理
控制信號由接收機的通道進入信號調制芯片,獲得直流偏置電壓。它內部有一個基准電路,產生周期為 20ms,寬度為 1.5ms 的基准信號,將獲得的直流偏置電壓與電位器的電壓比較,獲得電壓差輸出。最后,電壓差的正負輸出到電機驅動芯片決定電機的正反轉。當電機轉速一定時,通過級聯減速齒輪帶動電位器旋轉,使得電壓差為 0,電機停止轉動。當然我們可以不用去了解它的具體工作原理,知道它的控制原理就夠了
3)舵機的控制
舵機的控制一般需要一個 20ms 左右的時機脈沖,該脈沖的高電平部分一般為0.5ms~2.5ms 范圍內的角度控制脈沖部分。以 180 度角度伺服為例,那么對應的控制關系為。
0.5ms-------------0 度
1.0ms-------------45 度
1.5ms-------------90 度
2.0ms-------------135 度
2.5ms-------------180 度
具體的描述如下圖所示:
4)實現程序代碼:硬件連接:雲台上下轉動舵機連接 VCC、 GND、 PB6;雲台左右轉動舵機連接 VCC、GND、 PB8
- <span style="font-size:18px;font-weight: normal;">#define ANGLE_000 2 //0 度
- #define ANGLE_045 10 //45 度
- #define ANGLE_090 15 //90 度
- #define ANGLE_135 20 //135 度
- #define ANGLE_180 28 //180 度
- /* 全局變量 */
- static u8 CloudStand_Horizontal_Line = 15; //雲台水平移動
- static u8 CloudStand_Vertical_Line = 15; //雲台垂直移動
- </span>
- <span style="font-size:18px;font-weight: normal;">/* TIM4 PWM 部分初始化, PWM 輸出初始化, arr 為自動重裝值; psc 為時鍾
- 預分頻數 */</span>
- <span style="font-size:18px;font-weight: normal;">
- static void TIM4_PWM_Init(u16 arr,u16 psc)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- TIM_OCInitTypeDef TIM_OCInitStructure;</span>
- <span style="font-size:18px;"><span style="font-weight: normal;">
- </span>下面切記兩個 APB 時鍾初始化,調用不同的初始化函數,有同學不注意,經常
- 在這里出問題</span><span style="font-size:18px;font-weight: normal;">。
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,
- ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
- //設置該引腳為復用輸出功能,輸出 TIM4 的 PWM 脈沖波形
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_8;
- //TIM_CH1 TIM_CH3
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- //復用推挽輸出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- //初始化 GPIO
- //初始化 TIM4
- TIM_TimeBaseStructure.TIM_Period = arr;
- //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值
- TIM_TimeBaseStructure.TIM_Prescaler = psc;
- //設置用來作為 TIMx 時鍾頻率除數的預分頻值
- TIM_TimeBaseStructure.TIM_ClockDivision = 0;
- //設置時鍾分割
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- //TIM 向上計數模式
- TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
- //根據 TIM_TimeBaseInitStruct 中指定的參數初始化 TIMx 的時間基數單位
- //初始化 TIM4 通道 1 PWM 模式
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
- //選擇定時器模式:TIM 脈沖寬度調制模式 2
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
- //正向通道有效
- TIM_OCInitStructure.TIM_Pulse = 300;
- //占空時間 總的周期為 20ms 占空時間為約為 1ms
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
- //輸出極性:TIM 輸出比較極性高
- 這 里 的 TIM_OC1Init 、 TIM_OC1PreloadConfig 、 TIM_OC3Init 、
- TIM_OC3PreloadConfig 的調用,庫函數已經將管腳和 TIM 的通道進行匹配,讀者一
- 定要與自己的配置符合。
- TIM_OC1Init(TIM4, &TIM_OCInitStructure);
- TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
- //使能預裝載寄存器
- //初始化 TIM4 通道 3 PWM 模式
- TIM_OC3Init(TIM4, &TIM_OCInitStructure);
- TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
- //使能預裝載寄存器
- TIM_ARRPreloadConfig(TIM4, ENABLE);
- TIM_Cmd(TIM4, ENABLE);
- //使能 TIM4
- CloudStand_Middle();
- }
- void CloudStand_Up(void)
- {
- if(CloudStand_Vertical_Line > ANGLE_000 +1 )
- {
- CloudStand_Vertical_Line--;
- TIM_SetCompare1(TIM4,CloudStand_Vertical_Line);
- 注意:這里的 TIM_SetCompare1、 TIM_SetCompare3 函數的調用,要與前面的
- 硬件連接管腳、 TIM 通道一致,因為本人此處為 TIM1 通道和 TIM3 通道,所以這里調用 TIM_SetCompare1、 TIM_SetCompare3 函數。 <span style="font-weight: normal;">
- //將上下轉動值與寄存器 1 中的值進行比較,左右轉動值和寄存器 3 中的值進
- 行比較
- }
- if(CloudStand_Vertical_Line == ANGLE_000 +1 )
- {
- CloudStand_Vertical_Line++;
- }
- }
- void CloudStand_Down(void)
- {
- if(CloudStand_Vertical_Line < ANGLE_180 -1 )
- {
- CloudStand_Vertical_Line++;
- TIM_SetCompare1(TIM4,CloudStand_Vertical_Line);
- }
- if(CloudStand_Vertical_Line == ANGLE_180 -1 )
- {
- CloudStand_Vertical_Line--;
- }
- }
- void CloudStand_Left(void)
- {
- if(CloudStand_Horizontal_Line > ANGLE_000 +1 )
- {
- CloudStand_Horizontal_Line--;
- TIM_SetCompare3(TIM4,CloudStand_Horizontal_Line);
- }
- if(CloudStand_Horizontal_Line == ANGLE_000 +1 )
- {
- CloudStand_Horizontal_Line++;
- }
- }
- void CloudStand_Right(void)
- {
- if(CloudStand_Horizontal_Line < ANGLE_180 -1 )
- CloudStand_Horizontal_Line++;
- TIM_SetCompare3(TIM4,CloudStand_Horizontal_Line);
- }
- if(CloudStand_Horizontal_Line == ANGLE_180 -1 )
- {
- CloudStand_Horizontal_Line--;
- }
- }
- void CloudStand_Middle(void)
- {
- CloudStand_Horizontal_Line = 15;
- CloudStand_Vertical_Line = 15;
- TIM_SetCompare1(TIM4,ANGLE_000);
- TIM_SetCompare3(TIM4,ANGLE_090);
- }
- void CloudStand_Init(void)
- {
- TIM4_PWM_Init(199,7199); //PWM 頻率 = 50Hz
- }
小車方向控制相關原理
小車的方向就是通過控制stm32管腳的電平的高低來驅動LM298N實現所要的功能。詳情看附件中的代碼。在這里就不做過多的介紹,介紹多了會被人說成……………………。
2.上位機
在下一篇中將重點記錄上位機功能的實現。