petzval / btferret

Python and C Bluetooth Library
MIT License
125 stars 22 forks source link

slow HID mouse on raspbery pi zero W2 #55

Open j-lag opened 4 days ago

j-lag commented 4 days ago

Hello, I'm trying to emulate a HID mouse on raspbery pi zero W2 with a high frequency. I use the mouse.c example, add a custom block of code in the lecallback that calculate mouse displacement and feed it to the send_key function.

le_server take decisecond as timer input and i want to be awaken at 100 hertz so I change it to use milisecond directly in btlib.c --> int le_server(int(*callback)(int clientnode,int operation,int cticn),int timerms) and start it with 10 ms.

Whatever I do, I can't get it to run at higher speed than around 10 hertz... CPU is around 3% load... Profiling with valgrind was inconclusive. Is it a limitation of the bluetooth hardware speed or btferret code?

Any help would be greatly apreciated! Bye!

petzval commented 3 days ago

I assume you have the latest version 19 of btlib.c, and have changed the timms check.

  1. In le_server - this is the 10Hz setting.

    Line 3580
    readhci(LE_SERV,IN_LECMD,0,100,0);
    This waits for Bluetooth input for 100ms 
    so change to:
    readhci(LE_SERV,IN_LECMD,0,0,0);  
    Which will return immediately if there is no Bluetooth input
  2. Change the interval to the fastest possible. The connecting client normally sets the interval. If you have control of the client, get it to set the interval to 6. Check by enabling verbose print via set_print_flag(PRINT_VERBOSE) and look for the connection complete event:

    
    > Event 3E ...
       0000 04 3E 13 01 00 40 00 01 - 00 36 BA F5 32 A6 DC yy
       0010 xx 00 00 11 01 01
    The initial connection interval is xxyy - you want the fastest 0006.

Or look for a line that shows the client has changed the interval after connection: Interval changed to 0006


If this is not happening, the interval can be changed by the server callback in one of two ways. Set the interval to 6. See section 4-2-47 in the documentation

if(op == LE_CONNECT) {
set_le_interval_update(clientnode,6,6); // BUT may not work - so use _server version.... set_le_interval_server(clientnode,6,6); }


2. The Bluetooth packet transmission is deliberately slowed down because some are lost if they are sent too quickly.

Line 1375 gpar.hcidelay = 5; // 5ms delay on every send Change to gpar.hcidelay = 0;


But be aware that some packets may be lost if they are sent too fast. You will have to control the send rate.
j-lag commented 2 days ago

That is working perfectly, thank you! I don't care so much for lost packet at I have implemented an absolute positioning mouse and I don't need the button status...

Have a great day!