Android USB Host and Arduino Yun

Hello everyone,

I’m getting started with my first ‘real’ project with arduino Yun.
I’m trying to establish communication between Android Phone and the arduino yun via serial connection.

one of the project requirements is that the phone is powering the arduino unit therefore my configuration is as follow:
phone → OTG cable → micro usb cable → arduino yun

right now i’m looking for a basic example to see how the communication is made between android and yun. and also to examine the code for both android side and arduino yun side.

my search led me to 2 projects i found on the net:

http://android.serverbox.ch/?p=549
https://github.com/mik3y/usb-serial-for-android

on both i could compile and run the android side app (after changing a few things like VID/PID)
but i didn’t manage to work with the arduino’s side examples.
the reason for that i think is because those examples are made for general arduino but are not Compatible for Yun (also in the first link i didn’t understand what to do with this led_pwm.c)

from what i could understand from reading the yun manuals is that the serial connection is “controlled”
by the linux side and not from the micro-controller like other arduinos.

which make this code (found in the second link) unusable for yun

static int counter = 0;
void setup() {
Serial.begin(115200);
}
void loop() {
Serial.print("Tick #");
Serial.print(counter++, DEC);
Serial.print("\n");
if (Serial.peek() != -1) {
Serial.print("Read: ");
do {
Serial.print((char) Serial.read());
} while (Serial.peek() != -1);
Serial.print("\n");
}
delay(1000);
}

I know it is a bit of a long post but i was trying to be informative for if anyone else is going to try something similar.

anyone have suggestion on how to tweak the above code so it can work with yun?
or if there are any other good examples on this topic?

general advice on this setup? and is it the fastest and reliable way of communication between android and arduino yun?

EDIT:
in this link you will be able to find a step by step solution
https://groups.google.com/forum/#!topic/usb-serial-for-android/vlWQ7XO2JrE

Jaco1234: Hello everyone,

I'm getting started with my first 'real' project with arduino Yun. I'm trying to establish communication between Android Phone and the arduino yun via serial connection.

::::SNIP:::: 1) from what i could understand from reading the yun manuals is that the serial connection is "controlled" by the linux side and not from the micro-controller like other arduinos.

::::SNIP::::

2) anyone have suggestion on how to tweak the above code so it can work with yun? 3)or if there are any other good examples on this topic?

4) general advice on this setup? and is it the fastest and reliable way of communication between android and arduino yun?

@Jaco1234, Very Cool project. I'd be interested in the outcome. For those that do not know (like me), OTG is USB OTG.

On 1), your understanding is INCORRECT. There two (2) USB ports on the Yun.

  • A micro USB connected to the Atmel ATmega32U4 is on one side. This has two leds on the board that can be used to monitor data transfer.
  • The other a USB-A Host is connected to the Atheros AR9331. This is the wifi/linux side. I have NOT used this connector, so I can't give you more information on it.

On 2), your code looks sound. I see no issues with it.

On 3), the favorite is to try the examples in the IDE, like:

File->Examples->0.1Basic->Blink
File->Examples->Bridge->ConsolePixel

I also recommend

File->Examples->Bridge->YunSerialTerminal

After that, anything in the Playground.

As for your issue, I suspect you connect to wrong USB. Maybe? Let me know.

Jesse

NOTE: I just tried you code on my Yun. It works. Jesse

As for your issue, I suspect you connect to wrong USB. Maybe? Let me know

Using an OTG cable allow me to connect the phone micro USB to the arduino micro USB. And this configuration powers the arduino. Using USB A doesn't power it.

I added a blink on every cycle of the loop just to see that the yun is working. But how do I get indication that data is really sent over serial? Shouldn't the TX Led be blinking as well?

One more question just to see that I understand correct. the micro USB is connected to ATmega32U4 ATmega32U4. So I don't need to use bridge to get the serial connection working?

Jaco1234: ::::SNIP::::

1) Shouldn't the TX Led be blinking as well?

2) So I don't need to use bridge to get the serial connection working?

@Jaco1234, on #1, yes the TX LED should blink when it sends data.

on #2, correct the microUSB serial connects to the ATmega32U4, which controls the GPIO pins. The bridge is for communications with the ethernet, wifi, and Linux.

