gaoyang9992006 发表于 2021-11-9 22:40

做一辆用手机遥控的玩具车吧,超简单,留给孩子玩

#申请原创# @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 = '{';
            for(i=1;i<15;i++)
                cmd = getch();
            if(cmd=='}')
            {
                x=cmd;
                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板子,比如我做的这个丑八怪板子。{:lol:}

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;
    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 = '{';
            for(i=1;i<15;i++)
                cmd = getch();
            if(cmd=='}')
            {
                x=cmd;
                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 发表于 2021-11-9 22:46

本帖最后由 gaoyang9992006 于 2021-11-13 18:14 编辑

试车视频:https://www.bilibili.com/video/BV1Hf4y1T73F/扩展电路板收到了,把各个模块都插上。为何我这么做呢?不直接做一个完整的板子。
首先,这年头买模块比买芯片便宜。
另外单片机可以用论坛免费申请的,Microchip板块每个月都有开发板免费申请,赶紧参与进来。
另外就是用模块可以很快改变设计,让芯片重复利用。


huquanz711 发表于 2021-11-9 23:19

哈哈,不错,孩子喜欢吗?

yangxiaor520 发表于 2021-11-10 08:00

楼主是男孩还是女孩儿

gaoyang9992006 发表于 2021-11-10 09:10

yangxiaor520 发表于 2021-11-10 08:00
楼主是男孩还是女孩儿

都有。

gaoyang9992006 发表于 2021-11-10 09:10

huquanz711 发表于 2021-11-9 23:19
哈哈,不错,孩子喜欢吗?

{:lol:}必须的喜欢。

七毛钱 发表于 2021-11-10 09:27

这个说实在话我不太喜欢,哈哈

gaoyang9992006 发表于 2021-11-10 10:08

七毛钱 发表于 2021-11-10 09:27
这个说实在话我不太喜欢,哈哈

你做好看点就行了。哈哈,我这太简陋,因为打的板子刚刚收到,后面重新组装一下就好看了。

hu9jj 发表于 2021-11-10 16:56

建议改为三轮,一对驱动轮,一个万向轮,这样转弯更灵活方便。

yanzhengxin1 发表于 2021-11-11 09:14

可以啊,娃娃的玩具自己全部承包了。

gaoyang9992006 发表于 2021-11-11 11:38

yanzhengxin1 发表于 2021-11-11 09:14
可以啊,娃娃的玩具自己全部承包了。

哈哈,最近在学3D建模,到时候可以打印外壳了。

szmy8311 发表于 2021-11-11 12:18

这个有点6

Gavin3389 发表于 2021-11-11 15:05

楼主,对你搞APP的这个软件,越来越感兴趣了

lcczg 发表于 2021-11-11 16:11

帅帅帅

gaoyang9992006 发表于 2021-11-11 23:22

Gavin3389 发表于 2021-11-11 15:05
楼主,对你搞APP的这个软件,越来越感兴趣了

haha,那赶紧学起来,很容易上手的。

gaoyang9992006 发表于 2021-11-11 23:22

szmy8311 发表于 2021-11-11 12:18
这个有点6

哈哈,感谢支持,加油,一起学。

gaoyang9992006 发表于 2021-11-11 23:23

lcczg 发表于 2021-11-11 16:11
帅帅帅

有兴趣也学一下,很容易就做出来手机APP了。

toowm 发表于 2021-11-12 18:02

不管咋说,就两个字牛X

天意无罪 发表于 2021-11-13 11:41

楼主家的小孩儿是女孩还是男孩,喜欢玩吗?要不顺便培养一下他的兴趣,哈哈哈。

gaoyang9992006 发表于 2021-11-13 18:15

天意无罪 发表于 2021-11-13 11:41
楼主家的小孩儿是女孩还是男孩,喜欢玩吗?要不顺便培养一下他的兴趣,哈哈哈。 ...

男孩女孩都有。是的,喜欢啊,以后长大了肯定要跟我一样学这些内容了。
页: [1] 2 3
查看完整版本: 做一辆用手机遥控的玩具车吧,超简单,留给孩子玩