這篇文章介紹Raspberry Pi Pico W使用BTstack bluetooth HID功能,製作一組HID Bluetooth Mouse。使用模擬設備為HW-504 joystick 模組。
HW-504為一個x-y方向2D的電位計,因此在Pi Pico W使用GPIO pin 26(ADC NUM 0)接VRx腳位,GPIO pin 27(ADC NUM 1)接VRy腳位,SW開關壓下時為接地,本實驗使用的模組未接上拉電位,因此要先接一個上拉電阻。
BTstack example 有一個hid_mouse_demo.c程式碼,本次實驗直接使用,因為在檔案中很多宣告為static,所以在主程式中#include "hid_mouse_demo.c"當作程式的一部分。
根據 HID Descriptor, input report含有三個bytes,第一個byte 最小三個位元分別為代表滑鼠按鈕,值為0與1,第2個byte為x軸移動速度,值為-127~127,第個byte為y軸移動速度,值為-127~127。
主程式如下說明:
hid_device_request_can_send_now(hid_cid);
展示影片:
程式碼如下:
hid_mouse_demo.c需作下列三項修正。
- picow_bt_mouse_joystick.c
#include <stdio.h> #include "pico/stdlib.h" #include "hardware/adc.h" #include "hardware/gpio.h" #include "stdlib.h" #include "pico/cyw43_arch.h" #include "hid_mouse_demo.c" #define ADC_X_PIN 26 #define ADC_X_NUM 0 #define ADC_Y_PIN 27 #define ADC_Y_NUM 1 #define ADC_VREF 3.3 #define ADC_RANGE (1<<12) // pi pico 12 bits ADC #define BUTTON_PIN 16 #define STEP 256 // min 16, 2048/256=8, mouse moving speed 0~8 uint32_t adc_x_center=0; uint32_t adc_y_center=0; int main() { stdio_init_all(); if (cyw43_arch_init()) { printf("cyw43 arch init error\n"); return 0; } btstack_main(0, NULL); gpio_init(BUTTON_PIN); gpio_set_dir(BUTTON_PIN, false); adc_init(); // init and assign ADC pin adc_gpio_init(ADC_X_PIN); adc_gpio_init(ADC_Y_PIN); for (int i=0; i < 100; i++) { // average 100 samples as mouse static position adc_select_input(ADC_X_NUM); adc_x_center += adc_read(); adc_select_input(ADC_Y_NUM); adc_y_center += adc_read(); } adc_x_center /=100; adc_y_center /=100; printf("x:%d, y:%d\n", adc_x_center, adc_y_center); uint adc_raw=ADC_RANGE/2; uint adc_x=ADC_RANGE/2; uint adc_y=ADC_RANGE/2; bool button_pressed=false; bool mouse_moving=false; while(1) { if (abs(adc_x-adc_x_center) < 10 && abs(adc_y-adc_y_center) < 10) { mouse_moving=false; dx=dy=0; } if (!gpio_get(BUTTON_PIN)) { if(!button_pressed) { button_pressed = true; printf("button pressed\n"); buttons |= 1; dx=dy=0; mouse_moving = false; } } else { button_pressed = false; buttons = 0; adc_select_input(ADC_X_NUM); adc_raw = adc_read(); if(abs(adc_raw-adc_x_center) > 10) { adc_x=adc_raw; dx = (adc_raw - ADC_RANGE/2)/STEP; mouse_moving=true; } adc_select_input(ADC_Y_NUM); adc_raw = adc_read(); if(abs(adc_raw-adc_y_center) > 10) { adc_y=adc_raw; dy = (adc_raw - ADC_RANGE/2)/STEP; mouse_moving=true; } } if (dx || dy || buttons) { hid_device_request_can_send_now_event(hid_cid); } sleep_ms(10); } return 0; }
- CMakeLists.txt
# Generated Cmake Pico project file cmake_minimum_required(VERSION 3.13) set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 17) # Initialise pico_sdk from installed location # (note this can come from environment, CMake cache etc) set(PICO_SDK_PATH "/home/duser/pico/pico-sdk") set(PICO_BOARD pico_w CACHE STRING "Board type") # Pull in Raspberry Pi Pico SDK (must be before project) include(pico_sdk_import.cmake) if (PICO_SDK_VERSION_STRING VERSION_LESS "1.4.0") message(FATAL_ERROR "Raspberry Pi Pico SDK version 1.4.0 (or later) required. Your version is ${PICO_SDK_VERSION_STRING}") endif() project(picow_bt_mouse_joystick C CXX ASM) # Initialise the Raspberry Pi Pico SDK pico_sdk_init() # Add executable. Default name is the project name, version 0.1 add_executable(picow_bt_mouse_joystick picow_bt_mouse_joystick.c ) pico_set_program_name(picow_bt_mouse_joystick "picow_bt_mouse_joystick") pico_set_program_version(picow_bt_mouse_joystick "0.1") pico_enable_stdio_uart(picow_bt_mouse_joystick 1) pico_enable_stdio_usb(picow_bt_mouse_joystick 0) # Add the standard library to the build target_link_libraries(picow_bt_mouse_joystick pico_stdlib hardware_adc pico_util pico_cyw43_arch_none pico_btstack_cyw43 pico_btstack_classic) # Add the standard include files to the build target_include_directories(picow_bt_mouse_joystick PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/.. # for our common lwipopts or any other standard includes, if required ) pico_add_extra_outputs(picow_bt_mouse_joystick)
沒有留言:
張貼留言