打印
[活动]

我的无线DIY设计—基于STM32WB55_NUCLEO​的遥控小车

[复制链接]
980|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 zhangrui123 于 2023-1-29 02:22 编辑

                                                             基于STM32WB55_NUCLEO​的遥控小车
       很荣幸参加这次贸泽电子DIY设计,首先感谢贸泽电子提供的开发板、21ic社区对活动的支持,以及和我联系的21ic社区的项目经理!
       在本次DIY的设计当中,我的作品是基于STM32WB55_NUCLEO​的遥控小车,本次设计主要利用stm32wb55的蓝牙功能,由于stm32wb55是一个双核的MCU,同时具有低功耗的特点,因此在使用蓝牙低功耗的场合可以取代MCU+蓝牙模块的方案,对于减小产品的体积以及PCB的面积,有很大的优势。

一:项目方案构想
     STM32WB55_NUCLEO开发板支持蓝牙协议,并且ST官方有配套的手机端ST BLE ToolBox 软件,该软件可以与开发板的蓝牙进行连接并且进行数据交互。
手机端连接到开发板的蓝牙以后,进行数据交互。根据手机端输入的指令,开发板的蓝牙接收到数据以后对上位机的数据进解码,进而使STM32WB55_NUCLEO
输出PWM波,然后通过TB6612电机驱动进行对PWM波进行功率放大,进而驱动四个直流电机进行工作。从而完成在手机端对小车的控制。​

二:项目设计、搭建
      2.1硬件部分
      需要的电子元件:stm32wb55开发板、2节18650的充电锂电池、电池盒、1个4WD的小车底盘、洞洞板、2个电机驱动TB6612、LM2596电源模块、接线端子若干、杜邦线若干。


      LM2596电源模块用来降压,2节18650电池的电压充满电8V左右, 由于开发板可以使用5V进行供电,板内有转3.3V的电路,因此使用降压模块将电源降压至5V,
给单片机开发板以及电机驱动模块进行供电。
     小车底盘具有四个电机,分为左1、左2、右1、右2,即L1、L2、R1、R2。
     电机硬件接口:
     L1: PC12、PA6。    对应第一个TB6612的AIN1和AIN2(输入端)       输出端(AOUT1、AOUT2)直接接电机的两端。
     L2: PC13、PB1。    对应第一个TB6612的BIN1和BIN2(输入端)       输出端(BOUT1、BOUT2)直接接电机的两端。
     R1: PA8、PB15。    对应第二个TB6612的AIN1和AIN2(输入端)       .....
     R2: PC6、PA10。    对应第二个TB6612的BIN1和BIN2(输入端)       .....
      其中TB6612的STBY使能端节高电平。

      由于整体的设计比较简单,所以使用洞洞板来进行电路搭建,焊接洞洞板相对比较费时费力,焊接好的洞洞板如下图。


      最后将18650和LM2596带电源模块连接起来组成最终的电路,如下图。


     2.2 软件设计
     准备软件工具:STM32cubeIDE、串口助手、ST BLE ToolBox(可以从谷歌商店下载)
     我们使用STM32cubeIDE进行开发,其中集成了一些stm32wb55的demo,我们可以利用这些demo来快速完成我们的设计。
     首先打开STM32cubeIDE,在代码生成的过程中,我们选择例程demo,选择stm32wb55开发板,如下图示

      然后找到我们需要的例程,在本次设计当中手机作为服务器,而开发板作为客户端,因此我们选择BLE_p2pServer 例程。


      我们需要根据AN5289这个文档来找到p2p应用的时候,应该操作哪些函数。 AN5289.pdf (4.27 MB)
      找到70页,可以得到蓝牙协议栈接收到数据以后应用层的操作。

    然后在p2pserver.c文件中找到通知事件函数 P2PS_STM_App_Notification 。找到p2p写通知事件 case P2PS_STM_WRITE_EVT。


    case P2PS_STM_WRITE_EVT:
