一、超低功耗蓝牙 BLE 5.0 模组介绍
本次评测选用的是大联大 世平安森美 超低功耗蓝牙BLE 5.0 开发模组。
该模组包括蓝牙开发板和自发电无线遥控开关,蓝牙模组采用SiP封装集成天线,体积仅为:6x8x1.46mm 。具体参数参考安美森半导体官网。蓝牙开发模组和自发电无线遥控开关如下图所示:
开发板.jpg 开关.jpg
图1蓝牙开发模组和自发电无线遥控开关实物图
二、系统架构
本次评测实现的项目是“远程控制LED灯及红外报警”。系统架构如下图所示,包括BLE开发板、电源、红绿黄三色LED灯、红外对射、手机。
架构.jpg
图2系统架构图
三、功能展示
(1)系统运行后,通过手机上运行的蓝牙调试助手可以搜索到本项目的蓝牙名称“LED_ALARM”。当没有物体遮挡红外对射时,绿色LED灯亮起。如下图所示:
G.jpg
图3系统运行绿色灯亮
(2)当有物体遮挡红外对射时,红色LED灯亮起。此时为报警状态。如下图所示:
R.jpg
图4异物闯入红色灯亮
(3)通过手机向开发板发送“Y”,此时黄色LED灯亮起。如下图所示:
Y.jpg
图5手机控制黄色灯亮
四、关键代码
本项目主要用到GPIO的输入和输出,输入采用中断的方式,核心代码如下:
  1. /* ----------------------------------------------------------------------------
  2. * Function      : void DIO0_IRQHandler(void)
  3. * ----------------------------------------------------------------------------
  4. * Description   : Toggle the toggle status global flag.
  5. * Inputs        : None
  6. * Outputs       : None
  7. * Assumptions   : None
  8. * ------------------------------------------------------------------------- */
  9. void DIO0_IRQHandler(void)
  10. {
  11.     if (DIO_DATA->ALIAS[BUTTON_DIO] == 0)
  12.     {
  13.             LED_Flag='R';
  14.             PRINTF("ALARM START\r\n");
  15.     }
  16.     else if (DIO_DATA->ALIAS[BUTTON_DIO] == 1)
  17.         {
  18.             LED_Flag='G';
  19.                 PRINTF("ALARM STOP\n");
  20.         }
  21. }
  22. int main(void)
  23. {
  24.     App_Initialize();
  25.     Sys_GPIO_Set_High(LED_DIO_R);
  26.     Sys_GPIO_Set_High(LED_DIO_G);
  27.     Sys_GPIO_Set_High(LED_DIO_Y);
  28.     LED_Flag=0;
  29.     /* Debug/trace initialization. In order to enable UART or RTT trace,
  30.      * configure the 'OUTPUT_INTERFACE' macro in printf.h */
  31.     printf_init();
  32.     PRINTF("__peripheral_server has started!\n");
  33.     for (unsigned int i = 0; i < 40; i++)
  34.         {
  35.                 BLE_Receive[i] = 0;
  36.         }
  37.     /* Main application loop:
  38.      * - Run the kernel scheduler
  39.      * - Send notifications for the battery voltage and RSSI values
  40.      * - Refresh the watchdog and wait for an interrupt before continuing */
  41.     while (1)
  42.     {
  43.         Kernel_Schedule();
  44.         for (unsigned int i = 0; i < NUM_MASTERS; i++)
  45.         {
  46.             if (ble_env[i].state == APPM_CONNECTED)
  47.             {
  48.                 /* Send battery level if battery service is enabled */
  49.                 if (app_env.send_batt_ntf[i] && bass_support_env[i].enable)
  50.                 {
  51.                     PRINTF("__SEND BATTERY LEVEL %d\n",app_env.batt_lvl);
  52.                     app_env.send_batt_ntf[i] = 0;
  53.                     Batt_LevelUpdateSend(ble_env[i].conidx,
  54.                                          app_env.batt_lvl, 0);
  55.                 }
  56.                 /* Update custom service characteristics, send notifications if
  57.                  * notification is enabled */
  58.                 if (cs_env[i].tx_value_changed && cs_env[i].sent_success)
  59.                 {
  60.                     cs_env[i].tx_value_changed = false;
  61.                     (cs_env[i].val_notif)++;
  62.                     if (cs_env[i].tx_cccd_value & ATT_CCC_START_NTF)
  63.                     {
  64.                         memset(cs_env[i].tx_value, cs_env[i].val_notif,
  65.                                CS_TX_VALUE_MAX_LENGTH);
  66.                         CustomService_SendNotification(ble_env[i].conidx,
  67.                                                        CS_IDX_TX_VALUE_VAL,
  68.                                                        &cs_env[i].tx_value[0],
  69.                                                        CS_TX_VALUE_MAX_LENGTH);
  70.                     }
  71.                 }
  72.                 /* Update TX long characteristic if new RX long characteristic was received.
  73.                  * Write the inverted version of RX characteristic into TX */
  74.                 if (cs_env[i].rx_long_value_changed == true)
  75.                 {
  76.                     for (unsigned int j = 0; j < CS_RX_LONG_VALUE_MAX_LENGTH; j++)
  77.                     {
  78.                             BLE_Receive[j] = cs_env[i].rx_long_value[j];
  79.                             cs_env[i].rx_long_value[j]=0;
  80.                     }
  81.                     if(BLE_Receive[0]=='Y')
  82.                     {
  83.                             LED_Flag='Y';
  84.                             for (unsigned int i = 0; i < 40; i++)
  85.                                                 {
  86.                                                         BLE_Receive[i] = 0;
  87.                                                 }
  88.                     }
  89.                 }
  90.             }
  91.         }
  92.         if(LED_Flag=='R')
  93.         {
  94.                 Sys_GPIO_Set_Low(LED_DIO_R);
  95.                 Sys_GPIO_Set_High(LED_DIO_G);
  96.                 Sys_GPIO_Set_High(LED_DIO_Y);
  97.                 PRINTF("LED RED is ON\r\n");
  98.                 LED_Flag=0;
  99.         }
  100.         else if(LED_Flag=='G')
  101.         {
  102.                 Sys_GPIO_Set_High(LED_DIO_R);
  103.                 Sys_GPIO_Set_Low(LED_DIO_G);
  104.                         Sys_GPIO_Set_High(LED_DIO_Y);
  105.                         PRINTF("LED GREEN is ON\r\n");
  106.                         LED_Flag=0;
  107.         }
  108.         else if(LED_Flag=='Y')
  109.         {
  110.                 Sys_GPIO_Set_High(LED_DIO_R);
  111.                         Sys_GPIO_Set_High(LED_DIO_G);
  112.                         Sys_GPIO_Set_Low(LED_DIO_Y);
  113.                         PRINTF("LED YELLOW is ON\r\n");
  114.                         LED_Flag=0;
  115.         }
  116.         else
  117.         {
  118.                 ;
  119.                 //Sys_GPIO_Set_High(LED_DIO_R);
  120.                         //Sys_GPIO_Set_High(LED_DIO_G);
  121.                         //Sys_GPIO_Set_High(LED_DIO_Y);
  122.                         //PRINTF("ALL LED is OFF\r\n");
  123.         }
  124.         /* Refresh the watchdog timer */
  125.         Sys_Watchdog_Refresh();
  126.         /* Wait for an event before executing the scheduler again */
  127.         SYS_WAIT_FOR_EVENT;
  128.     }
  129. }

五、总结
本项目主要实现了红外对射判断是否有物体闯入并进行报警。当系统处于正常状态时为绿灯,当有物体闯入时为红灯,当需要进行维护时通过手机控制亮黄灯。可以将本项目进行拓展用于以下场景:
安防领域;
智慧交通;
生产线货物检测;
智能家居。