2015-01-14 2 views
2

Я пытаюсь установить связь между Arduino Mega Adk (ADK 2011) и устройством Android. Что-то идет нормально, но что-то идет совершенно неправильно. Передача данных с Android на Arduino через acc.read от Arduino side отлично работает. Но когда я пытаюсь отправить несколько байтов от Arduino на Android, произойдет что-то странное. Прежде всего здесь Arduino эскиз:Arduino Mega ADK странное поведение acc.write() (огромная задержка) Вопрос NAK кажется подтвержденным. Android генерирует NAK в результате acc.write

#include <Max3421e_constants.h> 
    #include <Max3421e.h> 
    #include <Usb.h> 
    #include <AndroidAccessory.h> 

    #define COMMAND_LED 0x2 
    #define TARGET_PIN_18 0x12 
    #define TARGET_PIN_19 0x13 
    #define V_ON 0x1 
    #define V_OFF 0x0 

    #define PIN_18 18 
    #define PIN_19 19 
    #define INPUT_PIN 30 


    AndroidAccessory acc("Google, Inc.", 
       "DemoKit", 
       "Ololo device board", 
       "1.0", 
       "http://www.android.com", 
       "0000000"); 

    byte rcvmsg[3]; 
    byte sndmsg[3]; 
    int buttonState = 0; 

    void setup(); 
    void loop(); 

    void led_setup(){ 
     pinMode(PIN_18, OUTPUT);  
     pinMode(PIN_19, OUTPUT); 
     pinMode(INPUT_PIN, INPUT); 
    } 
    void setup() 
    { 
     Serial.begin(115200); 
     Serial.print("\r\nStart"); 
     led_setup(); 
     acc.powerOn(); 
    } 
    void loop() 
    { 
     if (acc.isConnected()) { 
    buttonState = digitalRead(INPUT_PIN); 
     if (buttonState == 1){ 
     sndmsg[0] = 0x2; 
     sndmsg[1] = 0x1; 
     sndmsg[2] = 0x1; 
     int len = acc.write(sndmsg, 3); 
     digitalWrite(PIN_19, HIGH); 
     } 
     else { 
     //Nothing here for test 
     } 
    } 
    //usefull test for button 
    buttonState = digitalRead(INPUT_PIN); 
    if (buttonState == 1){ 
     digitalWrite(PIN_19, HIGH); 
     } 
     else { 
     digitalWrite(PIN_19, LOW); 
     } 
    } 

Ok. Когда выполняется acc.write(), для передачи данных на андроид требуется ~ 1 секунда. И это время не зависит от количества байтов в sndmsg. Только если я выполняю acc.write (sndmsg, 0) (отправка 0 байт) - все идет быстро. Это немного тревожно. Я попытался сменить совет на другой, но получил тот же результат. Все советы? может быть, это обычная ошибка, но в Интернете нет такой большой информации.

UPD: Написал очень простой код, который посылает только 3 байта через acc.write. здесь:

#include <Max3421e_constants.h> 
#include <Max3421e.h> 
#include <Usb.h> 
#include <AndroidAccessory.h> 

AndroidAccessory acc("Google, Inc.", 
      "DemoKit", 
      "Demokit board", 
      "1.0", 
      "http://www.android.com", 
      "0000000"); 


byte msg[3]; 
unsigned long time; 
void setup(); 
void loop(); 
void led_setup(){ 
} 
void setup() 
{ 
    Serial.begin(115200); 
    Serial.print("\r\nStart"); 
    acc.powerOn(); 
} 
void loop() 
{ 
    if (acc.isConnected()) { 
    Serial.print("\r\nis Connected"); 
    msg[0] = 0x1; 
    msg[1] = 0x1; 
    msg[2] = 0x1; 
    //Serial.print("\r\nSending"); 
    time = millis(); 
    Serial.print ("\r\nBefore write\r\n"); 
    Serial.print (time); 
    acc.write(msg, 3); 
    time = millis(); 
    Serial.print("\r\nAfter write: \r\n"); 
    Serial.print (time); 
    //delay(500); 
    } 
} 

И это выход отладки:

is Connected 
Before write 
6983 
After write: 
10958 
is Connected 
Before write 
10958 
After write: 
14491 
is Connected 

и так далее. Поэтому по некоторым причинам acc.write занимает много времени, и в приложении Android нет данных.

Новый UPD (19.01.2015):

Сегодня я провел некоторые эксперименты. Вот результаты. Во-первых, я уже посмотрел в AndroidAccessory.cpp и нашел функцию записи:

int AndroidAccessory::write(void *buff, int len) 
    { 
     usb.outTransfer(1, out, len, (char *)buff); 
     return len; 
    } 

Хорошо, тогда я заглянул в библиотеку USB хост щит и обнаружил там usb.cpp с outTransfer fucntion, который возвращает код ошибки, если ouccured и 0x00, если все в порядке. Поэтому я модифицировал функцию записи, чтобы вернуть код ошибки вместо длины, как это:

