这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » DIY与开源设计 » 电子DIY » 夏季在下季的自平衡小车进程帖

共20条 2/2 1 2 跳转至
助工
2015-10-14 20:55:34     打赏
11楼

10.实现小车自主避障

实验目的:小车前进时遇到障碍物会自动后退。

    要实现小车自主避障,就要用到超声波测距模块,几块钱就可以买到,实物图如下:

 

    超声波测距模块有4个接口,依次为:Vcc、 Trig(控制端)、 Echo(接收端)、 Gnd

    超声波测距使用方法:控制口发一个10US 以上的高电平,就可以在接收口等待高电平输出。一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,方可算出距离。如此不断的周期测,就可以达到你移动测量的值了。

超声波测距工作原理:

    超声波测距是借助于超声脉冲回波渡越时间法来实现的。设超声波脉冲由传感器发出到接收所经历的时间为t,超声波在空气中的传播速度为c,则从传感器到目标物体的距离D可用下式求出:D = ct /2

(1)采用IO 触发测距,给至少10us 的高电平信号;
(2)模块自动发送8 个40khz 的方波,自动检测是否有信号返回;
(3)有信号返回,通过IO 输出一高电平,高电平持续的时间就是超声波从发射到返回的时间;
(4)测试距离=(高电平时间*声速(340M/S))/2;



主要代码

(1)time.c中的超声波接收回波函数Read_Distane()

u16 TIM2CH4_CAPTURE_STA,TIM2CH4_CAPTURE_VAL;
void Read_Distane(void)
{   
PAout(2)=1;
delay_us(15);  
PAout(2)=0; 
if(TIM2CH4_CAPTURE_STA&0X80)//成功捕获到了一次高电平
{
Distance=TIM2CH4_CAPTURE_STA&0X3F;
Distance*=65536; //溢出时间总和
Distance+=TIM2CH4_CAPTURE_VAL; //得到总的高电平时间
Distance=Distance*170/1000;
TIM2CH4_CAPTURE_STA=0; //开启下一次捕获
} 
}

    首先定义两个变量 TIM2CH4_CAPTURE_STA和TIM2CH4_CAPTURE_VAL,用于辅助实现高电平捕获。TIM2CH4_CAPTURE_STA是用来记录捕获状态,把它当成一寄存器那样来使用,各位描述如下:


    TIM2CH4_CAPTURE_VAL用来记录捕获到下降沿的时候,TIM2_CNT的值。

    STM32发送大约15us的高电平信号通过控制端Trig给超声波测距模块,判断TIM2CH4_CAPTURE_STA的最高位为1时,捕获完成,计算接收与发送的高电平持续总时间,根据公式D=(高电平时间*声速(340M/S))/2,得到小车到障碍物的距离(因为在主函数中调用TIM2_Cap_Init(0XFFFF,72-1)函数,设置STM32的捕获计数器为1us计数一次,所以获得的距离是以mm为单位)。最后把TIM2CH4_CAPTURE_STA置零开启下一次捕获。

(2)control.c中速度PI控制函数velocity(int encoder_left,int encoder_right)有关程序

if(Distance<500)  
{
Movement+=700 ; 
   if(1==Flag_Qian) 
Movement=700;

}

    小车与障碍间的距离在 0.5m之内会后退。


观察现象



视频地址:http://player.youku.com/player.php/sid/XMTM1OTU5OTI2NA==/v.swf

    小车能够自主避障,当超声波测距模块检测到小车前方 0.5m处有障碍时会自动后退(由于小车前进的惯性和检测的延迟,小车会前冲一段距离再后退)。


助工
2015-10-14 22:51:32     打赏
12楼

11.实现体感小车

实验目的:利用姿态传感器mpu6050获取俯仰角(Angle_Y),横滚角(Angle_X),在OLED屏上实时显示,并通过Nrf24l01发送给小车,从而控制小车的前进、后退和左转、右转。

mpu6050前面已经介绍过了,下面介绍一下mpu6050模块,十几块钱就可以买到,实物图如下:


