zhangrui123 发表于 2023-1-29 02:08

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

本帖最后由 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应用的时候,应该操作哪些函数。
      找到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 == 0x01){ /* ALL Deviceselected - may be necessary as LB Routeur informs all connection */
      if(pNotification->DataTransfered.pPayload == 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 == 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 == 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 == 0x02){ /* end device 1 selected - may be necessary as LB Routeur informs all connection */
      if(pNotification->DataTransfered.pPayload == 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 == 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 == 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来完成设计,刚开始的时候需要阅读一些官方的文档,找到蓝牙协议栈以及应用操作函数。

四、作品展示、制作心得与总结。
       作品展示:             完整的小车如图:
               
      视频链接:https://www.bilibili.com/video/BV1pP4y167hQ/?vd_source=8b40a883db63049dd79fbf9aa99f9989

      制作心得:
      主要接触了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

不错,学习了
页: [1]
查看完整版本: 我的无线DIY设计—基于STM32WB55_NUCLEO​的遥控小车