Sorry headache coming on.

Jesse

OK so i made a little bit of progress i ran a bunch of examples and came to the following observation the example code i have posted works but the TX LED only start to blink when i enter the serial monitor. before that there is no blinks... and after i exit the serial monitor it continue to blink.

now the thing is because i test a serial connection i can only see something on the serial monitor when it is connected to the computer (via COM).

but when it is connected to my phone i get no indication.

the resolve it i need to understand why it's only start blinking when i open the serial monitor? anyway i can now assume the issue is on the android side?

any suggestion on how to test it? or what should i look for now?

Jaco1234: the resolve it i need to understand why it's only start blinking when i open the serial monitor?

The LED is controlled by the USB serial data channel. That channel is only started once a remote device actually opens the USB serial port. When you plug it into your computer, and open the Serial Monitor, that opens the USB serial port, so it starts to actually send data, and the Tx light blinks.

When you plug it into your Android phone, I assume you are not actually opening up a serial port. If you did, it should start the Tx light blinking.

I think you will find that the code really is running, it just isn't actually sending anything until the port is opened. Once opened, it doesn't realize if it was closed, so it keeps on sending data. A simple test: you have a delay at the end of your sketch, replace it with:

digitalWrite(13, HIGH);
delay(500);
digitalWrite(13, LOW);
delay(500);

Also add a pinMode(13, OUTPUT); call in setup(). Run it again. I think you will find that the D13 led blinks even when the Tx led isn't blinking. If so, congratulations: your sketch is running, even if nothing is listening to what it say.

OK thx ShapeShifter for the explanation that made the issue clear.

so i would guess that what i need to do is match the listening port on the android app to the yun serial port... but how do i know/configure on what port does the yun establish serial communication?

is it as simple as 0 or 1? or is there is something else?

When the Yun is connected to a host computer, it will show up as a USB serial port. The name of the port will vary by operating system. I’ve never used Android, so I don’t know what it will be called. On Windows, it will show up as COM**, and Linux as /dev/tty***

I have made a little bit of progress but still not getting to the bottom of it.

I'm now able to send information from the android side to Yun (RX LED blinks when i send data from the phone). which from my understanding means the connection is well defined.

but still Yun side doesn't send any data back (just as before, script works but no data flow on TX).

I'm now confuse, how can the arduino receive data but can't send back?

if i use "if (Serial)" in the setup stage the program halts indefinitely, which by the arduino reference means no USB CDC serial connection is open.