int AndroidAccessory::write(void *buff, int len) 
{ 
    byte rcode; 
    rcode = usb.outTransfer(1, out, len, (char *)buff); 
    return int(rcode); 
} 

и RECIVED «4» в качестве результата. В соответствии с MAX3421Econstants.h это код ошибки hrNAK (0x04). Любые идеи? Похоже, что аксессуар не извлекает NAK из Android, и в результате запись приводит к сбою.

Обновление ситуации: Проведено некоторое исследование. Есть акс NAK, когда аксессуар подключен. Вот свалка из USB-разъема: enter image description here

+0

Возможно, это рукопожатие isConnected, которое занимает второе место. Если подключенная сторона отключена, загорится кнопка, если она подключена. Затем перейдите в цикл обработки. Затем перейдите к кнопкам. Мой ардуино на пути из Гонконга ожидается до 9 января по 23 января. Я не могу дождаться. – danny117

+0

isConnected не занимает много времени после успешного завершения PowerOn. Если я прокомментирую строки acc.write - все идет быстро и плавно - даже чтение из андроида и действие (этот код не в этом примере, но работает). – mikebutrimov

+0

Я меняю тестовый код на очень простой и добавлю время отладки. Я буду обновлять сообщение, чтобы добавить новые данные. – mikebutrimov

ответ

0

Я нашел решение. И это очень просто - я не правильно установил связь с аксессуаром. Это не проблема Arduino. Ардуини прекрасно работает. Это как раз то, как андроид взаимодействует с аксессуаром android. Итак, результаты:

  • Когда AndroidAccessory подключен к Android и Android не установка связи с аксессуаром же, ОС Android будет посылать много USB ОПП с аксессуаром и это нормально.
  • При настройке связи с аксессуаром вы должны быть осторожны . Если вы допустили некоторые ошибки , вы можете получить такую ​​же ситуацию: возможно, можно записать на аксессуар, но аксессуар нельзя записать на андроид .
  • Если UsbManager правильно открывает аксессуар, он прекращает отправку NAK и начинает получать данные от arduino.

Это немного странно для меня, потому что это было действительно трудно нашла проблему: У меня есть приложение, написанные в соответствии с данным руководством: http://developer.android.com/guide/topics/connectivity/usb/accessory.html Но, так как я не очень хорошо знаком с андроидом, это кажется, что я сделал какую-то ошибку и получить странное поведение:

  • я был в состоянии написать Arduino
  • я был в состоянии retrive информации о Arduino, как андроид аксессуар
  • можно было попросить разрешения
  • но когда Arduino пытается записать андроид, это recievs много ОПП

Так я решил переписать программу более простым способом, только с одной функцией и пытался сделать это в правильном направлении. И после некоторой отладки он наконец начал работать, как я хочу. Так что спасибо всем, кто тратит время на это. Bonus: свалка обычного пакета, закончилась ПВЗ не НАКа enter image description here

UPD 26.01.2015: я нашел проблему, и это было в моем андроиде коды. вот объяснение:

В руководстве разработчика Android сказано, что функция, которая устанавливает связь с аксессуаром, должна запускать собственный поток, в котором хранятся все сообщения с входными и выходными потоками. Smth вот так:

private void openAccessory() { 
    Log.d(TAG, "openAccessory: " + accessory); 
    mFileDescriptor = mUsbManager.openAccessory(mAccessory); 
    if (mFileDescriptor != null) { 
     FileDescriptor fd = mFileDescriptor.getFileDescriptor(); 
     mInputStream = new FileInputStream(fd); 
     mOutputStream = new FileOutputStream(fd); 
     Thread thread = new Thread(null, this, "AccessoryThread"); 
     thread.start(); 
    } 
} 

Я действительно испортил эту штуку. Забыл создать новый поток в функции openAccessory и попытался сделать это в другом месте. И получить ад НАК. Тогда я изменил код и добавить некоторые функции отладки, как запустить(), как это:

public void run() { 
     final byte[] buffer = new byte[16384]; 
     int ret = 0; 
     int i = 0; 
     while (i<50) { 
      try { 
       ret = mInputStream.read(buffer); 
       i++; 
       Thread.sleep(500); 
      } catch (IOException e) { 
       break; 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

И пока этот метод запуска не существует (в то время как я < 50) андроид читает Arduino правильно. И когда поток заканчивается (i> 50) - Arduino начинает считывать код ошибки 4 (NAK) с Android.

Это все люди.

+1

Спасибо, что сделали исследование. – danny117

+1

Я заказал hc05. Я полагаю, что общение будет похоже. – danny117

+0

@ danny117 Думаю, да. Спасибо за ваше сотрудничество. – mikebutrimov

Смежные вопросы