Arduino + Android USB Host API = faulty packages - android

I'm trying to interact with my Arduino Uno from my Android tablet running 4.0.3 and got everything working using the Android USB Host API, which means I can send data over USB to the board and read it there via Serial.read() successfully.
Now I'm trying to implement a feedback functionality, which means the other way around, sending from the Arduino Uno and reading on the tablet. This works also quite well using Serial.write(), but I got a little problem: Sometimes, there are no bytes transferred and some other times, only some of them, so the content I'm sending is cut in half. How do I fix this?
I'm asssuming the Serial port has some issues sending all of the data. Should I perhaps change the baud-rate which is currently at 9600?
Here's the code on the Android side:
byte[]data = new byte[1024]; //Bigger size just to make sure...
int returnLen = conn.bulkTransfer(epIN,data,data.length,500); //epIN is the`
On the Arduino side a simple
Serial.write(5);
is used.

The read() behavior you are seeing is working as intended: sometimes, fewer bytes will be available than the amount you want. It's very similar to standard POSIX read() syscall behavior:
"It is not an error if this number is smaller than the number of bytes requested; this may happen for example because fewer bytes are actually available right now [..]"
Your application needs to handle this possibility. A common technique is to keep track of how many bytes you have read, and perform successive read() calls, accumulating bytes until you have the number desired.
Finally, consider using usb-serial-for-android, an open source library implementing FTDI and CDC (Arduino) USB drivers. Though it doesn't specifically deal with this application-level issue, it may save you trouble elsewhere, and has an active mailing list.

Related

How to increase the speed of transfer of data from android to arduino in bluetooth?

I'm trying to use an android app to do the processing of a path finding algorithm for a robot using Bluetooth. But currently, it takes 1 or 2 seconds for the transfer to complete, so that there is an output in the Arduino. Is there a way to minimise this to make the transfer-output instant?
This kind of delay is causing problems such as stopping instantly when an obstacle is detected. Is there any better way of doing this?
Thanks in advance!
You didn't mention which device you are using. I assume that you connected the Bluetooth chip set to UART port(As in arduino Uno), In that case the slowest part in whole communication is the serial interface between Arduino and Bluetooth chip set. Check what baud rate you are using and can it increase further. I think default will be 9600 which is only around 960 bytes per second. Set the maximum baud rate supported by your device and the Bluetooth chip.
Simple answer: You can't, bluetooth is laggy like that. If you instead had your path finding algorithm on the arduino board itself, you could avoid the issue. You can also try adding a delay to your arduino code, because it is possible that the arduino is sending messages repeatedly without taking into account the lag that bluetooth has.
Two simple solutions worked for me:-
Increase the delay to 50 - 100 milliseconds.
Add this after the Serial.begin(9600) in setup();
Serial.setTimeout(50);
Step two is the most important. It worked for me only after I added the above code. This is not mentioned very often in many other forums that I have looked when I had the exact same problem.

Measuring packet loss through Android N

I am working on a project that is meant for testing network diagnostics. The section I'm working on now involves testing TCP and UDP connections. One of the points of measurement is packet loss for both TCP and UDP.
In the past I used: '/statistics/rx_dropped' (I'm leaving off the beginning portion of that file path), suffice to say it points to the number of packets dropped in total on a specified network interface.
However, in Android N this file requires root to read and I can't assume that the phone this app will be on is rooted.
Does anyone have a decent way of measuring packet loss on the client side for at least TCP that doesn't require rooting?
I am mostly aware of networking jargon so don't be shy, the reason I ask is because the way I measure has to be fairly elegant (either using some existing java/android library or finding a legal way of reading packet loss from the device).

Android source and AudioRecord multi-utilisation

I'm currently building an android custom rom, which will be only controlled by voice:
So I came across this portion of code in the android source :
// refuse 2 active AudioRecord clients at the same time except if the active input
// uses AUDIO_SOURCE_HOTWORD in which case it is closed.
In https://android.googlesource.com/platform/hardware/libhardware_legacy/+/master/audio/AudioPolicyManagerBase.cpp line 997
I would like to know for which purpose it's done? hardware limitation?
In a playback scenario, multiple concurrent clients writing to the same output are handled by means of mixing, which is implemented in libaudioflinger.
To handle multiple concurrent clients in a recording scenario you'd need some sort of stream splitter that takes care of consuming audio buffers coming from the driver and feeding them to all the clients, and possibly perform resampling, mono/stereo conversion, etc. A vanilla Android implementation simply doesn't have a stream splitter (not the last time I looked anyway). When I worked at Sony we used a proprietary stream splitter on a few phones (the Xperia P, U, and Solo, IIRC), which allowed us to support multiple recording clients. So it is possible to do, but it's not trivial.
Its anyone's guess why that became the policy. Maybe it underlies a decision that the API would limit or pre-empt additional clients owning the mic's output.
Does it really matter? If you want to spawn threads and provide each a split copy of the Array of raw PCM bytes in the mic's output buffer, you are free to do that.
Look at "audiotrack" here for some background on a players use of a buffer.
then
implement one of the callback's here in your recorder's implementation , adding a split function on the buffers bytes. Then do whatever you want in your respective threads.

Capturing a stream of vector data and visualizing it on the Nexus tablet

Desperately need help!
The problem is as follows: there is a bunch of medical diagnostic devices packed in a box. They are all fed from the same battery, and their data is supposed to be visualized on a Nexus tablet, also enclosed in the box. Only one device at a time is connected to a tablet. Connection is via USB port, processing off-line only. Data is streaming in real-time (some devices may have recording capability, some don't) and needs to be visualized in real-time also.
The devices are "dumb" and there are no SDKs. Seemingly, the devices were never intended to be connected to any external visualizer or any other device. All we have to work with is the raw stream of data - the output of a device is not even a file but a stream of 256 vectors. This stream needs to be captured, written to a predefined buffer/series of buffers (how to determine size of such buffer to be generic enough to satisfy every device in the box?), and then translated into some format that Android tablet can visualize.
Is my understanding of the required architecture correct? What language shall this software be written in? can it be done in something truly cross-platform like Python? Does there exist any open-source functionality for capturing a stream (if so, please, kindly recommend)? Is it possible to have such a software generic so that changing a device/tablet/OS could be accommodated without an excruciating pain?

Sending large files with Android Beam (or S-Beam)

I've been tasked with adding support to an app for beaming large data files (tens of megabytes) from device to device via 'NFC' on Android.
I'm aware that genuine NFC on Android is painfully slow, but I know that ICS has support for doing hand-off of the bulk data transfer to Bluetooth; and Samsung have a proprietary mechanism for doing the same via Wifi Direct (S-Beam). So that's the approach I'd want to take.
Unfortunately I cannot find any information on how to actually do this.
I've looked at the Android Beam documentation, and there's no mention of special mechanisms to support large bulk data; so I took the standard AndroidBeamDemo app and simply added a large byte array to the packet size, in the hope that it would all Just Work. It seems not to --- sending a 10kB message takes about five seconds, and trying to send a 1MB message just doesn't do anything at all (although it tells me the message was sent successfully).
For Samsung's S-Beam, I simply cannot find any documentation whatsoever.
Has anybody made this work, and if so, can they point me at an example?
For Android Beam, you need to provide URIs to the files with the data using setBeamPushUris() (or setBeamPushUrisCallback() if the data is not fixed).
For S-Beam, I am not aware of any API that can be used. AFAICT, S-Beam only works with the built-in apps for pictures, video and music.

Categories

Resources