蓝牙控制esp32单片机(三)

目录

一.前期材料准备

二.具体操作

1.spp蓝牙串口app下载

2.具体操作流程

esp32单片机图例 

 测试代码

3.生成副本进行备份

三.总结

1.操作过程中存在的问题


一.前期材料准备

1.安装vs-code、准备好esp32 开发环境

2.一个电路板。一台电脑

3.一台已下载好spp蓝牙串口的手机

二.具体操作

1.spp蓝牙串口app下载

可在应用商店搜索下载,参照如下图蓝牙控制esp32单片机(三)_第1张图片

 下载完成之后就可以进行链接啦

1.先打开APP,进行注册

2.注册完成之后将进行程序写入

2.具体操作流程

1.使用VS-code打开Espressif中提供的文件,此处本人使用了指导老师提供的代码文件

蓝牙控制esp32单片机(三)_第2张图片

 先使用vs-code对该段程序进行编译、并写入单片机

2.打开蓝牙,使用spp蓝牙串口搜索,找到自己编写的蓝牙名称,JFBike,点击连接

蓝牙控制esp32单片机(三)_第3张图片

 连接成功之后如下图所示,与此同时,单片机蜂鸣器响

蓝牙控制esp32单片机(三)_第4张图片

 3.同时可发送数据,发送成功,蜂鸣器响

蓝牙控制esp32单片机(三)_第5张图片

esp32单片机图例 

蓝牙控制esp32单片机(三)_第6张图片

 测试代码

 以下代码段由指导老师提供,有些许改动,仅供参考。

/* Hello World Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/
/* GPIO Example

   This example code is in the Public Domain (or CC0 licensed, at your option.)

   Unless required by applicable law or agreed to in writing, this
   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
   CONDITIONS OF ANY KIND, either express or implied.
*/

#include 
#include 
#include 
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"

#include "lvgl_init.h"


#include "soc/rtc.h"
#include "driver/mcpwm.h"
#include "soc/mcpwm_periph.h"


#include "time.h"
#include "sys/time.h"
#include "sys/unistd.h"

#include "driver/adc.h"
#include "esp_adc_cal.h"

#include "esp_log.h"

#define _SUPPORT_BT_ 1




typedef unsigned char  u8;
typedef unsigned short u16;
typedef unsigned int   u32;

uint8_t DebugOn = 1;
#define DEBUG_CODE    if(DebugOn)

#define GPIO_OUTPUT_IO_BEEP         19


#define START_BEEP      {mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_0);}
#define STOP_BEEP       {mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_0);}

// #define POWER_ON        {mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_2);}
// #define POWER_OFF       {mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_2);}

#define SET_PWR(x)   {gpio_set_level(GPIO_OUTPUT_IO_PWR,   x);}

#define GPIO_OUTPUT_IO_LED2      15
#define GPIO_OUTPUT_IO_LED3      2
#define GPIO_OUTPUT_IO_LED4      4


#define GPIO_OUTPUT_PIN_SEL  ((1ULL<=BeepOFFTime)      //蜂鸣器响&&当前时间大于关闭时间
		{
			isBeepOn=0;             //低电平
			STOP_BEEP;              //关闭蜂鸣器
		}

}


void InitHardware()
{
    mcpwm_config_t pwm_config;
    pwm_config.frequency = 4000;    //frequency = 1000Hz
    pwm_config.cmpr_a = 80.0;       //duty cycle of PWMxA = 60.0%
    pwm_config.counter_mode = MCPWM_UP_COUNTER;
    pwm_config.duty_mode = MCPWM_DUTY_MODE_1;
    mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &pwm_config);   //Configure PWM0A & PWM0B with above settings
    mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_0);
    mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, GPIO_OUTPUT_IO_BEEP);

    gpio_config_t io_conf;
    //disable interrupt
    io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
    //bit mask of the pins, use GPIO4/5 here
    io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
    //set as input mode
    io_conf.mode = GPIO_MODE_INPUT;
    //enable pull-up mode
    io_conf.pull_up_en = 1;
    io_conf.pull_down_en = 0;
    gpio_config(&io_conf);


    io_conf.intr_type = GPIO_PIN_INTR_DISABLE;
    //set as output mode
    io_conf.mode = GPIO_MODE_OUTPUT;
    //bit mask of the pins that you want to set,e.g.GPIO18/19
    io_conf.pin_bit_mask = GPIO_OUTPUT_PIN_SEL;
    //disable pull-down mode
    io_conf.pull_down_en = 1;
    //disable pull-up mode
    io_conf.pull_up_en = 0;
    //configure GPIO with the given settings
    gpio_config(&io_conf);
    SET_LED2(0);
    SET_LED3(0);
    SET_LED4(0);
}




