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 = '\0'; } 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] = '\0'; } 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选择多种震动模式