#申请原创# @21小跑堂
这辆车有4个车轮,每个车轮可以独立驱动,所以我们可以叫它:四驱车
系统组成如下所示:通过蓝牙模块与手机APP通信,并根据接收的指令控制车轮的转动方向。如果富裕的话,还可以加上电子指南针之类的传感器,用于控制转向角度。这样可以防止在打滑的情况下转角不准。
这里我使用单片机是PIC18F16Q41 Curiosity Nano开发板。
我们可以看着开发板管脚的分布于MCC轻松配置管脚的分工。
串口UART1 连接BLE蓝牙模块,作为UART1的管脚是:RB7/TX1;RB5/RX1
由于该开发板仅仅有3组PWM,又因为我们用的减速电机,本身就跑的不会很快,所以这里我们就不调速了。
因此我们还需要4对IO来控制电机的正反转。如下所示:
我做的时候还利用了一路PWM控制舵机带动机械机构运动。这里可以不用。
感兴趣的另外自己加。
其实这个时候你电机线的顺序搞错了都没事,后面可以测一下确定,大不了软件里修改一下代码就行了。
其实只要测定后哪两个管脚控制某个轮子是正转的就行了,然后反转就是颠倒一下高低电平。比如我测定的正转时序如下所示
void up(void)
{
// 左前
IO_RC4_SetHigh();
IO_RC5_SetLow();
// 右前
IO_RC6_SetHigh();
IO_RC7_SetLow();
// 左后
IO_RB6_SetHigh();
IO_RB4_SetLow();
// 右后
IO_RA2_SetHigh();
IO_RC3_SetLow();
}
相应的你应该知道怎么修改让某个轮子反转,或者停止了吧。
电机的驱动我们采用驱动桥,因为单片机的IO直接驱动那怎么可以?电机驱动芯片与原理图如下所示。图是用visio绘制。
接下来实现手机APP与单片机的交互协议。
为了方便扩展,我们将一条质量设置长一些:{AT:ABCD1234UP}
这就是我们的指令模板,以一对大括号作为指令内容,通过识别是否遇到了大括号的开始作为收到指令的依据,如果收到了大括号开始,我们就开始接收数据,并判断大括号结束是否在正确的位置,如果是,那说明这一条指令是完整的,然后从中取出对应的位,判断是什么指令,然后执行对应的命令。
为了方便理解,我将识别指令的程序段,直接放主函数里,你也可以通过串口中断实现,这样就可以让单片机在没有指令的时候干别的事情了。
while(getch()=='{')
{
cmd[0] = '{';
for(i=1;i<15;i++)
cmd[i] = getch();
if(cmd[14]=='}')
{
x=cmd[12];
switch(x)
{
case 'U':
up();
printf("UP\n");
break;
case 'D':
down();
printf("DOWN\n");
break;
case 'L':
left();
printf("LEFT\n");
break;
case 'R':
right();
printf("RIGHT\n");
break;
case 'S':
stop();
printf("STOP\n");
break;
case 'T':
Triangle(1);
printf("T-UP ");
break;
case 'V':
Triangle(0);
printf("T-DOWN ");
break;
}
}
}
那么APP怎么实现呢?
以上是APP的设计界面和功能按钮。当发送指令成功后,单片机就返回对应的内容,就是上面代码中的printf内容。
APP的开发教程在
https://bbs.21ic.com/icview-3173112-1-1.html
大家可以根据需要修改。
今年的TI电赛有个加分项,就是测量的信息在手机上显示。大家如果选择那个题目的话,可以参考我这个方案。
另外如果不想使用杜邦线接一堆线,可以自己做PCB板子,比如我做的这个丑八怪板子。
PIC18F16Q41的源码如下所示,仅供参考,需要MCC配置的可以根据上述图中的管脚分布根据自己的需求配置
#include "mcc_generated_files/mcc.h"
uint16_t i=500;
void led(void)
{
PWM1_16BIT_SetSlice1Output1DutyCycleRegister(i);
PWM1_16BIT_LoadBufferRegisters();
LED_Toggle();
i=i+667;
if(i>1400) i=500;
printf("C\n");
}
/*
三角架开启与落下控制指令
*/
void Triangle(bool i)
{
if(i==true)
{
PWM1_16BIT_SetSlice1Output1DutyCycleRegister(1167);
PWM1_16BIT_LoadBufferRegisters();
LED_SetLow();
}
if(i==false)
{
PWM1_16BIT_SetSlice1Output1DutyCycleRegister(500);
PWM1_16BIT_LoadBufferRegisters();
LED_SetHigh();
}
}
void up(void)
{
// 左前
IO_RC4_SetHigh();
IO_RC5_SetLow();
// 右前
IO_RC6_SetHigh();
IO_RC7_SetLow();
// 左后
IO_RB6_SetHigh();
IO_RB4_SetLow();
// 右后
IO_RA2_SetHigh();
IO_RC3_SetLow();
}
void down(void)
{
IO_RC5_SetHigh();
IO_RC4_SetLow();
IO_RC7_SetHigh();
IO_RC6_SetLow();
// 左后
IO_RB4_SetHigh();
IO_RB6_SetLow();
// 右后
IO_RC3_SetHigh();
IO_RA2_SetLow();
}
void left(void)
{
// 左前后退
IO_RC5_SetHigh();
IO_RC4_SetLow();
// 右前前进
IO_RC6_SetHigh();
IO_RC7_SetLow();
// 左后后退
IO_RB4_SetHigh();
IO_RB6_SetLow();
// 右后前进
IO_RA2_SetHigh();
IO_RC3_SetLow();
}
void right(void)
{
// 左前前进
IO_RC4_SetHigh();
IO_RC5_SetLow();
// 右前后退
IO_RC7_SetHigh();
IO_RC6_SetLow();
// 左后前进
IO_RB6_SetHigh();
IO_RB4_SetLow();
// 右后后退
IO_RC3_SetHigh();
IO_RA2_SetLow();
}
void stop(void)
{
IO_RC4_SetLow();
IO_RC5_SetLow();
IO_RC6_SetLow();
IO_RC7_SetLow();
IO_RB6_SetLow();
IO_RB4_SetLow();
IO_RA2_SetLow();
IO_RC3_SetLow();
}
void main(void)
{
unsigned char x;
unsigned char cmd[15];
unsigned int i=0;
// Initialize the device
SYSTEM_Initialize();
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Disable the Global Interrupts
//INTERRUPT_GlobalInterruptDisable();
INT0_SetInterruptHandler(led);
printf("Hello MyCar\n");
while (1)
{
// {AT:ABCD1234UP}
// printf("Hello world!\n");
// __delay_ms(500);
while(getch()=='{')
{
cmd[0] = '{';
for(i=1;i<15;i++)
cmd[i] = getch();
if(cmd[14]=='}')
{
x=cmd[12];
switch(x)
{
case 'U':
up();
printf("UP\n");
break;
case 'D':
down();
printf("DOWN\n");
break;
case 'L':
left();
printf("LEFT\n");
break;
case 'R':
right();
printf("RIGHT\n");
break;
case 'S':
stop();
printf("STOP\n");
break;
case 'T':
Triangle(1);
printf("T-UP ");
break;
case 'V':
Triangle(0);
printf("T-DOWN ");
break;
}
}
}
}
}
APP中按键触发发送指令部分代码
事件 按钮上.被单击()
BLE蓝牙1.写入数据(服务UUID,通道UUID,文本到字节("{AT:ABCD1234UP}\r\n","GBK"))
结束 事件
事件 按钮下.被单击()
BLE蓝牙1.写入数据(服务UUID,通道UUID,文本到字节("{AT:ABCD1234DN}\r\n","GBK"))
结束 事件
事件 按钮左.被单击()
BLE蓝牙1.写入数据(服务UUID,通道UUID,文本到字节("{AT:ABCD1234LF}\r\n","GBK"))
结束 事件
事件 按钮右.被单击()
BLE蓝牙1.写入数据(服务UUID,通道UUID,文本到字节("{AT:ABCD1234RT}\r\n","GBK"))
结束 事件
事件 三角按钮上.被单击()
BLE蓝牙1.写入数据(服务UUID,通道UUID,文本到字节("{AT:ABCD1234T0}\r\n","GBK"))
结束 事件
事件 三角按钮下.被单击()
BLE蓝牙1.写入数据(服务UUID,通道UUID,文本到字节("{AT:ABCD1234V0}\r\n","GBK"))
结束 事件
事件 停止按钮.被单击()
BLE蓝牙1.写入数据(服务UUID,通道UUID,文本到字节("{AT:ABCD1234S0}\r\n","GBK"))
结束 事件
战车雏形
|