BL602&BL604综合项目2:dolphin蓝牙跳蛋

本项目为一款蓝牙跳蛋的设计,主控芯片为BL602,通过PWM控制震动马达的转速实现不同的震动强度变化,通过蓝牙连接设备,APP下发蓝牙指令实现设备的控制。

项目地址:

https://github.com/SmartArduino/Doiting_BL/tree/master/examples/dolphin

蓝牙初始化:

void do_ble_init(void){
    // Initialize BLE controller
    LOGI(TAG, "do_ble_init ");
    ble_controller_init(configMAX_PRIORITIES - 1);
    //Initialize BLE Host stack
    hci_driver_init();
    bt_enable(bt_ready_cb);
    bt_set_name("LVS-Lush122-XT");
    bt_gatt_service_register((struct bt_gatt_service *)&dis);
    notify_attrs = &ble_attrs[1];
    bt_conn_cb_register(&conn_callbacks);
    ble_start_advertise();
}

蓝牙接收到的数据处理:

//蓝牙处理函数
static void ble_reve_cb(struct bt_conn *conn, const char *buf, u16_t len){    
    
    char cmd[30] = "";
    char data[15] = "";
    char ret_str[20] = "OK";
    //LOGI(TAG, "ble_reve_buf: %s", buf);
    //do_ble_notify(conn, ret_str, strlen(ret_str));
    char *dp = strchr(buf,';');
    if(dp == NULL){
        return;
    }else{
        *dp = '';
    }
    LOGI(TAG, "ble_reve_buf: %s", buf);
    char *p = strchr(buf,':');

    if(p != NULL){
        strncpy(cmd, buf, p-buf);
        strncpy(data, p+1, len-(int)(p-buf)-2);
    }else{
        strcpy(cmd, buf);
        cmd[len-1] = '';
    }
    LOGI(TAG, "cmd: %s  data: %s", cmd, data);

    if(CDM_CMP(cmd, "Status")){
        LOGI(TAG, "get Status");
        do_ble_notify(conn, ret_str, strlen(ret_str));
    }
    
    
    else if(CDM_CMP(cmd, "Vibrate")){           //蓝牙在线模式控制
        LOGI(TAG, "set Vibrate");
        vibrate = atoi(data);
       Preset=0;
       current_Preset=0;
       //do_ble_notify(conn, ret_str, strlen(ret_str));
    }
    
    
    else if(CDM_CMP(cmd, "Preset")){            //9种预设模式选择
        LOGI(TAG, "set Vibrate");
        Preset = atoi(data);

    }
    
    else if(CDM_CMP(cmd, "Battery")){           //获取电量

        int32_t percent=get_battery();           //电池百分比
        if(percent==100) {ret_str[0]='1';ret_str[1]='0';ret_str[2]='0';}
        else{
        int8_t shiwei= percent/10; int8_t gewei= percent%10;
        ret_str[0]='0';
        ret_str[1]=shiwei+'0';
        ret_str[2]=gewei+'0';
    }
        ret_str[3]=';';
        do_ble_notify(conn, ret_str, strlen(ret_str));//设备蓝牙回复当前电量

    }
    
    else if(CDM_CMP(cmd,"Light")){      //灯光闪烁开关
        if(data[0]=='o'&&data[1]=='n'){ 
        light_flag=true;
        if(ble_connect) bl_gpio_output_set(LED_STATUS, 0);
        }
        if(data[0]=='o'&&data[1]=='f'&&data[2]=='f'){
        light_flag=false;
        }
    }
    
    else if(CDM_CMP(cmd,"PowerOff")){   //关闭设备
        sleep_start();   
    }

    else if(CDM_CMP(cmd,"OTA")){         //蓝牙发送  OTA;   进入OTA
    LOGI(TAG, "OTA");
    ota_flag=true;
    flash_storage_init();
    wifi_init(wifi_event_handler);
    vTaskDelay(500 / portTICK_RATE_MS);
    wifi_setup_sta();
    ota_time= hal_timer_now_s();          //记录OTA开始的时间
    char ota_ret[20]="OTA_START";
    do_ble_notify(conn, ota_ret, strlen(ota_ret));
    }

    else if(CDM_CMP(cmd,"WIFI")){          //蓝牙配网指令: "WIFI:账号,密码;"
    LOGI(TAG, "SET WIFI ");
    user_ssid_t *wifi_info = flash_get_user_ssid_config();
    memset(wifi_info->ssid, 0, sizeof(wifi_info->ssid));
    memset(wifi_info->password, 0, sizeof(wifi_info->password));
    flash_ssid_config_write();
    char *p = strchr(data,',');
      if(p != NULL){
        strncpy(wifi_info->ssid, data, p-data);
        strncpy(wifi_info->password, p+1, len-(int)(p-data)-2);
        flash_ssid_config_write();
        char ret[20]="SET_WIFI";
        do_ble_notify(conn, ret, strlen(ret));
        do_ble_notify(conn, wifi_info->ssid, strlen(wifi_info->ssid));
        do_ble_notify(conn, wifi_info->password, strlen(wifi_info->password));
        
    LOGI(TAG,"saved SSID: %s, passwd: %s", wifi_info->ssid, wifi_info->password);
    }
    }
    vTaskDelay(100 / portTICK_RATE_MS);

    //do_ble_notify(conn, ret_str, strlen(ret_str));
}