/* USER CODE BEGIN P2PS_STM_WRITE_EVT */
      if(pNotification->DataTransfered.pPayload[0] == 0x01){ /* ALL Deviceselected - may be necessary as LB Routeur informs all connection */
        if(pNotification->DataTransfered.pPayload[1] == 0x01)
        {
          BSP_LED_On(LED_BLUE);
          APP_DBG_MSG("-- P2P APPLICATION SERVER  : LED1 ON\n");
          APP_DBG_MSG(" \n\r");
          APP_DBG_MSG("go straight!\r\n");
          go_straight();
//          HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_SET);
//          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
//          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_15, GPIO_PIN_RESET);

          P2P_Server_App_Context.LedControl.Led1=0x01; /* LED1 ON */
        }
        if(pNotification->DataTransfered.pPayload[1] == 0x02)
        {
          BSP_LED_Off(LED_BLUE);
          APP_DBG_MSG("-- P2P APPLICATION SERVER  : LED1 OFF\n");
          APP_DBG_MSG(" \n\r");
          APP_DBG_MSG("go back!\r\n");
          go_back();
//          HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
//          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);

          P2P_Server_App_Context.LedControl.Led1=0x00; /* LED1 OFF */
        }
        if(pNotification->DataTransfered.pPayload[1] == 0x00)
        {
          BSP_LED_Off(LED_BLUE);
          APP_DBG_MSG("-- P2P APPLICATION SERVER  : LED1 OFF\n");
          APP_DBG_MSG(" \n\r");
          APP_DBG_MSG("STOP!\r\n");
          stop();

          P2P_Server_App_Context.LedControl.Led1=0x00; /* LED1 OFF */
        }

      }
#if(P2P_SERVER1 != 0)  
      if(pNotification->DataTransfered.pPayload[0] == 0x02){ /* end device 1 selected - may be necessary as LB Routeur informs all connection */
        if(pNotification->DataTransfered.pPayload[1] == 0x01)
        {
          BSP_LED_On(LED_BLUE);
          APP_DBG_MSG("-- P2P APPLICATION SERVER 1 : LED1 ON\n");
          APP_DBG_MSG(" \n\r");
          APP_DBG_MSG("turn left!\r\n");
          go_left();
//          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
//          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET);

          P2P_Server_App_Context.LedControl.Led1=0x01; /* LED1 ON */
        }
        if(pNotification->DataTransfered.pPayload[1] == 0x02)
        {
          BSP_LED_Off(LED_BLUE);
          APP_DBG_MSG("-- P2P APPLICATION SERVER 1 : LED1 OFF\n");
          APP_DBG_MSG(" \n\r");
          APP_DBG_MSG("turn right!\r\n");
          go_right();
//          HAL_GPIO_WritePin(GPIOC, GPIO_PIN_6, GPIO_PIN_SET);
//          HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_RESET);

          P2P_Server_App_Context.LedControl.Led1=0x00; /* LED1 OFF */
        }
        if(pNotification->DataTransfered.pPayload[1] == 0x00)
        {
          BSP_LED_Off(LED_BLUE);
          APP_DBG_MSG("-- P2P APPLICATION SERVER 1 : LED1 OFF\n");
          APP_DBG_MSG(" \n\r");
          APP_DBG_MSG("STOP!\r\n");
          stop();

          P2P_Server_App_Context.LedControl.Led1=0x00; /* LED1 OFF */
        }
      }


    找到写操作通知函数以后,我们就可以解析手机端发送给开发板的命令了。
    自定义协议帧:   
           0101  :小车前进
           0102  :小车后退
           0100  :小车停止
           0201  :小车左转
           0202  :小车右转
           0200  :小车停止
     可以先用串口助手调试好以后在与小车进行连接。

     此时使用ST BLE ToolBox与开发板进行连接,使用例程的时候开发板的蓝牙名称为P2PSRV1、

       连接到以后可以看到

     然后我们在手机端打开允许通知选项,可以看到串口数据显示


    然后我们可以使用写命令对开发板进行写数据,我们这里选择写入hex指令。

      然后在串口端得到

我们尝试写入其他命令

    可以发现没有问题,至此蓝牙指令下发与解析完成。

三、调试流程
    调试比较简单,主要是洞洞板焊接的电路不太牢固,有的线轻轻一碰可能就断了。程序主要修改官方的demo来完成设计,刚开始的时候需要阅读一些官方的文档,找到蓝牙协议栈以及应用操作函数。

四、作品展示、制作心得与总结。
       作品展示:             完整的小车如图:
               
      视频链接:

      制作心得:
      主要接触了STM32wb55无线MCU,由于官方的支持很全面,因此上手还是比较容易的,但是一些细节还是需要详细的进行学习。

      总结:
      虽然这次的DIY项目不难,但是通过这次设计我对于STM32WB55这款单片机有了一定的接触和了解,对于使用蓝牙应用的场合是一个很好的选择,由于自己的能力有限,很多东西还不是很了解,希望大家可以多多提出宝贵的意见。









使用特权

评论回复

相关帖子

沙发
gaochy1126| | 2023-1-31 20:29 | 只看该作者
这个ble的app,怎么设置uuid?读写的uuid是怎么确定的?

使用特权

评论回复
板凳
gaochy1126| | 2023-1-31 20:29 | 只看该作者
非常不错的设计,STM32WB55_NUCLEO做蓝牙控制小车的话,资源太充足了。

使用特权

评论回复
地板
lvyunhua| | 2023-2-2 11:59 | 只看该作者
不错,学习了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

201

帖子

1

粉丝