//BT-SPP{{{{{

#define TAG "HW"


uint8_t derived_mac_addr[6] = {0};
int BTHandle=-1;
#include 
#include 
#include 
#include 
#include "nvs.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_gap_bt_api.h"
#include "esp_bt_device.h"
#include "esp_spp_api.h"

#include "time.h"
#include "sys/time.h"

#include "mbedtls/sha256.h"

#define SPP_TAG "BT"
#define SPP_SERVER_NAME "SPP_SERVER"
#define EXCAMPLE_DEVICE_NAME "JFBike"   
#define SPP_SHOW_DATA 0
#define SPP_SHOW_SPEED 1
#define SPP_SHOW_MODE SPP_SHOW_SPEED    /*Choose show mode: show data or speed*/


#define SPP_DATA_LEN 20
static uint8_t spp_data[SPP_DATA_LEN];

#if _SUPPORT_BT_
static const esp_spp_mode_t esp_spp_mode = ESP_SPP_MODE_CB;
#endif

static const esp_spp_sec_t sec_mask = ESP_SPP_SEC_NONE;
static const esp_spp_role_t role_slave = ESP_SPP_ROLE_SLAVE;
static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
    switch (event) {
    case ESP_SPP_INIT_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_INIT_EVT");
        esp_bt_dev_set_device_name(EXCAMPLE_DEVICE_NAME);
        // {//设置配对密码,不起作用
        //         esp_bt_pin_type_t pin_type = ESP_BT_PIN_TYPE_VARIABLE;
        //         esp_bt_pin_code_t pin_code={'1','2','3','4','5','6',};
        //         esp_bt_gap_set_pin(pin_type, 6, pin_code);
        // }
        //esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
		esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE);  //---支持IDF4.3,Windows编译——ymj
        esp_spp_start_srv(sec_mask,role_slave, 0, SPP_SERVER_NAME);
        break;
    case ESP_SPP_DISCOVERY_COMP_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_DISCOVERY_COMP_EVT");
        break;
    case ESP_SPP_OPEN_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_OPEN_EVT");
        break;
    case ESP_SPP_CLOSE_EVT:  ///断连
        ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT,handle=%d",param->data_ind.handle);
		BTHandle=-1;
		BeepOn(300);
        break;
    case ESP_SPP_START_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_START_EVT");
        break;
    case ESP_SPP_CL_INIT_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_CL_INIT_EVT");
        break;
    case ESP_SPP_DATA_IND_EVT: //收到数据
		BTHandle=param->data_ind.handle;
        ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d",
                param->data_ind.len, param->data_ind.handle);
        esp_log_buffer_hex("",param->data_ind.data,param->data_ind.len);
        esp_spp_write(BTHandle,param->data_ind.len,param->data_ind.data);  //原样发送收到的数据
        BeepOn(100);     //成功接收数据蜂鸣器响100ms
        break;
    case ESP_SPP_CONG_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_CONG_EVT");
        break;
    case ESP_SPP_WRITE_EVT://发送数据
        ESP_LOGI(SPP_TAG, "ESP_SPP_WRITE_EVT");
       //BeepOn(50);    //发送成功蜂鸣器响50ms
        break;
    case ESP_SPP_SRV_OPEN_EVT:   //连接
        ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT,handle=%d",param->data_ind.handle);
		BTHandle=param->data_ind.handle;
		BeepOn(700);   //蓝牙链接成功蜂鸣器响700ms
        break;
    default:
        break;
    }
}

//}}}}}BT-SPP


