聚豐項(xiàng)目 > 四軸無人機(jī)姿態(tài)調(diào)整系統(tǒng)
隨著信息技術(shù)的高速發(fā)展,以傳感器為應(yīng)用的物聯(lián)網(wǎng)(IoT)得到了前所未有的發(fā)展, 物聯(lián)網(wǎng)產(chǎn)品應(yīng)用廣泛,市場規(guī)模巨大。主流傳感器中,又以位置、流量、氣體、濕度等傳感器備受市場青睞。 本項(xiàng)目是借助 IDT ZMID5201STKIT開發(fā)套件,利用ZMID520xMROT36001 Rotary Application Module模塊,將無人機(jī)飛行過程中的飛行方向偏移角發(fā)送給MCU,經(jīng)過MCU解析后,發(fā)送到NRF2401。通過NRF2401無線數(shù)據(jù)傳輸,最終將數(shù)據(jù)發(fā)送到手持設(shè)備上,可直觀的觀察到無人機(jī)姿態(tài)偏斜方向。 該項(xiàng)目的無人機(jī)具有一定的使用價值,可在科教、娛樂等領(lǐng)域應(yīng)用,在工業(yè)、民用安防、智慧城市建設(shè)方面具有一定的應(yīng)用價值,市場前景廣闊,在未來商業(yè)應(yīng)用方面潛力巨大。
llzhang
分享llzhang
團(tuán)隊(duì)成員
劉聽強(qiáng) 硬件工程師
1、主控芯片:STM32F103C8T6作為主控MCU,STM32F103C8T6采用
Corex-M3內(nèi)核,工作頻率可達(dá)到72MHz,20KB SRAM,共3個定時器和3個USART。48個LQFP引腳足夠外圍電路使用。如下圖所示。
圖1 主控芯片
2、電源部分:供電方案采用先升壓再降壓的方案,由于第一次使用1S的鋰離子電池,給四個空心杯進(jìn)行空載供電的時候,四軸啟動是沒有問題的。但是如果四個空心杯都帶上負(fù)載,如果瞬間提速到滿速,那么電池輸出電壓拉低到3V以下,如果不采用升壓方案,直接用電池給LDO供電,那LDO就會失效。所以通過升壓再降壓后給單片機(jī)系統(tǒng)供電是一個可行的方案,如下圖所示。
圖2 升壓電路部分
圖3 降壓電路部分
3、傳感器部分:MPU6050六軸傳感器芯片通過數(shù)據(jù)濾波處理把三軸陀螺儀數(shù)據(jù)和三軸加速度數(shù)據(jù)以及ZMID520xMROT36001 Rotary Application Module角度偏移數(shù)據(jù)引入MCU進(jìn)行IMU姿態(tài)解算,如下圖所示。
圖4 陀螺儀
4、四軸空心杯:無人機(jī)能否平穩(wěn)操控,主要在四個電機(jī)上,空心杯選的好,對應(yīng)姿態(tài)的穩(wěn)定有較大的幫助。當(dāng)然了驅(qū)動電機(jī)的MOS管上、陀螺儀上、PCB對四軸最終的效果也起到關(guān)鍵的作用。電機(jī)的頻率,會才生干擾的頻率點(diǎn),會使無人機(jī)振動較大不好控制。另外就是同一批次的電機(jī)性能差異很大,導(dǎo)致PID調(diào)節(jié)的輸出差異很大,最終會影響MOS管的壽命、電機(jī)壽命。空心杯電機(jī)使用SI2302這款MOS管進(jìn)行驅(qū)動,這是非常常見的一款MOS管,便宜又好用。如下圖所示。
圖5 空心杯(前)
5、射頻部分:采用NRF2401,這是一塊常用芯片,性能也是可以的,無線發(fā)射可以做到7dB,加上發(fā)射和接收端都采用陶瓷天線,可以達(dá)到50m的通訊距離。如果加上AP,那達(dá)到100米應(yīng)該沒有問題。通過兩個低成本的0歐電
阻對電源進(jìn)行了單點(diǎn)接地,防止電機(jī)回路的電流波動串進(jìn)射頻回路對射頻造成干擾。
圖7 射頻部分
6、燈光模塊:采用3個SOT23-3封裝的MOS管進(jìn)行開關(guān)控制,與MCU隔離電源。
7、遙控器電路:采用傳統(tǒng)的DBUS遙控器反向電路。
1、無線射頻傳輸部分代碼:
/**********************************************************************
配置NRF2401為RX模式,準(zhǔn)備開始接收數(shù)據(jù)
***********************************************************************/
void RX_Mode(void)
{
CE_LOW; //拉低CE,進(jìn)入待機(jī)模式,準(zhǔn)備開始往NRF2401中的寄存器中寫入數(shù)據(jù)
SPI_Write_Byte(WRITE_REG_CMD + CONFIG, 0x0f); //配置為接收模式
SPI_Write_Byte(WRITE_REG_CMD + STATUS, 0x7e); //寫0111 xxxx 給STATUS,清除所有中斷標(biāo)志,防止一進(jìn)入接收模式就觸發(fā)中斷
CE_HIGH; //拉高CE,準(zhǔn)備接受從外部發(fā)送過來的數(shù)據(jù)
}
/**********************************************************************
從NRF2401的RX的FIFO中讀取一組數(shù)據(jù)包
輸入?yún)?shù)rx_buf:FIFO中讀取到的數(shù)據(jù)的保存區(qū)域首地址
***********************************************************************/
void NRF2401_ReceivePacket(u8* rx_buf)
{
CE_LOW;
SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH); //從RX端的FIFO中讀取數(shù)據(jù),并存入指定的區(qū)域,注意:讀取完FIFO中的數(shù)據(jù)后,NRF2401會自動清除其中的數(shù)據(jù)
SPI_Write_Byte(FLUSH_RX,0xff); //清除接收FIFO
CE_HIGH; //重新拉高CE,讓其重新處于接收模式,準(zhǔn)備接收下一個數(shù)據(jù)
}
/**********************************************************************
配置NRF2401為TX模式,并發(fā)送一個數(shù)據(jù)包
輸入?yún)?shù)tfbuf:即將要發(fā)送出去的數(shù)據(jù)區(qū)首地址
***********************************************************************/
void NRF2401_SendPacket(u8* tfbuf)
{
CE_LOW; //拉低CE,進(jìn)入待機(jī)模式,準(zhǔn)備開始往NRF2401中的寄存器中寫入數(shù)據(jù)
// SPI_Write_Buf(WRITE_REG_CMD + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); //裝載接收端地址,由于這里只有一個通道通訊,不用改變接收端的NRF2401的接收通道地址,所以,這句可以注釋掉
SPI_Write_Buf(WR_TX_PLOAD, tfbuf, TX_PLOAD_WIDTH); //將數(shù)據(jù)寫入TX端的FIFO中,寫入的個數(shù)與TX_PLOAD_WIDTH設(shè)置值相同
SPI_Write_Byte(WRITE_REG_CMD + CONFIG, 0x0e); //將NRF2401配置成發(fā)射模式
SPI_Write_Byte(WRITE_REG_CMD + STATUS, 0x7e); //寫0111 xxxx 給STATUS,清除所有中斷標(biāo)志,防止一進(jìn)入發(fā)射模式就觸發(fā)中斷
CE_HIGH; //拉高CE,準(zhǔn)備發(fā)射TX端FIFO中的數(shù)據(jù)
delay_ms(1); //CE拉高后,需要延遲至少130us
}
void WaitFlY_Connection(void)
{
static u8 cnt = 0,preaddr;
ConnectingDisplay();//斷線連接狀態(tài)顯示
while(1)
{
if(FLY_Connect_OK)
{
cnt = 0;
if(preaddr != TX_ADDRESS[TX_ADR_WIDTH-1])
{
PID_WriteFlash();
// printf("Address save :%d preaddr:%d\r\n",TX_ADDRESS[4],preaddr);
}
// printf("Fly connect OK!!!\r\n");
return;
}else if(cnt++ < 10)
{
PID_ReadFlash(); //讀取上一次保存的飛機(jī)的NRF2401地址
preaddr = TX_ADDRESS[TX_ADR_WIDTH-1];
NRF2401_Config();
delay_ms(50);
// printf("Flash read NRF2401addr:%d\r\n",TX_ADDRESS[4]);
}
else
{
TX_ADDRESS[TX_ADR_WIDTH-1]++ ;
RX_ADDRESS[TX_ADR_WIDTH-1]++ ;
if(TX_ADDRESS[TX_ADR_WIDTH-1]>AddrMax && RX_ADDRESS[TX_ADR_WIDTH-1]>AddrMax)
{
TX_ADDRESS[TX_ADR_WIDTH-1] = 0x00;
RX_ADDRESS[TX_ADR_WIDTH-1] = 0x00;
}
SPI_Write_Buf(WRITE_REG_CMD + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);
SPI_Write_Buf(WRITE_REG_CMD + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH);
delay_ms(100);
}
if(ADC_CALIBRATOR_OK)
{
OLED_ShowString(byte(2),line4,"Calibration",8);
}
else
{
OLED_ShowString(byte(2),line4,"Connecting...",8);
}
}
}
void ReconnectionFly(void)
{
if(Reconnection_flag)
{
ConnectingDisplay();
if(FLY_Connect_OK) //遙控已重新連接
{
Display_init();
Reconnection_flag = 0; //斷線重連標(biāo)志復(fù)位
return;
}
NRF2401_Config();
}
}
圖8 無線射頻傳輸部分代碼
2、手持終端顯示部分代碼:
void ButtonCMDDisplay(void)
{
if(GET_FLAG(FLY_ENABLE))
{
OLED_ShowString(byte(11),line4,"Nolink",6);
}else
{
OLED_ShowString(byte(11),line4,"Link ",6);
}
SenserOffsetDisplay();
WiFiOnOffDisplay();
ModeSelectDisplay();
}
void ConnectingDisplay(void)
{
OLED_Clear();
OLED_ShowCHinese(1,line1,WiFi,0); //信號強(qiáng)度
OLED_ShowString(byte(3)+4,line1," IDT_Fly",8); //大賽名
OLED_ShowCHinese7x7(121,line1,BATT,0); //電池圖標(biāo)
OLED_ShowString(111,line1,"%",6); //
OLED_ShowNum(108,line2,0,2,6); //電池電壓比例
}
}
圖9 無線射頻傳輸部分代碼
四軸無人機(jī)下方為自制的指南針,用來定位起飛前的方向。南針放在四軸無人機(jī)下方,為了防止電機(jī)風(fēng)力而引起的擺動。
無人機(jī)起飛、平衡性并不理想,主要還是在數(shù)據(jù)傳輸部分,不能及時將傳感器發(fā)送的數(shù)據(jù),進(jìn)行其實(shí)的處理去調(diào)整無人機(jī)的姿態(tài)。但是是MPU6050還是ZMID520xMROT傳輸?shù)臄?shù)據(jù),都能顯示在RGB LED屏上。
圖9 正面圖
圖10 背面圖
圖11 連接圖
(0.55 MB)下載