zoukankan      html  css  js  c++  java
  • 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选择多种震动模式

  • 相关阅读:
    Markdown语法
    window环境下获取python安装的路径
    JS 获取当天所在月的第一天的日期,最后一天日期,所在周的每天的日期,时间,所在每月日期,时间的计算
    Vue中父组件向子组件echarts传值问题
    echarts修改X、 Y坐标轴字体的颜色
    Ultibo--树莓派嵌入式系统开发工具
    mORMot使用synDBDataSet时字段类型不正确引起的问题
    UNIGUI接收普通消息和被动回复用户消息
    unigui验证微信服务器的有效性
    unigui不是单个网页相应的链接,而是整体Web Application,如何把webApp的子功能映射到微信公众号菜单?
  • 原文地址:https://www.cnblogs.com/doiting/p/14131714.html
Copyright © 2011-2022 走看看