I want to have a 2 two way (in and out) HID communication between a leonardo and an Android tablet (acting as a host). On the leonardo, I use Nicohood HID project
I have successfully managed to make the code work on Linux, Windows and MacOs, so it is possible.
Using a pure android implementation, I can only receive data from the leonardo but not send to it...
From what I have seen in the descriptor, the data are sent from the device (IN direction) using a specific endpoint. For the other way (OUT, to the device), we must use the control endpoint.
Nevertheless, it doesn't work on android. Here is the code I used :
UsbDeviceConnection mUsbConnection = mUsbManager.openDevice(myDevice);
byte data[] = {7, 11, 13, 17};
int resOut = mUsbConnection.controlTransfer(0x21, 9, 200, 2, data, data.length, 50);
// => resOut value is always -1 (didn't succeed to communicate)
For the parameters, I used the answers to this question: Using Android to Communicate with a USB HID Device and looked at libusb / nicohood hid communication examples on linux...
Out of luck, I tried to change the value from "200" to "0" or the index from 0 to 1 or 2, but I don't really know what they mean, and it didn't really help...
How can I send data to the device using the control endpoint with android ?
PS : I can read HID messages from the device, so it is not a permission issue.
Related
I'm developing an app for a custom peice of bluetooth hardware.
The spec for the device has a number of commands which can be sent to the device, via a specific Bluetooth Characteristic.
we are currently using this version of Flutter Blue; flutter_blue:^0.7.2
So far we have it discovering the device, connecting, and discovering the correct services and characteristics.
We also have it sending commands and receving the expected responses.
This works by listing on the correct chartacteristic like so;
await notify.setNotifyValue(true);
notify.value.listen((event) {
_handleEvent(event);
});
and then sending the commnads like so;
await recv.write(command, withoutResponse: true);
(where the command is a List representing the payload bytes).
The problem comes in where a response includes more than one packet.
In this case the inital packet is received but the following expected packets do not arrive.
On ios it's working slightly better in that the inital packet is 4 times the size of the Android response and includes the expected data, BUT if the data is too big it's not included.
I've attempted to modify the MTU but this dosen't seem to have any effect on the issue.
Any help would be greatly appeciated.
In this case the issue was totally releated to the MTU setting.
I was under the impression that if you requested to set it too high it would automatically go to it's highest possible value. But looks like that is not the case.
If you are seeing a similar issue try setting the MTU to 251
Long Description:
I have a DJI Osmo Mobile 3 gimbal with Bluetooth 5.0, which supports ActiveTrack 3.0 technology. It connects to your phone via Bluetooth and using the DJI Mimo app you can select an object and track it.
I want to implement this technique in Python using OpenCV.
As I understood, the phone calculates position of the object using computer vision and then sends the coordinates via Bluetooth to the gimbal, which then follows them. I connected to the gimbal with NRF Connect app for android and looked for its services and characteristics, and this is what I found:
Services
Some unknown information getting sent
UPD: looks like the 4 bytes after 57 on the picture mean the joystick values. Fisrt 2 are responsible for left-right tilt, the other ones indicate up-down state. Looks like all of them can be max. 256, but I don't understand, why do they need 2 bytes for each action?
First 2 Bytes:
d2, 03 (210, 3) - full right
c2, fb (194 251) - full left
Last 2 Bytes:
5a, 04 (90, 4) - full up
a6, fc (166, 252) - full down
HID Control, which doesn't return any information
The characteristic with UUID
0xFFF5
Looks like what I need, but now I need to find out, in which format the coordinates are getting sent. For this purpose I want do simulate same BLE services as on the gimbal and let the phone think it is a real one. After the connection it should send data to some of the characteristics. So now the main question.
Main question:
How to emulate BLE Services and their Characteristics using Android, RPI, ESP32 or whatever to get data being sent to those characteristics? Is there any app, library or piece of code for such purpose?
I've seen dongles like CC2045, which are designed to work on 2.4GHz frequencies and sniff BLE Traffic, but it will take for a long time for them to arrive to me. Also nRF52840 based donglas are not an option right now. So I want to implement it using things I have. Is it possible? Thanks!
I'm having a project in android that need to print RAW text (to support ESC/P command) using UsbManager class. I did it using bulkTransfer, and the code looks like this. And now I should give an option to cancel the job. How can I do it?
I've tried to search and somehow I couldn't find it anywhere. And I'm new to android too. Thanks.
Edit:
The printer I use is Tally T5040 and Epson PLQ-30.
What I've tried is clear printer buffer by sending 0x18 (CANCEL DATA) command. But still no luck.
Edit 2:
Finally I was able to soft reset the printer (clearing all buffer) by using controlTransfer. The full command is controlTransfer(0x21, 2, 0, 0, null, 0, 0). I got the references from this site. But the problem right now is the reset command only work on Epson PLQ-30.
According to Universal Serial Bus Device Class Definition for Printing Devices, there is a Class-Specific Request called SOFT_RESET:
This class-specific request flushes all buffers and resets the Bulk OUT and Bulk IN pipes to their default states. Thisrequest clears all stall conditions. This reset does NOT change the USB addressing or USB configuration.
So you just need to send SOFT_RESET request using controlTransfer, the code is (Kotlin):
controlTransfer(0x21, 2, 0, 0, null, 0, 0)
The reason why my other printer (Tally T5040) didn't work was because the firmware didn't support SOFT_RESET request. I already contact them and got the update for the firmware to support SOFT_RESET.
In case anyone looking for references about how to print in Android using USB (including soft reset, checking paper status), you can check my project here.
I am new to android studios and I have the task to develop an app which transfers data from an app (Acceleration sensor data - i have created this app already which shows the data) to matlab (on the pc).
I don't really know how I should do this. I've experimented a bit with bluetooth apps, but I don't have a clue how to connect to Matlab.
I would be greatful for your help.
Thanks in advance,
Annika
Unfortunately I can not speak to the android side of things, but MatLab can connect to generic devices with the UART interface, which is fairly low level.
The process with some microprocessors that I am using is to connect the device to the PC, and then note the Outgoing com port.
(In windows 10, these can be found in Bluetooth settings -> More Bluetooth options)
Then you can use
s = serial('COM<what you found in settings>');
s.Baudrate=115200;
s.InputBufferSize = 100;
fopen(s{i});
serials = instrfindall;
to open an connection. The critical command is serial, the other parameters depend on your device/ configuration. Sometimes there can be issues, in which case one options is to build a loop that tries again until it works.
You then collect the data sent via UART via
flushinput(serials);
temp = fscanf(serials,'%s');
and then split the string. If data is sent continuously, you wrap this into a while loop.
After you are done, you can clean up via
fclose(s{i});
delete(instrfind)
instrreset
It should be noted, that establishing a connection takes longer, the more enabled COM ports there are. So it might be worth disabling all those you don't need.
For more specific things matlab can do, check out What Is the MATLAB Serial Port Interface
I am trying to send some data from one Android phone(Nexus 5), which is working as Usb Host, to Android tablet(Samsung Tab 4).
I am using bulkTransfer() method to transfer data from Nexus 5, which is returning the length of data that has been transferred successfully.
My question is How can I verify on the other end (at Samsung Tab), that yes I am getting the data that I had transferred from Nexus 5 ?
Here is some code snippet of transferring data
usbDeviceConnection = manager.openDevice(device);
boolean flag = usbDeviceConnection.claimInterface(usbInterface, true);
String text = textValue.getText().toString();
byteArray = text.getBytes();
// data transfer
int a = usbDeviceConnection.bulkTransfer(endpointOut, byteArray, byteArray.length, 0);
if(a>0){
textInfo.setText("Data has been transferred successfully..."
+"\n"+"Length of data: "+a
);
Please help me to do this task...!
After digging the Usb Host API I have found something that the other end (Samsung Tab) can work in Accessory mode and we can access the Usb Host(Nexus 5) by using the "android.hardware.usb.accessory" library.
Since the android phone who can support the Usb Host feature for example like Nexus 5 can access the device connected to it using "android.hardware.usb.host" library.
The other one for example Samsung Tab(It must support AOAP Protocol ) who does not support the Usb Host feature will access the device connected to it using "android.hardware.usb.accessory" library.
To understand The Usb Host feature you can open the link
http://developer.android.com/guide/topics/connectivity/usb/host.html
To understand The Usb Accessory feature you can open the link
http://developer.android.com/guide/topics/connectivity/usb/accessory.html