Am trying to understand how the Android Open Accessory API works with the Arduino ADK board, I've been able send and receive information but I just want to know how everything works. I got to this function description:
int AndroidAccessory::read(void *buff, int len, unsigned int nakLimit) {
return usb.newInTransfer(1, in, len, (char *)buff, nakLimit);
}
From some googling I figured that NAK is some code that gets sent if something went wrong during the handshake, so is NAK limit the number of communication errors one is able to receive?
NAK is no Communication error. It simply states that the Device is not ready to send a reply or that there are no data to send at this moment. As I understand it the NAK limit in this function will just make sure that there's a defined end for the function. In case of Full Speed USB a NAK will be generated every 1ms. For more information about the NAK try this: http://www.beyondlogic.org/usbnutshell/usb3.shtml#USBPacketTypes
Related
I have started working with Nordic android SDK. And I have managed to make my sensors-devices subscribe and publish to group I have them assigned to. Problem is that my messages that I should receive in meshMessages doesn't contain enough data. From my device-sensor I have data sent in packed like code bellow.
{
uint32_t srcMac4;
uint8_t remoteTypeID;
uint8_t opCode;
uint8_t statusData[16];
} generic_onoff_status_msg_pkt_t;
I can read data in my meshMessages when I cast them to GenericOnOfStatus. Problem is that I'm receiving only 6 bytes and I should see more like 12 in one message.
How can I make my app receive more byte data in GenericOnOfStatus messages?
I have used Nordic app as guideline for me how to implement code so far. https://github.com/NordicSemiconductor/Android-nRF-Mesh-Library
I have found solution. Problem is with Nordic SDK. They have problem's with their library at the moment. When we try to set unicast address in filter (White or Black listing) somehow it doesn't recognize it as unicast address and that makes app crash. Workaround at this moment until they have it patched is to switch to dev branch of library.
I am getting crazy with a project where I need to send firmware files from an Android device to a STM32F4 chip using Bluetooth LE.
I have already implemented BLE on both ends successfully and I am working with it with several characteristics for a long period without any problem.
Now a file transfer ought to be implemented that shall be able to send files in size of about 250K. My implementation seem to work but only in one of 10 cases. It does start sending packets in chunks of 20 bytes but then it
stops communication in 90% of the test cases on an undetermined point. I need to disconnect/reset and restart to get things up again.
Characteristic for file transger on the STM32F4 are defined as:
ret = aci_gatt_add_char(fileServiceHandle,
UUID_TYPE_128, // File xfer UUID
uuid, // Char UUID
FILEIO_RECORD_LEN, // Maximum length of the characteristic value (20)
CHAR_PROP_WRITE|CHAR_PROP_WRITE_WITHOUT_RESP|CHAR_PROP_NOTIFY, // WRITE NOTIFY me
ATTR_PERMISSION_NONE, // Nothing special
GATT_NOTIFY_ATTRIBUTE_WRITE, // The application will be notified when a client writes to this attribute.
// An #ref EVT_BLUE_GATT_ATTRIBUTE_MODIFIED will be issued.
16, // Encryption key size
0, // is fixed length (1== variable size)
&fileRequestHandle); // ReturnValue als handle
In Andoid I am setting the WRITE_TYPE_NO_RESPONSE flag in the service characteristic to
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
... aServiceCharacteristic.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
Writing the packets is done in the onCharacteristicWrite call back function for a FIFO of maximum 8 packets.
Build up to 8 fragments of file data and queue it to a fifo
wrtCharacteristic.setValue(firstQueueItem);
in onCharacteristicWrite call back: if queue not empy { wrtCharacteristic.setValue(nextQueueItem); }
If the last packet is received in the STM32F4, all packets in that group are verified and an acknowledge is send back causing an event in the APP.
The event then triggers sending the next 8 packets.
This looks pretty straight forward to me and seem to work sometimes. It works always though if I am setting the number of consecutive blocks to 1. All other sizes do not complete sending the in files in almost all cases.
There is no evidence of when the transfer is broken, sometimes immediately, sometimes after sending more than 80% of the data.
I have also tried to skip writing the received data on the STM32F4 to the flash storage to avoid SPI interferences without any changes in behavior.
Is there anything that I am missing here? Where could I check for errors. Any help wouldbe very much appreciated.
For unknown reasons, this problem does occur any longer. My implementation has not changed compared to what I stated on top. I tried to request a BLE response for the last packet of each group but that does not seem to make any difference.
I thank everybody who read and commented on this entry.
I am working on a group project where we are sending serial data over Bluetooth from Arduino to Android. We are all fairly new at both Arduino and Android.
Hardware used include Arduino Uno R3 and HC-05 bluetooth module.
I am sending dummy data for a 3 axis accelerometer packet and successfully read the packet data from Android.
However, we have this blob of data (about 50+ bytes usually and has ranged up to 512 bytes) that always gets sent to the app in the beginning. Its a randomly sized chunk of bytes, which we can't interpret because it doesn't seem to match the packet format we set up for our data. We managed to avoid looking at this byte chunk by checking to see if the packet size is small enough. But this adds a lot of overhead (4 - 5 seconds), so we'd like to figure out what this blob of data is. So, does the HC-05 send some proprietary Bluetooth related data first or is there some thing wrong with my script that's causing the unexpected data to be sent?
This is the Arduino code.
#include <SoftwareSerial.h>
SoftwareSerial bluetooth(10,11);
void setup(){
bluetooth.begin(9600);
}
void loop() {
int x = random(360);
int y = random(360);
int z = random(360);
formAccelerometerPacket(x, y, z);
delay(5000); // wait 5 sec
}
void formAccelerometerPacket(int xVal, int yVal, int zVal) {
printSensorVal('A', xVal);
printSensorVal(':', yVal);
printSensorVal(':', zVal);
}
void printSensorVal(char flag, int sensorVal) {
bluetooth.print(flag);
bluetooth.print(sensorVal);
}
I've looked at it with a Bluetooth terminal app but nothing looks wrong from there. Its LogCat from the app that shows this content received from the app, but I can't interpret it as I said earlier, which is what I need to solve.
I've tried to look at other SO questions but none others could help me.
I don't have the code for the Android app as it is with another teammate, but I know that they followed the BluetoothChat example closely.
The only thought I had was that since Arduino loops the data, if the app starts after the Arduino starts, it might start reading some data part way from what was going on in the serial port before. But it doesn't explain the size difference in the blob of bytes.
Edit on 08/21/2014 at 10:33AM PST
Here is a screenshot of the LogCat. What we did was ran the Android app first and then I started the Arduino to make sure the board didn't have old data. Looking at this makes me think it might be a pairing issue as some one suggested. I am working on trying that fix.
Try Bluetooth SPP on Google Play, then connect to the HC-05. Check the output and then once you get clean data reset the arduino and see what happens. That's how I usually go about checking the output from my HC-05. And no there is nothing sent by the HC-05 when it starts up. I couldn't comment so had to post an answer, sorry.
I am not sure that is your case but may be it's usefull. When you send a data from HC-05(FC-114) to a Slave(HC-06) the first byte(or the first three/four) is sent immediatly and the rest with a delay of 5/10ms. I don't know why, but i see it using oscilloscope. If well managed, you can fix the problem when receive the packet of byte waiting for a while, otherwise, you can get crazy for understand what is happening.
I am trying to get an Android USB host program to connect to a slave which is effectively a USB-serial converter. The slave device is set up currently to return NAK when there is no data available, and I am polling the slave to see if there is any IN data by using queue() and requestWait() on the IN endpoint as part of an onAnimationUpdate listener. However the system is getting stuck in the requestWait() - presumably waiting till it gets a definitive reply to the queued request.
I would have thought that a NAK would be taken as an indication that the slave has reacted to the request and a null result or similar passed back. However, I can find no detailed documentation on this. Can anyone point me in the right direction for advice?
I have sort of resolved this issue - but not very satisfactorily.
It seems that the Android requestWait() function does not recognise a NAK response to an IN as indicating "no data is available" (I would have thought it would return a null since that what the correct result would be) but simply sits and waits until there IS some data available - locking up the system.
I have "solved" this by returning a "NULL" message from my device consisting of a 1-byte reply with ASCII NAK as the single byte. This works, as I am using ASCII for the message coding.
I need some help finding the documentation of .read(). I know this is easy, but I can't find it. I've search and searched, and this page on the android side is the closest I could find - http://developer.android.com/guide/topics/usb/accessory.html.
Here is the arduino code splice I am trying to interpret. I need to know how to modify the read() part for my needs. Thanks
AndroidAccessory acc("Manufacturer",
"Model",
"Description",
"1.0",
"hey.now.what",
"0000000012345678");
acc.read(msgIn, sizeof(msgIn), 1)
I was looking the same thing as you did. After googling around and trying it by myself, I managed to build up something like this:
Declaration:
int AndroidAccessory::read(void *buff, int len, unsigned int nakLimit);
Reads data from the Android device into the array pointed to by buff. It reads len number of bytes. Reading is stopped when len bytes is read or nakLimit number of NAKs is received from the USB controller. In case of Full Speed USB a NAK will be generated every 1ms. (according to the second source link).
The return value is the number of bytes available, not the number of bytes read. If you read less bytes than there are available, those extra bytes seem to be ignored.
In my experiments I found out that NAK interval is much smaller. With my Arduino Mega ADK, I found out that one second wait equals roughly nakLimit of 14000.
Sources:
http://developer.android.com/guide/topics/usb/adk.html (end of the page)
What is Nak Limit?