编程环境
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灯的亮灭情况。
以上为本人学习过程,可能还有些许错误,欢迎大家提出问题!一起学习!
感谢观看!