what does this function require to return true, I mean what do i need to do to make the connection open? alternatively is it possible to force send data (don't know if option even make sense)?

Jaco1234: ::::SNIP:::: what does this function require to return true, I mean what do i need to do to make the connection open? alternatively is it possible to force send data (don't know if option even make sense)?

@Jaco1234, Since you are connecting to an Android, your problem falls outside of normal troubleshooting. Here are some tips

  • The default setting for the Serial port is 9600 bps (SEE: ${IDE_DIR}/lib/preferences.txt - relevant section listed below)
  • The code that drive the serial port is Java, but the code that drives the serial bus is C++ (SEE: ${IDE_DIR}/hardware/arduino/avr/libraries/SoftwareSerial/SoftwareSerial.cpp It is a mixture of CPP and assembly. Note, "avr" is the ATmega32U4. Giving the code a quick look, I see TX and RX delays encode in tables. (Look for: DELAY_TABLE)
From:preferences.txt
serial.port=COM1
serial.databits=8
serial.stopbits=1
serial.parity=N
serial.debug_rate=9600

If I think of anything else, I will post it. I think Angelo or ShapeShifter may have some ideas, they will chime in, if they do. Please keep us updated either way. This project looks like fun.

Jesse

thanks for the help Jesse, i really appreciate it

From:preferences.txt serial.port=COM1 serial.databits=8 serial.stopbits=1 serial.parity=N serial.debug_rate=9600

I check those parm and they match the app (baud was 115200 in the app but also in the arduino example code) so no luck there.

The code that drive the serial port is Java, but the code that drives the serial bus is C++ (SEE: ${IDE_DIR}/hardware/arduino/avr/libraries/SoftwareSerial/SoftwareSerial.cpp It is a mixture of CPP and assembly. Note, "avr" is the ATmega32U4. Giving the code a quick look, I see TX and RX delays encode in tables. (Look for: DELAY_TABLE)

I took a look and to be honest Chinese look easier then this :)

I wanna try maybe a different approach, in the beginning of this post I linked a *.c code (led_pwm.c) which was related for the first android example.

I didn't understand how to compile it to be used as the arduino sketch but maybe it hold a trick that will solve this issue.

do you know maybe how can i use this code?

Jaco1234: ::::SNIP::::

do you know maybe how can i use this code?

@Jaco1234, I looked at the code. The origins are Switzerland. There is a domain in the comments www.mikrocontroller.net

A translation (german language) does not offer many clues.

The code suggests, from the comments (remember English is not a first language for the author) and I don't have the headers, the driver has two mode. Polling and interrupt driven. From uart_init(), it appears that the driver is set to 8N1, full duplex and interrupt driven.

As such it appears that main() just pulses the LED. Also, volatile uint8_t data appears to be a flag or the data itself.

So my assessment is that code offers no clues.

So I went back to the Cpp code the Arduino. I see in the comments

// When set, _DEBUG co-opts pins 11 and 13 for debugging with an
// oscilloscope or logic analyzer.  [b]Beware: it also slightly modifies
// the bit times, so don't rely on it too much at high baud rates[/b]

Given this, my thought is make sure to run the serial port at 9600 baud/bps or wait for someone else that might have a clue or see if the author of the code has a clue.

From the source code http://arduiniana.org/ http://arduiniana.org/2011/01/newsoftserial-11-beta/

I'm up against the wall right now.

Jesse

@Jaco1234,

I made a mistake. I saide the Serial driver was here

SEE: ${IDE_DIR}/hardware/arduino/avr/libraries/SoftwareSerial/SoftwareSerial.cpp

It's here

SEE: ${IDE_DIR}/hardware/arduino/avr/cores/arduino/HardwareSerial?.cpp

There are multiple files.

Jesse

@Jaco1234,

I'm doing research on the Linux Serial ports when I find this:

Serial Console->Considerations->USB->Cellphone Data Cables

http://wiki.openwrt.org/doc/hardware/port.serial#cellphone_data_cables

Which links to this:

NSLU2-Linux->Howto AddASerialPort-> (scroll down to Using a mobile phone data cable (DB9 serial port types)) http://www.nslu2-linux.org/wiki/HowTo/AddASerialPort

There more stuff on the openwrt website. Not sure if it will help.

Jesse

Jesse, I took a look into those links but i didn't got any new ideas from it.

It's here

SEE: ${IDE_DIR}/hardware/arduino/avr/cores/arduino/HardwareSerial?.cpp

I started digging into the arduino code in hope of creating a patch in the code that can mimic what happen when i open the serial monitor. meaning creating some kind of custom code that will open the cdc usb and allow data to be send even if no one is listening.

i didn't got very far, but this is what i have tried.

in : ..\hardware\arduino\avr\cores\arduino\USBAPI.h i have added a new function to the serial class

virtual void forceOpen(void); // my test function to force open the cdc usb port

in : ..\hardware\arduino\avr\cores\arduino\CDC.cpp (which implement the serial class) i have added

// my test function
void Serial_::forceOpen(void)
{
    _usbLineInfo.lineState = 0x01;
}

so now in the arduino code this function will bypass the while condition

  Serial.forceOpen();
  while(!Serial);

but it still doesn't send data out... but i'm thinking of a solution in that line

the answer might be somewhere in this function int USB_Send(u8 ep, const void* d, int len) in : ..\hardware\arduino\avr\cores\arduino\USBCore.cpp

Hi, You can look at this app : code source app inventor + arduino , Usb Bridge for app inventor 2 android . Control arduino card with an android device and app inventor. Very easy to use.

Good luck

thanks that look great... might just be the answer to all my question. will take a look at it first thing tomorrow :)

got excited to early... it's not an open source, in fact there is no source. it does prove the concept works