蓝牙控制esp-32单片机(四)

编程环境

vs-code、电路板、手机APP:spp蓝牙串口

 

 

基本内容操作

本次是基于前两篇文章相结合所得到的应用

使用vs-code将蓝牙链接和单片机开关控制简单的结合

测试代码如下


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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 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  //LED灯引脚
#define GPIO_OUTPUT_IO_LED3      2
#define GPIO_OUTPUT_IO_LED4      4
#define GPIO_OUTPUT_IO_BEEP        19  // 蜂鸣器引脚

#define GPIO_OUTPUT_PIN_SEL  ((1ULL<<GPIO_OUTPUT_IO_LED2) | (1ULL<<GPIO_OUTPUT_IO_LED3) | (1ULL<<GPIO_OUTPUT_IO_LED4))

#define SET_LED2(x)    {gpio_set_level(GPIO_OUTPUT_IO_LED2,   x);}
#define SET_LED3(x)  {gpio_set_level(GPIO_OUTPUT_IO_LED3, x);}
#define SET_LED4(x)   {gpio_set_level(GPIO_OUTPUT_IO_LED4,  x);}


#define GPIO_INPUT_IO_SW3     14  //开关引脚
#define GPIO_INPUT_IO_SW4     12
#define GPIO_INPUT_IO_SW5     13

#define GPIO_INPUT_PIN_SEL  ( (1ULL<<GPIO_INPUT_IO_SW3)|(1ULL<<GPIO_INPUT_IO_SW4)|(1ULL<<GPIO_INPUT_IO_SW5))


#define GET_SW3 (gpio_get_level(GPIO_INPUT_IO_SW3))
#define GET_SW4 (gpio_get_level(GPIO_INPUT_IO_SW4))
#define GET_SW5 (gpio_get_level(GPIO_INPUT_IO_SW5))


long CurrentTime=0;
void UpdateCurrentTime(void)  //重置时间
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    CurrentTime=tv.tv_sec*1000+tv.tv_usec/1000;
}
   
int isBeepOn=0;
long BeepOFFTime=0;   //蜂鸣器关闭的时间

void BeepOn(int ms)   //控制蜂鸣器响的时间
{
    UpdateCurrentTime();  //时间置为0
	isBeepOn=1;            //置1 
	START_BEEP;            //蜂鸣器响
	BeepOFFTime=CurrentTime+ms;   //蜂鸣器关闭的时间
}

void BeepHandle()   //处理蜂鸣器
{
    		//BEEP  如果置1,当前时间 > 蜂鸣器关闭的时间
		if(isBeepOn&&CurrentTime>=BeepOFFTime)
		{
			isBeepOn=0; //置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 <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#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);  ///断连 响300ms
        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");
        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(800);   //连接成功 响800ms
        break;
    default:
        break;
    }
}

//}}}}}BT-SPP


//LED灯  {{{
void TaskReadSW3(void* arg)
{
    uint32_t io_num;

    while(1)
	{
		if(gpio_get_level(GPIO_INPUT_IO_SW3))//按下是1,松开是0
		{
			gpio_set_level(GPIO_OUTPUT_IO_LED2, 0);//输出0,灯灭
		//gpio_set_level(GPIO_OUTPUT_IO_BEEP, 0);//输出0,蜂鸣器不响
		}else
		{
            gpio_set_level(GPIO_OUTPUT_IO_LED2, 0);//输出0,灯灭
            vTaskDelay(200 / portTICK_RATE_MS);//延时200ms
			gpio_set_level(GPIO_OUTPUT_IO_LED2, 1);//输出1,2灯亮
            vTaskDelay(50 / portTICK_RATE_MS);//延时50ms
            gpio_set_level(GPIO_OUTPUT_IO_LED3, 1);//输出1,3灯亮
            vTaskDelay(50 / portTICK_RATE_MS);//延时50ms
            gpio_set_level(GPIO_OUTPUT_IO_LED4, 1);//输出1,4灯亮
            vTaskDelay(100 / portTICK_RATE_MS);//延时100ms

            BeepOn(50);   //蜂鸣器 响50ms

            vTaskDelay(50 / portTICK_RATE_MS);//延时50ms

		}
		vTaskDelay(500 / portTICK_RATE_MS);//延时500ms
       // BeepOn(500);   //蜂鸣器 响500ms
	}
}