我们只需要STM32与mpu6050模块之间的通讯,它们是通过IIC传递信息的,所以只需要连接4个接口(红圈内):VCC、GND、SCL、SDL


硬件电路如下图所示



主要代码修改

(1)修改无线通讯程序24l01.c中的void NRF24L01()函数

void NRF24L01(void)
{
u8 mode=1,count;
u8 tmp_buf[33];
if(mode==0)//RX模式
{
RX_Mode();
while(1)
{
if(NRF24L01_RxPacket(tmp_buf)==0)//一旦接收到信息,则显示出来.
{
printf("%d\r\n",tmp_buf[1]);
if(tmp_buf[1]>120)Flag_Qian=1,Flag_Hou=0,Flag_Left=0,Flag_Right=0;

else  if(tmp_buf[1<60)Flag_Qian=0,Flag_Hou=1,Flag_Left=0,Flag_Right=0;
else  if(tmp_buf[2]>120)Flag_Qian=0,Flag_Hou=0,Flag_Left=1,Flag_Right=0;
else  if(tmp_buf[2<60)Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=1;
else  Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=0;
}else break;

};
}else//TX模式
{
TX_Mode();
while(1)
{
if(++count>100)count=0;
tmp_buf[1]=Angle_Y+90;
tmp_buf[2]=Angle_X+90;
oled_show();
if(NRF24L01_TxPacket(tmp_buf)==TX_OK)
{
printf("%d\r\n",tmp_buf[1]);
}else
break;
}
}
}

角度为加了90度之后的角度,实际为:

俯仰角(Angle_Y)>30度,小车向前;

俯仰角(Angle_Y)<-30度,小车向后;

横滚角(Angle_X>30度,小车左转;

横滚角(Angle_X<-30度,小车右转。
(2)修改显示程序show.c中oled_show()程序

void oled_show(void)
{
Count=0;
OLED_Display_On();  //显示屏打开Distance
//=============显示角度Angle_Y================//
OLED_ShowString(0,00,"Angle_Y");
if(Angle_Y<0) OLED_ShowNumber(60,00,Angle_Y+360,3,12);
else            OLED_ShowNumber(60,00,Angle_Y,3,12);
//=============显示角度Angle_X================//
OLED_ShowString(0,12,"Angle_X");
if(Angle_X<0) OLED_ShowNumber(60,12,Angle_X+360,3,12);
else           OLED_ShowNumber(60,12,Angle_X,3,12);
//=============刷新=======================//
OLED_Refresh_Gram();
}

实验现象


放在桌面上的俯仰角(Angle_Y),横滚角(Angle_X

向前倾斜时的俯仰角(Angle_Y),横滚角(Angle_X




视频地址:http://player.youku.com/player.php/sid/XMTM1OTgzMTcyMA==/v.swf

    可以看到,板子前倾30度以上,小车向前;板子后倾30度以上,小车向后;板子左倾30度以上,小车左转;板子右倾30度以上,小车右转,实现小车体感控制。


助工
2015-10-16 21:36:57     打赏
13楼

12.实现PS2摇杆控制小车

实验目的:利用PS2摇杆来控制小车的前进、后退,左转,右转和启停,采集PS2摇杆的两路电压值(VRx、VRy)实时显示在OLED屏上

    首先介绍一下PS2游戏摇杆模块,几块钱可以买到,实物图如下:


    模块接口有5个,依次为GND、VCC、VRx、VRy、SW。其中VRx、VRy为2路模拟输出,SW为1路按钮数字输出。

    十字摇杆为一个双向(X,Y方向)的10K电阻器,随着摇杆方向不同,抽头的阻值随着变化,输出电压(模拟输出)也会变化。因为MCU为STM32,所以本模块使用3.3V供电,原始状态下读出电压为1.65V左右,当随不同方向按下,读出电压值随着改变,最大到3.3V,最小为0V。Z方向是数字输出,类似于按钮。

硬件电路如下

 

主要代码修改

(1)修改模拟数据采集程序adc.c中的Get_volt(u8 ch)函数

int Get_volt(u8 ch)   
{  
int Volt;
Volt=Get_Adc(ch)*3.3*100/4096;
return Volt;
}
    在原始数据上扩大了100倍,方便后面无线数据的传输。

(2)MiniBalance.c中的5ms中的函数中添加语句

VRx=Get_volt(0);                              //===获取电压

VRy=Get_volt(1); 
    用到PA0的ADC1_IN0和 PA1的ADC1_IN1   

(3)修改无线通讯程序24l01.c中的void NRF24L01()函数

void NRF24L01(void)
{
u8 mode=1,count;  
u8 tmp_buf[33];
if(mode==0)//RX模式
{
RX_Mode();  
while(1)
{            
if(NRF24L01_RxPacket(tmp_buf)==0)//一旦接收到信息,则显示出来.
{
VRx=tmp_buf[1]*256+tmp_buf[2];
VRy=tmp_buf[3]*256+tmp_buf[4];
Flag_Stop=tmp_buf[5];
if(VRy<100)Flag_Qian=1,Flag_Hou=0,Flag_Left=0,Flag_Right=0;
else if(VRy>230)Flag_Qian=0,Flag_Hou=1,Flag_Left=0,Flag_Right=0;
else  if(VRx<100)Flag_Qian=0,Flag_Hou=0,Flag_Left=1,Flag_Right=0;
else if(VRx>230)Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=1;
else  Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=0;
}else break;   
   
};
}else//TX模式
{    
TX_Mode();
while(1)
{  
     if(++count>100)count=0;
tmp_buf[1]=VRx/256; 
tmp_buf[2]=VRx%256; 
tmp_buf[3]=VRy/256; 
tmp_buf[4]=VRy%256;
tmp_buf[5]=Flag_Stop;
oled_show();
if(NRF24L01_TxPacket(tmp_buf)==TX_OK)
{
}else  
break;    
}
}      
}

    其中Flag_Stop表示小车的启、停状态,是通过PS2摇杆Z方向数字输出改变的,类似于按键。
(4)修改显示程序show.c中oled_show()程序

void oled_show(void)
{
OLED_Display_On();  //显示屏打开
//=============显示VRx======================//
                     OLED_ShowString(00,00,"VRx");
                     OLED_ShowString(58,00,".");
                     OLED_ShowString(80,00,"V");
                     OLED_ShowNumber(45,00,VRx/100,2,12);
                     OLED_ShowNumber(68,00,VRx%100,2,12);
if(VRx%100<10)     OLED_ShowNumber(62,00,0,2,12);
//=============显示VRy======================//
                     OLED_ShowString(00,12,"VRy");
                     OLED_ShowString(58,12,".");
                     OLED_ShowString(80,12,"V");
                     OLED_ShowNumber(45,12,VRy/100,2,12);
                     OLED_ShowNumber(68,12,VRy%100,2,12);
if(VRy%100<10)     OLED_ShowNumber(62,12,0,2,12);
//=============显示小车状态==============//
if(1==Flag_Stop)    OLED_ShowString(00,24,"stop ");
         else                OLED_ShowString(00,24,"start");
//=============刷新=======================//
OLED_Refresh_Gram();
}
    前两行显示模拟电压值;

    第三行显示显示小车状态:Flag_Stop=1,小车停止,显示stop;Flag_Stop=0,小车运转,显示start。


实验现象



原始状态,两路电压显示1.65V左右,小车状态stop


   



视频地址:http://player.youku.com/player.php/sid/XMTM2MTQwOTcyNA==/v.swf

    PS2摇杆可以正常控制小车的前进、后退,左转,右转和启停,OLED屏显示数据正常。


助工
2015-10-18 20:20:58     打赏
14楼

13.实现按键控制小车

实验目的:利用按键控制小车的前进、后退,左转、右转、平衡状态及启停,小车的状态实时显示在OLED屏上,分别为:qian、hou、zuo、you、balance、stop。

    按键分布如下图

主要代码修改

(1)修改按键程序key.c和key.h

void KEY_Init(void)
{
RCC->APB2ENR|=1<<3; //使能PORTB时钟
GPIOB->CRH&=0X0000FFFF;
GPIOB->CRH|=0X88880000;//PB12 PB13 PB15 PB15 上拉输入

GPIOB->CRL&=0XFFFFFF00;
GPIOB->CRL|=0X00000088;//PB0 PB1上拉输入
GPIOB->ODR|=0X0000F003; //PB0 PB1 PB12 PB13 PB15 PB15 上拉
}

void KEY_Scan (void)
{
if(s1==0)
{
delay_ms(10);
if(s1==0)
{
Key_flag=1;
while(!s1);
}
}


if(s2==0)
{
delay_ms(10);
if(s2==0)
{
Key_flag=2;
while(!s2);
}
}


if(s3==0)
{
delay_ms(10);
if(s3==0)
{
Key_flag=3;
while(!s3);
}
}


if(s4==0)
{
delay_ms(10);
if(s4==0)
{
Key_flag=4;
while(!s4);
}
}


if(s5==0)
{
delay_ms(10);
if(s5==0)
{
Key_flag=0;
while(!s5);
}
}


if(s6==0)
{
delay_ms(10);
if(s6==0)
{
while(!s5);
Flag_Stop=~Flag_Stop;
Key_flag=0;
}
}
}

(2)修改无线通讯程序24l01.c中的void NRF24L01()函数

void NRF24L01(void)
{
u8 mode=1,count;
u8 tmp_buf[33];
if(mode==0)//RX模式
{
RX_Mode();
while(1)
{
if(NRF24L01_RxPacket(tmp_buf)==0)//一旦接收到信息,则显示出来.
{
Key_flag=tmp_buf[1];
Flag_Stop=tmp_buf[2];

if(1==Key_flag)Flag_Qian=1,Flag_Hou=0,Flag_Left=0,Flag_Right=0;
else if(2==Key_flag)Flag_Qian=0,Flag_Hou=1,Flag_Left=0,Flag_Right=0;
else  if(3==Key_flag)Flag_Qian=0,Flag_Hou=0,Flag_Left=1,Flag_Right=0;
else if(4==Key_flag)Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=1;
else  Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=0;
}else break;
};
}else//TX模式
{
TX_Mode();
while(1)
{
if(++count>100)count=0;
tmp_buf[1]=Key_flag;
tmp_buf[2]=Flag_Stop;

oled_show();
if(NRF24L01_TxPacket(tmp_buf)==TX_OK)
{
}else
break;
}
}
}

(3)修改显示程序show.c中oled_show()程序

void oled_show(void)
{
OLED_Display_On();  //显示屏打开
//=============显示Key_flag===================//
OLED_ShowString(00,00,"Key_flag");
OLED_ShowNumber(88,00,Key_flag,1,12);
//=============显示小车状态===================//
if(1==Flag_Stop)      OLED_ShowString(00,12,"stop   ");
else if(1==Key_flag)  OLED_ShowString(00,12,"qian   ");
else if(2==Key_flag)  OLED_ShowString(00,12,"hou    ");
else if(3==Key_flag)  OLED_ShowString(00,12,"zuo    ");
else if(4==Key_flag)  OLED_ShowString(00,12,"you    ");
else  OLED_ShowString(00,12,"balance");
//=============刷新=======================//
OLED_Refresh_Gram();
}


观察现象








    初始状态,OLED屏上显示按键标志位Key_flag为0和小车状态stop。



视频地址:http://player.youku.com/player.php/sid/XMTM2Mjk4Mjk2OA==/v.swf

    按键可以正常控制小车前进、后退,左转、右转、平衡状态及启停,OLED屏显示正常。


助工
2015-10-19 20:30:57     打赏
15楼

14.实现变速小车

实验目的:按键控制小车速度,6个按键控制6档(6个速度),小车的移动用第12节的PS2遥杆控制,相关信息显示在OLED屏上。

    先来看看源代码


    小车的前进、后退度有Movement控制,在注释中已经介绍很清楚了,数值越大,速度越快,反之相反,我们用变量Move代替。


    小车的左右转速度由红框中的数值决定,数值越大,速度越快,反之相反,我们用变量Move_Turn代替


    按键分布如下图

    1档:Move值:150            Move_Turn值:300

    2档:Move值:300            Move_Turn值:600

    3档:Move值:450            Move_Turn值:900

    4档:Move值:600            Move_Turn值:1200

    5档:Move值:750           Move_Turn值:1500

    6档:Move值:900            Move_Turn值:1800


主要代码修改

(1)修改按键程序key.c和key.h

void KEY_Init(void)
{
RCC->APB2ENR|=1<<3;    //使能PORTB时钟    
GPIOB->CRH&=0X0000FFFF; 
GPIOB->CRH|=0X88880000;//PB12 PB13 PB15 PB15 上拉输入

GPIOB->CRL&=0XFF0FFF00; 
GPIOB->CRL|=0X00800088;//PB0 PB1 PB5上拉输入
GPIOB->ODR|=0X0000F023; //PB0 PB1 PB5 PB12 PB13 PB15 PB15 上拉



void KEY_Scan (void)
{
if(s1==0)
{
delay_ms(10);
if(s1==0)
{
Move=15;
Move_Turn=30;
while(!s1);
}
}


if(s2==0)
{
delay_ms(10);
if(s2==0)
{
Move=30;
Move_Turn=60;
while(!s2);
}
}

if(s3==0)
{
delay_ms(10);
if(s3==0)
{
Move=45;
Move_Turn=90;
while(!s3);
}
}


if(s4==0)
{
delay_ms(10);
if(s4==0)
{
Move=60;
Move_Turn=120;
while(!s4);
}
}


if(s5==0)
{
delay_ms(10);
if(s5==0)
{
Move=75;
Move_Turn=150;
while(!s5);
}
}


if(s6==0)
{
delay_ms(10);
if(s6==0)
{
Move=90;
Move_Turn=180;
while(!s5);
}
}
}


(2)修改无线通讯程序24l01.c中的void NRF24L01()函数

void NRF24L01(void)
{
u8 mode=1,count;  
u8 tmp_buf[33];
if(mode==0)//RX模式
{
RX_Mode();  
while(1)
{            
if(NRF24L01_RxPacket(tmp_buf)==0)//一旦接收到信息,则显示出来.
{
VRx=tmp_buf[1]*256+tmp_buf[2];
VRy=tmp_buf[3]*256+tmp_buf[4];
Flag_Stop=tmp_buf[5];
Move=tmp_buf[6]*10;
Move_Turn=tmp_buf[7]*10;

if(VRy<100)Flag_Qian=1,Flag_Hou=0,Flag_Left=0,Flag_Right=0;
 else if(VRy>230)Flag_Qian=0,Flag_Hou=1,Flag_Left=0,Flag_Right=0;
else  if(VRx<100)Flag_Qian=0,Flag_Hou=0,Flag_Left=1,Flag_Right=0;
 else if(VRx>230)Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=1;
else  Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=0;
}else break;   
   
};
}else//TX模式
{    
TX_Mode();
while(1)
{  
     if(++count>100)count=0;
tmp_buf[1]=VRx/256; 
tmp_buf[2]=VRx%256; 
tmp_buf[3]=VRy/256; 
tmp_buf[4]=VRy%256;
tmp_buf[5]=Flag_Stop;
tmp_buf[6]=Move;
tmp_buf[7]=Move_Turn;
oled_show();
if(NRF24L01_TxPacket(tmp_buf)==TX_OK)
{
}else  
break;    
}
}      
}


(3)修改显示程序show.c中oled_show()程序

void oled_show(void)
{
OLED_Display_On();  //显示屏打开
//=============显示VRx==================//
                     OLED_ShowString(00,00,"VRx");
                     OLED_ShowString(58,00,".");
                     OLED_ShowString(80,00,"V");
                     OLED_ShowNumber(45,00,VRx/100,2,12);
                     OLED_ShowNumber(68,00,VRx%100,2,12);
if(VRx%100<10)     OLED_ShowNumber(62,00,0,2,12);
//=============显示VRy====================//
                     OLED_ShowString(00,12,"VRy");
                     OLED_ShowString(58,12,".");
                     OLED_ShowString(80,12,"V");
                     OLED_ShowNumber(45,12,VRy/100,2,12);
                     OLED_ShowNumber(68,12,VRy%100,2,12);
if(VRy%100<10)     OLED_ShowNumber(62,12,0,2,12);
//=============显示Flag_Stop===============//
                     
if(1==Flag_Stop)      OLED_ShowString(00,24,"stop ");
   else              OLED_ShowString(00,24,"start");

//=============显示Move==================//
OLED_ShowString(00,36,"Move");
OLED_ShowNumber(80,36,Move*10,3,12);
//=============显示Move_Turn==============//
OLED_ShowString(00,48,"Move_Turn");
OLED_ShowNumber(80,48,Move_Turn*10,4,12);
//=============刷新=====================//
OLED_Refresh_Gram();
}


观察现象







    原始状态,两路电压显示1.65V左右,小车状态stop,Move为150,Move_Turn为300。




视频地址:http://player.youku.com/player.php/sid/XMTM2Mzk2NDg5Ng==/v.swf

    按键可以控制小车的速度,实现变速小车,OLED屏显示正常。


助工
2015-10-25 11:24:33     打赏
16楼

15.简易遥控DIY

实验目的:DIY板子,实现多种方式控制小车。控制小车的方法有四种,分别为:蓝牙、体感(参见11节)、遥杆(参见12节)、按键(参见13节)。另外DIY板子可以实现小车的速度调节(参见14节),相关信息显示在OLED屏上。

    先看看板子整体布局:


    四种控制方式有按键模块的最右边的按键决定,设置标志位为Flag_Mode。

当Flag_Mode=0时,蓝牙控制方式;

当Flag_Mode=1时,体感控制方式(参见11节);

当Flag_Mode=2时,遥杆控制方式(参见12节);

当Flag_Mode=3时,按键控制方式(参见13节)。

    在按键控制方式下,前5个按键分别表示前进、后退、左转、右转、平衡状态;在其他控制方式下,前5个按键分别表示速度档位(1档、2档、3档、4档、5档)(参见14节)。

主要代码修改

1)修改按键程序key.ckey.h

void KEY_Init(void)
{
RCC->APB2ENR|=1<<3; //使能PORTB时钟
GPIOB->CRH&=0X0000FFFF;
GPIOB->CRH|=0X88880000;//PB12 PB13 PB15 PB15 上拉输入

GPIOB->CRL&=0XFF0FFF00;
GPIOB->CRL|=0X00800088;//PB0 PB1 PB5上拉输入
GPIOB->ODR|=0X0000F023; //PB0 PB1 PB5 PB12 PB13 PB15 PB15 上拉
}

u8 click(void)
{
static u8 flag_key=1;//按键按松开标志
if(flag_key&&s6==0)
{
flag_key=0;
return 1; // 按键按下
}
else if(1==s6) flag_key=1;
return 0;//无按键按下
}

void KEY_Scan (void)
{
if(0==Flag_Mode||1==Flag_Mode||2==Flag_Mode)
{
if(s1==0)
{
delay_ms(10);
if(s1==0)
{
Move=15;
Move_Turn=30;
while(!s1);
}
}
if(s2==0)
{
delay_ms(10);
if(s2==0)
{
Move=30;
Move_Turn=60;
while(!s2);
}
}

if(s3==0)
{
delay_ms(10);
if(s3==0)
{
Move=45;
Move_Turn=90;
while(!s3);
}
}

if(s4==0)
{
delay_ms(10);
if(s4==0)
{
Move=60;
Move_Turn=120;
while(!s4);
}
}

if(s5==0)
{
delay_ms(10);
if(s5==0)
{
Move=75;
Move_Turn=150;
while(!s5);
}
}
}

else if(3==Flag_Mode)
{
if(s1==0)
{
delay_ms(10);
if(s1==0)
{
Key_flag=1;
while(!s1);
}
}

if(s2==0)
{
delay_ms(10);
if(s2==0)
{
Key_flag=2;
while(!s2);
}
}

if(s3==0)
{
delay_ms(10);
if(s3==0)
{
Key_flag=3;
while(!s3);
}
}

if(s4==0)
{
delay_ms(10);
if(s4==0)
{
Key_flag=4;
while(!s4);
}
}

if(s5==0)
{
delay_ms(10);
if(s5==0)
{
Key_flag=0;
while(!s5);
}
}
}
}

2)修改无线通讯程序24l01.c中的void NRF24L01()函数

void NRF24L01(void)
{
u8 mode=1;
u8 tmp_buf[33];
if(mode==0)//RX模式
{
RX_Mode();
while(1)
{
if(NRF24L01_RxPacket(tmp_buf)==0)//一旦接收到信息,则显示出来.
{
switch(Flag_Mode)
{
case 0:{Flag_Mode=tmp_buf[1];
Move=tmp_buf[2]*10;
Move_Turn=tmp_buf[3]*10;
oled_show();
break;}
case 1:{Flag_Mode=tmp_buf[1];
Angle_Y=tmp_buf[2];
Angle_X=tmp_buf[3];
Move=tmp_buf[4]*10;
Move_Turn=tmp_buf[5]*10;
oled_show();

if(Angle_Y>120)Flag_Qian=1,Flag_Hou=0,Flag_Left=0,Flag_Right=0;
else if(Angle_Y<60)Flag_Qian=0,Flag_Hou=1,Flag_Left=0,Flag_Right=0;
else  if(Angle_X>120)Flag_Qian=0,Flag_Hou=0,Flag_Left=1,Flag_Right=0;
else if(Angle_X<60)Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=1;
else  Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=0;
break;}
case 2:{Flag_Mode=tmp_buf[1];
VRx=tmp_buf[2]*256+tmp_buf[3];
VRy=tmp_buf[4]*256+tmp_buf[5];
Flag_Stop=tmp_buf[6];
Move=tmp_buf[7]*10;
Move_Turn=tmp_buf[8]*10;
oled_show();

if(VRy<50)Flag_Qian=1,Flag_Hou=0,Flag_Left=0,Flag_Right=0;
else if(VRy>280)Flag_Qian=0,Flag_Hou=1,Flag_Left=0,Flag_Right=0;
else  if(VRx<50)Flag_Qian=0,Flag_Hou=0,Flag_Left=1,Flag_Right=0;
else if(VRx>280)Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=1;
else  Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=0;
break;}
case 3:{Flag_Mode=tmp_buf[1];
Key_flag=tmp_buf[2];
oled_show();

if(1==Key_flag)Flag_Qian=1,Flag_Hou=0,Flag_Left=0,Flag_Right=0;
else if(2==Key_flag)Flag_Qian=0,Flag_Hou=1,Flag_Left=0,Flag_Right=0;
else  if(3==Key_flag)Flag_Qian=0,Flag_Hou=0,Flag_Left=1,Flag_Right=0;
else if(4==Key_flag)Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=1;
else  Flag_Qian=0,Flag_Hou=0,Flag_Left=0,Flag_Right=0;
break;}
default:break;
}
}else break;
};
}else//TX模式
{
TX_Mode();
while(1)
{
switch(Flag_Mode)
{
case 0:{tmp_buf[1]=Flag_Mode;
tmp_buf[2]=Move;
tmp_buf[3]=Move_Turn;
oled_show();
break;}
case 1:{tmp_buf[1]=Flag_Mode;
tmp_buf[2]=Angle_Y+90;
tmp_buf[3]=Angle_X+90;
tmp_buf[4]=Move;
tmp_buf[5]=Move_Turn;
oled_show();
break;}
case 2:{tmp_buf[1]=Flag_Mode;
tmp_buf[2]=VRx/256;
tmp_buf[3]=VRx%256;
tmp_buf[4]=VRy/256;
tmp_buf[5]=VRy%256;
tmp_buf[6]=Flag_Stop;
tmp_buf[7]=Move;
tmp_buf[8]=Move_Turn;
oled_show();
break;}
case 3:{tmp_buf[1]=Flag_Mode;
tmp_buf[2]=Key_flag;
oled_show();
break;}
default:break;
}


if(NRF24L01_TxPacket(tmp_buf)==TX_OK)
{
}else
break;
}
}
}

3)修改显示程序show.coled_show()程序
void oled_show(void)
{
switch(Flag_Mode)
{
case 0:{OLED_Display_On();  //显示屏打开
//=============显示控制模式=================//
OLED_ShowWord(00,00,0);//蓝
OLED_ShowWord(32,00,1);//牙
OLED_ShowWord(64,00,2);//小
OLED_ShowWord(96,00,3);//车
//=============显示Move===================//
OLED_ShowString(00,36,"Move");
OLED_ShowNumber(80,36,Move*10,3,12);
//=============显示Move_Turn===============//
OLED_ShowString(00,48,"Move_Turn");
OLED_ShowNumber(80,48,Move_Turn*10,4,12);
//=============刷新======================//
OLED_Refresh_Gram();
break;}

case 1:{OLED_Display_On();  //显示屏打开
//=============显示控制模式================//
OLED_ShowWord(00,00,4);//体
OLED_ShowWord(32,00,5);//感
OLED_ShowWord(64,00,2);//小
OLED_ShowWord(96,00,3);//车
//=============显示Move==================//
OLED_ShowString(00,36,"Move");
OLED_ShowNumber(80,36,Move*10,3,12);
//=============显示Move_Turn==============//
OLED_ShowString(00,48,"Move_Turn");
OLED_ShowNumber(80,48,Move_Turn*10,4,12);
//=============刷新====================//
OLED_Refresh_Gram();
break;}

case 2:{OLED_Display_On();  //显示屏打开
//=============显示控制模式==============//
OLED_ShowWord(00,00,6);//遥
OLED_ShowWord(32,00,7);//
OLED_ShowWord(64,00,2);//小
OLED_ShowWord(96,00,3);//车
//=============显示Move================//
OLED_ShowString(00,36,"Move");
OLED_ShowNumber(80,36,Move*10,3,12);
//=============显示Move_Turn============//
OLED_ShowString(00,48,"Move_Turn");
OLED_ShowNumber(80,48,Move_Turn*10,4,12);
//=============刷新==================//
OLED_Refresh_Gram();
break;}

case 3:{OLED_Display_On();  //显示屏打开
//=============显示控制模式=============//
OLED_ShowWord(00,00,8);//按
OLED_ShowWord(32,00,9);//
OLED_ShowWord(64,00,2);//小
OLED_ShowWord(96,00,3);//
//=============显示Move==============//
OLED_ShowString(00,36,"Move");
OLED_ShowNumber(80,36,Move*10,3,12);
//=============显示Move_Turn==========//
OLED_ShowString(00,48,"Move_Turn");
OLED_ShowNumber(80,48,Move_Turn*10,4,12);
//=============刷新================//
OLED_Refresh_Gram();
break;}
default:break;
}

}


观察现象

    四种控制方式下的OLED屏显示如下:











    上电默认为蓝牙控制,然后依次为体感控制、遥杆控制、按键控制,下面两行为小车的速度Move=150,Move_Turn=300(默认值)。

    上图显示在遥杆控制模式下,小车速度Move=600,Move_Turn=1200,速度增大。


视频地址:http://player.youku.com/player.php/sid/XMTM2ODQyODcyMA==/v.swf

    通过按键依次切换控制模式,小车运动正常(由于手机用于拍摄,所以蓝牙控制模式在视屏中没有演示),在遥杆控制(个人最喜欢这种方式了,有点游戏手柄的感觉)下,调节速度正常。OLED屏显示正常。


菜鸟
2017-07-31 11:31:14     打赏
17楼
赞赞赞

菜鸟
2017-09-08 15:04:07     打赏
18楼
很详细

助工
2017-11-01 10:21:06     打赏
19楼

谢谢,有点意思的


助工
2017-11-01 10:21:06     打赏
20楼

谢谢,有点意思的


共20条 2/2 1 2 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]