对蓝牙下发的指令进行解析,根据解析后的指令经行震动马达和灯光的控制:

void mada_task(void *arg){         //mada模式

uint32_t duty = 0;
int i=0;
while(1){
    if(!ble_connect&&(charge_status == DISCHARGE)){                        //四档离线模式
        if(Grade==0) motor_g_set_vibrate(0);
        if(Grade==1) motor_g_set_vibrate(8);
        if(Grade==2) motor_g_set_vibrate(12);
        if(Grade==3) motor_g_set_vibrate(16);
        if(Grade==4) motor_g_set_vibrate(20);
    }
    else if(ble_connect&&(charge_status == DISCHARGE)&&Preset==0){          //蓝牙在线模式
        motor_g_set_vibrate(vibrate);
        if(vibrate==0)led_status_flash(0);                                     
    }
    else if(ble_connect&&(charge_status == DISCHARGE)&&Preset!=0){
        memcpy(currentPreMod,presetMod[Preset-1],8);
        for(i=0;i<8;i++){
        duty =currentPreMod[i]*100;
        motor_g_set_duty(duty);
        current_Preset=currentPreMod[i];
        if(light_flag){led_status_flash(115-current_Preset);}                   //9种预设模式灯光,在此实现跟马达同时变化
        vTaskDelay(300 / portTICK_RATE_MS);
        LOGI(TAG, "presetMod:%d",currentPreMod[i]);
    }
    }
    else {motor_g_set_vibrate(0);Grade=0;vibrate=0;}
    vTaskDelay(100/portTICK_RATE_MS);
}
}

9种预设模式变化频率,可以在此调整每个模式下的震动频率变化

const uint8_t presetMod[9][8] =
{
        { 100, 20, 100, 20, 100, 20, 100, 20 },     //Mod1
        { 50, 100, 50, 100, 50, 100, 50, 100 },     //Mod2
        { 40, 60, 80, 100, 100, 80, 60, 40 },       //Mod3
        { 100, 25, 100, 25, 100, 25, 100, 25 },     //Mod4
        { 75, 100, 75, 100, 75, 100, 75, 100 },     //Mod5
        { 20, 100, 60, 100, 60, 100, 30, 60 },      //Mod6
        { 75, 30, 20, 30, 100, 30, 25, 60 },        //Mod7
        { 100, 100, 100, 100, 100, 100, 100, 100 }, //Mod8
        { 38, 100, 80, 47, 28, 20, 28, 44 },        //Mod9
};

自动低功耗休眠任务:

void sleep_task(void *arg){           //大于1200S无震动,进入休眠模式
static int times=0;
while(1){
//LOGI(TAG, "start sleep");
    if(Grade==0&&vibrate==0&&(charge_status == DISCHARGE)&&Preset==0) times++;
    else times=0;
    if(ota_flag) times =0;

   //LOGI(TAG, "times:%d",times);

    while(times>1200) {        
        hal_hbn_init(&key_weakup_pin, 1);
        hal_hbn_enter(0);}
    while(ota_flag&&(hal_timer_now_s()-ota_time>300)){
        hal_hbn_init(&key_weakup_pin, 1);
        hal_hbn_enter(0);
    }
        vTaskDelay(1000 / portTICK_RATE_MS);
}

}

 

将程序编译好后烧录到芯片中,手机下载APP,连接设备蓝牙控制震动马达。

1.扫码下载APP

2.连接设备

 

3. APP控制设备,可在APP选择多种震动模式

原文地址:https://www.cnblogs.com/doiting/p/14131714.html