[PIC/AVR MCU]做一辆用手机遥控的玩具车吧,超简单

这辆车有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的开发教程在
开发BLE蓝牙手机上位机软件竟是如此的简单 - - 21ic电子技术开发论坛
大家可以根据需要修改。
今年的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"))        

结束 事件

战车雏形 

 ---------------------
作者:gaoyang9992006
链接:https://bbs.21ic.com/icview-3176988-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值