void app_main()
{

    InitHardware();  //初始化

    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK( ret );

    BeepOn(100);

/
//BT-SPP{{{{{


	esp_read_mac(derived_mac_addr, ESP_MAC_BT);

	for (int i = 0; i < SPP_DATA_LEN; ++i) {
        spp_data[i] = 0x30+i;
    }
    esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT();
    if ((ret = esp_bt_controller_init(&bt_cfg)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s initialize controller failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }else
    {
        ESP_LOGI(SPP_TAG, "esp_bt_controller_init() ok");
    }
    if ((ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s enable controller failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }else
    {
        ESP_LOGI(SPP_TAG, "esp_bt_controller_enable() ok");
    }

    if ((ret = esp_bluedroid_init()) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s initialize bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }else
    {
        ESP_LOGI(SPP_TAG, "esp_bluedroid_init() ok");
    }

    if ((ret = esp_bluedroid_enable()) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s enable bluedroid failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }else
    {
        ESP_LOGI(SPP_TAG, "esp_bluedroid_enable() ok");
    }

    if ((ret = esp_spp_register_callback(esp_spp_cb)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s spp register failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }else
    {
        ESP_LOGI(SPP_TAG, "esp_spp_register_callback() ok");
    }

    // esp_power_level_t min,max;
    // esp_bredr_tx_power_get(&min,&max);
    // ESP_LOGI(TAG, "BT Power(init): %d/%d",min,max);
    // min=ESP_PWR_LVL_N12;
    // max=ESP_PWR_LVL_N9;
    // esp_bredr_tx_power_set(min,max);
    // esp_bredr_tx_power_get(&min,&max);
    // ESP_LOGI(TAG, "BT Power(new): %d/%d",min,max);


    if ((ret = esp_spp_init(esp_spp_mode)) != ESP_OK) {
        ESP_LOGE(SPP_TAG, "%s spp init failed: %s\n", __func__, esp_err_to_name(ret));
        return;
    }else
    {
        ESP_LOGI(SPP_TAG, "esp_spp_init() ok");
    }

	ESP_LOGI(TAG, "BT Started.");
	//xTaskCreate(SPPC_Send_task, "SPPC_Send_task", 10000, NULL, 5, NULL);
	//ESP_LOGI(TAG, "xTaskCreate(SPPC_Send_task)");

//}}}}}BT-SPP
/
//CSDN小赖的Today
//修改以下代码进行调试
   
   printf("System Started\n");
    int i;
    char SendStr[100];
    long LastReportTime=0;
    while(1)
    {
        if(CurrentTime-LastReportTime>=5000)  //5000ms=5s
        {
            LastReportTime=CurrentTime;
            for(i=0;i<=5;i++)  //可将SendStr[0]改为循环进行数据发送
            {
                SendStr[i]='a'+i;
            }
          //  SendStr[0]='a';
           // SendStr[1]='b';
           // SendStr[2]='c';
           // SendStr[3]='d';
          //  SendStr[4]='e';
            printf("UpdateCurrentTime = %ld\n",CurrentTime);
            if(BTHandle>=0)
            {
                esp_spp_write(BTHandle, 5, (unsigned char *) SendStr);
            }
            
        }
        BeepHandle();
        UpdateCurrentTime();
        vTaskDelay(10/ portTICK_RATE_MS);
    }

}
//CSDN小赖的Today

3.生成副本进行备份

在调试过程中,当代码出现问题时,有备份能够最简单的恢复到最近状态,可以尽可能的减小代码出问题引起的灾难。

复制粘贴完成之后,可以将下图标记的两个灰色文件夹删除,减少所占内存空间。最后,修改文件名称。

蓝牙控制esp32单片机(三)_第7张图片

蓝牙控制esp32单片机(三)_第8张图片

三.总结

1.操作过程中存在的问题

1.在使用Espressif中提供的文件时,犯了一个很大的错误。

在选择文件时,我直接选择了总的bluetooth大文件,这个大文件它包含了很多小文件,在vs-code中直接打开去编译是错误的

蓝牙控制esp32单片机(三)_第9张图片

正确的文件选择可以选择classic_bt中的文件

蓝牙控制esp32单片机(三)_第10张图片

打开classic_bt可以看到有许多文件,选择一个文件打开,如图所示。接着从vs-code选择一个文件,其打开后可以看到 Makefile 文件,则选择正确。此处我选择的是bt_spp_initiator文件

蓝牙控制esp32单片机(三)_第11张图片

以上为本人学习过程,可能还有些许错误,欢迎大家提出问题!一起学习!

感谢观看!

你可能感兴趣的:(单片机学习,单片机,嵌入式硬件,物联网)