void TaskReadSW4(void* arg)
{
    uint32_t io_num;

    while(1)
	{
		if(gpio_get_level(GPIO_INPUT_IO_SW4))//按下是1,松开是0
		{
			gpio_set_level(GPIO_OUTPUT_IO_LED3, 0);//输出0,灯灭

		}else
		{
            gpio_set_level(GPIO_OUTPUT_IO_LED3, 0);//输出0,灯灭
            vTaskDelay(200 / portTICK_RATE_MS);//延时200ms
            gpio_set_level(GPIO_OUTPUT_IO_LED4, 1);//输出1,4灯亮
            vTaskDelay(50 / portTICK_RATE_MS);//延时50ms
			gpio_set_level(GPIO_OUTPUT_IO_LED3, 1);//输出1,3灯亮
            vTaskDelay(50 / portTICK_RATE_MS);//延时50ms
			gpio_set_level(GPIO_OUTPUT_IO_LED2, 1);//输出1,2灯亮
            vTaskDelay(50 / portTICK_RATE_MS);//延时50ms
		}
		vTaskDelay(500 / portTICK_RATE_MS);//延时500ms
	}
}
void TaskReadSW5(void* arg)
{
    uint32_t io_num;

    while(1)
	{
		if(gpio_get_level(GPIO_INPUT_IO_SW5))//按下是1,松开是0
		{
			gpio_set_level(GPIO_OUTPUT_IO_LED4, 0);//输出0,灯灭

		}else
		{
            gpio_set_level(GPIO_OUTPUT_IO_LED4, 0);//输出0,灯灭
             vTaskDelay(200 / portTICK_RATE_MS);//延时200ms
           ///BeepOn(20);   //蜂鸣器 响20ms
			gpio_set_level(GPIO_OUTPUT_IO_LED4, 1);//输出1,4灯亮
            vTaskDelay(50 / portTICK_RATE_MS);//延时50ms
            gpio_set_level(GPIO_OUTPUT_IO_LED2, 1);//输出1,2灯亮
             vTaskDelay(50 / portTICK_RATE_MS);//延时60ms
            gpio_set_level(GPIO_OUTPUT_IO_LED3, 1);//输出1,3灯亮
            vTaskDelay(50 / portTICK_RATE_MS);//延时50ms


		}
		vTaskDelay(500 / portTICK_RATE_MS);//延时500ms
	}
}

/}}}
//LED灯


void app_main()
{
    ///{{
    控制LED灯
    gpio_config_t io_conf;
    //disable interrupt
    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 = 0;
    //disable pull-up mode
    io_conf.pull_up_en = 0;
    //configure GPIO with the given settings
    gpio_config(&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;
    gpio_config(&io_conf);

   //}}

   //蓝牙
    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
/

   
    //start gpio task
    xTaskCreate(TaskReadSW3, "TaskReadSW3", 2048, NULL, 10, NULL);
    xTaskCreate(TaskReadSW4, "TaskReadSW4", 2048, NULL, 10, NULL);
    xTaskCreate(TaskReadSW5, "TaskReadSW5", 2048, NULL, 10, NULL);

    int cnt = 0;

   printf("System Started\n");
    
    char SendStr[100];
    long LastReportTime=0;
    while(1)
    {
        if(CurrentTime-LastReportTime>=5000)
        {
            LastReportTime=CurrentTime;
            SendStr[0]='a';
            SendStr[1]='b';
            SendStr[2]='c';
            SendStr[3]='d';
            SendStr[4]='e';

            if(BTHandle>=0)
            {
                esp_spp_write(BTHandle, 5, (unsigned char *) SendStr);
            }
            
        }


        BeepHandle();
        UpdateCurrentTime();
        vTaskDelay(10/ portTICK_RATE_MS);
    }

}


将此代码下载至电路板,可同时使用spp蓝牙串口APP进行蓝牙链接和开关控制LED灯

总结

功能不足,需待加强。

下一步应将LED灯与蓝牙连接起来,实现手机远程蓝牙控制LED灯的亮灭情况。

 

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

感谢观看!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

久长愿长久

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值